Docs

Start here

Errors

Every error the API can return, what causes it, and what to do about it. The `docs` field in an error body links straight to its entry here.

Every refusal has the same shape, and the docs field points at this page:

{
  "error": "insufficient_credits",
  "error_type": "PaymentError",
  "message": "Not enough credits for this request.",
  "retry": "never",
  "charged": "no",
  "required": 29,
  "docs": "…/errors#insufficient_credits",
  "request_id": "54b4754a-3e17-4629-adb1-7d3f067e97d3"
}

Match on error, never on message — the sentence is written for a person and may be reworded. request_id is on every response, success or not, and in the X-Request-Id header; quote it if you ask us about one.

error_type is the class of the refusal — a short list that does not grow with the codes. retry says what sending the request again does: same_key, nothing moved and the identical request may succeed later; after_retry_after, the same after the Retry-After header's seconds; new_key, this idempotency key is spent and trying again is a new request and a new charge; poll_first, a job may exist and its charge may stand, so read it before resending anything; never, the same request is refused the same way. charged says what happened to the money: no, refunded, stands, or unknown, when the job's own credits_charged answers it. Three codes say charged as a boolean about the one request instead — true is stands, false is no — as they always have. A response that a retry cannot help, or that may pay twice, also carries x-should-retry: false.

Each entry prints the status a response carrying its code answers. On the queue hosts — queue.auray.run and auray.run, which MCP's tools call too — a refusal of what the request says (an option, the body, a field), decided while reading it and before anything is charged, is answered 422 instead of its 400, with detail a list of {loc, msg, type} naming where the problem is (["body"] when the parser names no field); so is the model's own refusal of the request as it was written — its content filter, a value or a file it would not take — which is also what the result read of such a job answers. Those entries print both. A dispatch the queue hosts could not confirm is answered 202 with the request's status document rather than 502 (dispatch_unresolved).

/openai/v1 answers in OpenAI's error object, and some statuses differ there because OpenAI's clients branch on them: an empty wallet (insufficient_credits) and a spent key ceiling (key_credit_ceiling) are 429 insufficient_quota, and any other 402 is a 429 too; output_limit_reached is 400, as OpenAI answers a completion its max_tokens cut off; a catalogue language model's own parser refuses its input at 422, as on the queue hosts, in an object that has no detail — what the translation from OpenAI's fields refuses stays 400; and the model's own refusal of the request as written — its content filter, or a value or a file it would not take — is 400, as OpenAI answers an invalid or refused request, where the queue hosts answer it 422. On our own chat models a refusal that comes after the 200 was committed, on a stream or a long answer kept alive, arrives inside that 200. OpenAI-compatible clients has the details. Anywhere else a code is answered at a status its entry prints.

This page is generated from the error registry every route is typed against, so a code that exists here is one the API can return or a job can carry, and one it can return cannot be missing from here.

#Before your request is looked at

These are decided from the key and the headers alone, before any body is parsed and before anything is charged.

#account_banned

403 · retry never · charged no

The account that holds this key has been banned. Every key it held was revoked with it, and the account is checked before the key, so this is also what one of those revoked keys answers.

What to do. Nothing a new key would fix — a reinstated account mints new keys, a banned one cannot. Contact support with the request_id to appeal.

#account_limited

403 · carries bucket · retry never · charged no

The account is limited: it may read and may not spend or write. bucket names the one that was refused — generate, interactive, write or egress.

What to do. Reads still work, so a job already running can be polled and its result fetched. For the rest, contact support with the request_id.

#account_suspended

403 · retry never · charged no

The account that holds this key is suspended. Its keys are intact and every one of them is refused on every bucket, reads included, until the suspension is lifted.

What to do. Nothing on your side. Do not mint another key; it is refused the same way. Contact support with the request_id.

#api_disabled

503 · retry never · charged no

The public API, or the one product you called (a model family, chat, embeddings), is paused. For the whole API the answer is the same for a valid key and an invalid one, so it says nothing about your key. message carries our note when there is one — why, and often until when.

What to do. Nothing on your side, and nothing was charged. Wait and send the same request again later; a retry within seconds meets the same answer.

#browser_origin_refused

403 · retry never · charged no

Your request carried an Origin header. This API is not callable from a browser — no Access-Control-* header is ever sent, so a browser could not use the response anyway, and a key in front-end code is a key that has been published.

What to do. Call from your server. Some HTTP clients set Origin by default even outside a browser; if you are getting this from a backend, remove that header.

#insufficient_scope

403 · carries required, accepted, scopes · retry never · charged no

The key is valid but was not minted with a scope this route accepts. accepted lists every scope that would have done — the kind of output first (image:write), then the older name a key minted with the older scope names may carry (photo:write, auray-ai-video:write, external:write); required is the first of them — the one to mint a new key with, except two that Account does not mint: external:write, which comes from a door that names no model (a read of an upload that names neither address nor product, a catalogue job's cancel by a key holding no kind), and auray-ai-video:write, which comes from the withdrawn product: "video" upload and its read, open only to the keys that used them — that name, or video:write beside external:write, as the message says; scopes is what the key has.

What to do. Scopes cannot be added to an existing key. Mint a new one with the scope named in required — or, where that is external:write, name the model instead: the address on an upload's read, or a key with the kind the job's model makes. Where it is auray-ai-video:write, there is nothing to mint: no address reads that bucket, and a file for a video model goes up through its address. Listing webhooks needs jobs:read, not webhooks:write.

#invalid_api_key

401 · retry never · charged no

The key is not well formed, or no live key matches it. Length, prefix, alphabet and a checksum are all checked before any database read, so a typo is usually caught here. A key's public ID — the twelve characters Account → API Keys lists beside each key, with or without auray_sk_ in front — is not the key, and the message says so when that is what was sent.

What to do. Check the key was copied whole — it is 71 characters. The key is shown once, when it is created, and cannot be shown again; if all you have is its ID, or it looks right and still fails because it was deleted, create a new one in Account → API Keys.

#key_expired

401 · retry never · charged no

This key is past its expiry. Every key has one — 30, 90, 180 or 365 days — and it is not optional.

What to do. Mint a new one, and set a calendar reminder before its expiry rather than after.

#key_revoked

401 · retry never · charged no

This key was revoked.

What to do. Mint a new one. A revoked key never comes back.

#keys_not_configured

503 · retry never · charged no

This deployment has no key pepper configured, so no key can be verified.

What to do. Nothing on your side. Tell us, with the request_id.

#missing_authorization

401 · retry never · charged no

No Authorization header.

What to do. Send Authorization: Bearer auray_sk_…. A bare key without Bearer is also accepted.

#Rate limits and budgets

Five token buckets — read, write, generate, interactive (chat and language-model calls) and egress — refill continuously and are reported on every response in both RateLimit-* and X-RateLimit-* headers. A refusal here is about pace, except where it is about a plan, and the two look different on purpose.

#body_too_large

413 · carries limit_bytes · retry never · charged no

The request body is over 1 MiB. It is checked against content-length first and then while streaming, so an unset length does not get past it.

What to do. Send less. Images belong behind POST /uploads, which returns a signed URL you PUT the bytes to directly, precisely so they never travel through a JSON body.

#export_too_large

413 · carries window · retry never · charged no

The usage export for this window would carry more debits than one file holds, so it was refused rather than cut short — a statement with rows missing and nothing to say so.

What to do. Ask for a narrower window (month or last_month rather than 12m), or read the JSON document, which aggregates instead of listing.

#key_credit_ceiling

403 · carries ceiling, spent, required · retry never · charged no

This key has its own monthly credit budget and this request would exceed it. The account may still have plenty; the key does not.

What to do. Use a different key, or wait for the period to roll over. To lift the cap, mint a replacement key on the current plan and revoke this one. A ceiling of zero means no cap and never refuses. If a pass covered this job when you sent it, it had ended before the job started; nothing was charged — send it again under a new idempotency key.

#limiter_unavailable

503 · retry after_retry_after · charged no

The rate limiter itself could not be reached, and this API refuses rather than waving traffic through unmetered.

What to do. Retry after 5 seconds, as the Retry-After header says.

#plan_has_no_api_generate

403 · carries plan, bucket · retry never · charged no

Your plan's API keys may not spend the bucket bucket names. That is a plan figure, not running out of tokens: GET /v1/plans serves limits.api.may_generate as false for such a plan, or that bucket's burst as 0.

  • generate closed: no render starts from the API.
  • interactive closed: no chat turn, completion, response or embedding. A POST to each of these is refused:
    • /v1/chat
    • /openai/v1/chat/completions
    • /openai/v1/responses
    • /openai/v1/completions
    • /openai/v1/embeddings

Reads still answer, such as GET /openai/v1/models and GET /v1/me.

What to do. Choose a plan whose keys may generate in Account → Plan & Billing: limits.api.may_generate true and the bucket's burst above 0. Waiting does not help, because a bucket of zero never refills.

#queue_too_long

429 · carries waiting, max · retry same_key · charged no

More requests were already waiting for this product than the ?max_queue_length you sent allowed, so the request was refused rather than queued behind them. NOTHING WAS CHARGED and no job exists: the depth is read before the waiting row is written, which is the only moment the answer can still be “then do not queue me at all”.

What to do. Retry without the option to queue anyway, raise it, or come back later. waiting is how deep the queue actually was.

#rate_limited

429 · carries bucket, retry_after, reason · retry after_retry_after · charged no

reason says which limit: bucket_spent — you spent the bucket named in bucket faster than it refills (buckets are per key and refill continuously rather than resetting on a schedule); instance_fuse — more requests from this key arrived inside one second than the largest burst any plan grants, a guard against a runaway loop that sits above every plan's burst while our rate limiter answers; while it is failing, the fuse on generate, interactive and write drops below every plan's burst until it recovers, and RateLimit-Limit names that lower ceiling. Both carry RateLimit-* headers for the limit they were held to.

What to do. Wait retry_after seconds — it is also in the Retry-After header — and pace future requests against the RateLimit-Remaining header rather than retrying blind.

#request_too_large

413 · carries plan, bucket, limit · retry never · charged no

The request costs more of this bucket than the bucket can ever hold.

What to do. Ask for less in one call — fewer images, a shorter clip — or upgrade to a plan with a larger bucket.

#stream_declined

503 · carries declined · retry after_retry_after · charged no

GET <model>/requests/{id}/status/stream was refused a seat. A stream holds one function open for up to five minutes, and it is counted against THE SAME three caps ?wait= is — platform, product, account — because both are the same held connection as far as the deployment is concerned. declined says which one was full: platform_busy (nothing would have helped), product_busy (another product's queue might), account_busy (your own streams and waits are already using every seat your account may hold). NOTHING ABOUT THE REQUEST IS AFFECTED — it is queued or running exactly as it was, and this is a read.

What to do. Poll GET <model>/requests/{id}/status instead; it is the same document this stream emits, and poll_after_seconds on GET /v1/jobs/{id} paces it. Retry-After says when a seat is worth asking for again. On account_busy, close streams you are no longer reading — an abandoned connection frees its seat only when it is actually closed.

#usage_window_too_large

413 · carries window · retry never · charged no

The usage document for this window would read more of your account's credit ledger than one request is given time for, so it was refused rather than answered late or cut short. The same window refuses again: it is the size of the window, not a failed read.

What to do. Ask for a narrower window (month or last_month rather than 12m). Nothing was charged.

#vendor_budget_exhausted

503 · retry same_key · charged no

This model has reached its capacity for now. It is not your balance and not your key's ceiling.

What to do. This is ours to raise, not yours. Retry later, and tell us with the request_id if it persists.

#wait_capacity

429 · carries wait_declined, charged · retry after_retry_after · charged no

A model run on auray.run — and a completion on /openai/v1/chat/completions for a catalogue model, which is one — is held open while it runs, and every held connection counts against three caps: the platform's, the product's and your account's — one seat for every API seat you can hold across the products, 12 as shipped, and as many as the lanes in force allow. All the seats this request could have used were taken, so it was refused BEFORE IT CHARGED ANYTHING: charged is false and this request created no job. A resend of an idempotency_key that already ran — the recovery run_timed_out recommends — is refused the same way while every seat is taken, because the seat is asked for before the key is looked up: that job still exists and was charged once, and the same resend is handed it once a seat is free. wait_declined says which cap was full when it could be read. On /openai/v1/chat/completions a catalogue model refused at admission is answered with this code too, since a completion has nothing to poll: your account's catalogue seats full (account_busy, too_many_jobs on the queue host) or the API's share of them (product_busy, lane_busy there).

What to do. Retry after the Retry-After header's few seconds; this request charged nothing, so retrying it cannot pay twice. The official OpenAI SDKs retry a 429 on their own. On account_busy, run fewer at once: each run holds a seat until its answer arrives. Or submit to queue.auray.run, which holds no connection and queues instead.

#webhook_unsupported

400 · retry never · charged no

?webhook / ?fal_webhook was sent to one of the catalogue's addresses, which do not deliver a per-request callback yet. It is refused rather than accepted and dropped: answering 200 to “call me when this is done” and then never calling is a failure with no moment at which anything says so. The four auray-ai/ models deliver it today.

What to do. Register a standing endpoint with POST /v1/webhooks — it fans out for every product, including this one — or poll GET /v1/jobs/{id}. The option becomes available on these addresses later.

#The request itself

The envelope was wrong: the body, a query parameter, or a value we could not read.

#band_not_priced

422 · carries message · retry never · charged no

This model is priced by what you ask of it — a length, a size, a quality, a step count — and the combination you sent is outside every one we have a measured price for: a longer clip, a larger size or a setting above the most we priced, or a quality no price covers. We refuse it rather than charge a price measured for something cheaper. Nothing was charged.

What to do. Read message: it names the setting and what is priced. Ask within it — a shorter clip, a smaller size, a lower setting — or tell us the address and the configuration, and we will measure it and price it.

#conflicting_options

400 · 422 on the queue hosts · carries options, option · retry never · charged no

One option was sent twice, or under two spellings that disagree — ?webhook and ?fal_webhook, X-Auray-Priority and X-Fal-Queue-Priority. Both spellings are read and neither wins: choosing silently is how a client bug becomes a job that reported to the wrong webhook.

What to do. Send one of them. options names the two that disagreed.

#conversation_required

400 · retry never · charged no

A chat turn needs a conversation to belong to.

What to do. Create one with POST /chat/conversations and pass its id, or omit the id and let the turn open one.

#input_invalid

400 · retry never · charged no

An element of input was not a string — usually pre-tokenised input, an array of integers.

What to do. Send text. Pre-tokenised input is refused rather than guessed at: this deployment does not hold the tokenizer it would need to price it or to check it against the model's window.

#input_required

400 · retry never · charged no

input was missing, empty, or neither a string nor an array of strings.

What to do. Send input as a non-empty string, or a non-empty array of strings.

#input_too_long

400 · retry never · charged no

One string in input is longer than the embedding model's context window.

What to do. Chunk that string. The window is per STRING, not per request: a batch of a thousand short inputs is fine and one input above the window is not.

#input_too_many

400 · retry never · charged no

input carried more strings than one request may embed.

What to do. Split the array into batches. The ceiling is a latency bound rather than a safety one — the endpoint embeds each string separately, so a very long array runs past the request's own lifetime and is killed with the charge held.

#invalid_before

400 · retry never · charged no

before is not an ISO 8601 timestamp.

What to do. Pass the next_before value from the previous page back unchanged.

#invalid_body

400 · 422 on the queue hosts · retry never · charged no

The body parsed as JSON but was not an object — an array, a string or null.

What to do. Send a JSON object.

#invalid_category

400 · carries category, categories · retry never · charged no

GET /models?category= was given a task no model in this catalogue is filed under.

What to do. The refusal carries categories, the full list — it is derived from the models that exist rather than declared, so it is the only authoritative spelling. Two categories the desktop can draw are absent from it because nothing claims them yet.

#invalid_expand

400 · carries expand · retry never · charged no

GET /models?expand= was given something other than openapi.

What to do. expand=openapi embeds each row's full OpenAPI 3.1 contract. It is the only expansion today, and it caps limit at 25 with a default of 10 — the documents average 22 kB. For one model's contract on its own, GET /models/{address}/openapi.json is cheaper.

#invalid_idempotency_key

400 · 422 on the queue hosts · retry never · charged no

idempotency_key must match [A-Za-z0-9._-]{1,64}. Colons in particular are refused, because credit keys are built by joining fields with them and a colon here could shape another account's key. On /openai/v1/embeddings this is the body's idempotency_key. On /openai/v1/chat/completions and POST /v1/chat/conversations, which read no key before, a key outside the set — the Idempotency-Key header or the body's field — is folded into one inside it rather than refused, and the embeddings header is too.

What to do. Use a UUID, or any opaque string from that alphabet.

#invalid_json

400 · 422 on the queue hosts · retry never · charged no

The body is not JSON.

What to do. Check the serialiser, and that Content-Type: application/json is set.

#invalid_kind

400 · carries kind · retry never · charged no

GET /models?kind= was given something other than ours, resold, chat or embedding, or a comma-separated list of them — an empty word in the list included.

What to do. Use one of the four or a list, as in kind=chat,embedding; leave kind out to list the addresses (ours and resold). ours lists the models behind the apps, resold the rest of the catalogue, chat and embedding the models the chat and embeddings endpoints take.

#invalid_limit

400 · carries max · retry never · charged no

limit must be between 1 and 100.

What to do. Ask for at most 100 and follow next_before for the rest.

#invalid_logs

400 · 422 on the queue hosts · carries allowed · retry never · charged no

?logs= must be 1, 0, true or false. The first pair is what the queue protocol documents and what its JavaScript client sends; the second is what its Python client sends, because httpx serialises a bool that way.

What to do. Send ?logs=1 to ask for the runner's lines, or omit it.

#invalid_max_queue_length

400 · 422 on the queue hosts · carries max, option · retry never · charged no

?max_queue_length= must be a whole number of waiting requests, 0 or more. 0 is a real value and means “only if nobody is waiting”.

What to do. Send a non-negative integer, or omit it to queue however deep the queue is.

#invalid_products

400 · carries allowed · retry never · charged no

A webhook's products array names something that is not a product.

What to do. Use values from allowed, or send an empty array to receive every product.

#invalid_request_timeout

400 · 422 on the queue hosts · carries min, max, option · retry never · charged no

The request-timeout header must be a number of seconds between 1 and 86,400. It is a time to START, not a bound on how long the model may take: past it, a request still waiting for a seat is failed instead of dispatched.

What to do. Send a number of seconds in range. Omit it and the platform's own 30 minutes applies instead — which you may raise as well as lower.

#invalid_status

400 · carries status · retry never · charged no

GET /models?status= was given something other than connected, described, undescribed, paused or retired.

What to do. Use connected for models a request dispatches to, described for the ones that answer 501, undescribed for addresses with no published shape, paused for the ones that are paused (each row carries the code and sentence a submit would answer), retired for the ones that answer 410 — or omit it for all of them.

#invalid_title

400 · retry never · charged no

A conversation title is over 200 characters.

What to do. Shorten it, or send an empty title and let the first message name the conversation.

#invalid_url

400 · 422 on the queue hosts · carries reason · retry never · charged no

A webhook URL was refused. reason distinguishes them: not a URL, not https, a private or local host, or credentials embedded in it.

What to do. Use a public https URL with no user info. Private addresses are refused in every form we can recognise, including IPv4-mapped IPv6.

#invalid_wait

400 · 422 on the queue hosts · carries max · retry never · charged no

?wait= must be a whole number of seconds from 1 to 300.

What to do. Send an integer in range, or omit it and poll.

#messages_invalid

400 · retry never · charged no

A message was not an object, or its content was neither a string nor a list of text parts. On our own three models also: an assistant's tool_calls entry without an id or a function name, or a tool message that does not answer a call made by the assistant message just before it (only other tool results may sit between them).

What to do. Give every message a string content, or a list of {type: "text", text} parts; an assistant message carrying tool_calls may have content: null. These endpoints serve text: an image, audio or file part is refused rather than dropped, because a prompt with the picture silently missing is still charged for. Send each tool result, with the tool_call_id of its call, straight after the assistant message that made the call.

#messages_last_not_user

400 · retry never · charged no

The last message was the assistant's.

What to do. End the array with the user's message — or, on our own three models, with the tool results the assistant's last calls asked for. Assistant prefill — asking the model to continue its own half-written reply — is not supported here.

#messages_required

400 · retry never · charged no

messages was missing, not an array, or empty.

What to do. Send messages as a non-empty array of {role, content} objects.

#messages_role_unsupported

400 · retry never · charged no

A message carried a role the model does not take: function (the legacy spelling of a tool result) anywhere, and tool on a catalogue model.

What to do. Our own three models take system, developer, user, assistant and tool; a catalogue model takes the first four. A tool result folded into prose is a different request than a tool result, so it is refused instead of reshaped — send it to a model that takes tools.

#messages_system_only

400 · retry never · charged no

A system or developer message had nothing after it — no user message, no tool result.

What to do. Follow it with the user's message. There is nothing for the model to answer yet. (A catalogue model that has no system prompt of its own folds system text onto the next user message; our own three keep it as its own message.)

#method_not_allowed

405 · retry never · charged no

GET or DELETE was sent to /mcp. The Model Context Protocol's HTTP transport uses those to open a server-initiated stream and to end a session, and this server keeps neither: it is stateless and answers one JSON-RPC message per POST.

What to do. Send POST /mcp with one JSON-RPC 2.0 message; the Allow header says the same.

#model_deprecated

410 · carries successor, deprecated_at · retry never · charged no

That address was withdrawn. It resolved to a model this platform published and no longer runs — the request was understood and refused, which is why it is 410 and not 404.

What to do. The body carries successor when there is one: the address to move to, and the same request body will usually work against it. When successor is null the model was withdrawn with no replacement, and GET /models lists what is still offered. deprecated_at says when, so a client that broke can tell whether this is why.

#model_not_described

404 · retry never · charged no

There is no model published at that address. Either the path is a typo, or it names a model whose documentation nobody has read yet — the two look the same from outside, and both mean there is nothing to send.

What to do. GET /models lists every address this platform answers at. Note the path is the model's full name, slashes and all — bria/fibo-edit/blend, not bria.

#model_not_synchronous

400 · carries queue_url, expected_seconds, wait_ceiling_seconds · retry never · charged no

auray.run/<model> holds the connection until the model answers, and this request cannot finish inside the longest wait the model allows: either the model may not be waited for at all — its cheapest job outlives any connection worth holding — or this request usually takes longer than that wait, which the body says as expected_seconds beside wait_ceiling_seconds (a textured, rigged or controlled 3D model does). The address is real; this HOSTNAME cannot serve this request.

What to do. Send the same request to the queue host named in queue_url, then poll status_url, stream it, or register a webhook. Nothing was charged.

#path_not_found

404 · retry never · charged no

Nothing is served at that path on that host. It is decided from the path and the hostname alone, so it says nothing about your key — a mistyped endpoint used to be answered as a missing authorization, which sent people to debug the wrong thing. A path segment whose percent-escapes do not decode to UTF-8 text (%E0%A4) names nothing on any host, and is answered the same way.

What to do. Read the refusal's message: it names the absolute base that serves the path you asked for. The platform API is https://api.auray.ai/v1 (GET it for an index, or read https://api.auray.ai/v1/openapi.json); OpenAI-compatible clients use https://api.auray.ai/openai/v1; model addresses are submitted at https://queue.auray.run/<address> and run at https://auray.run/<address>. If the message says the path is not UTF-8 text, encode each segment with encodeURIComponent before sending it.

#price_out_of_range

400 · 422 on the queue hosts · carries message · retry never · charged no

As written, this request costs more than the per-job ceiling set for that model. The usual cause is a duration, a resolution or a count at the top of its range.

What to do. Ask for less — a shorter clip, fewer images, a smaller size — or split the work across several jobs. The request is refused rather than quietly trimmed, so what you asked for and what you would have been billed for cannot differ.

#queue_not_offered

400 · 422 on the queue hosts · carries option, model · retry never · charged no

You sent a queue option — X-Auray-Priority or ?max_queue_length — to a model that does not queue: when its capacity is full it refuses at once rather than parking the job, so there is no wait in a queue for the option to shape. GET /v1/models says which models queue (lifecycle.queue). A request timeout (X-Auray-Request-Timeout, or X-Fal-Request-Timeout, which a queue-protocol client sends for client_timeout) is not refused: it bounds the time to start, and a model that starts or refuses at once always meets it.

What to do. Drop the option for this model, and retry on service_busy or lane_busy with backoff.

#response_format_unsupported

400 · retry never · charged no

response_format asked for something the model cannot give. Our own three models answer json_object and json_schema through a function of their own, so they refuse a format sent beside tools (an answer could then be either), a type other than text, json_object or json_schema, and a format that is not an object; a catalogue model takes json_object or json_schema only where it declares JSON output.

What to do. Send tools or response_format, not both, on our own models; otherwise pick a model whose capabilities.response_format in GET /openai/v1/models lists what you need.

#tools_rejected

400 · retry never · charged no

On /openai/v1/chat/completions, one of our own three models was sent tools (or a tool_choice, or a response_format it answers through a function) and the model's server refused the request as written — before answering, or inside the stream before a word of answer. A schema the server cannot read is the usual cause. Nothing was charged.

What to do. Check that each tool's parameters is a valid JSON Schema object and that tool_choice names one of the tools you sent. Retrying the same request gets the same answer. Streamed, the refusal arrives as OpenAI's in-stream error chunk.

#tools_unsupported

400 · retry never · charged no

Tools were sent where they cannot be answered. On /openai/v1/chat/completions, a catalogue model (auray-serverless/model/…) was sent tools, functions, a tool_choice naming a tool, an assistant message carrying tool_calls, or a tool result: the task interface those models run behind returns no tool calls, so answering as if the tools were there would be a lie your agent loop could not detect. On our own three models — which do take function tools — a tool of a hosted type (web_search, file_search, …) that this surface would have to run, or the legacy functions/function_call fields.

What to do. Send tools to glm-5-3-flash, deepseek-v4-1-flash or kimi-k3, as function tools (a custom tool is taken too, as a function of one string); send tools and tool_choice instead of functions and function_call. On a catalogue model, send the request without tools — tool_choice: "none" or "auto" with no tools is accepted and ignored.

#unknown_content_type

400 · carries accepted, max_bytes · retry never · charged no

The file's type is not one the address takes: an upload named by address accepts only the kinds of file that address's fields read (an image model takes no audio), and one named by the older product accepts what that bucket holds. accepted lists the types; max_bytes is the ceiling.

What to do. Convert to a type in accepted, and declare the same type on the PUT that follows.

#unknown_effort

400 · retry never · charged no

The chat effort named does not exist.

What to do. Use light, balanced or deep. On /openai/v1/chat/completions the field is reasoning_effort: our own three models take minimal, low, medium or high, and a catalogue model takes its own levels — the sentence lists them, GET /openai/v1/models publishes them as capabilities.reasoning_effort, and the nearest level is used for a word the model does not have.

#unknown_format

400 · carries allowed · retry never · charged no

format is not json or csv. allowed lists them.

What to do. Send format=csv for one row per charged job, or leave it out for the JSON document.

#unknown_model

400 · carries allowed · retry never · charged no

The model named is not one this surface serves.

What to do. Use glm-5-3-flash, deepseek-v4-1-flash or kimi-k3. On /openai/v1/chat/completions a catalogue language model is accepted too, by its address (auray-serverless/model/<slug>) or its slug; GET /openai/v1/models lists every model that surface serves, and an address that is not a language model, or is withheld from the catalogue, is answered with this code (one model paused answers model_disabled, and every model of a family paused whole vendor_disabled). allowed lists the chat models on /v1/chat; POST /v1/uploads checks its address against the catalogue and sends no list — GET /v1/models is that list. The older qwen and kimi still resolve to the first two and will be withdrawn. A name with -thinking-<level> (minimal, low, medium, high, xhigh or max) and then -fast after it — what Cursor sends when a thinking level or Fast is picked — is read as the model it extends, the level as its reasoning_effort unless the body names one; any other suffix is this refusal.

#unknown_priority

400 · 422 on the queue hosts · carries allowed, option · retry never · charged no

The priority header must be normal or low. low puts the request behind every normal one in the same queue; there is no way to buy your way in front of other people.

What to do. Send normal, low, or nothing.

#unknown_product

400 · carries allowed, products · retry never · charged no

The product named is not one this route serves.

What to do. Use one of the values in allowed.

#unknown_window

400 · carries allowed · retry never · charged no

window is not one of the usage document's four: month, last_month, 90d or 12m. allowed lists them.

What to do. Send one of the four, or leave window out for the current month.

#upload_not_accepted

400 · carries address · retry never · charged no

No field of the address in address takes a file — a text-to-image model, or our music and video products, read words and settings — so there is nothing to upload for it.

What to do. Upload for the address you will submit the file to. GET /v1/models/{address} lists its fields; one of kind image, audio, video, mesh or file is where an upload goes.

#wait_unsupported

400 · 422 on the queue hosts · carries product · retry never · charged no

Video does not accept ?wait=. A render takes minutes, and holding a connection open for one would time out somewhere between us and you rather than at a moment either of us chose.

What to do. Poll GET /jobs/{id}, or register a webhook and be told.

#What each product accepts

Every one of these is a 400 from the product's own parser, decided before capacity is checked and long before anything is charged.

#bad_value

400 · 422 on the queue hosts · retry never · charged no

A field is present with a value the model's spec does not allow: the wrong JSON type (a quoted number where a number is wanted, a string where a list is), a value outside a documented enum or range, a string that is not a URL where a URL is wanted. Some ranges are narrower than the model maker's document says, because we measured the model: a language model that cannot answer below a number of output tokens refuses a smaller max_tokens here, before anything is charged, and GET /openai/v1/models publishes that floor as min_output_tokens. On /openai/v1/chat/completions it is also a tool definition that cannot be sent as written — a name outside 1 to 64 letters, digits, _ or -, two tools with one name, parameters that is not an object, more than 128 tools — or a tool_choice naming a tool the request does not offer.

What to do. The message says which field and which rule. Types are strict: send 4, not "4"; true, not "true"; a list for a list field. Nothing was charged.

#control_data_invalid

400 · 422 on the queue hosts · retry never · charged no

control_data could not be read as the control type you named.

What to do. Check the shape against the tier's documentation.

#control_not_supported_by_tier

400 · 422 on the queue hosts · retry never · charged no

That control does not apply to that tier.

What to do. Use a tier that accepts it, or drop the control.

#control_type_required

400 · 422 on the queue hosts · retry never · charged no

A controlled 3D tier needs control_type.

What to do. Name the control you are supplying.

#duration_out_of_range

400 · 422 on the queue hosts · carries min, max · retry never · charged no

The duration is outside what the product sells — video 5 to 15 whole seconds, music 10 to 300.

What to do. Send a value between min and max.

#duration_required

400 · 422 on the queue hosts · retry never · charged no

Music needs duration_seconds.

What to do. Send a whole number of seconds.

#fbx_needs_a_rigged_tier

400 · 422 on the queue hosts · retry never · charged no

out_format: "fbx" only means something for a tier that produces a skeleton.

What to do. Ask for a rigged tier, or take glb.

#image_required

400 · 422 on the queue hosts · retry never · charged no

3D starts from an image, and none was given.

What to do. Upload one with POST /uploads and pass the path it returns — not a URL of your own.

#image_unreadable

400 · carries reason · retry never · charged no

The uploaded image cannot be used, and reason says why: missing (nothing at that path), empty, not_an_image (not a PNG, JPEG or WebP a decoder can read), too_small (a side under 32 pixels), too_large (over 89,478,485 pixels) or fully_transparent. Nothing was charged.

What to do. Upload a PNG, JPEG or WebP of the object itself, at least 32 pixels a side, and check the PUT actually returned 200.

#lyrics_too_long

400 · 422 on the queue hosts · retry never · charged no

The lyrics are over the limit.

What to do. Shorten them, or send none for an instrumental.

#missing_field

400 · 422 on the queue hosts · retry never · charged no

A field the model requires is absent, or null.

What to do. Send it. The message names the field as a path; the model's OpenAPI document says what it takes.

#num_images_invalid

400 · 422 on the queue hosts · retry never · charged no

num_images is outside 1 to 4.

What to do. Ask for at most four. Each is priced separately.

#prompt_and_lyrics_too_long

400 · 422 on the queue hosts · carries tokens, max_tokens · retry never · charged no

A song's prompt and lyrics together come to more than the model can read: max_tokens tokens of its own tokenizer, counted over both with the few the model adds around them, before anything is charged. tokens is what this request came to. Each field's own character limit is not the whole story — Chinese, Japanese or Korean lyrics, or a long prompt beside long lyrics, reach the token budget first.

What to do. Shorten the lyrics or the prompt until tokens is at most max_tokens. Nothing was charged.

#prompt_required

400 · 422 on the queue hosts · retry never · charged no

The prompt is missing or empty after trimming.

What to do. Send one.

#prompt_too_long

400 · 422 on the queue hosts · carries tokens, max_tokens · retry never · charged no

The prompt is over the product's limit — 7,000 characters for video; for photo, 4,000 characters with a style's trigger phrase counted, or more than the model reads: max_tokens tokens of its own tokenizer, about 2,000 characters of English or 1,400 of Indonesian. A refusal in tokens says what this prompt came to in tokens. Nothing is charged.

What to do. Shorten it. Past the limit the model would not have read the rest, a style's trigger included.

#reference_must_be_uploaded

400 · 422 on the queue hosts · retry never · charged no

A video's first_frame_path or one of its reference_image_paths is not the path of a picture of yours — another kind of file, or nothing there any more. Video renders only pictures you uploaded for it, never a URL of your own.

What to do. Upload the picture with POST /uploads naming the video address, PUT its bytes to upload_url, then send the path it answered. Uploads are kept three days. Nothing was charged.

#seed_out_of_range

400 · 422 on the queue hosts · carries max · retry never · charged no

The seed is not a whole number from 0 to max — 2,147,483,647 for photo, music and 3D, 4,294,967,295 for video, which takes every seed its renderer can draw — so the render could not use it. It used to be dropped for a random seed after the charge; it is refused before anything is charged.

What to do. Send a whole number from 0 to max, or leave seed out to have one chosen. A finished video's seed renders the same clip again.

#start_frame_with_references

400 · 422 on the queue hosts · retry never · charged no

The video names a first frame and reference pictures together. The model's reference mode takes no first frame, so a clip either opens on a picture or is held by references.

What to do. Drop first_frame_path to keep the references, or drop reference_image_paths to open on the frame. Nothing was charged.

#text_required

400 · retry never · charged no

A chat turn with no text.

What to do. Send some.

#text_too_long

400 · retry never · charged no

A chat message is over 24,000 characters.

What to do. Split it, or summarise what came before.

#too_many_references

400 · 422 on the queue hosts · carries max · retry never · charged no

More reference pictures than the model takes: max, which is 9.

What to do. Send at most max. Several angles of one subject hold it better than one, but each takes a slot.

#unknown_aspect

400 · 422 on the queue hosts · carries aspect_ratios · retry never · charged no

The aspect ratio is missing, or not one this product renders.

What to do. Use a value from aspect_ratios. Video renders 16:9 or 9:16 and nothing else.

#unknown_field

400 · 422 on the queue hosts · retry never · charged no

The body carries a key the model does not take. The message names it as a path — parameters.extra, image_ref[].size — because a nested body is judged leaf by leaf. Our own auray-ai/ addresses are judged the same way but only WARN for now: a body this code would refuse there is still served, with a Deprecation header and a Link to this entry, and is refused with this code (or missing_field, bad_value) once enforcement starts — no sooner than thirty days after those warnings began.

What to do. GET /models/{address}/openapi.json lists every field, with its place in the body. Remove the key, or check its spelling. A response carrying Deprecation is the same request being warned before it is refused.

#unknown_resolution

400 · 422 on the queue hosts · carries resolutions · retry never · charged no

The resolution is missing, or not one photo renders: 1024 or 2048 only.

What to do. Use a value from resolutions.

#unknown_style

400 · 422 on the queue hosts · retry never · charged no

The style named is not one we carry.

What to do. Omit it, or use one from GET /me.

#unknown_tier

400 · 422 on the queue hosts · carries tiers · retry never · charged no

The tier named does not exist, or none was named where one is required. 3D requires one — geometry, textured, rigged, controlled-object or controlled-character — and has no default. Video has one — fast. standard was retired on 2026-08-27 because it rendered identically to pro on slower hardware and cost more, and pro followed on 2026-09-10 when video collapsed to a single configuration; both names are refused here.

What to do. Use a value from tiers. On 3D, name one; on video, leaving it out gives you fast.

#unsupported_encoding

400 · 422 on the queue hosts · retry never · charged no

The field is documented as a multipart form part — file bytes in a form field — and this platform sends JSON bodies only. Nothing was charged.

What to do. The message names the field's URL sibling when there is one (mesh → mesh_url); upload the file somewhere reachable and send its URL there instead.

#What your plan allows

A 403 rather than a 402: the account is in good standing, it simply does not include this. Credits will not help; a different plan will.

#duration_not_in_plan

403 · carries plan, max · retry never · charged no

Retired. A plan once limited how long a clip or a song could be. Every plan that carries video or music may ask for every length the model makes.

What to do. Nothing to fix. A length the model does not make is refused as duration_out_of_range.

#images_not_in_plan

403 · carries plan, max · retry never · charged no

Retired. A plan once limited how many images one request could ask for. Every plan that carries Photos may ask for as many as the model makes in one request.

What to do. Nothing to fix. More images than the model makes are refused as num_images_invalid.

#job_over_plan_ceiling

403 · carries plan, model, credits, ceiling · retry never · charged no

This one job would cost credits, above the ceiling your plan sets for a single catalogue job.

What to do. Ask for less — a shorter clip, fewer outputs — or upgrade. If a pass covered this job when you sent it, it had ended before the job started; nothing was charged — send it again under a new idempotency key.

#lyrics_not_in_plan

403 · carries plan · retry never · charged no

Retired. A plan once decided whether songs could have vocals. Every plan that carries music may send lyrics.

What to do. Nothing to fix.

#model_not_in_plan

403 · carries plan, model, modality · retry never · charged no

Your plan does not run this catalogue model: a plan with no catalogue seat runs none, plans open catalogue models by what they make (modality), and a catalogue copy of a model behind the apps follows the plan that runs that app.

What to do. Pick a model whose output your plan includes, or upgrade. GET /v1/plans lists each plan's catalogue seat (limits.external.max_concurrent) and outputs. A pass for this model, where one is offered, runs it on any plan.

#pass_does_not_cover

403 · carries pass, why, plan, model · retry never · charged no

Your plan runs this catalogue model only through your pass for it (pass), and the pass does not cover this job. why says what it leaves out: door — the way the job was sent (the API, MCP or the app); shape — what the job is made from, or how long or large it is.

What to do. Nothing was charged. Send it the way your pass works, or as a job it covers: GET /v1/me lists each pass's doors and covers_lines.

#plan_has_no_chat

403 · carries plan · retry never · charged no

Your plan does not include chat.

What to do. Upgrade to Pro or above.

#plan_has_no_music

403 · carries plan · retry never · charged no

Your plan does not include music.

What to do. Upgrade to Pro or above.

#plan_has_no_photo

403 · carries plan · retry never · charged no

Your plan does not include image generation.

What to do. Upgrade to Pro or above.

#plan_has_no_threed

403 · carries plan · retry never · charged no

Your plan does not include 3D.

What to do. Upgrade to Pro or above.

#plan_has_no_video

403 · carries plan, upgradeTo · retry never · charged no

Your plan does not include video.

What to do. Upgrade to the plan named in upgradeTo.

#resolution_not_in_plan

403 · carries plan, max · retry never · charged no

Retired. A plan once limited the photo resolution. Every plan that carries Photos may render at every resolution the model offers.

What to do. Nothing to fix. A resolution the model does not offer is refused as unknown_resolution.

#tier_not_in_plan

403 · carries plan, tier · retry never · charged no

Retired. A plan once limited which tiers it could run, in 3D and in video. Every plan that carries 3D or video runs every tier the model makes.

What to do. Nothing to fix. A tier the model does not make is refused as unknown_tier.

#upscale_not_in_plan

403 · carries plan · retry never · charged no

upscale_2k: true is refused on every plan. The 2K pass is retired: no plan, promotion or price includes it, so nothing an account can buy turns it back on.

What to do. Drop the flag, or send it false. This is not an upgrade prompt — no plan accepts it.

#Where the model licences reach

3D runs on Tencent Hunyuan3D, whose licence does not cover every country. That is a licence boundary rather than a policy of ours, which is why it is neither a 403 nor a 404.

#region_blocked

451 · carries region · retry never · charged no

The model's licence does not reach the country your account declares — our 3D and the catalogue models that carry its licence.

What to do. Nothing on your side, and this is not a plan problem — no upgrade changes it. The other four products are unaffected.

#region_invalid

428 · carries region · retry never · charged no

The declared country is not one we recognise.

What to do. Set a valid ISO country code in Account → Language & Region.

#region_required

428 · retry never · charged no

This model's licence reaches only some countries (our 3D, and every catalogue model carrying the same licence), so it needs to know which country your account operates from, and none has been declared.

What to do. Set it in Account → Language & Region. It is one field, and it is asked once.

#When there is no room

When a product is busy, a job waits or is refused before anything is charged. None of these charge anything: admission runs before the money.

#lane_busy

429 · carries limit, plan, tier · retry same_key · charged no

Every place set aside for this kind of traffic — requests through API keys, or the app's own — is taken, so a script cannot crowd out the people using the app. Requests through API keys are not guaranteed a place at busy times. plan and tier say what the request was admitted against.

What to do. Retry with backoff; nothing was charged. The share frees up as jobs finish.

#pass_busy

429 · carries pass, model, ends_at, why · retry same_key · charged no

A pass runs one job at a time, and your pass for this model already has one running (why: yours) — or so many people's passes for this model are running right now that there is no free place for another (why: full). The job is not kept: pass names the pass, model the model and ends_at when the pass ends.

What to do. Wait the Retry-After header's seconds, then send the same request with the same key once the running job finishes. Nothing was charged.

#pass_line_full

429 · carries pass, model, waiting · retry same_key · charged no

Your pass for this model already has waiting jobs waiting their turn behind the one that is running.

What to do. Send this one again when one of them starts. Nothing was charged.

#service_busy

503 · retry same_key · charged no

There is no room for this product right now, or something we decide on could not be read — our admission check, or your plan's figures on an instance that has not read them yet — and we refused rather than guessing. Either way it was decided before anything was charged or registered. 3D fills up soonest, and requests through API keys are not guaranteed a place at busy times.

What to do. Wait the Retry-After header's seconds, then send the same request with the same key. Nothing was charged.

#tier_busy

429 · carries tier, limit · retry same_key · charged no

Every video slot is busy. tier is always fast: it is still reported because admission counts per tier, not because there is a choice.

What to do. Retry with backoff — nothing was charged, and this clears on its own as renders finish. There is no other tier to submit to.

#too_many_jobs

429 · carries limit, plan, tier · retry same_key · charged no

You already have limit jobs of this kind in flight. The cap is per account: your plan's figure, kept one under the share of the product reserved for the way you called (the API, or the app), so through a key it can be lower than GET /v1/plans says. Video counts it per tier — which since 2026-09-10 is one tier, so tier comes back fast and the distinction no longer separates anything. Jobs a pass of yours pays for are not counted here: each pass runs its own job, one at a time, beside these.

What to do. Wait for one to finish. Webhooks are cheaper than polling for knowing when.

#Credits

#insufficient_credits

402 · carries required, balance · retry never · charged no

The account does not hold required credits.

What to do. Buy credits in Account → Plan & Billing, wait for next month's plan credits, or ask for something cheaper — a shorter clip, fewer images, the fast tier.

#refunded

402 · retry never · charged refunded

The job's credits were given back — or, for a job a promotion paid for, it did not succeed — so its output is no longer yours to fetch. This is what a failed or cancelled render looks like from the assets route.

What to do. Nothing to do. Read the job itself for why it failed.

#Reading, cancelling and fetching a job

#already_completed

400 · retry never · charged unknown

PUT <model>/requests/{id}/cancel on a request that had already finished, failed or been cancelled. There was nothing running to stop. The body's charged is that job's own: stands for one that finished and kept its charge, refunded for one that failed or was cancelled before, no for one that was never charged (waived, or free), and unknown only when its ledger could not be read.

What to do. Nothing: the request is in the state you wanted. Read it with GET <model>/requests/{id} for the outcome. Our own POST .../cancel and DELETE /v1/jobs/{id} answer 200 with cancelled: false for the same case, on purpose.

#cancel_failed

502 · retry after_retry_after · charged stands

The rendering service did not accept the cancel.

What to do. Retry after 5 seconds. If it keeps failing the job will settle on its own.

#cancel_not_offered

409 · carries product · retry never · charged stands

This model cannot be stopped once it starts. The job is still running and is still charged; nothing you or we can send stops it.

What to do. Stop watching it if you no longer want the result — the charge stands if it delivers. A job that never finishes is ended at its model's stall_ceiling_seconds (on GET /v1/models) and refunded in full. Next time, pick a model whose address accepts a cancel, or keep jobs short enough that you would let them finish.

#cancel_raced

409 · retry poll_first · charged unknown

The job settled while the cancel was in flight.

What to do. Read the job — it has a terminal status now.

#cancel_refused

409 · carries status · retry never · charged stands

The job is past the point where cancelling would save anything.

What to do. Let it finish; you will be charged for what was produced.

#cancel_unconfirmed

409 · retry poll_first · charged stands

The service has not confirmed that this job started, and it is still inside the time a dispatch may take, so there is nothing running to stop yet. Only a video storyboard revision answers this: its dispatch was not confirmed, and its charge stands until the service answers or that time passes.

What to do. Read the job. If it starts, cancel it then. If it never started, the reconcile sweep puts it back and refunds its charge on its own once that time has passed — nothing to resubmit, and nothing is charged twice.

#cancel_unsupported

400 · carries product · retry never · charged no

This product has no cancel at all. A chat turn is streamed by the request that pays for it, so there is no job anywhere else to stop.

What to do. Close the connection that is streaming the turn; that stops it, and what was delivered is what is charged.

#conversation_not_found

404 · retry never · charged no

No such conversation, or not yours.

What to do. Check the id, or create a new conversation.

#expired

410 · carries reason · retry never · charged no

The stored object is gone. Output is not kept forever.

What to do. Re-render. Fetch and store what you need when a job finishes rather than later.

#idempotency_key_owned

409 · retry new_key · charged no

This idempotency key already names a job a DIFFERENT API key on your account submitted — one that has started, or one still waiting in the queue, which is charged to that key when it starts. Two keys sending the same key for the same product compute the same internal reference, so before this refusal existed the second one was answered with the first one's job — a render it had not paid for, and not the request it actually sent.

What to do. Send a key of your own. An idempotency key is scoped to the API key that first used it, so give each integration its own namespace — prefixing with something per-key is enough. Nothing was charged for the refused request, and the original job is unaffected: the key that owns it can still replay it, and any key on the account can still read it with jobs:read.

#in_flight

409 · carries message_id · retry poll_first · charged stands

This idempotency key is already running. Reusing it is how a retry finds the original rather than starting a second one.

What to do. Poll the job it names. Use a fresh key only when you actually want a second render.

#key_settled

409 · carries message_id · retry new_key · charged unknown

This idempotency key already finished. Keys are not reusable once settled, which is what stops a replay charging twice. On /v1/chat the body's message_id names the turn that settled it, and that turn's charge is its own. On /openai/v1/embeddings the key's batch was already embedded and its vectors are not stored. On a model address a settled key whose finished job exists is answered as that job, replayed: true, rather than with this code: here it means the charge was given back before any job was recorded, so there is no job, no message_id, and nothing stands.

What to do. Read the finished turn or job if there is one, or send a new key.

#not_covered

409 · carries pass · retry new_key · charged no

You sent X-Auray-Covered-Only: 1 — run this job only if a pass or a promotion pays for it — and none did when it was about to start. pass names your pass for this model, if you hold one; it may not work the way this job was sent, or cover this kind of job, or it had ended.

What to do. Nothing was charged. Send it again under a new idempotency key without the header to pay for it with credits, or check what your pass covers with GET /v1/me.

#not_found

404 · retry never · charged no

No such job, or not yours — and in the Community no such work, profile, comment or collection, or one that is not shown to you. The two are deliberately the same answer: telling them apart would let anyone map which ids exist.

What to do. Check the id. Job ids are <product>_<idempotency_key> and are known before dispatch; a Community work is named by the id its page or a feed answered, a profile by its handle. A work its author unpublished, or our team took down, answers this for good.

#not_ready

409 · carries status · retry poll_first · charged no

The job has not finished, so it has no assets yet.

What to do. Wait for a terminal status. poll_after_seconds on the job read says how long is worth waiting.

#product_not_available

404 · carries product · retry never · charged no

That product is not configured on this deployment.

What to do. Nothing on your side.

#request_in_progress

400 · carries status, queue_position, job_id, status_url, response_url, cancel_url · retry after_retry_after · charged no

GET <model>/requests/{id} — the result — on a request that has not finished: it is still IN_QUEUE or IN_PROGRESS, which the body's status says, with queue_position while it waits. A request has a result once its status is COMPLETED, and not before; whatever a job has made part-way is not its output. Every host of the queue protocol answers the same read the same way.

What to do. Poll status_url (or stream it) until it says COMPLETED, then read the result again — or ask again after the Retry-After header's seconds. Reading costs nothing and the request is unaffected; do not submit it again.

#settle_failed

500 · retry poll_first · charged unknown

The cancel reached the service but we could not record the outcome.

What to do. Read the job again in a moment. Tell us if it stays open.

#taken_down

410 · carries taken_down_at · retry never · charged no

We took this job's output down after a report, at taken_down_at. The job is still yours and its row still answers — its status, its charge, its error — but nothing will sign or serve its files again, and it no longer appears in GET /v1/jobs.

What to do. Nothing you send changes this. If you believe the report was wrong, write to support and quote the request_id at once: a takedown lifted within its first minutes restores the files without a re-render, and after that the stored objects are deleted and only a re-render brings the output back.

#upstream_lost

410 · retry new_key · charged no

This job's record is no longer available; an old id reads the same as one that never existed.

What to do. Re-submit. If the job was recent, tell us with the request_id.

#Why a job stopped

These are what a job's error_code says once it has stopped — the request was accepted, priced and dispatched — and they are also the error a result read answers with on queue.auray.run, where the status is the class's: 422 for a refusal of the input, 409 for a cancellation, 5xx for a failure of ours or the model's. A few are also answered at submit, when the service refuses the request outright, and the status shown is that one. A cancelled job always reads as cancelled, and one that failed with no reason as unknown_failure. Every word our own services write is here; a catalogue model can also fail with its own word, which is classed ExecutionError.

#abandoned

502 · retry new_key · charged refunded

The job's record was lost before it finished; it was refunded.

What to do. Nothing on your side; the sweep settles and refunds it. Resubmit with a new idempotency key.

#cancelled

409 · retry new_key · charged refunded

You cancelled this request while it was running.

What to do. Nothing. Submit again with a new idempotency key if you want the render after all.

#cancelled_before_dispatch

409 · retry new_key · charged no

You cancelled this request while it was still queued, so it never reached the service at all.

What to do. Nothing, and nothing was spent on the model. Submit again with a new idempotency key.

#dispatch_lost

502 · retry new_key · charged refunded

The request was charged and never started; it was refunded. A submit answers it at once, with refunded, when the request never reached the model; otherwise the job says so once it has waited longer than the product's dispatch window.

What to do. Nothing on your side: the charge is refunded, by the submit or by the sweep. Submit again with a NEW idempotency key — the old one is settled.

#dispatch_unresolved

502 · carries refunded · retry poll_first · charged stands

Your submit reached the service and we never learned whether it started — a timeout, a 5xx, or the service rate-limiting the dispatch itself. THE CHARGE STANDS, because a job that did start and is not paid for is the worse of the two mistakes. On queue.auray.run the submit answers 202 with the request id rather than 502, since 2026-09-02: a 5xx is retryable to every HTTP client alive, and the queue protocol's JavaScript client retries one three more times by default, which would be four charges and four jobs for one submit.

What to do. Poll the job before you resubmit: the id in the response is real and the row exists. If it never starts, the reconcile sweep declares dispatch_lost and refunds it. Resubmitting with the same idempotency key finds the original; with a new one it charges again.

#embeddings_upstream

502 · retry new_key · charged refunded

The embedding endpoint answered with something that was not a set of vectors.

What to do. Retry. Nothing was charged — a request that produced no vector is reversed in full, including one that returned the wrong NUMBER of vectors, which is refused rather than returned partially. A key you named is not used up by it: the identical request is tried again under it, and the error's retry says same_key when it will be.

#embeddings_warming

503 · carries retry_after · retry after_retry_after · charged refunded

The embedding model was starting after a quiet spell and took longer than this request is held. A request after a quiet spell is normally held until the model answers.

What to do. Retry after the interval in Retry-After, which the error's retry_after repeats. NOTHING WAS CHARGED: the reserve was reversed in full before this answer. The identical request, idempotency key included, is a fresh attempt: a key whose batch came back whole is not used up. A key that cannot be tried again — past its attempts, or a call a promotion paid for — says retry: "new_key" with x-should-retry: false: send the batch again under a new key.

#empty_result

500 · retry new_key · charged refunded

The model finished and produced nothing at all — no picture, no clip to take to 2K — and none was withheld by the filter.

What to do. Send it again with a new idempotency key. The charge was refunded.

#filtered

422 · retry never · charged refunded

The image was rendered and every picture it produced was withheld by the content filter on what it drew.

What to do. Change the prompt. The same prompt is likely to be withheld again. The charge was refunded.

#generation_timeout

504 · retry new_key · charged refunded

The model did not finish inside its own time limit — for 3D, a stage that stalled past every retry, or a run past its hour.

What to do. Send it again with a new idempotency key, or ask for less — a shorter duration, a 3D tier without texture. The charge was refunded.

#gpu_error

500 · retry new_key · charged refunded

Generation failed on our side before it finished — a fault of ours, not of your request.

What to do. Send it again with a new idempotency key. The charge was refunded.

#gpu_out_of_memory

500 · retry new_key · charged refunded

The model ran out of memory while generating. Sending it again usually succeeds.

What to do. Send it again with a new idempotency key; a shorter duration is less likely to meet it. The charge was refunded.

#inference_failed

500 · retry new_key · charged refunded

The model failed while rendering — an image, or a video clip or scene — for a reason of its own rather than of your prompt.

What to do. Send it again with a new idempotency key. The charge was refunded.

#input_unfetchable

400 · 422 on the queue hosts · retry never · charged refunded

A catalogue model could not fetch or read a file the request named by URL — the field is in the message, down to the element when the model said which (inputs.images[0]); on /openai/v1 it is the part you sent the file in (messages[0].content[1].image_url, or input[0].content[1].image_url on /responses), also in the error's param. The model downloads each file when the job starts and gives up on a host that has sent nothing within about ten seconds; a host that answers and then sends the file slowly holds the job until the model's stall ceiling (stall_ceiling_seconds on /v1/models, five minutes for most image models), where it fails as stalled. A host that refuses automated downloads, a link that needs a login or answers with a page or a 404, and a file in a format the field does not take are refused the same way.

What to do. Send a URL anyone can download at once, in a format the field accepts — or upload the file with POST /v1/uploads and send the URL it returns, which the model always reaches. The charge was refunded.

#internal_error

500 · retry new_key · charged refunded

The music model failed for a reason it did not classify. It is the service's own catch-all, not a statement about your request.

What to do. Send it again with a new idempotency key. The charge was refunded.

#invalid_generation_input

400 · 422 on the queue hosts · retry never · charged refunded

The service that runs the model accepted the request and then could not use the input as written — a value its own checks refused, or one the model failed on. For a catalogue model the message names the field and, where the model stated one, the rule it broke: the range, the multiple, or the sizes it takes — a width that is not a multiple of 64, a size outside the model's set, a frame image the model needs and the request did not carry. The same input fails the same way.

What to do. Change the field the message names to a value its rule allows, or send the one it says is missing. If you leave out width and height, some models are sent their documented values for you — never beside a resolution, an aspect ratio or a size you chose, and never where the rules on the model's page forbid a size beside what you sent, as many video models do beside the frame or the clip they start from — and every other default is the model's own: name the size yourself whenever it matters. The charge was refunded.

#loop_lost

502 · retry new_key · charged refunded

The same as dispatch_lost, for a job that was already past its first step when the dispatch stopped resolving.

What to do. Nothing on your side; it is refunded by the sweep. Resubmit with a new idempotency key.

#missing_artifacts

500 · retry new_key · charged refunded

The 3D service reported success and returned no files. A job that delivers nothing is recorded as failed rather than succeeded.

What to do. Send it again with a new idempotency key. The charge was refunded.

#missing_audio

500 · retry new_key · charged refunded

The music service reported success and returned no audio. A job that delivers nothing is recorded as failed rather than succeeded.

What to do. Send it again with a new idempotency key. The charge was refunded.

#model_failed

500 · retry new_key · charged refunded

The model ran and failed, and the reason it gave is not one we pass on. It is the model's failure rather than a refusal of your request, and nothing about the request is known to be wrong. On /openai/v1/chat/completions it is answered 500 server_error without x-should-retry: false, so OpenAI's own clients retry it twice: each retry is a new job, charged and refunded like this one.

What to do. The charge was refunded. Send it again; if it keeps failing for one model, tell us with the request_id.

#model_not_loaded

503 · retry never · charged refunded

The model could not be loaded for this job. That is ours to fix, and it fails every job until we do.

What to do. Nothing on your side. Tell us with the request_id; the charge was refunded.

#operator_closed

502 · retry new_key · charged refunded

Our team closed this job before the platform's own deadline, after it still reported running or its record was lost — the close stalled or abandoned would have been, brought forward for a job somebody looked at. A job that had already finished is delivered, never closed this way.

What to do. Nothing on your side; the whole charge is refunded. Resubmit with a new idempotency key.

#output_limit_reached

422 · retry never · charged refunded

A language model spent all of the max_tokens you allowed before it finished its answer. Its reasoning counts against the same limit, so a model that thinks first can run out before it writes a word. A language model whose server came back empty without giving a reason is reported the same way: every such failure we have measured was this one. Our own chat models (glm-5-3-flash, deepseek-v4-1-flash, kimi-k3) report it too, when the plan's ceiling — or a lower max_tokens you sent — or the time one turn may run went on reasoning before a word of answer or a tool call: on /v1/chat the turn is failed with this code and finish_reason: length, and its reasoning can still be read back. On /openai/v1/chat/completions this is answered 400 invalid_request_error with x-should-retry: false, because the same request stops at the same place. That status needs the stop to come within the first seconds: a completion that is not streamed answers 200 once those have passed, to keep its connection alive, so a later stop is the same error object as the body under that 200, with no choices. A stream ends in OpenAI's error chunk carrying this code.

What to do. Send it again with a lower reasoning_effort (effort on /v1/chat) on a model that takes one, or a larger max_tokens (or max_completion_tokens) — on our own chat models max_tokens can lower the plan's ceiling and never raise it. The charge was refunded.

#price_changed

409 · retry new_key · charged no

The job waited in the queue for a seat, and when one came free its model cost more than the price it was quoted when it was queued. It was not started and never reached the model, rather than being charged more than that quote.

What to do. Nothing was charged. Check the model's price now and send it again with a new idempotency key.

#prohibited_content

400 · 422 on the queue hosts · retry never · charged refunded

The filter refused this specific content. Where rejected is the general refusal, this is the one the service names.

What to do. Change the prompt or the input image. Retrying unchanged cannot succeed.

#prohibited_likeness

400 · 422 on the queue hosts · retry never · charged refunded

The prompt asks for intimate imagery of an identifiable, named person, which the filter refuses before anything is rendered.

What to do. Describe the subject you want instead of naming a real individual. Retrying unchanged cannot succeed.

#prohibited_voice_cloning

400 · 422 on the queue hosts · retry never · charged refunded

The music request asks for a real, named artist's voice, which the filter refuses before anything is generated.

What to do. Describe the style you want rather than the person. Retrying unchanged cannot succeed.

#queued_row_unreadable

500 · retry new_key · charged no

The request waited in the queue and could no longer be read as a valid request when a seat came free — a limit narrowed while it waited. It never reached the model.

What to do. Nothing was charged. Send it again with a new idempotency key, within today's limits.

#queued_too_long

504 · retry new_key · charged no

The platform was full when you submitted, so the request waited — and no seat came free within the product's own limit on how long a queued request may hold its place (photo 30 minutes, video 60 minutes, music 60 minutes, 3D 90 minutes). It never reached the model.

What to do. Nothing was spent on the model. Resubmit with a NEW idempotency key, or send X-Auray-Request-Timeout to choose your own deadline — it may be longer than ours as well as shorter.

#rejected

400 · 422 on the queue hosts · 502 from a catalogue model whose refusal carried no code, and video when its service refuses with anything but 422 · retry never · charged refunded

The service that runs the model refused the request as it was sent and gave no code saying why — the runner's fallback for a refusal of the body (400, 413 or 422) that carried none. A filter that names itself answers prohibited_content, a value the model would not take invalid_generation_input, a file it could not fetch input_unfetchable, and a service that said no about itself, rather than about your request, upstream_refused; a catalogue model answers one of those, never this, unless its refusal carried no code.

What to do. Check the request against the model's documented fields and the prompt against its content rules: the same request will be refused again, and a retry spends a request for nothing. Credits for a refused job are not charged.

#request_timeout

504 · retry new_key · charged no

The deadline YOU sent as X-Auray-Request-Timeout (or X-Fal-Request-Timeout) passed while the request was still queued, so it was failed instead of dispatched. That header is a time to start: it says nothing about how long the model may then take.

What to do. Nothing was spent on the model. Send a longer deadline, or none, and resubmit with a new idempotency key.

#response_format_unmet

422 · retry new_key · charged unknown

One of our own chat models was asked for a json_object or json_schema response_format, which it answers through a function of its own, and answered with neither that call carrying a JSON object nor a JSON object written as text. The turn was refunded — all of it when the model wrote no reasoning first, and otherwise all but that reasoning, which stays readable on the job, and the prompt it read, at their token price with no per-turn base; streamed, it arrives as OpenAI's in-stream error chunk. A stream sends the call's arguments as content as they come, so arguments whose end shows them no object (one never closed) were sent before the error, and what was sent is charged as delivered. charged says which for the instance: refunded when nothing was kept, stands when something was.

What to do. Send it again with a new idempotency key, or with a prompt that asks for the format. X-Auray-Credits-Charged, on an answer that is not streamed, and the job's credits_charged say what the turn cost.

#run_timed_out

504 · carries queue_request_id, idempotency_key, status, waited_seconds, charged, status_url, response_url, cancel_url · retry poll_first · charged unknown

You ran a model on auray.run and the connection's deadline passed before it finished. queue_request_id is the id the request has on the queue host — the body's request_id is the HTTP call, as it is on every failure this API answers. It is NOT a gateway failure and it is not request_timeout, which is a job that never started: this request was admitted and is still alive. charged says where its money is. true: it was charged and dispatched and is still running, and nothing was refunded. false: your plan's lane was full, so it is still waiting in our queue (status is IN_QUEUE) and has not been charged — it is charged when it starts, unless you cancel it first. waited_seconds is how long this connection actually waited. X-Auray-Request-Timeout-Type: user (and the queue protocol's X-Fal-Request-Timeout-Type: user) on the response says the deadline was yours. A run that could not be given a connection to wait in is not this: it is refused 429 wait_capacity before anything is charged.

What to do. Poll status_url, or fetch response_url when it reports COMPLETED — the body carries all three addresses — or PUT cancel_url if you no longer want it. Do not resend the request blind: resubmitting with the same idempotency_key (the body names the one that was used, and Idempotency-Key: as a header survives a retrying proxy) replays this request instead of paying for a second. Queue it on queue.auray.run instead if the model routinely takes longer than you can hold a connection.

#stage_failed

500 · retry new_key · charged refunded

One stage of a 3D render failed. A failure is ours, so the whole job was refunded, and nothing it finished before failing is kept: none of its files can be fetched.

What to do. Send it again with a new idempotency key. If the rig stage failed on an object rather than a character, send it to a tier without a rig.

#stalled

504 · retry new_key · charged refunded

The service still answers and still says this job is running, well past the longest this product has ever taken. It is a deadline of ours rather than a failure the service reported.

What to do. Nothing on your side; it is refunded. Resubmit with a new idempotency key, and tell us with the request_id if it keeps happening for one model.

#stream_failed

502 · retry new_key · charged unknown

A chat answer broke partway through. What was delivered before it broke is kept, and charged as delivered; when nothing was delivered, the whole reserve comes back. The job's credits_charged says which.

What to do. To get the rest, ask the model to continue, with a new idempotency key: in the same conversation the answer is sent back to it marked as cut off, its end kept, and on /openai/v1 send what you received as the assistant message. Sending the same message again asks for a new answer from the start.

#stream_lost

502 · retry new_key · charged unknown

A chat answer's stream died with nobody left to settle it, and the sweep closed the turn. What was delivered before it died is what was charged.

What to do. Send the message again with a new idempotency key.

#submit_lost

502 · retry new_key · charged refunded

The request was charged and never reached the service — the older spelling of dispatch_lost, still on jobs from before the two were merged.

What to do. Nothing on your side: it was refunded. Send it again with a new idempotency key.

#tool_choice_unmet

422 · retry new_key · charged unknown

One of our own chat models was sent a tool_choice of required, or one tool by name, and answered without making that call — in text, or by calling another tool. These models' servers take the field without enforcing it, so the answer is checked here: text written before the call is held back, a call to a tool other than the one named is never handed over nor charged, a turn that writes about a page of text is stopped there, and one that ends without the call is refunded. The refund is all of the turn when the model wrote no reasoning first; otherwise it is all but that reasoning, which was streamed and stays readable on the job (GET /v1/jobs/{id}?include_reasoning=true), and the prompt it read, at their token price with no per-turn base. charged says which for the instance: refunded when nothing was kept, stands when something was. Streamed, it arrives as OpenAI's in-stream error chunk, and none of the text and no other call is sent.

What to do. Send it again with a new idempotency key — a model can answer differently — or with a prompt that asks for the tool, or a lower reasoning_effort. X-Auray-Credits-Charged, on an answer that is not streamed, and the job's credits_charged say what was kept.

#unknown_failure

500 · retry new_key · charged unknown

The job failed and whatever settled it recorded no reason. It is the answer for a failure we cannot name, and it never means the request was refused.

What to do. Read the job's credits_charged for whether the charge came back, and send it again with a new idempotency key. Tell us with the request_id if it repeats.

#upstream_refused

502 · retry new_key · charged refunded

The service that runs the model refused the request and did not say the input was at fault — it could not find what it was asked for, answered about another task, handed back nothing we could follow, refused a value this platform sets on every request (the model's own identifier, say) or one no published field carries, or gave a reason we do not pass on. Nothing about your request is known to be wrong.

What to do. The charge was refunded unless the body says refunded: false. Send it again with a new idempotency key; if it keeps happening for one model, tell us with the request_id.

#Webhook endpoints

#too_many_webhooks

409 · carries limit · retry never · charged no

The account already holds as many endpoints that are not dead as its plan allows; limit in the body says how many.

What to do. Delete one you no longer use. Re-registering the same URL resets it rather than adding another.

#webhook_delete_failed

500 · retry same_key · charged no

The delete did not go through. It is reported rather than swallowed, because an endpoint that is still there goes on receiving callbacks.

What to do. Retry. Read GET /webhooks to see whether it survived.

#webhook_not_created

500 · retry same_key · charged no

The endpoint could not be stored.

What to do. Retry. Tell us with the request_id if it persists.

#webhook_read_failed

500 · retry same_key · charged no

Your endpoint could not be read. This is a failed lookup rather than a missing endpoint — the two used to share a not_found.

What to do. Retry. Nothing about the endpoint changed.

#webhook_url_refused

409 · carries reason · retry never · charged no

The endpoint's stored URL was fine when you registered it and is not one we will send to any more — most often a name that used to resolve publicly now resolves to a private address. reason says which check it fails.

What to do. Register the endpoint again with a public https URL; this one will not be challenged or called.

#Help, status and filing a request

The only routes on this surface that take no key at all, so none of these are about a credential. What they are about instead is cost: an unauthenticated write path is one anybody can point at us, so filing a request is metered by address, by network, by email and by domain, and has to carry a solved proof of work. The status page is the one route here that never refuses for load and never answers 503 on its own account -- an endpoint that goes down with the platform cannot tell you the platform is down.

#challenge_expired

400 · retry never · charged no

The challenge was issued more than ten minutes ago.

What to do. Ask for a new one. Nothing else about the request needs to change.

#challenge_invalid

400 · retry never · charged no

The challenge was not issued by us, or has been altered. It is signed, so this is decided by one comparison before the work is looked at.

What to do. Ask for a new one and send it back exactly as it was given, unchanged.

#challenge_required

400 · retry never · charged no

The request carried no challenge and nonce.

What to do. Call POST /v1/support/challenge — or, for a report sent without a key, POST /v1/community/reports/challenge, which answers while support is closed — find a nonce such that sha256("<salt>.<nonce>") begins with bits zero bits, and send both back.

#challenge_spent

409 · retry never · charged no

That challenge has already been used. One challenge is one submission, whatever number of nonces happen to solve it.

What to do. Ask for a new challenge and solve it. Do not resend a solution you have already sent.

#challenge_unsolved

400 · retry never · charged no

The nonce does not produce a digest with enough leading zero bits.

What to do. Keep searching. bits in the challenge response says how many are needed, and it is raised during an incident -- so read it rather than assuming the number you saw last time.

#support_closed

503 · retry never · charged no

New requests are not being accepted right now. This is our switch rather than a limit, and it does not affect the status page or the topic list.

What to do. Read GET /v1/status, and write to support@auray.ai, which is not affected by this.

#support_disabled

503 · retry never · charged no

The support endpoints are closed on this deployment. It is answered before anything else, so every one of them behaves identically here.

What to do. Nothing on your side. Write to support@auray.ai, which is the same queue by another door.

#support_email_invalid

400 · retry never · charged no

No usable email address was given. It is checked for shape only, because the round trip that follows is what actually proves an address.

What to do. Send email as a string of at most 320 characters with one @ and a dot after it.

410 · retry never · charged no

The link was ours and has expired. A confirmation link lasts 72 hours; a status link lasts 30 days from its last use and never more than 180 from issue.

What to do. Write to us again and we will send another. Nothing about your request is lost.

404 · retry never · charged no

That link is not one we issued, or it has been revoked. Revoked and never-existed answer identically on purpose — revoking a link that was forwarded is only a real action if the forwarded copy stops telling its holder anything.

What to do. Write to us again and we will send a new one.

#support_message_invalid

400 · retry never · charged no

The message was missing, empty, or longer than 20000 characters.

What to do. Send message as a string of 1 to 20000 characters.

#support_not_configured

503 · retry never · charged no

Support is switched on here and is missing a secret it needs to serve safely, so it refuses rather than serving without one.

What to do. Nothing on your side, and retrying will not help. Tell us with the request_id.

#support_rate_limited

429 · carries retry_after · retry after_retry_after · charged no

Too many requests from this address, this network, this email address or this domain. Four buckets are checked from the most specific to the least, and the first to refuse answers -- so a single caller exhausts their own budget long before they touch a shared one.

What to do. Wait retry_after seconds. The RateLimit-* headers say which allowance you are against and when it refills, exactly as they do on the keyed routes.

#support_score_invalid

400 · retry never · charged no

A satisfaction survey's score was missing, not a whole number, or outside one to five. Nothing was recorded.

What to do. Send score as a whole number from 1 to 5, with the token from the survey link.

#support_subject_invalid

400 · retry never · charged no

The subject was missing, empty, or longer than 300 characters.

What to do. Send subject as a string of 1 to 300 characters.

#support_topic_unknown

400 · carries topic · retry never · charged no

The topic given is not one we have. Topics are rows and change without a release.

What to do. Read GET /v1/support/topics and send one of the id values from it, or omit topic.

#support_unavailable

503 · retry same_key · charged no

The support store could not be read or written.

What to do. Retry. Nothing was recorded, so retrying cannot duplicate anything.

#The Community

Publishing a result, a public profile, likes, follows, comments, collections and reports. Reading the Community takes no key; everything else takes community:write. Nothing here is ever charged: a remix of somebody's work is a generation you pay for through the model's own address.

#already_published

409 · retry never · charged no

That file is already published — one work per file of a job, whoever asks. Another image of the same batch, or another of the job's files named by asset, is a work of its own.

What to do. Change the work that exists rather than publishing it twice, or unpublish it first.

#bad_request

400 · retry never · charged no

A field of the request is not one this route reads, or not of the type it reads: a field it does not know, a true-or-false sent as a string, a required field left out. The message names the field.

What to do. Correct the field the message names against this route's reference, which lists every field and its type.

#collection_full

409 · carries max · retry never · charged no

A collection holds at most max works, and this one is full.

What to do. Start another collection.

#collections_full

409 · carries max · retry never · charged no

An account keeps at most max collections, and this one has that many.

What to do. Delete one, or add to one you have.

#comments_paused

503 · retry never · charged no

Our team has paused comments in the Community: a new comment or reply waits until it reopens. The message is the sentence our team wrote for the pause, when there is one. Nothing was posted; the comments already there stay shown, and deleting one still works.

What to do. Send the comment again once the pause is over; resending sooner changes nothing.

#community_restricted

403 · retry never · charged no

This account may not do that in the Community: a suspended or banned account writes nothing, publishing needs an active account, and a public profile our team has hidden cannot publish or comment.

What to do. Nothing a retry or another key changes. Write to us if you think the account's standing is wrong.

#community_unavailable

503 · retry same_key · charged no

The Community could not be read or written just now — the database did not answer.

What to do. Send the same request again in a few seconds. Every write here is a set rather than a count, so a resend cannot do it twice.

#content_held

409 · retry never · charged no

A report about it, or a takedown, holds it: a job held so cannot be published, and a profile whose work a report holds cannot be deleted until the report is decided.

What to do. Nothing on your side. It is decided by our team, usually within a day.

#feeds_paused

503 · retry never · charged no

Our team has paused the Community's feeds and search — trending, new, top, the featured shelf, a reader's following and every search answer this until it reopens. The message is the sentence our team wrote for the pause, when there is one. A work's own link, profiles and their lists, comments, remixes and collections still answer.

What to do. Read a work by its id or a profile by its handle meanwhile, and ask the feed again later; nothing about the request needs to change.

#handle_cooldown

409 · carries after · retry never · charged no

A handle can change once in a set number of days, and this profile changed its own too recently. after is when it can again.

What to do. Wait until after. Nothing else on the profile is held back.

#handle_held

409 · carries handle · retry never · charged no

That handle was replaced by the profile that held it within the hold period, so it still leads to that profile and is theirs alone to take back until the hold ends.

What to do. Choose another; it becomes anybody's once the hold is over.

#handle_invalid

400 · carries handle · retry never · charged no

A handle is three to thirty characters of lower-case letters, digits, . and _, starts and ends with a letter or a digit, never has two dots in a row, and holds at least one letter. handle is what was read, normalised.

What to do. Choose another. GET /v1/community/handles/{handle} answers whether one can be claimed before you try.

#handle_reserved

409 · carries handle · retry never · charged no

That handle is one our own pages, routes or roles use, or it contains the platform's name.

What to do. Choose another.

#handle_taken

409 · carries handle · retry never · charged no

Somebody else holds that handle.

What to do. Choose another.

#invalid_cursor

400 · retry never · charged no

cursor is not one a page of this list answered. Cursors are never guessed at: a malformed one is refused.

What to do. Send the next_cursor the previous page answered, unchanged, with the same filters; or none for the first page.

#invalid_query

400 · carries max · retry never · charged no

A search needs one to max characters with at least one letter or digit in them.

What to do. Send a shorter or a non-empty q.

#invalid_sort

400 · carries allowed · retry never · charged no

sort is not one this list reads; allowed lists those it does.

What to do. Send one of allowed.

#job_expired

410 · retry never · charged no

The job's three days are over: its files are gone, so there is nothing to copy. A work is copied when it is published, and only then kept.

What to do. Publish within three days of making something. Make it again to publish it now.

#job_not_paid

409 · retry never · charged no

The job's charge was given back — a refund or a failed delivery — so its result was never paid for and cannot be published.

What to do. Nothing to change on this job. Make it again.

#job_not_ready

409 · retry never · charged no

Only a job that succeeded can be published, and this one is still running, or failed, or was cancelled.

What to do. Wait for it to succeed and publish then. A failed or cancelled job cannot be published at all.

#licence_required

400 · retry never · charged no

Publishing grants the display licence and the remix licence the Terms state, for this one work, and the request did not say licence: true.

What to do. Read the Community section of the Terms and send licence: true with the publish.

400 · carries index, kinds · retry never · charged no

A profile carries at most five links, each https to the host its kind names (kinds lists them; website may be anywhere), at most two hundred characters. index is the first that broke a rule.

What to do. Fix that link, or send it as a website.

#media_invalid

400 · carries field, reason · retry never · charged no

A file of the work could not be taken: field names it and reason says why — an index the job does not have, a poster the API could not read or that is too large, or a waveform that is not a list of peaks between 0 and 1. Cinema Studio answers it too, for a clip's poster (poster_upload_id) whose bytes are no PNG, JPEG or WebP picture of the type its upload ticket named (not_a_picture).

What to do. Correct that file, or leave the optional one out: the API makes what it can on its own. A Studio poster is drawn again from a frame and uploaded with a new ticket.

#not_publishable

400 · retry never · charged no

That job's result is not a work the Community shows: an answer in text, a list of numbers, or a file of no kind it takes.

What to do. Publish an image, a video, an audio file or a 3D model.

#not_visible

409 · retry never · charged no

The work is not shown right now — hidden while a report about it is reviewed, withdrawn, or taken down — so it cannot be changed, and it cannot be remixed.

What to do. Nothing a retry changes. Its author sees why on its page; our team's decision restores it or not.

#pins_full

409 · carries max · retry never · charged no

A profile pins at most max works to its top, and this one has that many already.

What to do. Unpin one first.

#profile_exists

409 · retry never · charged no

This account already has a public profile; there is one per account.

What to do. Change it with POST /v1/community/profiles/{handle} — its handle included — rather than claiming another.

#profile_required

428 · retry never · charged no

That needs a public profile: a work, a comment, a follow and a public collection are all shown with one, and the account has not claimed a handle yet.

What to do. Claim one with POST /v1/community/profiles, then send the request again.

#publish_failed

502 · retry same_key · charged no

The work's files could not be copied into the Community's folder, so nothing was published. The staged work was deleted, and nothing was ever public.

What to do. Send the same request again. The source job keeps its files for its three days.

#publishing_paused

503 · retry never · charged no

Our team has paused publishing in the Community: a new work, and new words on a published one (a title or a description), wait until it reopens. The message is the sentence our team wrote for the pause, when there is one. Nothing was published or changed, and unpublishing, hiding a prompt, leaving the feeds and pinning still work.

What to do. Send it again once the pause is over; resending sooner changes nothing.

#remix_invalid

400 · retry never · charged no

remix_of must name a work that is shown, with remix_kind one of recreate, animate, upscale or edit — and one account's works may credit one work only a few times, so a credit past that is refused.

What to do. Name the work by the id its page answered, and say how it was used; or leave both out and publish without the credit.

#reply_invalid

400 · retry never · charged no

A reply answers a comment that is shown on the same work (or, in Cinema Studio, the same item) and is not itself a reply, nor deleted: comments go one level deep.

What to do. Reply to the comment the thread started with.

#self_target

400 · retry never · charged no

A profile cannot follow itself, and an author cannot report their own work, profile or comment.

What to do. Unpublish or delete your own instead.

#terms_required

428 · carries terms_version · retry never · charged no

A publish needs Terms this account accepted that state what it grants: the display and remix licences for a work, and for a Cinema Studio project also what the published project shows, its members' uploads included. One of these is true:

  • This account has not accepted such a version.
  • terms_version named a version this account has not accepted.
  • terms_version named a version older than the first Terms that state it.
  • terms_version is left out, so the current Terms are asked about, and this account has not accepted them yet.

terms_version in the body is the current version, the one to accept.

What to do. Accept the current Terms in the desktop (Account, or the sheet it opens), then publish again with terms_version left out or set to the current version this answer names. Where this account already accepted a version that states what the publish grants, name that version in terms_version instead.

#text_invalid

400 · carries field, max · retry never · charged no

One of the words sent is too long or carries a control character: field names it and max is its limit in characters. A title, a name and a headline are one line; a description, a bio and a comment may break lines.

What to do. Shorten it, or take out the character, and send it again.

#text_refused

422 · carries fields · retry never · charged no

The automatic check refused the words in fields: something in them is not published here. Nothing was saved, and for a publish nothing was copied.

What to do. Change those words. The check reads only what you wrote — a title, a description, a shown prompt, a profile's name, headline or bio, a comment — never the work itself, which our team reviews before it reaches a public feed.

#visibility_cooldown

409 · carries after · retry never · charged no

You hid this profile too recently to show it again yet: a hidden profile is shown again no sooner than an hour after it was hidden, because each hide and each show moves every file of every work to a new address. after is when it can be shown. Hiding is never refused.

What to do. Wait until after, then send hidden: false again. The refused request changed nothing; any other change to the profile, sent without hidden, is taken meanwhile.

#Cinema Studio

Projects, their folders, items, Trash and briefs, elements and saved presets, and uploads into them — /v1/studio. Every route takes a key: reading takes studio:read (or studio:write, which reads too), changing takes studio:write. A project is private, so one you are not a member of is answered not_found exactly as one that does not exist. Nothing here is ever charged: a generation started in a project pays through the model's own address.

#already_member

409 · retry never · charged no

The address invited belongs to an account that is already a member of the project.

What to do. Nothing to send. To change what they may do, give them another role (POST /v1/studio/projects/{project}/members/{member}).

#brief_invalid

400 · retry never · charged no

A brief is a rich-text document as an editor writes it: an object whose type is "doc", with a content list if it has any.

What to do. Send the document your editor produced, unchanged.

#brief_too_large

413 · carries max_bytes · retry never · charged no

A brief is kept up to max_bytes of JSON.

What to do. Move long material out of the brief — into a linked document, or the project's items — and save again.

#call_failed

502 · retry same_key · charged no

The call service did not answer as it should, so nothing was joined and no way into the call was handed out.

What to do. Try again in a few seconds.

#call_full

409 · carries max · retry never · charged no

The project's call already holds as many people as one call takes: max.

What to do. Wait for someone to leave, then join again.

#calls_not_configured

503 · retry never · charged no

Calls are not set up on this deployment: it holds no RealtimeKit credentials (REALTIMEKIT_ACCOUNT_ID, REALTIMEKIT_APP_ID or REALTIMEKIT_API_TOKEN is missing). Nothing else in the project is affected.

What to do. Use the project's chat and comments meanwhile. The call's configured says when calls are on.

#canvas_invalid

400 · carries problems · retry never · charged no

That is not a canvas document this API keeps: problems names each part that does not read, one line each — a node of no kind, settings of the wrong shape, an edge from a port that does not exist or into one that does not take its type, a loop, or a bound passed.

What to do. Fix each part problems names and send the document again.

#canvas_too_large

413 · carries max_bytes · retry never · charged no

A canvas document is kept up to max_bytes of JSON.

What to do. Move part of it onto another canvas of the project — a page, or a group of nodes — and save again.

#comment_invalid

400 · carries field, reason · retry never · charged no

A comment points somewhere its item has no place for — a pin on a clip, a time on a picture, a time past the end — or carries a drawing that does not read or has nothing to lie on, or names a reaction that is not one. field and reason say which.

What to do. Pin a picture with x and y from 0 to 1; mark a clip or a song with whole milliseconds inside its length; react with one of the reactions listed.

#copy_failed

502 · retry same_key · charged no

A file could not be copied into the project's kept folder just now — a result being added, an item being copied, a picture an element is made from. What did not land was not filed.

What to do. Send the same request again. A copy is made server side, and making it twice keeps one.

#cover_invalid

400 · retry never · charged no

A project's cover is one of its own pictures or clips that is not in its Trash; cover_item_id named something else.

What to do. Name an image or video item of the same project, or upload a picture with purpose: "cover" and send cover_upload_id.

#crdt_invalid

400 · retry never · charged no

The update is not a shared document's update: not base64, not a Yjs update, or one that writes something other than the document the route names.

What to do. Send Y.encodeStateAsUpdate (or an update event's bytes) of the brief's own document, base64.

#crdt_too_large

413 · carries max_bytes · retry never · charged no

With this update merged, the shared document would be larger than it is kept at: max_bytes.

What to do. Move long material out of the brief and push again; a document's history counts towards its size.

#director_invalid

400 · 422 on the queue hosts · carries problems · retry never · charged no

The composer's choices sent with a generation do not read as a director spec — studio.director on a generation started in a project, or the director record beside our video's prompt: problems names each field, one line each — a word that is not one of the choices, a list longer than it may be, a spec larger than it is kept at. The spec is kept for a recreate and never sent to the model.

What to do. Send the spec the composer made, unchanged, or leave director out: the prompt alone is what renders, and a generation started in a project is filed into it either way.

#files_invalid

400 · carries index, reason · retry never · charged no

An element holds one to 6 pictures or clips. files was not a list, held none or too many (index null), or the file at index is not one: reason says whether it is not one of the element's own, not a picture or a clip, or not a file reference at all.

What to do. Keep a file it has as { "id": "0" } (its place in files), add an upload made for an element as { "upload_id": … }, or a picture or clip of a project as { "item_id": … }.

#film_export_running

409 · carries export_id · retry poll_first · charged no

An export of this film is still being made — export_id names it — and one film exports one at a time.

What to do. Read GET /v1/studio/projects/{project}/films/{film}/exports/{export_id} until it is done or failed, then export again.

#film_invalid

400 · carries problems · retry never · charged no

That is not a film document this API keeps, or it holds nothing to export: problems names each part, one line each — a clip's in and out points, a fade longer than half the shorter clip it joins, more than sixty clips or ten minutes of film, a music bed's level, or a clip or song that is not ready to be exported.

What to do. Fix each part problems names and send the film again.

#invite_invalid

410 · retry never · charged no

That invitation opens nothing: unknown, past its moment, withdrawn, declined, used up, or to a project that is gone. One answer for all of them, so a token cannot be probed for which.

What to do. Ask whoever invited you for a new invitation.

#invite_not_yours

403 · retry never · charged no

That invitation was sent to another email address than the one this account signs in with.

What to do. Sign in with the address the invitation was sent to, or ask for an invitation to this one.

#item_source_invalid

400 · carries fields · retry never · charged no

An item is added from one of your results (job_id) or one of your uploads (upload_id) — the request named neither, or both. fields lists what it sent.

What to do. Send exactly one of the two.

#not_published

409 · retry never · charged no

The project has no publication of yours to change or take down: it was never published, it was unpublished, or it was published by the account that owned it before you.

What to do. Publish it with POST /v1/studio/projects/{project}/publication, or read where it stands with a GET of the same path.

#offer_invalid

409 · retry never · charged no

That offer of the project cannot be made or answered: it names the owner or someone who is not a member, no offer stands, it was made to somebody else, or it lapsed.

What to do. Read the project's ownership (GET /v1/studio/projects/{project}/ownership) and act on the offer it answers.

#owner_must_transfer

409 · retry never · charged no

The owner cannot leave a project or be taken out of it: a project always has one owner.

What to do. Offer the project to another member (POST /v1/studio/projects/{project}/ownership); once they accept, you stay as an admin and may leave.

#preset_invalid

400 · carries field, reason · retry never · charged no

A saved palette is a name and eight #rrggbb colours; a lighting rig is a few lights — colour, intensity and diffusion from 0 to 1, azimuth from 0 to 360, elevation from -90 to 90 — and an ambient light. field and reason say which part did not read, or kind was neither palette nor lighting.

What to do. Send the value in that shape, under the field its kind names.

#reference_invalid

400 · carries field · retry never · charged no

A field names something that is not there or not yours to use here: a folder of another project, a project you are not in or may not change, an upload made for something else, an item of a project you cannot read. field names it.

What to do. Send an id from one of your own lists — GET /v1/studio/projects, its folders, its items — or leave the field out.

#request_decided

409 · carries state · retry never · charged no

That request was approved, declined or withdrawn already; state says which.

What to do. Read the project's requests again. A declined asker may ask that project again after 7 days.

#revision_conflict

409 · carries rev · retry never · charged no

The brief or the canvas was saved from somewhere else since you read it, so the base_rev you sent is no longer its latest — rev is. Nothing was overwritten. A canvas's shared document answers it too to a seed when one is stored already, and to an update when none is stored yet.

What to do. Read it again, merge your change into it, and save over the rev it answers. For a shared canvas, load its state and send your update over it — or, when none is stored, send the canvas's first state as a seed.

#role_forbidden

403 · carries required · retry never · charged no

You are a member of that project, and your role in it does not hold the capability this needs — required names it (manage_settings, delete_project, edit_items…). Never answered about a project you are not in.

What to do. Ask the project's owner to do it, or to give you a role that may.

#role_not_assignable

403 · carries role · retry never · charged no

The role named is not one you may give here: nobody gives owner (a project changes hands only by an offer the member accepts), an admin gives a collaborator's or a viewer's role and never another admin's, nobody changes their own role, and a request asks for a role above the one the asker holds. role is the one refused.

What to do. Pick a role below your own, or ask the project's owner to give it. To raise your own role, ask for it with POST /v1/studio/access-requests.

#selection_too_large

400 · carries max · retry never · charged no

One move, copy, Trash or restore names at most max items.

What to do. Split the selection into calls of max or fewer.

#slug_invalid

400 · carries slug · retry never · charged no

A project's slug is the address segment its links carry: 3 to 60 lower-case letters and digits, in runs joined by single hyphens. slug echoes what was sent.

What to do. Send one of that shape, or leave it out and the project's name gives one.

#slug_taken

409 · carries slug · retry never · charged no

Another of your projects already has that slug. A slug you ask for is kept exactly; one left out is made unique with a number.

What to do. Choose another slug, or leave it out.

#snapshot_empty

400 · retry never · charged no

A project publication shows the folders and items it names, never what is in the Trash or not ready yet — and everything this one named was one or the other, or went while its files were copied.

What to do. Choose folders or items that hold something shown in the project, and publish again.

#snapshot_too_large

400 · carries max · retry never · charged no

One publication of a project shows at most max items, and the folders and items named hold more.

What to do. Publish fewer folders or items — a selection of the best of them, or one folder at a time as its own project.

#studio_fault

500 · retry never · charged no

What this request would have kept in the Studio broke one of the Studio's own rules — a fault on our side, not in your request — so nothing was kept. Sending the same request again is refused the same way until we fix it.

What to do. Do not resend it. Tell us with the request_id; nothing was changed and nothing was charged.

#studio_limit_reached

409 · carries limit, max, whose · retry never · charged no

That would pass one of the Studio's bounds — limit names which (projects, folders, items, elements, presets, canvases, members, invites, requests, comments) and max how many it keeps. Projects and elements are your plan's figures (studio.max_projects, studio.max_elements on GET /v1/plans), a project's items, canvases and members its owner's plan's (the project's limits), so max is the figure in force: a plan moved lower keeps everything already there and refuses only what is new past it. A project's items count its Trash: every item is a kept copy, kept until deleted. whose says whose plan a plan figure is — yours, or the project's owner's — and is absent for the five bounds no plan raises.

What to do. Delete what you no longer need — empty a project's Trash, delete a project, an element or a preset — or hold a plan that keeps more, then send it again. whose: owner — the project is held to its owner's plan; ask them to make room or to choose a plan that keeps more. GET /v1/studio/plan answers your own figures in force, what you hold against them and your fullest projects.

#studio_not_in_plan

403 · carries feature, whose, plan · retry never · charged no

The plan that decides does not open this: owning projects and elements follows your own plan, everything inside a project follows its owner's. feature names it (studio, calls, publish) and whose whose plan it is; reading, downloading, deleting, leaving and withdrawing always work. plan is your plan's id, sent only when whose is yours: you are never told another account's plan. Nothing was changed and nothing was charged.

What to do. whose: yours — GET /v1/studio/plan says what your plan opens now (figures); choose a plan whose limits.studio.<feature> is true on GET /v1/plans (for studio, limits.studio.enabled). whose: owner — ask the project's owner: they choose such a plan, or offer the project to a member whose plan includes it.

#studio_restricted

403 · retry never · charged no

The account is suspended or banned, and may not change anything in the Studio until that is lifted. Reading it still works.

What to do. Nothing a request can change. Write to support@auray.ai if you think this is wrong.

#studio_unavailable

503 · retry same_key · charged no

The Studio could not be read or written just now — the database or the file store did not answer, or a file could not be signed. Nothing was changed that the same request would repeat.

What to do. Send the same request again in a few seconds.

#trim_invalid

400 · carries max · retry never · charged no

A trim is in and out points in whole milliseconds on a clip or a song, in before out, inside its length — max is its length when it is known.

What to do. Send in_ms below out_ms, both within the clip, or null to clear the trim.

#upload_missing

409 · carries upload_id · retry never · charged no

The upload upload_id names exists, and its bytes never arrived at the address its ticket gave — or arrived after the ticket lapsed, 15 minutes after it was issued.

What to do. Ask POST /v1/studio/uploads for a new ticket, PUT the file to its upload_url with its headers, then file it again.

#upload_too_large

413 · carries max_bytes · retry never · charged no

The file is larger than its kind is kept at — max_bytes says how large — or more bytes arrived than the ticket declared, which a PUT bound to the declared length cannot do.

What to do. Send a smaller file, and declare its exact size in bytes when you ask for the ticket.

#video_paused

503 · carries message · retry never · charged no

Video is paused for the moment, so no film is exported; message says why when a reason was given.

What to do. Try again later. Nothing was started.

#window_invalid

400 · carries field · retry never · charged no

A usage window does not read: since or until is not a day written YYYY-MM-DD, or until comes before since. field names which.

What to do. Send both as YYYY-MM-DD (UTC), the start first, or leave them out for the month up to today.

#When it is our fault

Nothing here is caused by your request. Where a charge had already landed it has been reversed, and the entry says so.

#callback_origin_unset

503 · retry never · charged no

This deployment has not been told where the rendering services should call back, has been told an address that is not ours to be called back on, or holds no key to address a callback to a job, so a job submitted here could not be settled.

What to do. Nothing on your side. Nothing was charged.

#catalogue_unavailable

503 · retry same_key · charged no

The catalogue could not be read, so we could not say which models run.

What to do. Retry. The list of models itself does not change often; a cached copy is safe to use meanwhile.

#chat_not_configured

503 · retry never · charged no

Chat is not configured here.

What to do. Nothing on your side.

#chat_start_failed

500 · retry new_key · charged refunded

The turn could not be recorded.

What to do. The charge was reversed. Retry.

#chat_upstream

502 · retry new_key · charged refunded

One of our own chat models refused the request — the request we sent it, before its answer or inside its stream, not one you could have written differently.

What to do. Retry with a new idempotency_key. Nothing was charged when nothing was answered.

#conversation_not_created

500 · retry same_key · charged no

The conversation could not be stored.

What to do. Retry. With an idempotency_key, send the same one: the thread is made once however often it is sent.

#conversation_read_failed

500 · retry same_key · charged no

A thread or its messages could not be read back. Nothing about the thread changed.

What to do. Retry the same read.

#credit_reserve_failed

500 · retry same_key · charged no

Credits could not be reserved.

What to do. Retry. Nothing was charged.

#dispatch_not_resolved

500 · retry same_key · charged no

The request reached the part of this platform that prices catalogue models without the price it needs. That is a fault here, not anything about your request, and it deliberately refuses rather than falling back to a default price.

What to do. Retry with the same idempotency_key, and tell us with the request_id if it repeats.

#embeddings_not_configured

503 · retry never · charged no

This deployment holds no credential for the embedding endpoint.

What to do. Nothing you can do; it is a deployment that is missing a value. Tell us.

#job_not_created

500 · retry same_key · charged no

The request was accepted and admitted, but the row that tracks it could not be written. Nothing was dispatched and nothing was charged.

What to do. Retry with the same idempotency_key. If it repeats, tell us with the request_id.

#job_read_failed

500 · carries charged, queue_request_id, idempotency_key, status_url, response_url, cancel_url · retry poll_first · charged unknown

Your job could not be read. It is not a statement that the job is missing — a failed lookup used to answer 404 not_found, which said the id was wrong or not yours when neither had been established. On auray.run and /openai/v1/chat/completions it means the job ran and settled and only the read of its result failed: charged is true and the body names the job.

What to do. Retry the read. The job is untouched, and nothing was charged or refunded by the attempt. When the body says charged: true, read status_url rather than sending the request again — or resend it with the same idempotency_key, which is handed the same job instead of a second one.

#job_record_failed

500 · retry new_key · charged refunded

The job was accepted but we could not record it, so it was never sent to the model.

What to do. The charge was reversed, which settles the idempotency key: send the request again with a new one.

#model_busy

429 · a failed job's read answers 503 · retry new_key · charged refunded

One of our own chat models was busy and said so before it answered anything. Nothing was served and the whole reserve came back.

What to do. Retry shortly with a new idempotency_key. A chat turn is not replayed under a key it already used.

#model_disabled

503 · carries message · retry never · charged no

This one model is paused — an address, a chat model, the embedding model or a single tier of one. message is our note for why, or names the address you called when there is none. Nothing was charged, and every door answers it with x-should-retry: false.

What to do. Nothing on your side, and nothing to upgrade to. Use another model, or the same one when GET /v1/models stops reporting it paused.

#model_not_connected

501 · retry never · charged no

The model is described — its request shape is published — but it is not open yet, so the job cannot run. Nothing was charged.

What to do. Nothing on your side. GET /models?status=connected lists the ones that can actually run today.

#model_not_priced

501 · retry never · charged no

The model runs, but no price has been set for the shape of request you sent. We will not guess: a job that runs at a price nobody wrote down is one nobody can explain on an invoice.

What to do. Nothing on your side. Tell us the address and the request_id — a missing band is one row for us to add, with no deploy.

#model_timeout

504 · retry new_key · charged unknown

One of our own chat models stopped answering before its first word. Nothing reached you, so the reserve came back at once (refunded).

What to do. Retry with a new idempotency_key.

#model_unavailable

502 · retry new_key · charged unknown

One of our own chat models could not be reached, sent back nothing, or failed on its own account before answering. Nothing reached you, so the reserve came back at once (refunded).

What to do. Retry with a new idempotency_key.

#music_not_configured

503 · retry never · charged no

Music is not configured here.

What to do. Nothing on your side.

#no_signing_credential

503 · retry same_key · charged no

We could not sign a download URL.

What to do. Retry. Tell us with the request_id if it persists.

#not_configured

503 · retry never · charged no

This deployment is missing something it needs to answer.

What to do. Nothing on your side.

#photo_not_configured

503 · retry never · charged no

Image generation is not configured here.

What to do. Nothing on your side.

#price_ambiguous

503 · retry never · charged no

Two price bands both match this request, so the platform does not know what it costs. Falling through to the cheaper one would be a silent undercharge nobody would ever see.

What to do. Nothing on your side. Tell us with the request_id; it is a row for us to correct.

#price_invalid

500 · retry never · charged no

We could not put a whole, positive price on this request, so it was refused before anything was reserved or charged. Usually that is a fault in our pricing table; it can also be a value the price is worked out from that came through as something other than a number — a count sent as a word, say.

What to do. Nothing was charged. Check that every count and number in the body is a number; if they are, retrying will not help — tell us with the request_id and the exact body you sent.

#profile_read_failed

500 · retry same_key · charged no

Your account could not be read.

What to do. Retry. Nothing was charged.

#provider_not_configured

503 · retry never · charged no

This model isn't available on this deployment. That is a fact about the deployment, which is why this is not the same answer as a model that is not open yet.

What to do. Nothing on your side. Tell us, with the request_id.

#service_auth_failed

500 · a failed job's read answers 503 · retry never · charged refunded

The service that runs this model refused the credential WE send it. It says nothing about your key, which was accepted. The charge was refunded.

What to do. Nothing on your side, and retrying will not help until we fix it. Tell us with the request_id.

#service_unavailable

502 · retry poll_first · charged stands

Retired. The video service could not be reached, or did not answer in time. Since 2026-09-02 the same outcome is dispatch_unresolved, for every product.

What to do. Read dispatch_unresolved. It is the same situation and the charge may stand: poll the job before resubmitting.

#threed_not_configured

503 · retry never · charged no

3D is not configured here.

What to do. Nothing on your side.

#upload_url_failed

503 · retry same_key · charged no

A signed upload URL could not be created.

What to do. Retry.

#usage_unavailable

503 · retry same_key · charged no

Your usage could not be read: the credit ledger, the wallet or the usage report did not answer. It is a failed lookup, not a statement that nothing was spent — the figures are never answered as zeros.

What to do. Retry after a moment. Nothing was charged.

#vendor_disabled

503 · carries message · retry never · charged no

This model's family is paused for now. It is temporary and deliberate, and message says why when we have said. Every door answers it with x-should-retry: false, so a client that honours the header stops at once instead of asking again within seconds: it does not change until the family is resumed.

What to do. Nothing on your side, and nothing to upgrade to: this is not a plan limit. Try another model, or the same one later. GET /v1/models reports the model paused with the same sentence within a minute.

#video_not_configured

503 · retry never · charged no

Video is not configured here.

What to do. Nothing on your side.

#wallet_read_failed

503 · retry same_key · charged no

Your credit balance could not be read. A chat turn and an embeddings request size their reserve from it, and a submit to a model address checks it before queueing, so rather than guess we refused before anything was reserved or charged. It is a failed lookup, not a statement that the balance is empty — and not a sign the platform is busy, which is service_busy.

What to do. Retry after a moment. Nothing was charged.

Start typing to search every page of the documentation.

Up arrow Down arrow to moveEnter to openEscape to close