Errors and limits
Error envelope
Section titled “Error envelope”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 codes
Section titled “Status codes”Inference requests
Section titled “Inference requests”| 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
Section titled “Rate limits”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.
Spending limits
Section titled “Spending limits”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.
Idempotency
Section titled “Idempotency”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: trueReusing 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 guidance
Section titled “Retry guidance”- Retry
429,502, and503with exponential backoff and jitter. - Honor
Retry-Afterwhen present. - Do not retry
400,401,403,404, or409without changing the request. - Use an idempotency key when retrying non-streaming chat completions.
- Retry
402only after topping up the wallet or raising a spending cap.