Home / Docs / Errors

Errors

Every status code the gateway returns, what actually causes it, and the fix.

Errors return JSON with a type and a human-readable message. Status codes follow the Anthropic and OpenAI conventions.

{"type": "error", "error": {"type": "authentication_error", "message": "invalid api key"}}

Status codes

CodeMeaningMost common real causeFix
400Bad requestMissing max_tokens on Messages, or a malformed messages arrayCheck the body against Messages
401UnauthenticatedKey sent in the wrong header for the formatx-api-key for Messages, Bearer for Chat Completions
402Payment requiredBalance exhausted or plan expiredTop up or buy a plan
403ForbiddenKey revoked, or model not enabled for the accountCreate a new key; check /v1/models
404Not foundBase-URL mistake — usually a doubled or missing /v1See Base URLs
429Rate limitedToo many concurrent requestsBack off exponentially; see Rate limits
500Gateway errorUnexpected internal failureRetry once; if it persists, contact support with the request id
529Upstream overloadedProvider capacity, not your accountRetry with backoff — usually clears in seconds

Error types

typeMeaning
invalid_request_errorThe body is malformed or a required field is missing
authentication_errorKey missing, malformed, or revoked
permission_errorKey is valid but not allowed to use that model
not_found_errorUnknown path or unknown model id
rate_limit_errorThrottled
api_errorInternal failure
overloaded_errorUpstream capacity exhausted

Retrying correctly

Retry 429, 500, 502, 503 and 529. Never blind-retry 400, 401, 402 or 403 — the same request fails identically, and for partially generated responses you may pay twice.

import time, httpx

def call(body, key, tries=4):
    for i in range(tries):
        r = httpx.post(class="s">"https://aiprimetech.io/v1/messages", json=body, timeout=120,
                       headers={class="s">"x-api-key": key,
                                class="s">"anthropic-version": class="s">"2023-06-01"})
        if r.status_code in (429, 500, 502, 503, 529):
            time.sleep(2 ** i)          class=class="s">"c"># 1s, 2s, 4s, 8s
            continue
        r.raise_for_status()
        return r.json()
    raise RuntimeError(class="s">"upstream unavailable after retries")
Add jitter to the sleep in production. Synchronised retries from many workers turn one blip into a thundering herd against the same upstream.