Error Format
All errors follow a consistent JSON format:Error Types
| HTTP Status | Error Type | Description |
|---|---|---|
400 | invalid_request_error | Malformed request body or missing required fields |
401 | authentication_error | Missing, invalid, or expired API key |
402 | payment_required | Insufficient credits — top up your account |
403 | permission_error / forbidden_error | Key doesn’t have access to the requested provider or resource |
413 | invalid_request_error | Request body too large (max 10 MB) |
429 | rate_limit_error | Rate limit exceeded (RPM or daily cap) |
502 | server_error | Upstream provider request failed |
503 | server_error | No available providers for the requested model |
Common Errors and Solutions
401 — Invalid API Key
403 — Provider Not Allowed
allowed_providers restriction. Use a different key
or update the allowed providers via the management API.
429 — Rate Limited
502 — Upstream Failed
Handling Errors in Code
- Python (OpenAI)
- Node.js (OpenAI)
- Go
Retry Strategy
For production applications, we recommend:- Retry on 429 and 502 with exponential backoff
- Do not retry on 400, 401, 403 — these are permanent errors
- Set a max retry count (e.g., 3 attempts)
- Consider multi-model routing — if one model cannot serve the request, send an ordered candidate list via
modelsandroute
Handling Errors During Streaming
When streaming (stream: true), errors behave differently depending on when they occur:
- Before any tokens are sent — ARouter returns a standard HTTP error response with a non-200 status code. Handle this the same as non-streaming errors.
- After tokens have been sent — The HTTP status is already 200 OK. The error is delivered as an SSE event in the stream body.
finish_reason on each chunk. If it’s "error", the stream has terminated abnormally.