Errors
The API uses standard HTTP status codes and OpenAI-compatible JSON error
responses. Use the HTTP status for broad handling and error.code when you
need to distinguish errors that share a status, such as the two 429
responses.
Error envelope
Celeris API errors use this shape:
{
"error": {
"message": "Invalid or missing API key.",
"type": "authentication_error",
"code": "invalid_api_key"
}
}
message: a human-readable description.type: a broad error class, such asauthentication_errororrate_limit_exceeded.code: a stable, machine-readable code. Use it to distinguish errors that share an HTTP status. See429.
Some 5xx responses may not include a JSON body. Retry all 5xx responses by
status rather than requiring an error.code value.
If you send an X-Client-Trace-Id header, Celeris echoes it in API responses
so you can correlate failures with application logs and support cases.
| Status | code | Retry? |
|---|---|---|
400 | max_output_tokens_exceeded or another validation code | After fixing the request |
401 | invalid_api_key | After fixing credentials |
402 | insufficient_quota | After adding credit |
404 | not_found | After fixing the URL |
413 | payload_too_large | After reducing the request body |
429 | rate_limit_exceeded / service_busy | Yes; honor Retry-After |
502 | upstream_error | Yes, with backoff |
503 | service_unavailable | Yes, with backoff |
400 Bad Request
The request is invalid. The response body describes the validation error.
Common causes:
- Malformed JSON, or a
messagesarray that doesn't match the chat format. - An explicit
max_tokens,max_completion_tokens, ormax_output_tokensabove the model's output limit returnsmax_output_tokens_exceeded. Reduce that value before retrying, or contact support if you need a higher limit. max_tokensis zero or negative, or prompt tokens plusmax_tokensexceed 131,072. Requests are not silently truncated; see Models.- On
/v1/responses, an image part missing its requireddetail, or one written with the chat spellings (text,image_url) instead ofinput_text/input_image. The400body carries a schema error for every input shape the request was checked against, rather than naming the missingdetail; see Image input. - A JSON-mode request with an invalid
json_schema, or whose output could not be produced as conforming JSON. Streaming aresponse_formator a forcedtool_choicerequest also returns400.
What to do: correct the request before retrying.
401 Unauthorized
Code: invalid_api_key (type authentication_error). The Authorization
header is missing, malformed, or carries a key that is unknown or revoked.
{"error": {"message": "Invalid or missing API key.", "type": "authentication_error", "code": "invalid_api_key"}}
Common causes:
- No
Authorization: Bearer ck_...header, or a typo in it. - A revoked or rotated key still deployed somewhere.
- A recently created key that is still within the documented activation window.
What to do: check the header and the key's status in the Console. Don't retry unchanged requests. If the key was just created or rotated, wait up to one minute before trying again.
402 Payment Required
Code: insufficient_quota (type insufficient_quota). Your workspace has no
prepaid credit remaining.
{"error": {"message": "Your prepaid credit balance is exhausted. Add credit to continue.", "type": "insufficient_quota", "code": "insufficient_quota"}}
What to do: top up credits under Settings → Billing, then retry. Do not retry until credit is available. Because the balance is shared by all keys in the workspace, production systems should alert on this response.
404 Not Found
Code: not_found (type invalid_request_error). The URL does not identify an
available model, usually because of a typo in the model segment of the
base URL.
{"error": {"message": "No model is served at this path. Check the URL path segment.", "type": "invalid_request_error", "code": "not_found"}}
What to do: compare the URL and request-body model field with the values
in Models.
413 Payload Too Large
Code: payload_too_large (type invalid_request_error). The request body
exceeds the endpoint's 64 MiB (67,108,864-byte) maximum size.
{"error": {"message": "The request body exceeds the maximum allowed size for this model.", "type": "invalid_request_error", "code": "payload_too_large"}}
What to do: reduce the request body before retrying. A prompt that fits the
byte limit but exceeds the input headroom left by max_tokens returns a
400.
429 Too Many Requests
Two codes share this status. Both are retriable and include a Retry-After
header in seconds:
rate_limit_exceeded: the workspace exceeded its request-rate limit.service_busy: the service is temporarily unable to accept more work.
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 1
{"error": {"message": "You have exceeded your workspace's request rate. Slow down and retry, or contact support for a higher sustained limit.", "type": "rate_limit_exceeded", "code": "rate_limit_exceeded"}}
{"error": {"message": "The service is busy. Please retry in a moment.", "type": "rate_limit_exceeded", "code": "service_busy"}}
Requests that return 429 are not charged.
What to do: wait at least as long as Retry-After, then retry with
exponential backoff and jitter. If rate_limit_exceeded persists, reduce
concurrency or contact support about a higher
sustained rate. Report persistent service_busy responses to support.
502 Bad Gateway
Code: upstream_error (type api_error). The model service is temporarily
unavailable.
{"error": {"message": "The model service is temporarily unavailable. Please retry with backoff.", "type": "api_error", "code": "upstream_error"}}
What to do: retry with backoff.
503 Service Unavailable
Code: service_unavailable (type api_error). The service is temporarily
unavailable.
{"error": {"message": "The service is temporarily unavailable. Please retry shortly.", "type": "api_error", "code": "service_unavailable"}}
What to do: retry with backoff. If the error persists, check the Console
or contact support. Retry any 5xx by status;
do not require a JSON body or a specific error code.
Retries and timeouts
- Retry
429,502, and503, with exponential backoff and jitter, honoringRetry-Afterwhen present. - Don't retry
400,401,402, or404without changing something first. - Set client timeouts. Choose a timeout that matches your workload and latency objective. Treat timeouts as transient and retry with backoff.
A note for OpenAI SDK users
OpenAI SDKs expose Celeris errors as HTTP exceptions. Branch on the HTTP
status, or inspect error.code when you need to distinguish the two
429 responses:
from openai import APIStatusError
try:
response = client.chat.completions.create(...)
except APIStatusError as err:
if err.status_code == 429:
... # back off and retry
elif err.status_code == 401:
... # fix credentials; do not retry
else:
raise