Errors and Debugging

Diagnose validation, authentication, credit, and upstream issues.

Error Codes

NameTypeRequiredDescription
400
Bad RequestInvalid schema or parameters.
401
UnauthorizedMissing/invalid API key.
402
Payment RequiredInsufficient credits.
404
Not FoundUnknown route or resource.
429
Too Many RequestsRate limited.
500
Internal Server ErrorGateway internal failure.
502
Bad GatewayUpstream/provider failure.
503
Service UnavailableTemporary service outage.

Standard Error Shape

json
{
  "error": {
    "message": "Rate limit exceeded",
    "type": "rate_limit_error",
    "code": 429,
    "param": null
  }
}

402 Extended Error Shape

json
{
  "error": {
    "type": "insufficient_credits",
    "message": "Insufficient balance β€” top up to continue",
    "code": "insufficient_credits",
    "balance": {
      "current": 250,
      "current_usd": 2.5,
      "threshold": 0,
      "currency": "cr",
      "currency_display": "USD"
    },
    "actions": {
      "top_up_url": "/v1/customer/credits/packages",
      "support_url": "/support"
    }
            }
}

This 402 payload is an extension that adds error.balance and error.actions. The extension may use a semantic code value ("insufficient_credits") while standard errors use the canonical {message, type, code, param} shape.

404 Unknown Model (model_not_found)

json
{
  "error": {
    "message": "Model 'anthropic/claude-sonnet-5-5' not found",
    "type": "invalid_request_error",
    "code": "model_not_found",
    "param": "model",
    "did_you_mean": "anthropic/claude-sonnet-5",
    "suggestions": ["anthropic/claude-sonnet-5"],
    "docs": "https://docs.therouter.ai/models",
    "trace_id": "req_..."
  }
}

suggestions lists up to three catalog model ids close to the one you sent, best first; did_you_mean is the first of them. Both always name standard model ids. On /v1/messages the same 404 uses the Anthropic shape (error.type: "not_found_error"), names the suggestions in error.message, and adds error.suggestions when there are any.

Debugging Headers

NameTypeRequiredDescription
x-request-id
response headerCanonical request identifier for support/debugging.
x-router-model-mapped / x-router-resolved-model
response headerSent when the model id you sent was mapped to a different standard model id (an alias, an unprefixed name or a short name); x-router-resolved-model names the model that served and billed the request.
x-router-model-shadow-fuzzy
response headerSent when the model id you sent is not in the catalog and was served as its closest catalog match. Send the id named in x-router-resolved-model instead.
x-router-prompt-cache
response headerSent on /v1/chat/completions and /v1/messages when your request carried cache_control breakpoints. It reports breakpoint handling only, not cache hits or billing. forwarded: every breakpoint was sent upstream unchanged. stripped: at least one breakpoint was removed before the upstream call. Possible causes: the model or provider is not on the prompt-caching allowlist; the request is not eligible for caching (for example it uses managed capabilities, skills or plugins); cache pricing for the route is not loaded; the provider does not support prompt caching on TheRouter; or a breakpoint could not be carried through the /v1/messages to OpenAI-format translation. Non-streaming responses describe the attempt that produced the response. Streaming responses describe the first dispatched attempt, because stream headers are sent before the upstream answers: a later failover is not reflected, and if the provider rejects the breakpoints and the gateway retries without them, a stream can say forwarded although the breakpoints were removed. Absent when the request had no breakpoint, and on response-cache hits (X-Cache: HIT).
Retry-After
response headerSeconds to wait before retrying a 429 response.
502 Type
502 responses use api_error in the error type field.
Help & contact