Error Reference
Complete reference for all error codes, HTTP status codes, and troubleshooting steps.
Error Response Format
Every AI Gateway endpoint (chat, vision, audio, embeddings, …) returns errors as flat JSON. The error field is always present and is a string — for gateway-level failures it is a human-readable phrase (with a machine code in code), while endpoint-level failures use the machine code directly as error (e.g. "bad_request").
{
"error": "Error message describing what went wrong",
"message": "Human-readable details",
"code": "machine_code"
}Fields by failure class:
The error envelope is not OpenAI's
{ "error": { "message", "code", "type" } }shape. Parseerroras a string.
HTTP Status Codes
Gateway-level Codes
These come from the shared gateway middleware before the endpoint runs:
Endpoint-level Codes
The AI endpoints return these via error (and code where meaningful):
Security guards (input/output) return their own blocked responses with error, message, and reasons in the 4xx range.
Rate Limit Headers
Rate-limited responses include X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix timestamp in milliseconds), and every gateway response carries X-Request-Id for correlation.
429 responses also set a standards-compliant Retry-After header in seconds. The same value is available as retry_after_ms in the body.
Error Handling Example
try {
const response = await cencori.ai.chat({ model: 'gpt-4o', messages });
} catch (error: any) {
if (error.status === 429) {
const retryAfter = error.retryAfterMs ?? 60_000;
// Wait and retry...
}
}Troubleshooting
credit_balance_exhausted(403) — top up inOrganization → Billing. Free/Enterprise tiers aren't credit-gated.rate_limit_exceeded(429) — 60 requests/min per project for all tiers. Back off forRetry-Afterseconds or use a second project.monthly_request_limit_reached(429) — free tier resets on the monthly cycle (see reset-usage cron).provider_error(400) — read themessage; the truncated upstream body is included.

