Skip to navigation

Errors

Every error code the API returns, what causes it, and which ones you retry.

The error envelope

Every JSON error uses one shape. The HTTP status carries the class. The code carries the reason.

{ "error": { "code": "string", "message": "string" } }

The envelope is the same on every model endpoint: the eight decision-machine-1 capabilities, the OpenAI-compatible endpoints and rakeaudio.

A wrong method or an unrouted path returns 404 with the code unknown_route. A GET on a model path hits this case. The API checks the key first, so a request without a key gets 401 instead.

Codes

CodeStatusCause
invalid_request400The body failed validation. The facade also raises it for a chat request with no user text, and for a tool_choice that names a tool outside tools.
invalid_schema400An extract schema is not an object with properties.
invalid_image400The image field is not decodable base64 of a JPEG, PNG or WebP. A URL value raises it too: the API never fetches an image.
image_too_large400The image is over 5 MB decoded. The check runs on the base64 length, before any decode.
image_with_texts400The body carries image and texts. Send image alone, or with text.
image_schema_too_large400An extract schema on an image holds more than 5 fields. The message reads extract on an image accepts at most 5 fields. Split the schema across calls, or send the text instead.
invalid_audio400rakeaudio only. The body is empty, or the API cannot decode it as audio.
audio_too_long400rakeaudio only. The audio is longer than 60 minutes.
unsupported_media_type415rakeaudio only. The Content-Type is not audio/* or application/octet-stream.
model_unavailable503The model is not available. Retry later.
unsupported_request400A chat request the model does not serve: plain chat, response_format of text or json_object, or tool_choice: "none" without a usable response_format.
missing_api_key401The request carries no Authorization: Bearer header. The message reads Send your key as Authorization: Bearer test_sk-....
invalid_api_key401The key is malformed, unknown or revoked. The message reads Incorrect API key provided.
production_access_disabled403Production access is unavailable. Open Billing to refresh your status; buy a bundle of at least $10 if you have no qualifying purchase.
unknown_route404The path or the method is wrong. The message names the valid model paths.
model_not_found404A wrong model id on POST /v1/chat/completions, or a wrong id on GET /v1/models/{id}.
rate_limit_exceeded429The organization passed its request or input-token limit. The response carries retry-after in seconds.
insufficient_quota429The key’s credit pool is exhausted. Wait for the monthly test renewal, or add purchased credits for production keys.
runner_error502Inference failed on one slot, then failed the retry on a second slot. The message reads Inference failed twice. Retry.
overloaded529No inference slot became free inside the wait window. The message reads Every inference slot stayed busy. Retry with backoff.
http_errorfrom the exceptionAn internal HTTP exception reached the error handler.
internal_error500Anything else. The message reads Internal Server Error.

The spec declares 502 and 529 on the eight capability endpoints. It declares 529, but not 502, on POST /v1/chat/completions.

Validation messages

invalid_request reports the first three validation issues. Each issue reads path: message. The issues join with ; , and the path is body when the rule covers the whole object.

{"error":{"code":"invalid_request","message":"labels: Too small: expected array to have >=2 items"}}

The message body: provide text, texts or image also appears when you send none of the three fields. All eight capabilities need exactly one of text, texts or image.

OpenAI-compatible errors

The facade rejects requests it cannot map to a capability.

{"error":{"code":"unsupported_request","message":"decision-machine-1 decides, it does not chat. Send response_format.json_schema for structured extraction, tools for function calling, or use the capability endpoints under /v1/decision-machine-1/."}}
{"error":{"code":"model_not_found","message":"Unknown model \"gpt-4o\". Use \"decision-machine-1\"."}}

A wrong id on GET /v1/models/{id} returns a shorter message.

{"error":{"code":"model_not_found","message":"Unknown model. Use \"decision-machine-1\"."}}

Which errors you retry

StatusRetry?Action
400NoFix the request. The same body fails again.
401NoFix the key, or create a new one in the console. See Authentication.
403NoRefresh your status in Billing. Buy a qualifying credit bundle only if you have no qualifying purchase.
404NoFix the model id, the path, or the method.
429Only for rate_limit_exceededWait for retry-after. Do not retry insufficient_quota until the applicable credit balance changes.
500NoDo not loop. Capture the message and the request body, then report them.
502Yes, once or twiceThe service already retried on a second slot. Wait, then send the call again.
529Yes, with backoffEvery slot stayed busy. Back off and send the call again.

Only 429 rate_limit_exceeded carries retry-after. A 429 insufficient_quota requires a credit balance change, not a timed retry.

Use exponential backoff with jitter on 502 and 529. Honour retry-after on 429. Cap the attempts at three. Treat 529 as backpressure, not as a fault. Lower your concurrency when you see it often.

Retry code

The examples below retry 502 and 529 only, and give up after three attempts.

for attempt in 1 2 3; do
code=$(curl -s -o /tmp/dm.json -w '%{http_code}' \
-X POST https://api.milliseconds.ai/v1/decision-machine-1/yes-no \
-H 'Content-Type: application/json' \
-H 'authorization: Bearer test_sk-...' \
-d '{"text":"The server returned a 500.","statement":"This reports an outage."}')
if [ "$code" != "502" ] && [ "$code" != "529" ]; then break; fi
sleep $((attempt * 2))
done
cat /tmp/dm.json

Authentication and rate-limit errors

Both authentication failures return 401:

{"error":{"code":"missing_api_key","message":"Send your key as Authorization: Bearer test_sk-..."}}
{"error":{"code":"invalid_api_key","message":"Incorrect API key provided."}}

A rate-limit breach returns 429. The message names the limit, requests or tokens:

{"error":{"code":"rate_limit_exceeded","message":"Rate limit reached for tokens on this organization. Retry after 12s."}}

Read retry-after on 429 rate_limit_exceeded. It gives the wait in seconds. Limits and rate limits documents the x-ratelimit-* headers that let you stay below the limit.

Next

  • Authentication covers the key format and the 401 codes.
  • Limits and rate limits lists every field limit that raises invalid_request.
  • Input shows how to shape text and texts correctly.
  • Extract documents the schema rules behind invalid_schema.