Errors & Rate Limits
Error response shapes, the full HTTP status code table, rate limit behavior, and a retry strategy that works with Atlas Cloud.
Error response shapes
Atlas Cloud returns three different error shapes depending on which part of the API you call. Check the shape before writing a parser.
Used by the LLM protocol endpoints and the media generation endpoints:
{
"code": 401,
"msg": "unauthorized",
"request_id": "…",
"data": null
}Every response carries an X-Request-ID header. Log it — it is the fastest way for support to trace a specific call.
HTTP status codes
| Status | Meaning | What to do |
|---|---|---|
400 | Malformed request: unparseable body, missing model, wrong content type, invalid retention header, or an invalid webhook_url | Fix the request. The msg field names the specific problem |
401 | Authentication failed — key missing, unknown, or expired | Check the key. Note that a wrong URL path also returns 401, so verify the endpoint too |
402 | Insufficient balance, or a Coding Plan allowance that has run out | Top up |
403 | Account or user is not permitted — includes using a Coding Plan key on a model that does not accept one | Check the key's scope, or contact support |
404 | Resource not found. For models this also covers models that are not available to your account | Check the model ID against the catalog |
413 | Request body exceeds 50 MB | Send a URL instead of inline Base64, or upload the file first |
429 | Rate limit reached | Back off and retry — see below |
451 | Blocked in your region | Not retryable |
500 | Internal error | Retry once, then report with the request ID |
503 | Temporarily unavailable | Retry with backoff |
504 | A synchronous request exceeded the maximum wait | Switch to the asynchronous flow and poll |
A 401 does not always mean your key is wrong. The gateway authenticates before routing, so a typo in the path also produces 401 rather than 404. If a key works elsewhere, check the URL first.
Job-level error codes
When an asynchronous job fails, data.error_code carries a numeric platform code that is more specific than the HTTP status. For example, 1039 indicates the input was rejected by content moderation.
data.error holds a human-readable description. Log both, along with the prediction ID.
Rate limits
Rate limits apply per account and per model. Exceeding one returns 429.
LLM and media endpoints do not return X-RateLimit-Limit, X-RateLimit-Remaining, or Retry-After. You cannot read your remaining quota from response headers — implement backoff on the client instead.
The /public/v1 billing endpoints are the exception: their 429 responses do include Retry-After.
If you need higher limits for a production workload, contact us with your expected request volume and model mix.
Retry strategy
Retry on 429, 500, 503, and 504, plus network-level failures. Do not retry 400, 401, 402, 403, 404, or 451 — they will fail identically.
Retry read requests freely. Be careful with retrying generation submissions: a request that timed out may still have been accepted, and a blind retry can create — and bill for — a second job. Prefer submitting asynchronously and polling, so a lost response never means a lost job.
import time, random, requests
RETRYABLE = {429, 500, 503, 504}
def call_with_retry(url, payload, api_key, max_attempts=4):
for attempt in range(max_attempts):
response = requests.post(
url,
json=payload,
headers={"Authorization": f"Bearer {api_key}"},
timeout=60,
)
if response.status_code not in RETRYABLE:
return response
if attempt == max_attempts - 1:
break
# Exponential backoff with jitter, so clients don't retry in lockstep
delay = min(2 ** attempt, 30) * (0.5 + random.random() / 2)
time.sleep(delay)
return responseStreaming errors
When a streaming request fails before the stream opens, you get a normal HTTP error. Once the stream has started, the connection stays open and the error arrives as an event in the stream — so a 200 on a streaming call does not guarantee a complete response. Always handle mid-stream termination.
Streams may also contain SSE comment lines beginning with : as keep-alive signals. These are not data and must be ignored — most SSE clients do this for you, but hand-rolled parsers often do not.
Getting help
When reporting a problem, include:
- The
X-Request-IDheader from the failing response - The prediction ID, for asynchronous jobs
- The exact model ID and the timestamp
Reach us through Support.
Related
Last updated on