OneRouter
Docs /Errors
Build

Errors

Every code the gateway can return, generated from the same catalog the gateway itself uses.

Every API error carries a stable code and a message that ends in a URL. Each URL resolves to an anchor on this page, and the anchor id is the code.

This page is generated from the same catalog the gateway serves from. It cannot drift, because there is nothing to keep in sync.

json
{
  "error": {
    "message": "Rate limited: this key allows 60 requests/minute. Raise it at https://onerouter.dev/keys",
    "type": "rate_limit_error",
    "code": "rate_limited",
    "param": null
  }
}
Retryable means the identical request may succeed later

Not that you should retry immediately. Honour Retry-After where it is present, and back off where it is not. A non-retryable error needs a change from you first — retrying it unchanged will fail the same way.

Invalid API key#

HTTP 401invalid_request_errornot retryable
invalid_api_key
Invalid API key. Keys start with `or-live-` and are created at https://onerouter.dev/keys, or with `POST /v1/keys`. A key from another gateway will not work here.

Fix. Create a key at https://onerouter.dev/keys. Rotation with the recovery secret replaces the key immediately — there is no grace window, so swap it in one move.

No bearer token#

HTTP 401invalid_request_errornot retryable
missing_api_key
Missing bearer token. Send your key as 'Authorization: Bearer or-live-...'.

Fix. Send the header. A client that holds the key but omits it is almost always reading an unset environment variable — echo it before blaming the gateway.

Insufficient credit#

HTTP 402invalid_request_errornot retryable
insufficient_credit
Insufficient credit: this key's balance will not cover the request, so it was not sent and nothing was charged. Top up at https://onerouter.dev/pay

Fix. Add credit. The message tells you which case you hit. A pre-request refusal names your balance and the worst-case estimate it could not cover, and nothing was sent or charged. A mid-stream stop names what the delivered tokens actually cost. The x-onerouter-balance-usd header on the 402 is the same available balance.

Unknown model#

HTTP 404invalid_request_errornot retryable
unknown_model
Unknown model 'claude-sonnet-5'. Did you mean 'anthropic/claude-sonnet-5'? Full list: https://onerouter.network/v1/catalog

Fix. Use an id from the catalog, in author/name form. The suggestion is computed from the closest published id, so an agent can correct itself without a human.

All upstreams unavailable#

HTTP 503api_errorretryable
model_unavailable
All upstream hosts for 'meta-llama/llama-3.3-70b-instruct' are failing right now (we tried 3). Live status: https://onerouter.dev/providers. Working alternatives at this moment: 'deepseek/deepseek-v4-flash', 'mistralai/mistral-nemo'.

Fix. Retry, or switch to one of the named alternatives. Naming a live alternative inside the error is deliberate: an agent can act on it without a human reading the providers page.

No model available for auto#

HTTP 503api_errorretryable
auto_unresolvable
'onerouter/auto:code' has no model available for this request right now — every candidate was unavailable, not allowed on this key, or unable to price the request. Name a model directly, or retry shortly. Current picks: https://onerouter.dev/models/auto

Fix. Auto walked its ordered list and every candidate failed one of three tests. The resolution table is public; pick a model by name to bypass the router entirely.

No Open Tier capacity#

HTTP 503api_errorretryable
no_free_route
No verified free route is available. This request was not switched to a paid model and nothing was charged. Availability: https://onerouter.dev/models/auto/free

Fix. Retry later. The Open Tier never falls back to paid, so adding credit will not resolve this — name a paid model explicitly if you need the request served now.

Open Tier allowance spent#

HTTP 429rate_limit_errorretryable
free_quota_exceeded
Your Open Tier allowance is exhausted. Retry after the time in Retry-After. Quotas reset at 00:00 UTC.

Fix. Wait for the reset. Every key on the account shares one allowance, so minting another key does not reset it, and adding credit does not raise it.

Rate limited#

HTTP 429rate_limit_errorretryable
rate_limited
Rate limited: this key allows 60 requests/minute. Raise it at https://onerouter.dev/keys

Fix. Back off for the number of seconds in Retry-After, then retry the identical request. The message names both the limit and the knob — a 429 that names neither is a dead end.

Budget spent#

HTTP 429rate_limit_errorretryable
budget_exhausted
This request exceeds the daily cap on budget 'nightly-agents' ($20.00/day, $19.94 used). Review it at https://onerouter.dev/docs/budgets

Fix. Raise the named budget or wait for its window to reset. Open reservations count immediately, so concurrent requests cannot bypass a cap a serial request would have hit.

Context too long#

HTTP 400invalid_request_errornot retryable
context_too_long
Request is 182,400 tokens but 'meta-llama/llama-3.3-70b-instruct' accepts 131,072. Models with larger context: https://onerouter.dev/models

Fix. Shorten the prompt or pick a longer-context model. The counts are named so you can tell how far over you are without instrumenting your own tokenizer.

Request body too large#

HTTP 413invalid_request_errornot retryable
payload_too_large
Request body exceeds the 10 MB limit.

Fix. Trim the request. A body this size is almost always an accidentally inlined file or a runaway conversation history. The edge refuses it before reading it all rather than buffering it into memory.

Upstream error#

HTTP 502api_errorretryable
upstream_error
The upstream returned an error after we had begun streaming, so we could not move to another host without corrupting the response. Live status: https://onerouter.dev/providers

Fix. Retry the request. If output had barely started — under 50 tokens — the charge is written off automatically rather than billed for a response you cannot use.

Request timed out#

HTTP 504api_errorretryable
request_timeout
No first token from any upstream within 30s, across 3 hosts. Live status: https://onerouter.dev/providers

Fix. Retry. Before the first byte reaches you we can and do switch hosts automatically; after it, we cannot.

Invalid request#

HTTP 400invalid_request_errornot retryable
invalid_request
'messages' must be a non-empty array. See https://onerouter.dev/docs/errors#invalid_request

Fix. Check the field named in the message. On the Open Tier this also covers routing overrides — models, provider, route, fallbacks — which are refused rather than silently ignored. For base-URL mistakes, use https://onerouter.network/v1 with no endpoint suffix.

Endpoint not served#

HTTP 400invalid_request_errornot retryable
unsupported_endpoint
Embeddings are not served by this gateway. OneRouter serves text generation only.

Fix. Move to /v1/chat/completions, /v1/responses or /v1/messages. Unsupported surfaces answer with a sentence rather than a 404 so a misconfigured client is told what to do instead of guessing.

Account suspended#

HTTP 403invalid_request_errornot retryable
account_suspended
This account is suspended. Contact https://onerouter.dev/support to resolve it.

Fix. Contact support. Suspension follows a chargeback, a sanctions-screening hit, or an acceptable-use breach — the reply names which.

Unhandled error#

HTTP 500api_errorretryable
internal_error
Internal server error.

Fix. Retry, then report it with the receipt id from x-onerouter-receipt. This message carries no detail on purpose: an unhandled exception must never surface a stack frame that could carry prompt text into a response body or a log line.