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_classHTTPMeaning
client_invalid400Bad request shape or parameters
model_protocol_not_offered400The logical model does not declare this inbound protocol (app_error_id=4005). Switch endpoint or model
provider_invalid400Upstream rejected the request (upstream returned a 4xx other than 401/403/408/429)
provider_unsupported400The upstream does not support this endpoint (for example some video models reject DELETE cancel)
provider_timeout408Upstream request timed out
auth401API key authentication failed
billing_insufficient402Insufficient balance
policy403Model not allowed or no policy bound
quota429Platform quota or limit hit
provider_rate_limit429Upstream rate limit (upstream returned 429)
gateway_internal500Gateway internal error (catch-all)
billing_system502Billing system unavailable
provider_server502Upstream server error
provider_unauthorized502Upstream credential rejected (bucketed as 5xx; upstream-key issues are not exposed to callers)
provider_unavailable503No available provider
route_unconfigured503Model 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-ID and X-Trace-ID from the response headers; the error body also carries a top-level trace_id with the same value.
  • On 429, honor the Retry-After response 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 error field, treat it as a failure (such a mid-stream break maps to provider_stream_broken and is not returned as a separate HTTP status).
  • If the error is client_invalid and the message names 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: