Docs
Status
OverviewQuickstartSetup promptsThe core loopAuthenticationOverviewCoding agentsModelsAdding modelsAnthropic APIErrorsCredits & billingTelemetryAPI reference

Get started

  • Overview
  • Quickstart
  • Setup prompts
  • The core loop
  • Authentication

Guides

  • Overview
  • Coding agents
  • Models
  • Adding models
  • Anthropic API
  • Errors

Billing & usage

  • Credits & billing
  • Telemetry

Reference

  • API reference
PreviousAnthropic APINextCredits & billing

Guides

Errors

Every error the gateway returns is an OpenAI-compatible envelope with a stable code. The messages are written so an agent can self-correct from the code and message alone.

The error envelope

Every failure on /v1/chat/completions, /v1/responses, and /v1/models returns the same shape, so existing OpenAI error handling keeps working:

{
  "error": {
    "message": "The requested model alias is not granted to this identity.",
    "type": "permission_error",
    "code": "model_not_granted",
    "param": null
  }
}

Branch on code, not the message text; the message is human-readable and may change, the code is stable.

Stable codes

codeHTTPMeaningHow to recover
model_location_not_supported403The request location is outside this model maker's supported regions, or could not be verified.Choose another model or contact support if the location is incorrect. Retrying, changing keys, or adding credits will not resolve this policy refusal.
invalid_json400The request body is not valid JSON.Fix the request body.
invalid_request400The request is malformed.Read the message, fix the request, and resend.
invalid_parameter400A field is invalid; param names it. Tool and structured-format descriptions are capped at 65,536 characters (raised from 8,192 in engine 0.7.41; the message names the limit and the offending length).Correct that field and resend.
unsupported_capability400A whole capability the model route does not expose (a tool, a modality, reasoning) was requested.Pick a capable model; check supported_params and modalities in /api/models.
unsupported_parameter400A specific request parameter the model route rejects (e.g. temperature on a reasoning-only route, or top_k / frequency_penalty / presence_penalty / top_logprobs where the route does not accept them); param names it.Remove the field, or choose a model whose Supported parameters include it (shown on the model page).
refusal400The provider refused the request on policy grounds. The message is always "provider refused the request: <phrase>" with a fixed phrase (never provider prose), and the envelope carries one extra field, refusal_reason, naming the category: cyber_policy, cbrn, content_policy, recitation, data_inspection, or unspecified.Retrying does not help; the same content is refused again. Change the request, or pick a model from another provider. Not a key, credit, or limit problem.
previous_response_not_found400previous_response_id is unknown or expired on this worker.Resend the full conversation instead of continuing.
invalid_key401The key is missing, malformed, expired, or revoked.Fix the Authorization header.
model_not_granted403Your organization cannot call this slug — or the name is not a gateway slug at all. Gateway slugs use the DOT form (claude-fable-5.1, claude-haiku-4.5); Anthropic's dashed wire ids (claude-fable-5-1, dated ids) fail here.Use a slug exactly as returned by GET /v1/models.
idempotency_conflict409The same Idempotency-Key was reused with a different body.Use a fresh Idempotency-Key.
idempotency_replay_unavailable409 / 500The original keyed result is gone after a restart.Resend with a new Idempotency-Key.
insufficient_quota429A spend limit, a free-tier allowance, or your credit balance is exhausted; the message prefix says which — see the free-tier and cap messages below.Add credits, raise the limit, or opt in to credits overflow (platform-funded lane only).
unavailable_route429 / 503Throttled, or no healthy route right now.Retry with backoff.
gateway_overloaded429The bounded replay window is full.Retry with backoff.
request_cancelled499The client disconnected before completion.Reissue the request if you still want the result.
provider_internal502"provider stream failed": the upstream provider accepted the request and then closed the stream (before or during output) without a terminal event. Not a credit or limit problem; the gateway already retried the rung once.Retry with backoff — provider-side incidents are episodic (OpenAI's Astra backend dropped large-prompt streams in bursts on 2026-09-06). Claude Code retries 10× on its own; if a burst outlasts that, retry later.
all_routes_failed502Every provider in the waterfall failed.Retry; if you are on BYOK, check your provider key.
provider_output_too_large502Provider output exceeded the gateway response limit.Lower max output tokens.
gateway_draining503This instance is draining and is not taking new requests.Retry; the request lands on another instance.
deadline_exceeded504The request ran past the gateway deadline.Shorten the work or retry.
internal_error500An unexpected failure.Retry with backoff.

unsupported_capability and unsupported_parameter are distinct: the first means a whole capability is off the table for this route (it serves no tools, or no reasoning at all), so switch models; the second means the route serves the capability but rejects one field of your request (for example temperature on a reasoning-only route) — drop that field and resend, or pick a model whose Supported parameters include it.

A refusal is the one error that adds a field to the envelope. refusal_reason is a closed vocabulary (cyber_policy, cbrn, content_policy, recitation, data_inspection, unspecified), so branch on it rather than on the message. It is present on every refusal on /v1/chat/completions, /v1/responses, and /v1/messages, and absent from every other error:

{
  "error": {
    "message": "provider refused the request: cybersecurity policy",
    "type": "invalid_request_error",
    "code": "refusal",
    "param": null,
    "refusal_reason": "cyber_policy"
  }
}

Any unknown /v1 path returns 404 with code=not_found. The gateway serves /v1/models, /v1/chat/completions, /v1/responses, and the Anthropic Messages API at /v1/messages(whose errors use Anthropic's envelope shape with the same codes).

Free-tier and cap messages

Every insufficient_quota response starts its message with one of these prefixes. Branch on the prefix when you need to know which ceiling you hit; they are stable.

message prefixMeaningHow to recover
free_limit_reachedThis model's free-tier allowance is spent — an hourly or daily token window, a recurring dollar cap, or a lifetime cap — and your org's credits overflow is off (it turns on automatically at your first real payment, and can be turned on by hand only once the org has a card on file and the settled $1 verification), so the free lane throttles. The message names the exact limit and its reset when one exists; a lifetime cap never resets.If the message names a reset you can wait for it; otherwise (or to keep going now) add credits or subscribe — any real payment turns credits overflow on for the org. A verified org (card + settled $1 verification) can also flip it directly (model page → "Past the free limit → Use credits", or POST /api/credits-overflow with the org's key; both answer 402 verification_required — "add a card and complete the $1 verification to unlock credits overflow" — before that). Or use your own provider key (BYOK is never throttled).
free_tier_requires_paymentThe free tier needs a card on file AND a settled $1 charge; the org has not met that yet.Add a card and buy any credits once on /credits; the free tier unlocks on the settled charge.
promo_byok_onlyThe free tier is spent and the org's credit balance cannot cover this request's worst case, so only your own provider key (BYOK) can serve it.Add credits, or connect your own provider key for this model.
key_daily_capThis API key's daily spend cap would be exceeded by the request's worst case (the message shows the cap, today's usage, and the request's worst case).Raise the cap under the key's limits, use another key, or wait for 00:00 UTC.
insufficient_creditsThe org's credit balance cannot cover the request's worst case.Add credits on /credits.
The free tiers throttle at their limit by default — they never drain your credits silently. Overflowing to paid credits is an org-wide switch that turns on at your first real payment (Pro, a top-up, or an auto-recharge). A verified org (a card on file and the settled $1 verification) can also flip it by hand — "Past the free limit → Use credits" on any free-tier model page, or your agent's POST /api/credits-overflowwith the org's gateway key (it only ever enables) — but an unverified org gets 402 verification_required from both: the free allowance is all there is until the card is verified. The switch belongs to the org that owns the key you are calling with — check which org is active in the dashboard before assuming it is on.

Symptoms in Claude Code

Claude Code rewrites some gateway responses into its own copy, so the text you see is not always the gateway's. These are the ones that mislead.

What Claude Code showsWhat actually happenedFix
Not logged in · Please run /loginClaude Code has no usable key. Either the key changed under a running session (auth is read at startup), or you once answered No to its "Detected a custom API key… do you want to use it?" prompt — that No is remembered in <config dir>/.claude.json under customApiKeyResponses.rejected and the env key is ignored forever after.Restart the session (claude --resume <session-id> keeps the conversation). If it persists, answer Yes to the prompt, or move the key's entry from rejected to approved in .claude.json. Do not run /login.
API Error: 403 The requested model alias is not granted…The model name is not a gateway slug (Anthropic's dashed id such as claude-fable-5-1) or the key's org lacks the alias.Use the dot-form slug from GET /v1/models (claude-fable-5.1).
502 provider stream failed · RetryingThe upstream provider closed the stream. Episodic and provider-side; large-context sessions are hit hardest.Let the retries run; if all 10 fail, resume the session a few minutes later. It is not a credit or limit problem.
"gpt-6-astra" isn't described by this version's model catalog… auto-compact keeps this session within 200k tokensClaude Code assumes a 200k window for any model name it does not know and compacts early.Set CLAUDE_CODE_MAX_CONTEXT_TOKENS to the catalog window (gpt-6-astra: 1050000; read context_window from GET /api/models/<slug>). The unrecognized_model stderr line is cosmetic.
Fable missing from the /model pickerClaude Code 2.1.263 hides Fable rows on API-key auth even when the org is entitled; the model still serves.Set "model": "claude-fable-5.1" in the session's settings.json, or pass --model claude-fable-5.1.
Never run /login on a gateway session. It starts an Anthropic OAuth flow whose token then outranks ANTHROPIC_BASE_URL + ANTHROPIC_API_KEY, and your calls stop reaching the gateway. Claude Code also hides the gateway's 401 body (you only see its login prompt) while it prints 403 bodies verbatim — so a key problem looks like a login problem.

What to retry

  • Retry 429 (throttled or overloaded), 502, 503, and 504 with exponential backoff.
  • Do not blindly retry 400, 401, 403, or 409. Fix the request first; the same call fails the same way.
  • insufficient_quota is not transient: it clears when you add credits or raise a limit, not on retry.
Delivery is at-least-once: an ambiguous network failure that you retry can dispatch and bill the underlying provider twice. Pass an Idempotency-Key header so an exact retry replays the original result instead of running again.

See also

The API reference documents each endpoint, and /llms.txt carries this same error table for agents.