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:

JSON
{
  "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

Statuserror_typeMeaning
400invalid_requestMalformed body, missing model/messages, unsupported parameter.
400context_length_exceeded / max_tokens_exceededPrompt or requested output exceeds the model limit.
401unauthorizedMissing, malformed, disabled or revoked API key.
402insufficient_creditsBalance or key limit cannot cover the request; see limit_source.
403forbidden / content_policy_violationAccount disabled, or the provider refused the content.
404not_foundUnknown or deactivated model; unknown generation id.
408timeoutProvider did not answer in time.
429rate_limit_exceededProvider or NXIO rate limit. Honour Retry-After.
502server / provider_overloadedProvider error. Safe to retry with backoff.
503provider_unavailableNo 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.