Create a generation task

The unified asynchronous generation endpoint. One path serves every modality: images and video today, with audio arriving here later at the same path and the same shape.

Unlike the vendor-compatible endpoints it does not wait. It returns a task ID immediately and generation continues in the background.

High-quality image generation often takes 80-115 seconds in practice, and any timeout along the synchronous request path can leave the client without a result even though upstream generation and billing have already occurred.

Billing matches the synchronous path: an upper bound is reserved at submit, then settled against actual usage. An insufficient balance returns 402 at submit time.

Edits with reference images use this endpoint too: switch the Content-Type to multipart/form-data and send reference images as files (image or image[]), with mask for the optional mask.

Model-specific parameters are not here

This endpoint serves every modality, and each model takes a different set — images have size / quality, video has duration and frame rate, audio has voice and sample rate. Putting them in one table means most of it does not apply to any given call, and nothing tells you which parts do.

So only the model-independent fields are listed here. For what your model accepts and what each field allows, see that model's own reference (grouped by model under Images).

Callbacks: webhook_url

When the task reaches a terminal state, the platform POSTs this payload to that address:

{
  "event": "task.succeeded",
  "sent_at": "2026-09-01T04:31:00.000Z",
  "task": { … }
}

task uses the same schema as GET /v1/tasks/{id}, so the same parsing code can be reused.

Verify the signature

The request carries Amux-Signature: t=<unix seconds>,v1=<hex>, an HMAC-SHA256 over ${t}.${raw body}.

Without signature verification, any party that learns the URL can forge callback payloads. The signing secret is derived per workspace — one per workspace — and workspace admins can view it on the API keys page in the console.

The signature covers t.body rather than the body alone, so stale timestamps should also be rejected. A five-minute acceptance window is a reasonable default.

Retries

Anything that is not 2xx (3xx included) and any timeout counts as a failure. After the first try we back off 10s / 1m / 5m / 30m / 1h, retrying at most five more times (six in total, spanning about two hours). So:

  • Return 2xx quickly and move downstream processing onto your own queue;
  • Deduplicate on task.id, because retries can deliver the same event more than once.

Redirects are not followed

The callback endpoint must return 2xx directly. Any 3xx response counts as a failure.

This endpoint does not stream

stream: true, and partial_images above 0, return 400 here.

Streaming would mean this request runs the work to completion and pushes it down the connection — the task never enters the queue, and the result is gone when the connection drops. Surviving a dropped connection is the reason this endpoint exists.

For the result within this request use Prefer: wait below, which returns exactly the same JSON as GET /v1/tasks/{id}. For low-resolution preview frames use the vendor-compatible /v1/images/generations with stream: true.

post/v1/tasks

Request

  • Base URL: https://gateway.amux.ai
  • URL: https://gateway.amux.ai/v1/tasks
  • Auth: HTTP bearer

Headers

Preferstring
Example:wait=60

wait=N keeps the current request open for up to N seconds. If the task finishes in time, the endpoint returns 200 with the full result; otherwise it returns 202.

N is capped at 90. Use it when you want to avoid an extra poll without switching to SSE.

Idempotency-Keystring

Retrying with the same key does not create a second task and does not reserve funds a second time; the original task is returned.

Idempotency keys are scoped to the workspace. When retrying the same submit, reuse the same key.

Request body

modelstring required

A catalog model ID, optionally with a :provider suffix.

The modality comes from the model — there is no separate field. Naming an image model makes this an image task.

promptstring required

The prompt.

webhook_urlstring uri

Where to POST the result once the task reaches a terminal state; see the "Callbacks" section above for the shape.

https only, and it must not point at a private network — we deliver from our servers. The address is checked at submit time, so a bad one fails immediately rather than after the task has run.

Example request

{
  "model": "openai/gpt-image-2",
  "prompt": "A ginger cat running through fresh snow"
}

Response

Either already terminal (a Prefer: wait that finished) or a replay of the same idempotency key.

Kept separate from 202 on purpose: 202 says "I took on a piece of work", and neither of these took on anything new.

idstring

The task ID. Use it to retrieve the result and to find the call in your logs.

status'queued' | 'running' | 'succeeded' | 'failed' | 'canceled' | 'expired'

The last four are terminal and will not change again.

expired means the task did not complete and its result can no longer be retrieved. Those are not charged and the reserve has been released.

modelstring

The model this task ran on.

created_atstring date-time

When the task was submitted.

coststring

What was actually charged, in USD. Failed and expired are 0.

notesstring[]

What we did to your request. Present only when something was done — no key means it went upstream unchanged.

Two kinds: parameters this upstream does not have were dropped, and a value was filled in for you. There is one case of the latter today: MiniMax text-only generation requires a concrete ratio (adaptive has no material to follow), so 16:9 is sent and noted here.

Example response

{
  "id": "task_01M1CG35C16CJ790D00BV1RBVM",
  "model": "openai/gpt-image-2",
  "cost": "0.2108",
  "notes": [
    "dropped audio: this model decides the soundtrack itself"
  ]
}

Changes

No recorded changes to this operation across all 1 revision of this API.