Skip to main content

Error Response Format

All API errors follow a consistent JSON structure:
{
  "detail": "Error message describing what went wrong"
}
For some errors, additional context is provided:
{
  "detail": {
    "status": "shutting_down",
    "timestamp": "2026-03-02T10:30:00.000Z",
    "instance_id": "i-abc123xyz"
  }
}

HTTP Status Codes

The Kortix API uses standard HTTP status codes to indicate success or failure.

2xx Success

200 OK
success
Request succeeded
201 Created
success
Resource created successfully

4xx Client Errors

400 Bad Request
error
Invalid request format or parameters
401 Unauthorized
error
Missing or invalid authentication credentials
403 Forbidden
error
Authenticated but lacking required permissions
404 Not Found
error
Requested resource does not exist
429 Too Many Requests
error
Rate limit exceeded (currently 25 concurrent IPs per instance)

5xx Server Errors

500 Internal Server Error
error
Unexpected server error occurred
503 Service Unavailable
error
Service temporarily unavailable (maintenance, shutdown, or overload)

Authentication Errors

401 Unauthorized

Returned when authentication credentials are missing, invalid, or expired.
{
  "detail": "No valid authentication credentials found"
}
Source: core/utils/auth_utils.py:136-492

Common Causes

  1. No Authentication Header: Missing both X-API-Key and Authorization headers
  2. Wrong API Key Format: API key not in pk_xxx:sk_xxx format
  3. Invalid Credentials: Wrong API key or JWT token
  4. Expired Token: JWT token past its exp timestamp
  5. Token Forgery: Signature verification failed (possible attack)

Resolution

curl https://api.kortix.com/v1/agents \
  -H "X-API-Key: pk_abc123:sk_xyz789"

403 Forbidden

Returned when credentials are valid but lack required permissions.
{
  "detail": "Not authorized to access this thread"
}
Source: core/utils/auth_utils.py:143-146, 651-670, 963

Common Causes

  1. Wrong Account: Resource belongs to a different account
  2. Team Access: Not a member of the resource’s team
  3. Public vs Private: Attempting write access on read-only public resource
  4. Admin Only: Endpoint requires admin privileges

404 Not Found

Returned when a resource doesn’t exist or user lacks access to view it.
{
  "detail": "Worker run not found"
}
Source: core/utils/auth_utils.py:319, 636, 895
For security, 404 responses don’t reveal whether the resource exists but user lacks access, or doesn’t exist at all.

Server Configuration Errors

500 Internal Server Error

Returned when server configuration is incorrect or an unexpected error occurs.
{
  "detail": "Server authentication configuration error"
}
Source: core/utils/auth_utils.py:130-132, 222-225, 288-291, 680-684

503 Service Unavailable

Returned when the service is temporarily unavailable.
{
  "detail": {
    "status": "shutting_down",
    "timestamp": "2026-03-02T10:30:00.000Z",
    "instance_id": "i-abc123xyz"
  }
}
Source: api.py:450-459, core/utils/auth_utils.py:548-549, 675-679

Common Causes

  1. Deployment: Kubernetes rolling update in progress
  2. Maintenance: Scheduled maintenance window
  3. Database Issues: Connection pool exhausted or shutdown
  4. Redis Issues: Cache unavailable (degraded mode)

Retry Strategy

For 503 errors, implement exponential backoff:
import time
import requests

def retry_request(url, max_retries=3, backoff=2):
    for attempt in range(max_retries):
        response = requests.get(url)
        if response.status_code == 503:
            wait_time = backoff ** attempt
            time.sleep(wait_time)
            continue
        return response
    raise Exception("Max retries exceeded")

API-Specific Errors

API Key Errors

{
  "detail": "Invalid API key format. Expected format: pk_xxx:sk_xxx"
}
Source: core/services/api_keys.py:335-456
API key validation errors return generic messages to prevent enumeration attacks. Check server logs for detailed error information.

JWT Token Errors

{
  "detail": "No valid authentication credentials found"
}
Source: core/utils/auth_utils.py:151-266

Thread Access Errors

{
  "detail": "Thread not found"
}
Source: core/utils/auth_utils.py:591-684

Sandbox Access Errors

{
  "detail": "Sandbox not found - no resource exists for this sandbox"
}
Source: core/utils/auth_utils.py:845-1112

Validation Errors

400 Bad Request

Returned when request data is malformed or violates validation rules.
{
  "detail": [
    {
      "loc": ["body", "title"],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}
FastAPI automatically validates Pydantic models and returns detailed error information.

Debugging Errors

Enable Detailed Logging

In development, set log level to DEBUG:
export LOG_LEVEL=DEBUG

Health Check Endpoints

Use health endpoints to diagnose issues:
curl https://api.kortix.com/v1/health
Source: api.py:444-546

Debug Response Example

{
  "instance_id": "i-abc123xyz",
  "active_runs_on_instance": 5,
  "is_shutting_down": false,
  "timestamp": "2026-03-02T10:30:00.000Z"
}
Source: api.py:498-508

Redis Health Response

{
  "status": "healthy",
  "latency_ms": 1.23,
  "pool": {
    "size": 10,
    "in_use": 3
  },
  "timeouts": {
    "default": 5000,
    "streaming": 30000
  },
  "instance_id": "i-abc123xyz",
  "timestamp": "2026-03-02T10:30:00.000Z"
}
Source: api.py:510-545

Common Debug Scenarios

  1. Check API key format: pk_xxx:sk_xxx
  2. Verify key hasn’t expired or been revoked
  3. Confirm JWT token hasn’t expired
  4. Check JWT algorithm (ES256 or HS256)
  5. Ensure SUPABASE_JWT_SECRET is configured (HS256)
  6. Verify JWKS endpoint is reachable (ES256)
  1. Verify resource belongs to your account
  2. Check if you’re a team member
  3. Confirm resource isn’t private
  4. Check if write access is required
  5. Verify admin key for admin endpoints
  1. Confirm resource ID is correct
  2. Check if resource was deleted
  3. Verify you have access (404 may hide 403)
  4. Ensure correct account/project scope
  1. Check health endpoints
  2. Verify database connectivity
  3. Check Redis status
  4. Look for deployment in progress
  5. Review server logs (if accessible)

Error Handling Best Practices

1

Check Status Code

Always check the HTTP status code first to categorize the error
2

Parse Error Detail

Extract the detail field from the response body
3

Implement Retry Logic

For 5xx errors, retry with exponential backoff
4

Log for Debugging

Log all errors with request context for troubleshooting
5

User-Friendly Messages

Convert technical errors to user-friendly messages in your UI

Example Error Handler

import requests
import time

def handle_api_error(response):
    """Handle API errors with proper retry logic"""
    
    if response.status_code == 401:
        # Authentication error - refresh token or re-authenticate
        raise AuthenticationError("Please log in again")
    
    elif response.status_code == 403:
        # Permission error - show access denied message
        raise PermissionError("You don't have access to this resource")
    
    elif response.status_code == 404:
        # Not found - resource may not exist or no access
        raise NotFoundError("Resource not found")
    
    elif response.status_code == 429:
        # Rate limit - wait and retry
        retry_after = int(response.headers.get('Retry-After', 60))
        time.sleep(retry_after)
        # Retry request...
    
    elif response.status_code == 503:
        # Service unavailable - retry with backoff
        for attempt in range(3):
            time.sleep(2 ** attempt)
            # Retry request...
    
    elif response.status_code >= 500:
        # Server error - log and show generic message
        error_detail = response.json().get('detail', 'Unknown error')
        logger.error(f"Server error: {error_detail}")
        raise ServerError("Something went wrong. Please try again later.")

Next Steps

Authentication

Learn about authentication methods

API Introduction

Return to API overview

Build docs developers (and LLMs) love