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:
Using the API Playground: When testing endpoints in the documentation playground, enter your API key in the format: Bearer your_api_key_here (including the word “Bearer” and a space before your key).
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 at the top of each hour (e.g., 1:00 PM, 2:00 PM)
  • Rate limit headers included in all responses
  • X-RateLimit-Reset shows exact UTC timestamp of next reset
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 new loops
  • View loops you created or are a member of
  • Update and delete loops you created (creator only)
  • Add/remove members from loops you created (creator only)
  • View loop statistics and member lists
  • Create requests in loops you created
  • View requests in loops you’re a member of
  • Cancel your own requests
  • Add feedback to completed requests you created
  • Access request history and response data

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": "Missing Authorization header"
}
Solutions:
  • Include the Authorization header in your request
  • Use the correct format: Authorization: Bearer your_api_key_here
{
  "error": true,
  "msg": "Invalid Authorization header format. Use 'Bearer <api_key>'"
}
Solutions:
  • Ensure header starts with “Bearer ” (with a space after it)
  • Check for typos in the header format
  • Don’t use quotes around the API key value
{
  "error": true,
  "msg": "Invalid API key"
}
Solutions:
  • Verify API key is correct (no typos or extra spaces)
  • Check if key has been revoked or deleted
  • Regenerate a new API key if needed
  • Ensure you’re not using an old/expired key
{
  "error": true,
  "msg": "API key is inactive"
}
Solutions:
  • Check API key status in your dashboard
  • Reactivate the key if it was disabled
  • Generate a new API key if needed
{
  "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": "[email protected]",
    "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 API key"
}
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