Errors & Rate Limits
Error shape
json
{
"error": {
"code": 401,
"message": "unauthorized",
"metadata": {
"request_id": "req_xxx",
"error_class": "auth",
"app_error_id": 4011
}
},
"trace_id": "..."
}Besides the error object, the body carries a top-level trace_id field (matching the X-Trace-ID response header; omitted when tracing is disabled) so you can grep logs by it. metadata.reason is an optional subtype (for example model_not_in_catalog). Full catalog and verified examples: API catalog.
Common categories
| error_class | HTTP | Meaning |
|---|---|---|
client_invalid | 400 | Bad request shape or parameters |
model_protocol_not_offered | 400 | The logical model does not declare this inbound protocol (app_error_id=4005). Switch endpoint or model |
provider_invalid | 400 | Upstream rejected the request (upstream returned a 4xx other than 401/403/408/429) |
provider_unsupported | 400 | The upstream does not support this endpoint (for example some video models reject DELETE cancel) |
provider_timeout | 408 | Upstream request timed out |
auth | 401 | API key authentication failed |
billing_insufficient | 402 | Insufficient balance |
policy | 403 | Model not allowed or no policy bound |
quota | 429 | Platform quota or limit hit |
provider_rate_limit | 429 | Upstream rate limit (upstream returned 429) |
gateway_internal | 500 | Gateway internal error (catch-all) |
billing_system | 502 | Billing system unavailable |
provider_server | 502 | Upstream server error |
provider_unauthorized | 502 | Upstream credential rejected (bucketed as 5xx; upstream-key issues are not exposed to callers) |
provider_unavailable | 503 | No available provider |
route_unconfigured | 503 | Model route has no upstream configured |
Billing of failed requests
- Pre-authorization: every accepted request freezes balance based on an estimate; after the request ends it is settled by actual usage and any excess is released immediately.
- Successful requests, and streaming requests that already delivered content, are settled by the usage actually returned.
- Requests that were dispatched to the upstream provider but ultimately failed (upstream 4xx/5xx, upstream timeout, mid-stream disconnect, or the client closing the connection while waiting for the response) are settled at the pre-authorized amount and are not refunded. The upstream provider has already incurred cost for such requests; the platform bears it at the pre-authorized figure and bills the caller accordingly.
- Requests rejected before reaching an upstream provider (validation, authentication, policy, quota, insufficient balance, gateway internal errors) release the full pre-authorization and incur no charge.
- The settlement basis is visible in the console's usage transactions; records settled at the pre-authorized amount carry the failure reason.
Troubleshooting
- Keep
X-Request-IDandX-Trace-IDfrom the response headers; the error body also carries a top-leveltrace_idwith the same value. - On
429, honor theRetry-Afterresponse header and back off exponentially (the platform sets it when a platform rate limit is hit). - If a streaming response delivers a chunk with an
errorfield, treat it as a failure (such a mid-stream break maps toprovider_stream_brokenand is not returned as a separate HTTP status). - If the error is
client_invalidand themessagenames the request body limit, the body exceeded 10 MiB. Compress or resize base64-inlined images (keep one raw image under about 7.5 MiB) and retry.
For endpoint details see: