API reference
Errors and limits
Status codes, error codes, and technical limits.
Error shape
Failures before a stream commits use the OpenAI error envelope:
{
"error": {
"message": "Invalid API key.",
"type": "authentication_error",
"param": null,
"code": "invalid_api_key"
}
}Once a stream has committed, Router cannot change the status code, so late failures surface as a truncated event stream instead.
Status codes
| Status | Meaning | Usual fix |
|---|---|---|
400 | Invalid JSON, request shape, route selector, or provider option | Fix the field named by param, when present |
401 | Missing, invalid, expired, or spend-cap-locked key (invalid_api_key), or a disabled one (api_key_deactivated) | Check that the client sends an active Router key, not a provider key. See Authentication |
402 | No available credit (insufficient_credits) | Add credit. A key stopped by a spend cap returns 401, not this |
403 | A provider is not currently available | Select another provider or model |
404 | A model is unavailable to this key | Use an ID from GET /v1/models |
413 | Request body exceeds 100 MiB | Send large inputs by URL instead of inline |
429 | Provider or gateway rate limit | Respect retry-after, or add a fallback |
500 | Router or gateway configuration failure | Retry briefly, then contact support with x-request-id |
501 | The selected provider cannot satisfy a requested capability | Change the request or check the capability table |
502 | Provider request, response, or all candidates failed | Retry with backoff or use another candidate |
503 | Credentials or pricing data are temporarily unavailable | Retry later or select another model and tier |
504 | Provider request or stream timed out | Retry or raise provider_timeout |
A provider's public model name is not necessarily available to your account, so
404 model_not_found for a model you know exists usually means it is not in
your catalog.
Capability translation
Router translates the OpenAI Responses request into the selected provider's
native format. A valid request can still use tools, content, reasoning, output
formats, or other options that the provider cannot represent. Router generally
returns 501 not_implemented_error for these translation failures.
Do not retry the same request unchanged. Remove the unsupported capability or choose a model that supports it. See Choose a model for current capability differences.
Provider transport failures
These messages indicate that a request reached provider execution, but Router could not obtain or finish reading a usable response:
| Message template | Status / code | What to do |
|---|---|---|
%s provider request failed. | 502 / provider_request_failed, or 504 on a deadline | Retry with backoff or use another provider. |
%s provider response could not be read. | 502 / provider_request_failed | Retry; report persistent failures with x-request-id. |
%s provider response was idle. | 504 / provider_request_failed | Retry or increase the allowed timeout. |
Fallback failures
Router advances through a models fallback list until a candidate starts a
response. If all candidates fail and Router has a specific last failure, it
preserves that failure's status, type, code, and param, then appends an
annotation to the message:
<last provider message> (all N candidates failed: provider:model STATUS code; ...)Use the last provider message as the primary diagnosis. The annotation shows
which candidates Router attempted and why each failed. If Router cannot expose
a more specific last failure, it returns 502 all_candidates_failed instead.
Retries
Router preserves provider retry-after and retry-after-ms headers when they
are available. Respect them rather than retrying immediately.
Router advances through a fallback list on its own but does not retry the same candidate. When every candidate fails, the error message summarizes what it tried.
Technical limits
| Limit | Current behavior |
|---|---|
| Request body | 100 MiB maximum |
| Route selectors | Exactly one of model or models |
| Explicit candidates | 1–15 provider:provider-model[:service-tier] entries |
| API keys | Up to 100 stored keys per user |
| API key list page | 1–100 items; offsets up to 10,000 |
| Dashboard time range | 90 days in the UI; the analytics API accepts at most 93 days |
| Streaming | Fallback ends once the stream commits |
Context windows, tools, media support, tiers, and rate limits vary by model.
Spend caps are applied after usage is recorded, so concurrent requests can take a key slightly over its cap.