Atlas Inference

Error codes

The status codes, error types, and codes Atlas emits — and which are worth retrying.

Errors use the OpenAI status codes and body shape, so existing retry and backoff logic works unmodified.

{
  "error": {
    "message": "Your organization has reached its tokens-per-minute limit for this model.",
    "type": "rate_limit_error",
    "param": null,
    "code": "rate_limit_exceeded",
    "request_id": "req_01k4v9m2..."
  }
}

param and code are always present, explicitly null when unknown, because that is what OpenAI sends and some clients read the keys unconditionally. request_id is additive; it is also the x-request-id response header.

Always capture request_id. Prompt and completion content is not retained, so the request id is the only handle Atlas has on a specific failed call. A report without one is very hard to act on.

Error types

TypeStatus
invalid_request_error400
authentication_error401
permission_error403
not_found_error404
rate_limit_error429
insufficient_quota429
server_error500
service_unavailable_error503

Both quota exhaustion and throttling are 429 so a client's existing backoff handles them; the type and code distinguish them for a human reading a log.

Codes

Request problems — fix and resend

CodeStatus
invalid_request_body400The body is not a valid chat completion request. param names the field.
unsupported_parameter400n greater than 1. One choice per request.
model_does_not_support_tools400Tools sent to a model without tool calling.
model_does_not_support_structured_output400json_schema sent to a model without it.
unsupported_json_schema400The schema is outside the published subset.
request_too_large413Body above the model's max_request_bytes.
model_not_found404No such model identifier.
model_retired404The identifier existed and has passed its shutdown date.
backend_rejected_request400The serving backend refused the request as malformed.

Every one of these is refused before admission: they cost no tokens and consume no rate-limit budget.

Authentication

A 401 authentication_error with code invalid_api_key is returned for every credential problem, with the same body: a missing key, a malformed key, an unknown key, a revoked key, an expired key, and a read-scoped key presented to the inference endpoint all look identical.

{
  "error": {
    "message": "Incorrect API key provided. You can find your key in the Atlas console.",
    "type": "authentication_error",
    "param": null,
    "code": "invalid_api_key",
    "request_id": "req_..."
  }
}

This is deliberate. Distinguishing "no such key" from "revoked" would turn the endpoint into an oracle telling an attacker which stolen keys are still worth trying. If you are debugging a 401, check the key's revoked_at and prefix in the console rather than reading anything into the response.

Output problems

Code
structured_output_not_jsonThe model's content did not parse as JSON.
structured_output_schema_violationIt parsed but did not validate against your schema.

On a stream these arrive as an in-band error frame after the deltas, with no [DONE].

Capacity and infrastructure — retry

CodeStatusRetry?
rate_limit_exceeded429Yes, honor retry-afterYour organization's limit for that model.
server_overloaded503Yes, your own backoffAtlas capacity, or Atlas's own upstream quota. No retry hint.
server_shutting_down503YesA deploy is draining.
backend_timeout503YesThe serving backend did not respond in time.
backend_unavailable500YesThe backend could not be reached or is not configured.
backend_protocol_error500MaybeThe backend's response could not be parsed.
backend_error500MaybeAn unclassified backend failure.
internal_error500MaybeAn Atlas fault. Report the request_id.

Client-side

CodeStatus
client_disconnected499You closed the connection before the response finished. Not an Atlas failure — but note that generated tokens are still metered.

429 versus 503

The distinction Atlas cares most about you getting right:

429 rate_limit_exceeded

Your organization exceeded its own configured limit. Carries retry-after, retry-after-ms, and the x-ratelimit-* headers. If this is frequent under normal load, ask for a higher limit.

503 server_overloaded

You were within your limits; Atlas capacity was the constraint. Carries no quota headers and no retry hint at all.

The absence of headers on the overload is enforced, not incidental. A retry hint present on one cause and absent on the other would let a client infer quota state from a capacity event — and a hint Atlas invented would have every caller retrying on the same beat, against a service that is already saturated.

Two causes map to server_overloaded: Atlas's fleet being saturated, and Atlas exhausting its own quota with an upstream provider. They are deliberately indistinguishable to you, because your correct action is identical.

If your alerting groups "5xx and 429" into one series, you cannot tell these apart — and only the 429 is something you can act on. Split them.

Retry guidance

  • Use your SDK's built-in retry. The OpenAI clients already retry 429 and 5xx with exponential backoff and jitter, and they already prefer retry-after-ms over retry-after.
  • Do not retry 400, 404, or 413. Nothing about a resend changes the answer.
  • Do not retry a 401 until you have checked the key. Repeated retries with a revoked key will not start working.
  • Treat a stream that ended without [DONE] as a failure, whatever the status was — see Streaming.

On this page