Skip to main content

Authentication

HITL.sh uses API key authentication for secure access to the API. All requests must include your API key in the Authorization header using the Bearer token format.

API Key Authentication

API keys are designed for server-to-server communication and automated workflows. They provide access to the HITL.sh API at https://api.hitl.sh/v1.

Getting Your API Key

  1. Log in to your HITL.sh dashboard
  2. Navigate to Settings → API Keys
  3. Click “Create New API Key”
  4. Copy the generated key (shown only once)
  5. Store securely in your environment variables

Using API Keys

Include your API key in the Authorization header with the Bearer prefix:
curl -H "Authorization: Bearer your_api_key_here" \
     -H "Content-Type: application/json" \
     https://api.hitl.sh/v1/api/loops
import requests

headers = {
    'Authorization': 'Bearer your_api_key_here',
    'Content-Type': 'application/json'
}

response = requests.get('https://api.hitl.sh/v1/api/loops', headers=headers)

API Key Rate Limits

Each API key has the following limits:

Rate Limits

  • 100 requests per hour per API key
  • Resets every hour from first request
  • Rate limit headers included in all responses
Rate limit headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 85
X-RateLimit-Reset: 1642237200

API Key Permissions

API keys have specific permissions based on your account:
  • Create, read, update, and delete loops
  • Manage loop members (add/remove)
  • View loop statistics and analytics
  • Create requests in loops you own
  • View and cancel your requests
  • Add feedback to completed requests
  • Access request history and analytics
  • Set up webhook endpoints
  • Configure webhook events
  • View webhook delivery logs

Security Best Practices

API Key Security

1

Environment Variables

Store API keys in environment variables, never in code:
export HITL_API_KEY="your_api_key_here"
import os
api_key = os.environ.get('HITL_API_KEY')
2

Key Rotation

Rotate API keys regularly:
  • Set up automatic rotation (recommended: every 90 days)
  • Have a backup key ready before rotating
  • Update all systems using the old key
3

Least Privilege

Use separate API keys for different environments:
  • Development keys with limited permissions
  • Production keys with full access
  • Testing keys for CI/CD pipelines
4

Monitor Usage

Track API key usage in your dashboard:
  • Monitor request patterns for anomalies
  • Set up alerts for unusual activity
  • Review access logs regularly

Secure Headers

Always use HTTPS and proper security headers:
import requests

headers = {
    'Authorization': 'Bearer your_api_key_here',
    'Content-Type': 'application/json',
    'User-Agent': 'YourApp/1.0.0',
    'Accept': 'application/json'
}

# Always use HTTPS
response = requests.get('https://api.hitl.sh/v1/api/loops', headers=headers)

Error Handling

Authentication Errors

{
  "error": true,
  "msg": "Invalid authorization token"
}
Solutions:
  • Verify API key is correct
  • Check if key has been revoked
  • Ensure proper Authorization header format with “Bearer ” prefix
  • Verify you’re not including extra spaces or characters
{
  "error": true,
  "msg": "Missing or invalid authorization header"
}
Solutions:
  • Include the Authorization header in your request
  • Use the correct format: Authorization: Bearer your_api_key_here
  • Check header name capitalization (case-sensitive)
{
  "error": true,
  "msg": "Access denied to this resource"
}
Solutions:
  • Check API key permissions
  • Verify resource ownership
  • Contact support for permission updates
{
  "error": true,
  "msg": "API rate limit exceeded",
  "data": {
    "usage_count": 100,
    "usage_limit": 100,
    "remaining": 0
  }
}
Solutions:
  • Wait for rate limit reset
  • Implement exponential backoff
  • Upgrade to higher tier if needed

Retry Logic

Implement robust retry logic for authentication failures:
import time
import requests
from functools import wraps

def retry_auth(max_retries=3):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_retries):
                try:
                    response = func(*args, **kwargs)
                    if response.status_code == 401:
                        # Log the authentication failure
                        print(f"Authentication failed on attempt {attempt + 1}")
                        if attempt < max_retries - 1:
                            # Wait before retrying (maybe refresh API key)
                            time.sleep(2 ** attempt)
                            continue
                    return response
                except Exception as e:
                    if attempt == max_retries - 1:
                        raise e
                    time.sleep(2 ** attempt)  # Exponential backoff
            return None
        return wrapper
    return decorator

@retry_auth()
def make_api_request(url, headers):
    return requests.get(url, headers=headers)

Testing Authentication

API Key Testing

Use the dedicated test endpoint to verify your API key:
# Test API key validity and get account info
curl -H "Authorization: Bearer your_api_key_here" \
     https://api.hitl.sh/v1/test

# Expected response for valid key:
{
  "error": false,
  "msg": "API key is valid",
  "data": {
    "api_key_id": "65f1234567890abcdef12349",
    "user_id": "65f1234567890abcdef12346", 
    "email": "user@example.com",
    "account_status": "active",
    "rate_limit": {
      "limit": 100,
      "remaining": 95,
      "reset_at": "2024-03-15T15:00:00Z"
    },
    "permissions": ["loops:read", "loops:write", "requests:read", "requests:write"]
  }
}

# Expected response for invalid key:
{
  "error": true,
  "msg": "Invalid authorization token"
}
The /test endpoint provides detailed information about your API key, including rate limits and permissions. Use this for debugging and monitoring.

Debug Authentication Issues

Use verbose curl to debug authentication problems:
# Verbose request to see headers and response
curl -v -H "Authorization: Bearer your_api_key_here" \
     -H "Content-Type: application/json" \
     https://api.hitl.sh/v1/api/loops

# Check if your header is being sent correctly
curl -H "Authorization: Bearer your_api_key_here" \
     -H "Content-Type: application/json" \
     -w "HTTP Status: %{http_code}\n" \
     https://api.hitl.sh/v1/api/loops

Environment-Specific Testing

Test across different environments:
import os
import requests

# Load environment-specific API key
def get_api_key():
    env = os.environ.get('ENVIRONMENT', 'development')
    key_mapping = {
        'development': os.environ.get('HITL_DEV_API_KEY'),
        'staging': os.environ.get('HITL_STAGING_API_KEY'),
        'production': os.environ.get('HITL_PROD_API_KEY')
    }
    return key_mapping.get(env)

def test_authentication():
    api_key = get_api_key()
    if not api_key:
        raise ValueError("API key not found for current environment")
    
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    
    response = requests.get('https://api.hitl.sh/v1/api/loops', headers=headers)
    
    if response.status_code == 200:
        print("✅ Authentication successful")
        return True
    else:
        print(f"❌ Authentication failed: {response.json()}")
        return False

# Test authentication
test_authentication()

Next Steps

I