Create task
最近更新:2026年9月1日
站内统一的异步生成入口。一条端点服务全部模态,提交拿 ID、按 ID 取结果。
站内统一的异步生成入口。一条端点承载全部模态;当前可用于图像,后续接入视频与音频时仍沿用同一路径与响应形状。
下表列出全部请求参数与响应字段。
https://gateway.amux.ai/v1/tasks鉴权
headerAuthorizationstring必填Bearer <你的 Amux 密钥> 控制台创建的 Amux 密钥。忘了可以回控制台的密钥页再看一次。
Preferstringwait=N 表示在当前连接上最多等待 N 秒。若任务完成则直接返回 200 和完整结果;未完成则返回 202。
N 最大 90;超过按 90 处理。适合想少一次轮询、但又不想改成 SSE 的场景。
Idempotency-Keystring相同键的重试不会再次创建任务,也不会再次预留费用;返回的是原有任务。
幂等键按工作区隔离。客户端重试同一次提交时,复用同一个键即可。
请求
application/jsonmodelstring必填站内模型 ID,可带 :供应商 后缀锁定供应商。
模态由模型决定,不用另外声明——填一个图像模型就是出图任务。
promptstring必填提示词。
webhook_urlstring任务到终态时往这里 POST 一份结果,形状见上面「回调」那一节。
只收 https,且不能指向内网——我们是从服务端发过去的。
地址在提交这一刻就校验,写错了当场报错,
而不是等任务跑完才发现回调从来没来。
响应
200response已经是终态(Prefer: wait 等到了),或者这是一次重放(同一个幂等键)。
和 202 分开是有意的:202 说「我接下了一件事」,而这两种情况都没有接下新的事。
202response任务已受理,并且预扣已经扣住。拿 id 去取结果。
返 202 而不是 200,是因为这次调用没有产出——它只是接下了一件事。
400response请求不合法。也包括 stream: true 或 partial_images 大于 0——这条端点是异步的, 同步流式在厂商兼容端点上(/v1/images/generations)。
402response可用余额不足以覆盖预扣上界。可用 = 余额 − 已过期批次 − 已冻结的预扣。
503response在途任务已满,稍后重试(响应带 Retry-After)。
什么时候用它
一次高质量出图实测 80–115 秒。走同步端点的话,这条路上任何一环超时(反向代理、网关、客户端的默认超时)都会让你拿不到图,而钱已经花了——上游已经出图并计了费。
异步接口把请求提交与结果获取拆开:提交立即返回,生成在后台进行,结果可按需轮询或回调接收。
和同步端点的关系
计费完全一致:提交时按上界预扣,完成后按实际结算、释放差额。
区别只有一处:预扣发生在提交这一刻。所以余额不足会在提交时就 402,而不是等跑完才发现扣不出来。
模态由模型决定
model 决定任务类型。图像模型对应图像任务,后续的视频或音频模型也会沿用同一规则。请求体中无需额外声明 type 一类的字段。
请求体支持两种形态
纯生成直接发 application/json。带参考图的编辑改用 multipart/form-data:参考图放 image 或 image[],蒙版放 mask,其余参数继续沿用同名字段。
用 webhook_url 接收结果
任务进入终态后,会向该地址 POST 一份结果:
{
"event": "task.succeeded",
"sent_at": "2026-09-01T04:31:00.000Z",
"task": { "id": "task_…", "status": "succeeded", "output": { "images": [...] }, "usage": {...}, "cost": "0.005925" }
}task 与取回接口的响应体保持一致,可直接复用同一套解析逻辑。
验证签名
请求带 Amux-Signature: t=<秒级时间戳>,v1=<hex>,签的是
`${t}.${原始请求体}`(HMAC-SHA256)。密钥在控制台的工作区设置里取。
如果不校验签名,任何知道该地址的人都可以伪造回调内容。
import { createHmac, timingSafeEqual } from 'node:crypto'
function verify(rawBody, header, secretHex) {
const m = /t=(\d+),v1=([0-9a-f]+)/.exec(header)
if (!m) return false
// ⚠️ 先校验时间戳,避免旧回调被重复使用
const age = Math.abs(Math.floor(Date.now() / 1000) - Number(m[1]))
if (age > 300) return false
const expected = createHmac('sha256', Buffer.from(secretHex, 'hex'))
.update(`${m[1]}.${rawBody}`)
.digest('hex')
// ⚠️ 使用定长比较,避免基于耗时的签名推断
return timingSafeEqual(Buffer.from(expected), Buffer.from(m[2]))
}⚠️ 校验对象必须是原始请求体字节,不能先 JSON.parse 再 stringify;重新序列化会改变键顺序或空白,从而导致签名不匹配。
重试与去重
非 2xx(3xx 也算)与超时都算失败。首次之后按 10 秒 / 1 分 / 5 分 / 30 分 / 1 小时退避,最多再试 5 次(合计 6 次,跨度约 2 小时)。
- 尽快返回 2xx,后续处理建议放入你自己的异步队列;
- 按
task.id去重,因为同一事件在重试场景下可能重复送达。
回调地址限制
仅支持 https,且不能指向私有网络地址。 地址会在提交时校验,不符合要求会直接报错。
不跟随重定向。 回调地址需要直接返回 2xx。
这条端点不流式
stream: true 与 partial_images 大于 0 在这里会返回 400。(partial_images: 0 是默认值,照常放行。)
流式意味着这个请求自己把结果跑完并顺着连接送出去——那样任务不会进队列, 连接断了结果就没有了,而「连接断了也不丢」正是这条端点存在的理由。
想在当前请求里拿到结果,用下面的 Prefer: wait:它返回的是和取回接口
完全一样的那份 JSON,你只需要维护一套解析逻辑。想要生成过程中的低清预览,
用厂商兼容端点 /v1/images/generations 并设置 stream: true。
短暂等待结果:Prefer: wait
发送 Prefer: wait=60 后,服务端会在当前连接上最多等待 60 秒。若任务在此期间完成,则直接返回 200 和完整结果,响应形状与取回接口一致。
如果超过等待时间仍未完成,则返回 202,后续继续按任务 ID 查询即可。
N 最大 90;超过按 90 处理。适合想少一次轮询、但又不想改成 SSE 的场景。
重试保护:Idempotency-Key
为创建请求指定 Idempotency-Key 后,相同键的重试不会再次创建任务,也不会再次预留费用;接口会返回原有任务。
适合处理“请求已发出但客户端未收到响应”的场景。
幂等键按工作区隔离。客户端重试同一次提交时,复用同一个键即可。
curl https://gateway.amux.ai/v1/tasks \
-H "Authorization: Bearer $AMUX_API_KEY" \
-H "Prefer: <value>" \
-H "Idempotency-Key: <value>" \
-d '{
"model": "openai/gpt-image-2",
"prompt": "A ginger cat running through fresh snow"
}'{
"id": "task_01M1CG35C16CJ790D00BV1RBVM",
"status": "queued",
"model": "openai/gpt-image-2",
"created_at": "<string>",
"output": {
"images": [
{
"index": 0,
"url": "<string>"
}
],
"videos": [
{
"index": 0,
"url": "<string>"
}
]
},
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"total_tokens": 0,
"output_video_seconds": 0
},
"cost": "0.2108",
"notes": [
"dropped audio: this model decides the soundtrack itself"
],
"error": {
"message": "<string>",
"code": "<string>"
}
}