Error codes
Use one error shape to debug faster: read the status code, then decide whether to retry.
On this page
Error response shape
Whether the error comes from the gateway or upstream, the body has one shape:
{
"error": {
"message": "insufficient balance for the requested maximum usage",
"type": "upstream_error",
"code": "insufficient_funds",
"retryable": false
}
}retryable says whether sending the same request again later could succeed. When contacting support, include the X-Maxx-Request-ID response header — it pins down the exact call.
HTTP status codes
| Status | Meaning | Retry? |
|---|---|---|
400 | Invalid body, unsupported parameter, or unknown model ID (model_not_supported) | No — fix the request |
401 | No key, or the key is invalid, disabled or expired | No |
402 | Balance can't cover this request's maximum possible cost (insufficient_funds) | No — top up first |
403 | This key may not call the model (API_KEY_MODEL_DENIED) | No |
404 | Path not found | No |
413 | Body too large to estimate cost (request_too_large) | No — trim the context |
422 | Estimated cost exceeds the per-request ceiling (billing_limit_exceeded) | No — lower max_tokens |
429 | Too many concurrent requests or upstream throttling; see Retry-After | Yes, with backoff |
500 | Gateway internal error | Yes |
502 | Upstream failed and every candidate provider failed too | Yes |
503 | No provider currently available for the model, or all are at capacity | Yes, or switch models |
Common error codes
| code | Meaning | What to do |
|---|---|---|
model_not_supported | Model ID misspelled or not currently offered | Check with GET /v1/models |
API_KEY_MODEL_DENIED | The model isn't in this key's allowed models | Edit the key's allowed models in the console |
insufficient_funds | Balance too low | Top up, or lower max_tokens |
context_length_exceeded | Input exceeds the model's context window | Trim history or use a longer-context model |
unsupported_parameter | The model doesn't accept one of the parameters | Drop it, or switch models |
api_key_concurrency_exceeded | Too many requests in flight on this key | See rate limits |
rate_limit_exceeded | Upstream throttling with no other provider to switch to | Back off and retry |
provider_saturated | Every provider for the model is at capacity | Retry shortly |
no_available_provider | No provider currently available for the model | Retry later, or switch models |
upstream_timeout | Upstream took too long | Retry |
content_policy_violation | Blocked by the upstream content policy | Adjust the prompt |
Recommended retry strategy
Retry only 408 / 429 / 5xx, at most three times, with exponential backoff and jitter. For 429, honour the Retry-After header first.
import time, random
from openai import OpenAI, APIStatusError
RETRY = {408, 429, 500, 502, 503}
def call_with_retry(client, **kwargs):
for attempt in range(3):
try:
return client.chat.completions.create(**kwargs)
except APIStatusError as e:
if e.status_code not in RETRY or attempt == 2:
raise
wait = (2 ** attempt) + random.random()
time.sleep(wait)Never retry 400 / 401 / 402 / 403. The outcome will not change, and the attempts tie up concurrency that real requests need.
Contact us
Something unclear, or need a human? Pick the channel that fits your question.
Supportsupport@apione.ai
WeCom
Telegram
Communityhttps://t.me/apione
Support tickets
Billing & accountConsole › Feedback