Errors
API error codes and response format
Error Response Format
Chat completions and the Skill endpoints (image, audio, search) answer errors in a structured format:
{
"error": {
"message": "Human-readable error description",
"type": "error_type",
"code": "error_code"
}
}Authentication failures (401) and rate-limit / credit-exhaustion errors
(429) are the exception: they still answer with a flat
{ "error": "message string" } — see
Authentication Errors and
Rate Limit Errors below. Branch on the HTTP status
first; only parse error as an object for endpoints that document one.
An upstream failure also carries the vendor's own request id, which is what support needs to ask them about one specific call:
{
"error": {
"message": "Rate limit exceeded",
"type": "rate_limit_error",
"code": "openrouter_429",
"upstream_trace_id": "gen-01J8Z3C4V9"
}
}The media endpoints — image, audio and search — used to answer in three
different shapes, including { "success": false, "error": "...", "code": "..." }.
They all answer in the format above now. If you were branching on success,
branch on the HTTP status instead.
code is namespaced so it stays readable in a log line. A refusal from the
gateway is prefixed by the capability that raised it — image_model_not_allowed,
tts_no_model_configured, asr_not_priced — while an upstream rejection is
prefixed by the provider, as in openrouter_429 above.
HTTP Status Codes
| Status | Meaning | Common Cause |
|---|---|---|
400 | Bad Request | Missing or invalid parameters |
401 | Unauthorized | Missing, invalid, or expired API key |
404 | Not Found | Resource doesn't exist or model not found |
413 | Payload Too Large | Request payload exceeds the size limit |
429 | Too Many Requests | Rate limit exceeded |
502 | Bad Gateway | Upstream provider returned an error |
503 | Service Unavailable | Provider temporarily unavailable or not configured |
Error Types
invalid_request_error
The request was malformed or missing required fields.
{
"error": {
"message": "model, max_tokens, and messages are required",
"type": "invalid_request_error",
"code": "invalid_request"
}
}server_error
An internal error occurred on the Router9 side.
{
"error": {
"message": "An unexpected error occurred. Please try again.",
"type": "server_error",
"code": "internal_error"
}
}upstream_error
The upstream LLM provider returned an error.
{
"error": {
"message": "Upstream provider error: rate limited",
"type": "upstream_error",
"code": "provider_error"
}
}Authentication Errors
| Error Message | Cause | Fix |
|---|---|---|
Missing authorization header | No API key provided | Add Authorization: Bearer sk-r9k-... header |
Invalid API key | Key doesn't exist or was deactivated | Check key or regenerate in dashboard |
API key expired | Key passed its expiration date | Regenerate a new key |
Rate Limit Errors
{
"error": "4-hour rate limit exceeded. Resets at 2025-04-06T16:00:00Z"
}See Rate Limiting for details on quotas and the Retry-After header.