07
Errors
Errors use the OpenRouter envelope: HTTP status equals error.code, error.metadata.error_type is a stable machine-readable category.
Envelope
All non-2xx responses (and mid-stream failures) have this shape:
{
"error": {
"code": 402,
"message": "Insufficient credits",
"metadata": {
"error_type": "insufficient_credits",
"limit_source": "nxio_credits",
"balance_usd": "0.0000000000",
"required_usd": "0.0138600000"
}
}
}Status codes
| Status | error_type | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed body, missing model/messages, unsupported parameter. |
| 400 | context_length_exceeded / max_tokens_exceeded | Prompt or requested output exceeds the model limit. |
| 401 | unauthorized | Missing, malformed, disabled or revoked API key. |
| 402 | insufficient_credits | Balance or key limit cannot cover the request; see limit_source. |
| 403 | forbidden / content_policy_violation | Account disabled, or the provider refused the content. |
| 404 | not_found | Unknown or deactivated model; unknown generation id. |
| 408 | timeout | Provider did not answer in time. |
| 429 | rate_limit_exceeded | Provider or NXIO rate limit. Honour Retry-After. |
| 502 | server / provider_overloaded | Provider error. Safe to retry with backoff. |
| 503 | provider_unavailable | No capacity for this model right now. |
Retry guidance
Retry 408, 429, 502 and 503 with exponential backoff and jitter; never retry 400, 401, 402 or 404 without changing the request. Every response carries X-Request-Id; include it when contacting support.