Getting started
Error codes
When a request to the ezrouter API fails, the response carries an ezrouter-specific error envelope that documents the failure. This page describes the codes you can expect to receive, the JSON shape they arrive in, and what to do about each one.
Error envelope
Every non-2xx response uses this shape:
{
"error": {
"code": "...",
"message": "...",
"type": "..."
}
}Some envelope variants also include an empty "param": "" field on upstream_error responses; treat as informational, not load-bearing.
| Field | Type | Notes |
|---|---|---|
error.code | string | Short machine-readable code. Sometimes populated, sometimes empty "" — see the table below. Switch on this when handling specific cases. |
error.message | string | Human-readable explanation. For some classes the message text is in Chinese, particularly authorization-related failures. Do not assume English when surfacing this to end-users. The message also embeds the request id inline as (request id: <id>). |
error.type | string | Category label. ezrouter uses three distinct values today: authentication_error, new_api_error, upstream_error. The taxonomy is inconsistent across endpoints — prefer switching on error.code or HTTP status over error.type. |
For tracing, every response — including errors — carries an x-oneapi-request-id header. Include this verbatim in support tickets.
Observed codes
The table below lists codes ezrouter has been observed to return in testing. The list is not exhaustive; treat unknown codes as terminal and surface the raw envelope to logs.
| HTTP | code | type | When it happens | Recommended action |
|---|---|---|---|---|
| 401 | invalid_api_key | authentication_error | The Authorization header is missing, malformed, or carries a key that the gateway no longer recognizes (revoked or never existed). | Verify the key. Rotate if compromised. Confirm the header form: Authorization: Bearer sk-.... |
| 403 | access_denied | new_api_error | The model in the request is not in the gateway catalog at all, or it exists but the calling key isn't authorized for it. Note: ezrouter intentionally returns the same code for both cases to avoid leaking the full catalog to unauthorized callers. The message text is in Chinese for this class. | Query GET /v1/models to see what's accessible. Contact [email protected] if you need access to a model you can't see. |
| 400 | "" (empty) | new_api_error | The request body could not be parsed — typically malformed JSON, or a Content-Type other than application/json. | Verify the body is valid JSON and the header is set. Common pitfall on Windows: PowerShell's curl alias mangles JSON quoting; use curl.exe and put the body in a file with --data "@body.json". |
| 400 | (populated, varies) | upstream_error | The request reached the gateway and was forwarded to the upstream model provider, but the provider rejected it. Often caused by sending a parameter the upstream model doesn't support. The envelope adds "param": "" and the message is "The upstream service returned an error. Please try again later.". | Do not retry blindly — this isn't transient. Check whether you're sending a parameter that the chosen model supports. Notable cases: prefix and reasoning_content on assistant messages are not supported via the OpenAI surface for several models. |
5xx server errors
Gateway-side 500-class responses are possible during outages or maintenance windows; they have not appeared in routine testing. If you encounter one, retry once or twice with exponential backoff (base 1 second, cap 60 seconds). If they persist, capture the x-oneapi-request-id and contact [email protected].
Codes not used by ezrouter
The following codes are common on other LLM APIs but ezrouter does not currently emit them:
| HTTP | Why not |
|---|---|
429 Too Many Requests | Under load the gateway uses silent upstream queueing instead of explicit backpressure. Latency grows; status code does not change. See Rate limits. Do not write if status == 429: retry handlers — they will never fire for capacity reasons. |
Standard Retry-After, X-RateLimit-, or RateLimit- response headers | Not emitted under any condition. Build client backoff against observed latency, not against rate-limit headers. |
Custom response headers
Every response (success or error) carries these ezrouter-specific headers:
| Header | Format | Purpose |
|---|---|---|
x-new-api-version | YYYYMMDD-HHMMSS | Gateway build stamp. Useful for filing reproducible bug reports. |
x-oneapi-request-id | opaque string | Request identifier. Always include this when filing a support ticket about a specific request. |