Skip to main content

Error Format

{
  "type": "about:blank",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid or expired token."
}
FieldDescription
typeError type URI
titleShort error name
statusHTTP status code
detailHuman-readable explanation

HTTP Status Codes

CodeTitleRetryableDescription
400Bad RequestNoInvalid request format
401UnauthorizedNoInvalid or missing token
402Payment RequiredNoInsufficient credits
403ForbiddenNoValid token, insufficient permissions
404Not FoundNoResource doesn’t exist
409ConflictNoResource already exists
422Unprocessable EntityNoValidation failed
429Too Many RequestsYesRate limit exceeded
500Internal Server ErrorYesServer error

Common Errors

401 - Invalid Token

{
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid or expired token."
}
Fix: Refresh your M2M token or verify the JWT session is valid.

403 - Missing Scope

{
  "title": "Forbidden",
  "status": 403,
  "detail": "Missing required scope: chat:invoke"
}
Fix: Request credentials with the required scope.

429 - Rate Limited

{
  "title": "Too Many Requests",
  "status": 429,
  "detail": "Rate limit exceeded. Retry after 60 seconds."
}
Headers:
Retry-After: 60
X-RateLimit-Remaining: 0
Fix: Wait for Retry-After seconds.

402 - Insufficient Credits

{
  "title": "Insufficient Credits",
  "status": 402,
  "detail": "Insufficient credits. Required: 75 credits. Available: 50 credits."
}
Fix: Purchase credits at dashboard.cuadra.ai or wait for monthly reset.

Rate Limits

ScopeLimit
Per organization300 requests/minute
Per user60 requests/minute

Retry Logic

Implement exponential backoff for 429 and 5xx errors:
import httpx
import time
import random

def request_with_retry(url, headers, data, max_retries=3):
    for attempt in range(max_retries):
        response = httpx.post(url, headers=headers, json=data)
        
        if response.status_code == 429:
            retry_after = int(response.headers.get('Retry-After', 60))
            time.sleep(retry_after + random.uniform(0, 1))
            continue
        
        if response.status_code >= 500:
            time.sleep((2 ** attempt) + random.uniform(0, 1))
            continue
        
        return response
    
    raise Exception("Max retries exceeded")

Best Practices

  1. Check status before parsing — Don’t assume success
  2. Implement retries — For 429 and 5xx errors
  3. Log error details — Include detail message for debugging
  4. Show user-friendly messages — Don’t expose raw errors to users
  5. Monitor error rates — Alert on spikes

FAQ

What format do Cuadra AI errors use?

All errors follow RFC 7807 Problem Details format with type, title, status, and detail fields.

How should I handle rate limits (429)?

Implement exponential backoff. Wait the time specified in Retry-After header, then retry. See retry logic examples above.

What does “insufficient_credits” mean?

Your organization has run out of credits. Purchase more at dashboard.cuadra.ai or upgrade your plan.