Skip to content

Errors and limits

Every error uses the OpenAI-compatible envelope:

{
"error": {
"message": "The model 'unknown-model' does not exist or is not available.",
"type": "invalid_request_error",
"param": null,
"code": "model_not_found"
}
}

Validation failures return 400 with code invalid_request and the offending field in param, for example messages.0.content.

Status Code Meaning
400 invalid_request Malformed body or invalid parameter
400 max_tokens_exceeded Requested output tokens exceed the per-request cap
401 invalid_api_key Missing or unknown API key
401 api_key_expired API key has expired
402 insufficient_quota Wallet balance cannot cover the request
402 insufficient_wallet_balance Wallet hold could not be placed
402 daily_spending_limit_exceeded Daily cap would be exceeded
402 monthly_spending_limit_exceeded Monthly cap would be exceeded
403 api_key_scope_denied Key lacks inference:read or inference:write
403 model_not_allowed Model is outside the effective allowlist
404 model_not_found Unknown, disabled, or unavailable model
409 idempotency_key_reused Same idempotency key, different payload
409 idempotency_key_expired Idempotency key can no longer be reused
409 duplicate_request Request with this key is already in progress or replay is unsupported
422 invalid_image, invalid_image_type, invalid_image_url Image part is invalid or unsupported
422 image_too_large Image exceeds the size limit
422 image_fetch_failed Remote image could not be fetched
429 rate_limit_exceeded Request rate limit exhausted
429 concurrent_request_limit_exceeded All concurrency slots are in use
502 upstream_error Provider failed after retries
503 pricing_unavailable No complete published pricing for the route
503 service_unavailable Temporary dependency failure
503 fx_unavailable Billing FX quote is unavailable

Admin, dashboard, and account endpoints are outside the scope of this reference.

Rate limits are applied per API key and per account. When rate limiting is enabled, successful inference responses include:

Header Meaning
X-RateLimit-Limit Requests allowed in the current window
X-RateLimit-Remaining Requests left in the window
X-RateLimit-Reset Seconds until the window resets
Retry-After Seconds to wait (sent with 429 responses)
X-Request-ID Stable identifier for the logical request

Rate-limited requests return 429 with code rate_limit_exceeded. Concurrency exhaustion returns 429 with code concurrent_request_limit_exceeded and Retry-After: 1.

Spending-limit errors include additional headers:

Header Meaning
X-Quota-Period daily or monthly
X-Quota-Limit-Paise Configured cap in paise
X-Quota-Used-Paise Already committed spend in paise
X-Quota-Remaining-Paise Remaining budget in paise
X-Quota-Reservation-Paise Reservation required by this request

Output-token limit errors include X-Quota-Max-Output-Tokens and X-Quota-Requested-Output-Tokens.

Limits are resolved from the stricter of the account policy and the API key policy. Spending windows use UTC calendar days and months. Only settled retail charges plus active reservations consume a cap.

Daily and monthly caps are set in the dashboard under Billing & wallet. Requests that would exceed a cap fail with 402 daily_spending_limit_exceeded or 402 monthly_spending_limit_exceeded and the quota headers listed above.

Send an Idempotency-Key header to make retries safe:

Idempotency-Key: 6f1c2a9e-...

For non-streaming chat requests, replaying the same key with the same body returns the stored response and sets:

X-Oxy-Idempotent-Replayed: true

Reusing a key with a different body returns 409 idempotency_key_reused. Replaying a streaming request after it has started processing returns 409 duplicate_request; streaming responses are not stored for replay.

  • Retry 429, 502, and 503 with exponential backoff and jitter.
  • Honor Retry-After when present.
  • Do not retry 400, 401, 403, 404, or 409 without changing the request.
  • Use an idempotency key when retrying non-streaming chat completions.
  • Retry 402 only after topping up the wallet or raising a spending cap.