Core Guides
Handle API errors
Read error codes, retry only when useful, and keep the Request ID
Handle errors by HTTP status and code. The message is written for people and can change without notice.
Chat Completions and Responses use an OpenAI-style error object. Anthropic Messages and Gemini keep their own error formats, so do not use one parser for every TokenLab API.
{
"error": {
"message": "Human-readable description",
"type": "error_type",
"code": "error_code",
"param": "parameter_name",
"retryable": true,
"retry_after": 30
}
}Only message and type are always present in OpenAI-compatible errors created by TokenLab. Other fields appear when they are relevant.
Status codes
| Status | Meaning | Typical action |
|---|---|---|
400 | A field, model ID, or input is invalid | Fix the request; do not repeat it unchanged |
401 | API key is missing, invalid, expired, or revoked | Replace the key |
402 | Balance or API-key limit is too low | Top up, raise the limit, or reduce the request |
403 | This key cannot use the resource or model | Change the key's permissions or model |
404 | Resource does not exist or is no longer available | Check the ID and the API key that created it |
413 | Request or uploaded file is too large | Reduce the input to the documented model or endpoint limit |
429 | Request limit reached | Wait for Retry-After |
500–504 | Service unavailable or network failure | Retry only when retryable is true; respect retry_after and limit attempts |
Common error codes
| Code | What it means | What to change |
|---|---|---|
invalid_api_key | The API key is missing, invalid, inactive, or revoked | Check the Authorization header and key value |
expired_api_key | The key has expired | Create or select an active key |
insufficient_balance | The account balance cannot cover the request | Add funds, reduce the request, or choose a lower-priced model |
quota_exceeded | The API key reached its own limit | Increase that key's limit or use a different authorized key |
model_not_allowed | The key cannot use the requested model | Update the key's model list or choose an allowed model |
model_not_found | The model ID is unknown or unavailable | Read /v1/models and use a current model ID |
context_length_exceeded | Input is longer than the model accepts | Remove history or choose a model with a larger context window |
rate_limit_exceeded | Too many requests were sent in the current window | Wait for Retry-After |
payload_too_large | The request body or file exceeds the endpoint limit | Reduce or compress the input |
all_channels_failed | The selected model cannot serve this request | Retry only when retryable is true; respect retry_after and limit attempts |
timeout_error | The request did not finish in time | Retry only when the operation is safe to repeat |
A 503 all_channels_failed or 503 delivery_tier_unavailable does not always mean a temporary outage. If the requested operation has no supply in the selected Delivery tier, retryable is false and retry_after is omitted. Do not repeat the same request. Check the operation and Delivery availability with GET /v1/models before selecting another model. Similar names do not prove availability; unverified alternatives are omitted.
Some OpenAI-compatible errors include optional did_you_mean, suggestions, alternatives, hint, retryable, or retry_after fields. See Errors agents can act on.
When a request ran on an Official route and the upstream service rejected the request itself, such as an input it does not accept or a content policy decision, the error also carries upstream: the upstream's message as reported, plus code and source (the upstream service name) when known. Anthropic Messages and Gemini errors carry the same object inside their own error. Keep branching on code and type; upstream.code values are defined by the upstream service and may change.
Retry decisions
| Error | Repeat the same request? |
|---|---|
400, 401, 402, 403, 404, 413 | No. Change the request, credentials, balance, permissions, or input. |
429 | Yes, after the server-provided delay. |
500–504 | Retry only when retryable is true; respect retry_after and limit attempts |
| Connection closed before any response | Sometimes. For create operations, check whether a task or side effect already exists. |
| Stream interrupted after output arrived | Do not call it a complete response. Repeating may generate different output or a second charge. |
For image, video, music, 3D, and Worlds creation, save the task ID as soon as it is returned. If a create request times out, check the task record before sending another create request.
Keep the Request ID
Response headers include a Request ID for tracing. Save it with the endpoint, model, time, and your own user or job ID. For async work, also save task_id and billing_transaction_id when present.
When contacting support, include those IDs and a redacted example. Never send API keys, management tokens, private media, signed URLs, or complete private prompts.