{"openapi":"3.1.0","info":{"title":"auray-ai/minimax-h3-v2/text-to-video","version":"1.0.0","description":"`POST https://queue.auray.run/auray-ai/minimax-h3-v2/text-to-video` submits; the response carries a `request_id` and the three URLs to use next.\n\nThis model cannot be waited on: its jobs outlive any connection worth holding. `POST https://auray.run/auray-ai/minimax-h3-v2/text-to-video` answers `400 model_not_synchronous` and `?wait=` is refused `wait_unsupported`, both before anything is charged. Submit it to the queue and poll `status_url`, stream the status, or pass `?webhook=` to be called when it is done.\n\nOne of the models behind Auray's apps.\n\nPrice: One price per clip for each length rung — up to 5, 10 and 15 seconds — one list for a clip from words alone and one for a clip with references, each rung's credits in force served by GET /v1/plans as `price_keys` (`video.h3v2.text.<rung>` and `video.h3v2.refs.<rung>`) and quoted when you submit. Refunded if the render fails.\n\nFields read from https://api.auray.ai/v1/openapi.json on 2026-08-31.\n\nEvery error code is explained at https://auray.ai/docs/api/errors.","contact":{"url":"https://auray.ai/docs"},"x-auray-model-id":"minimax-h3-v2","x-auray-hosted-by":"auray","x-auray-scope":"video:write","x-auray-scopes":["video:write","auray-ai-video:write"],"x-auray-price":{"kind":"quoted","note":"One price per clip for each length rung — up to 5, 10 and 15 seconds — one list for a clip from words alone and one for a clip with references, each rung's credits in force served by GET /v1/plans as `price_keys` (`video.h3v2.text.<rung>` and `video.h3v2.refs.<rung>`) and quoted when you submit. Refunded if the render fails.","metered":false},"x-auray-capability":{"address":"auray-ai/minimax-h3-v2/text-to-video","output":"video","operations":[{"id":"t2v","slots":{}},{"id":"video-refs","slots":{"referenceImages":{"min":1,"max":9,"required":false,"role":"pictures"},"referenceVideos":{"min":1,"max":1,"required":false,"role":"clips"},"referenceAudios":{"min":1,"max":3,"required":false,"role":"sounds"}}}],"limits":{"prompt":{"max":7000},"negative":null,"lyrics":null,"seconds":{"min":4,"max":15,"step":1,"words":[]},"shape":{"aspects":["16:9","9:16"],"resolutions":["768p","480p"],"sizes":null,"fps":null},"seed":{"min":0,"max":4294967295},"sound":"native","speech":null,"count":{"perJob":1}},"price":{"unit":"rung"}},"x-auray-surface-enabled":true},"servers":[{"url":"https://queue.auray.run"}],"paths":{"/auray-ai/minimax-h3-v2/text-to-video":{"post":{"operationId":"submit","summary":"Run auray-ai/minimax-h3-v2/text-to-video","tags":["Queue"],"parameters":[{"name":"logs","in":"query","required":false,"schema":{"type":"string","enum":["1","0","true","false"]},"description":"Include the runner's log lines on a read. Off by default, because a status polled at 10 Hz that carries a growing log is the same lines paid for a hundred times."},{"name":"webhook","in":"query","required":false,"schema":{"type":"string","format":"uri"},"description":"An https address to POST this job's success to, beside any endpoint the account has registered: sent when the job succeeds, tried once more if it is not acknowledged, and never for a job that fails or is cancelled — register an endpoint to hear those. Checked when it is stored and again before it is sent: https on the standard port (443) only, no user-info, no private or loopback host, at most 2,000 characters. Signed `Auray-Signature v2` with a `kid`; verify it against our JWKS. No ownership challenge here, so the body names the account the job belongs to in `account` (the `id` `GET /v1/me` returns), inside what the signature covers: a receiver compares it with its own and refuses anything else."},{"name":"fal_webhook","in":"query","required":false,"schema":{"type":"string","format":"uri"},"description":"An https address to POST this job's success to, beside any endpoint the account has registered: sent when the job succeeds, tried once more if it is not acknowledged, and never for a job that fails or is cancelled — register an endpoint to hear those. Checked when it is stored and again before it is sent: https on the standard port (443) only, no user-info, no private or loopback host, at most 2,000 characters. Signed `Auray-Signature v2` with a `kid`; verify it against our JWKS. No ownership challenge here, so the body names the account the job belongs to in `account` (the `id` `GET /v1/me` returns), inside what the signature covers: a receiver compares it with its own and refuses anything else. An alias for `webhook`; sending both with different values is refused with `conflicting_options`."},{"name":"max_queue_length","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":2147483647},"description":"Refuse with 429 `queue_too_long` rather than queue behind more than this many of your own waiting requests for this model. `0` is a real value and means \"only if none of mine is waiting\". Decided before anything is charged. On a model that does not queue — every catalogue model today, whose `lifecycle.queue` in `GET /v1/models` is `refuses` — sending it is refused 422 `queue_not_offered` before anything is charged."},{"name":"fal_max_queue_length","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":2147483647},"description":"Refuse with 429 `queue_too_long` rather than queue behind more than this many of your own waiting requests for this model. `0` is a real value and means \"only if none of mine is waiting\". Decided before anything is charged. On a model that does not queue — every catalogue model today, whose `lifecycle.queue` in `GET /v1/models` is `refuses` — sending it is refused 422 `queue_not_offered` before anything is charged. An alias for `max_queue_length`; sending both with different values is refused with `conflicting_options`."},{"name":"X-Auray-Priority","in":"header","required":false,"schema":{"type":"string","enum":["normal","low"]},"description":"`low` puts this request behind every normal one. Nothing else changes. On a model that does not queue — every catalogue model today, whose `lifecycle.queue` in `GET /v1/models` is `refuses` — sending it is refused 422 `queue_not_offered` before anything is charged."},{"name":"X-Fal-Queue-Priority","in":"header","required":false,"schema":{"type":"string","enum":["normal","low"]},"description":"`low` puts this request behind every normal one. Nothing else changes. On a model that does not queue — every catalogue model today, whose `lifecycle.queue` in `GET /v1/models` is `refuses` — sending it is refused 422 `queue_not_offered` before anything is charged. An alias for `X-Auray-Priority`; sending both with different values is refused with `conflicting_options`."},{"name":"X-Auray-Request-Timeout","in":"header","required":false,"schema":{"type":"number","minimum":1,"maximum":86400},"description":"Seconds to wait for a seat. A request still waiting past it is failed `request_timeout` and refunded. It is a time-to-START and never a bound on inference: a job that has been dispatched is not stopped by it. On a model that does not queue — every catalogue model today, whose `lifecycle.queue` in `GET /v1/models` is `refuses` — it is accepted and has nothing to bound: such a model starts at once or refuses at once."},{"name":"X-Fal-Request-Timeout","in":"header","required":false,"schema":{"type":"number","minimum":1,"maximum":86400},"description":"Seconds to wait for a seat. A request still waiting past it is failed `request_timeout` and refunded. It is a time-to-START and never a bound on inference: a job that has been dispatched is not stopped by it. On a model that does not queue — every catalogue model today, whose `lifecycle.queue` in `GET /v1/models` is `refuses` — it is accepted and has nothing to bound: such a model starts at once or refuses at once. An alias for `X-Auray-Request-Timeout`; sending both with different values is refused with `conflicting_options`."},{"name":"X-Auray-Covered-Only","in":"header","required":false,"schema":{"type":"string","enum":["1","true"]},"description":"Run this job only if a pass or a promotion of yours pays for it. A job neither pays for is refused 409 `not_covered` before anything is held or charged — or, when your pass had ended by the time the job started, refunded and refused so — where without this header your credits would pay for it; a job your plan runs only through a pass is refused as the plan refuses it (`model_not_in_plan`, `pass_does_not_cover`). For a job it lets through, the submit's answer on `queue.auray.run` says `credits_charged: 0` and what paid in `coverage`, and so does `GET /v1/jobs/{id}`; a run on `auray.run` answers the job's output, which says neither — read `GET /v1/jobs/{id}` with its `request_id`. `true` is read as `1`; any other value as no header."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Input"}}}},"responses":{"200":{"description":"Accepted, and charged and running — or, when the platform is full, waiting in the queue and charged when it starts: `credits_charged` is what has been taken, `credits_quoted` what it costs. Always this status: a submit's outcome is in `status`, never in the status line.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/QueueStatus"},{"type":"object","properties":{"product":{"type":"string","enum":["photo","music","threed","video","external"],"description":"Which of this platform's products ran it."},"provider_job_id":{"type":["string","null"],"description":"The id the job runs under, once it has been handed to its model — possibly while still `queued`; null before. Quote it to support."},"model":{"type":"string","description":"The address that ran it, echoed back."},"engine":{"type":["string","null"],"description":"The service's own name for the model that ran, where it reports one — a catalogue model's is its `id` on GET /v1/models; null otherwise. What `model` carried before it carried the address."},"attribution":{"type":["string","null"],"description":"The credit line the model's licence requires you to show; null where none is required."},"credits_charged":{"type":"integer","examples":[1],"description":"What this job cost. 0 on a replay, or when a pass or a promotion paid for it (`coverage` says which)."},"credits_quoted":{"type":"integer","examples":[1],"description":"What this job costs, in credits: the price it was quoted at submit. Equal to `credits_charged` once it has been charged; while it waits in the queue to start, `credits_charged` is 0 and this is what it will be charged when it starts (a cancel before then costs nothing) — and a replay of a job still waiting quotes the body that job was queued with, which is the one it runs, not the replay's. For a catalogue model it is the hold, and the settle may give part of it back — a settled read's `credits_charged` says what it finally cost."},"coverage":{"type":"object","description":"Present when a pass or a promotion paid for this job — `{\"by\": \"pass\", \"pass\": \"seedance-2-5\"}` or `{\"by\": \"promotion\"}`, and `credits_charged` is 0 — or when you hold a pass for this model that did not cover this job: `{\"by\": null, \"miss\": {\"pass\": \"video\", \"why\": \"door\"}}`, `why` being `door` (the pass does not work here) or `shape` (it does not cover this kind of job). Absent otherwise. Send `X-Auray-Covered-Only: 1` to run a job only if a pass or a promotion pays for it."},"credits_remaining":{"type":"integer","examples":[1],"description":"The balance after it."},"expected_seconds":{"type":"integer","examples":[1],"description":"A rough render time, for a progress bar; 0 where nothing is published."},"give_up_after_seconds":{"type":"integer","examples":[1],"description":"The longest this job may take from its submit: the longest it may wait to start (your X-Auray-Request-Timeout, or the product's queue deadline) plus the longest it may run before it is stopped and refunded. Waiting longer is waiting for nothing; the official clients wait this long by default. For a catalogue model the part it may run is its reap: `lifecycle.stall_ceiling_seconds` on GET /v1/models, lengthened for a video asked for more seconds than the length that figure is set for, in proportion to the seconds asked — so this figure, not the listing's, is the one to wait by. Otherwise these are the published limits: we may lengthen them during an incident, never shorten them."},"replayed":{"type":"boolean","description":"`true` when your `idempotency_key` matched a job this platform already had. Nothing was charged and nothing was rendered twice."},"waited":{"type":"boolean","description":"Present when `wait` was asked for. The rest of this group comes with it."},"timed_out":{"type":"boolean","description":"The wait ran out before the job settled. Still a 2xx, never a 408 or 504 — a library that retries on those would resubmit and you would pay twice. Poll `status_url`."},"wait_declined":{"type":"string","enum":["platform_busy","product_busy","account_busy"],"description":"No seat was free to hold the connection with, so the request was answered at once. `platform_busy`: no product would have helped. `product_busy`: another product's queue might. `account_busy`: you are already waiting on every seat your plan's lanes allow. The job is running either way; poll it."},"status_url":{"type":"string","description":"Poll this."},"response_url":{"type":"string","description":"Fetch the result from this once the status is COMPLETED."},"cancel_url":{"type":"string","description":"`PUT` to this to ask for a cancellation."}}}]}}}},"202":{"description":"The dispatch could not be confirmed (`dispatch_unresolved`): the charge stands, the request exists and is `IN_QUEUE`, and the body is its status document with `message` and `docs` beside it. Poll `status_url` — never resend under a new key, which would be a second charge. If it never starts, it is declared lost and refunded.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/QueueStatus"},{"type":"object","properties":{"status_url":{"type":"string","description":"Poll this."},"response_url":{"type":"string","description":"Fetch the result from this once the status is COMPLETED."},"cancel_url":{"type":"string","description":"`PUT` to this to ask for a cancellation."},"message":{"type":"string","description":"Why the dispatch could not be confirmed, and what to do."},"docs":{"type":"string","description":"The `dispatch_unresolved` entry on the errors page."}}}]}}}},"400":{"description":"A refusal: `error_type` is ConflictError or ValidationError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"A refusal: `error_type` is AuthenticationError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"A refusal: `error_type` is PaymentError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"A refusal: `error_type` is PermissionError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"A refusal: `error_type` is NotFoundError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"A refusal: `error_type` is ValidationError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A refusal: `error_type` is CancellationError or ConflictError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"A refusal: `error_type` is GoneError or NotFoundError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"A refusal: `error_type` is PayloadTooLargeError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"A refusal of what the request says — an option, the body, a field — decided before anything is charged, or the model's own refusal of the request as it was written (its content filter, a value or a file it would not take), refunded: `error_type` is ContentPolicyError or ValidationError, and `detail` is a list of `{loc, msg, type}`, `loc` naming where (`[\"body\"]` when the parser names no field). The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"428":{"description":"A refusal: `error_type` is PreconditionError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"A refusal: `error_type` is CapacityError or RateLimitError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"451":{"description":"A refusal: `error_type` is RegionError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"A refusal: `error_type` is ConfigurationError or InternalError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"A refusal: `error_type` is NotImplementedError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"A refusal: `error_type` is UpstreamError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A refusal: `error_type` is CapacityError or ConfigurationError or InternalError or UpstreamError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"A refusal: `error_type` is TimeoutError. The code is in `error`, and every code is explained at https://auray.ai/docs/api/errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auray-ai/minimax-h3-v2/text-to-video/requests/{request_id}":{"get":{"operationId":"result","summary":"The result","tags":["Queue"],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string"},"description":"The `request_id` the submit answered with."},{"name":"logs","in":"query","required":false,"schema":{"type":"string","enum":["1","0","true","false"]},"description":"Include the runner's log lines on a read. Off by default, because a status polled at 10 Hz that carries a growing log is the same lines paid for a hundred times."}],"responses":{"200":{"description":"The request and its output, once its status is COMPLETED.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/QueueStatus"},{"type":"object","properties":{"status_url":{"type":"string","description":"Poll this."},"response_url":{"type":"string","description":"Fetch the result from this once the status is COMPLETED."},"cancel_url":{"type":"string","description":"`PUT` to this to ask for a cancellation."}}}]}}}},"400":{"description":"The request has not finished: `request_in_progress`, with its `status` (`IN_QUEUE` or `IN_PROGRESS`), `queue_position` while it waits, and `Retry-After`. Nothing a job made part-way is its result: poll `status_url` until COMPLETED, then read this again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"The request produced no output. `error_type` is AuthenticationError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The request produced no output. `error_type` is PaymentError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The request produced no output. `error_type` is PermissionError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The request produced no output. `error_type` is NotFoundError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The request produced no output. `error_type` is ConflictError or CancellationError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"The request produced no output. `error_type` is GoneError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The request produced no output. `error_type` is PayloadTooLargeError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"The request produced no output. `error_type` is ValidationError or ContentPolicyError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"428":{"description":"The request produced no output. `error_type` is PreconditionError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"The request produced no output. `error_type` is RateLimitError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"451":{"description":"The request produced no output. `error_type` is RegionError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"The request produced no output. `error_type` is ExecutionError or InternalError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"501":{"description":"The request produced no output. `error_type` is NotImplementedError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"The request produced no output. `error_type` is UpstreamError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"The request produced no output. `error_type` is CapacityError or ConfigurationError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"The request produced no output. `error_type` is TimeoutError; the code is in `error` and the sentence in `detail`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auray-ai/minimax-h3-v2/text-to-video/requests/{request_id}/status":{"get":{"operationId":"status","summary":"The status","description":"The same document the result answers, and it is 200 for a failed or unfinished request where the result is not: this address reports, the result IS the output. `GET /auray-ai/minimax-h3-v2/text-to-video/requests/{request_id}/status/stream` streams this document as `text/event-stream` until it is COMPLETED; each stream closes after about five minutes with no final frame, having sent `retry:` at its top, so reconnect and keep reading until COMPLETED — every frame is the whole status, and the official clients reconnect on their own. It takes a seat from the same pool `wait` does and is 503 `stream_declined` when none is free.","tags":["Queue"],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string"},"description":"The `request_id` the submit answered with."},{"name":"logs","in":"query","required":false,"schema":{"type":"string","enum":["1","0","true","false"]},"description":"Include the runner's log lines on a read. Off by default, because a status polled at 10 Hz that carries a growing log is the same lines paid for a hundred times."}],"responses":{"200":{"description":"Where the request is.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/QueueStatus"},{"type":"object","properties":{"status_url":{"type":"string","description":"Poll this."},"response_url":{"type":"string","description":"Fetch the result from this once the status is COMPLETED."},"cancel_url":{"type":"string","description":"`PUT` to this to ask for a cancellation."}}}]}}}},"404":{"description":"A refusal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/auray-ai/minimax-h3-v2/text-to-video/requests/{request_id}/cancel":{"put":{"operationId":"cancel","summary":"Ask for a cancellation","description":"202 means REQUESTED, not cancelled: a model can decline to stop and keep going, so the body carries `cancelled` and the settled charge for a caller who needs to know which happened. `POST` to the same address answers this platform's own cancel envelope, unchanged.","tags":["Queue"],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string"},"description":"The `request_id` the submit answered with."}],"responses":{"202":{"description":"The cancellation was accepted.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","const":"CANCELLATION_REQUESTED"},"request_id":{"type":"string"},"job_id":{"type":"string","description":"The same job reference as `request_id`, under the one name every host uses."},"product":{"type":"string"},"job_status":{"type":"string"},"settled":{"type":"boolean"},"cancelled":{"type":"boolean"},"credits_charged":{"type":["integer","null"],"description":"What the job cost after the cancel's refund — the ledger's net; null, with `settled_unknown`, when it could not be read."},"credits_reserved":{"type":["integer","null"],"description":"What was taken when the job was charged."},"settled_unknown":{"type":"boolean","description":"Present, and `true`, when the cancel happened and its figures could not be read."}},"required":["status","request_id","job_id","cancelled"]}}}},"400":{"description":"A refusal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"A refusal.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"auray_sk_","description":"A platform key: auray_sk_ and 62 more characters, 71 in all. `Authorization: Bearer <key>` or `Authorization: Key <key>`; both are accepted on every address, and the scheme word is case-insensitive."}},"schemas":{"Input":{"type":"object","properties":{"prompt":{"type":"string","description":"What to film. Name references as <Picture 1>, <Video 1> and <Audio 1>, each kind counted from one in its list's order; the structured form in the guide works best, and plain sentences work too. With no reference, up to 3,800 characters and 4,096 tokens of the model's own tokenizer: prose in English, Indonesian, Chinese, Japanese, Thai or Hindi fits in the 3,800 characters, while rare characters and some scripts take several tokens a character and can reach 4,096 tokens first. Past either, the request is refused with prompt_too_long before anything is charged; a refusal in tokens carries `tokens` and `max_tokens`. Documented range: up to 7,000 characters."},"duration_seconds":{"type":"integer","default":5,"description":"Whole seconds; outside 4–15 it is refused with 422 duration_out_of_range, before any charge. Documented range: 4 to 15."},"aspect_ratio":{"type":"string","enum":["16:9","9:16"],"default":"16:9","description":"16:9 or 9:16."},"resolution":{"type":"string","enum":["768p","480p"],"default":"768p","description":"480p needs at least one picture or clip; from words alone a clip is made at 768p."},"image_references":{"type":"array","items":{"type":"string","format":"uri","examples":["https://v3b.auray.media/examples/samples/still-life.jpg"]},"description":"Up to 9 pictures that hold a subject — a face, a costume, a place — named in order as <Picture 1>, the next as the next number. JPEG, PNG or WebP. Accepts image/jpeg, image/png, image/webp. At most 25 MB. Documented range: up to 9. When the request also sends `audio_references`, this model makes the person in a picture here speak or move: a picture you upload, or a link from anywhere else, is taken once your account has accepted, one time, that you have the right to the faces and voices you use — send `acceptance: {\"real_people\": \"2026-11-03\"}` with the request, or accept in the Auray app — and is refused `403 acceptance_required` until then, before anything is charged. A picture made here — a job's result — asks nothing. While uploads are paused here, a picture you upload, or a link from anywhere else, is refused `403 likeness_not_made_here` instead, before anything is charged. The files the examples here send are ours, and are taken."},"video_references":{"type":"array","items":{"type":"string","format":"uri","examples":["https://v3b.auray.media/examples/samples/coffee-pour.mp4"]},"description":"One clip whose look and motion the new clip follows, named <Video 1>: H.264 in MP4 or MOV, up to 5.2 seconds. Its own sound is kept: a voice or a sound in it may guide the new clip. Accepts video/mp4, video/quicktime. At most 25 MB. Documented range: up to 1. This model may keep the sound of a clip here as a voice: a clip you upload with a sound track, or a link from anywhere else, is taken once your account has accepted, one time, that you have the right to the faces and voices you use — send `acceptance: {\"real_people\": \"2026-11-03\"}` with the request, or accept in the Auray app — and is refused `403 acceptance_required` until then, before anything is charged. A clip you upload with no sound track asks nothing, nor does one made here. When the request also sends `audio_references`, this model makes the person in a clip here speak or move: a clip you upload, or a link from anywhere else, is taken once your account has accepted, one time, that you have the right to the faces and voices you use — send `acceptance: {\"real_people\": \"2026-11-03\"}` with the request, or accept in the Auray app — and is refused `403 acceptance_required` until then, before anything is charged. A clip made here — a job's result — asks nothing. While uploads are paused here, a clip you upload with a sound track, or a link from anywhere else, is refused `403 voice_sample_not_made_here` instead, before anything is charged. While uploads are paused here, a clip you upload, or a link from anywhere else, is refused `403 likeness_not_made_here` instead, before anything is charged. The files the examples here send are ours, and are taken."},"audio_references":{"type":"array","items":{"type":"string","format":"uri","examples":["https://v3b.auray.media/examples/samples/electronic-loop.mp3"]},"description":"Up to 3 sounds — a voice or an ambience — named <Audio 1> and on: WAV, MP3, FLAC or M4A, up to 15 seconds each. A sound needs a picture or a clip beside it, and the 12 files of every kind together are the most one request sends. Accepts audio/wav, audio/x-wav, audio/wave, audio/mpeg, audio/flac, audio/x-flac, audio/mp4, audio/x-m4a. At most 25 MB. Documented range: up to 3. This model may keep the voice in a recording here: a recording you upload, or a link from anywhere else, is taken once your account has accepted, one time, that you have the right to the faces and voices you use — send `acceptance: {\"real_people\": \"2026-11-03\"}` with the request, or accept in the Auray app — and is refused `403 acceptance_required` until then, before anything is charged. Or send the request without it. While uploads are paused here, a recording you upload, or a link from anywhere else, is refused `403 voice_sample_not_made_here` instead, before anything is charged; send the request without it. The files the examples here send are ours, and are taken."},"seed":{"type":"integer","examples":[1],"description":"The same seed with the same prompt and settings makes the same scene again; small details can differ between runs. Outside the range it is refused with 422 seed_out_of_range, before any charge. Documented range: 0 to 4,294,967,295."},"idempotency_key":{"type":"string","minLength":1,"maxLength":64,"pattern":"^[A-Za-z0-9._-]{1,64}$","description":"Your own name for this request. Send the same one twice and the second call is answered with the first request rather than charged again. `Idempotency-Key:` as a header is accepted as an alias — that is the spelling a retrying proxy replays, and the one to use when running a model on `auray.run`, where a request that outlives its connection is answered 504 and recovered by replay. Omit it and the platform mints one."},"acceptance":{"type":"object","properties":{"real_people":{"type":"string","enum":["2026-11-03"],"description":"The version of the words you accept: that you have the right to every face and voice you upload, and to any voice or style you pick that sounds like a real person — it is yours, or you have permission — and that you are responsible for what you make with them."}},"additionalProperties":false,"description":"Your account's one acceptance, sent with the request that first needs it: a file of a real person's face or voice you upload, in a field this model makes speak or move, copies the voice of or puts into a clip, is taken once your account has accepted, one time, that you have the right to the faces and voices you use. Kept for your account before anything is charged, so no later request asks again — in any app or through the API — and asked of no file made here. You can accept in the Auray app (Account → Privacy) instead; an assistant cannot accept for you, so through MCP it is accepted in the app."}},"required":["prompt"],"additionalProperties":false,"x-auray-rules":[{"if":{"required":["audio_references"]},"then":{"anyOf":[{"required":["image_references"]},{"required":["video_references"]}]}},{"if":{"required":["resolution"],"properties":{"resolution":{"const":"480p"}}},"then":{"anyOf":[{"required":["image_references"]},{"required":["video_references"]}]}}],"description":"The model's own fields, in the shape the model reads them, plus `idempotency_key` and `acceptance`. Read from https://api.auray.ai/v1/openapi.json on 2026-08-31. Rules across fields, as the model's documentation states them, judged by this API before any charge (warned with a Deprecation header until enforcement starts): (1) When `audio_references` is sent, send at least one of `image_references` or `video_references`. (2) When `resolution` is \"480p\", send at least one of `image_references` or `video_references`."},"QueueStatus":{"oneOf":[{"type":"object","title":"IN_QUEUE","properties":{"status":{"type":"string","const":"IN_QUEUE"},"request_id":{"type":"string","description":"This request's job reference — `<product>_<your idempotency key>`. It is the id every other address on this platform takes, and it is what the three URLs below are built from. The id of the HTTP call itself is in `X-Request-Id` (and `x-fal-request-id` beside it)."},"job_id":{"type":"string","description":"The same job reference under the one name every host uses for it — `id` on `/v1`. `request_id` is the queue protocol's name for it on this host, and means the HTTP call on every other body this API sends."},"logs":{"type":"array","items":{"type":"object","properties":{"message":{"type":"string"},"timestamp":{"type":"string"}},"required":["message","timestamp"]},"description":"Empty unless `?logs=1` asked for them, and empty is a statement."},"metrics":{"type":"object","properties":{"inference_time":{"type":"number","description":"Seconds spent computing, when the runner reported it."}},"description":"`{}` when nothing was reported, which is what the queue protocol sends and what its clients test for."},"give_up_after_seconds":{"type":"integer","description":"Present while the request is open: the longest it may take from its submit — the longest it may wait to start plus the longest it may run before it is stopped and refunded, the figure the submit answered. Waiting longer is waiting for nothing; the official clients wait this long by default."},"queue_position":{"type":"integer","description":"How many requests are ahead of this one. `0` on a read today: the read path looks a job up by credit key and never selects the row id a position needs."}},"required":["status","request_id","job_id","logs","metrics","queue_position"]},{"type":"object","title":"IN_PROGRESS","properties":{"status":{"type":"string","const":"IN_PROGRESS"},"request_id":{"type":"string","description":"This request's job reference — `<product>_<your idempotency key>`. It is the id every other address on this platform takes, and it is what the three URLs below are built from. The id of the HTTP call itself is in `X-Request-Id` (and `x-fal-request-id` beside it)."},"job_id":{"type":"string","description":"The same job reference under the one name every host uses for it — `id` on `/v1`. `request_id` is the queue protocol's name for it on this host, and means the HTTP call on every other body this API sends."},"logs":{"type":"array","items":{"type":"object","properties":{"message":{"type":"string"},"timestamp":{"type":"string"}},"required":["message","timestamp"]},"description":"Empty unless `?logs=1` asked for them, and empty is a statement."},"metrics":{"type":"object","properties":{"inference_time":{"type":"number","description":"Seconds spent computing, when the runner reported it."}},"description":"`{}` when nothing was reported, which is what the queue protocol sends and what its clients test for."},"give_up_after_seconds":{"type":"integer","description":"Present while the request is open: the longest it may take from its submit — the longest it may wait to start plus the longest it may run before it is stopped and refunded, the figure the submit answered. Waiting longer is waiting for nothing; the official clients wait this long by default."}},"required":["status","request_id","job_id","logs","metrics"]},{"type":"object","title":"COMPLETED","properties":{"status":{"type":"string","const":"COMPLETED"},"request_id":{"type":"string","description":"This request's job reference — `<product>_<your idempotency key>`. It is the id every other address on this platform takes, and it is what the three URLs below are built from. The id of the HTTP call itself is in `X-Request-Id` (and `x-fal-request-id` beside it)."},"job_id":{"type":"string","description":"The same job reference under the one name every host uses for it — `id` on `/v1`. `request_id` is the queue protocol's name for it on this host, and means the HTTP call on every other body this API sends."},"logs":{"type":"array","items":{"type":"object","properties":{"message":{"type":"string"},"timestamp":{"type":"string"}},"required":["message","timestamp"]},"description":"Empty unless `?logs=1` asked for them, and empty is a statement."},"metrics":{"type":"object","properties":{"inference_time":{"type":"number","description":"Seconds spent computing, when the runner reported it."}},"description":"`{}` when nothing was reported, which is what the queue protocol sends and what its clients test for."},"error":{"type":["string","null"],"description":"The failure code, or `null` when the request produced its output."},"error_type":{"type":["string","null"],"enum":["AuthenticationError","PermissionError","PaymentError","ValidationError","ContentPolicyError","PayloadTooLargeError","NotFoundError","GoneError","ConflictError","CancellationError","PreconditionError","RegionError","RateLimitError","CapacityError","ConfigurationError","TimeoutError","UpstreamError","ExecutionError","InternalError","NotImplementedError",null],"description":"The class of the failure, or `null`. One of twenty; the code is in `error`."}},"required":["status","request_id","job_id","logs","metrics","error","error_type"]}],"discriminator":{"propertyName":"status"}},"Error":{"type":"object","properties":{"error":{"type":"string","description":"The code. Every one is explained at https://auray.ai/docs/api/errors."},"error_type":{"type":"string","enum":["AuthenticationError","PermissionError","PaymentError","ValidationError","ContentPolicyError","PayloadTooLargeError","NotFoundError","GoneError","ConflictError","CancellationError","PreconditionError","RegionError","RateLimitError","CapacityError","ConfigurationError","TimeoutError","UpstreamError","ExecutionError","InternalError","NotImplementedError"],"description":"The class of the code, also sent as the `X-Auray-Error-Type` header."},"message":{"type":"string","description":"What went wrong and what to do about it."},"detail":{"oneOf":[{"type":"string","description":"The same sentence as `message`. The queue protocol's key; its clients print it."},{"type":"array","description":"A refusal about the input, answered 422: one entry per problem, `loc` naming where it was spelt (`[\"query\", \"max_queue_length\"]`, `[\"header\", \"x-fal-request-timeout\"]`, or `[\"body\"]` when the parser reports no field).","items":{"type":"object","properties":{"loc":{"type":"array","items":{"type":"string"}},"msg":{"type":"string"},"type":{"type":"string","description":"The code, which is this platform's own taxonomy."}},"required":["loc","msg","type"]}}]},"docs":{"type":"string","description":"A link to this code's explanation."},"request_id":{"type":"string","description":"The HTTP call's id. Quote it."}},"required":["error","error_type","message","detail"]}}},"security":[{"apiKey":[]}],"request_id":"7dcebba9-846d-4a26-9df3-a0b5c48502f0"}