26j文档
试一试 →

任务完成回调(Webhook)

提交异步生成任务时带上回调地址,任务完成(成功或失败)后主动把结果 POST 给你,并可指定失败错误文案的语言。

提交视频 / 图片 / 音频等异步生成任务时,可以带上一个回调地址。任务完成(成功或失败)后,我们会主动把结果 POST 到你的地址,你就不用一直轮询查询了。对于视频和图片生成任务,还可以通过 language 指定失败回调中错误文案的语言。

快速开始

提交任务时,在请求体顶层加入 webhook 字段;如需翻译失败回调中的错误文案,再加入 language:

curl -X POST https://你的接入域名/v1/images/generations \
  -H "Authorization: Bearer 你的APIKey" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2",
    "prompt": "a red apple on a table",
    "size": "1024x1024",
    "webhook": "https://your-server.com",
    "language": "zh"
  }'

任务做完后,我们会向 你的地址 + /callback 发一个 POST 请求。

视频、音频等其它异步任务接口同理,webhook 应放在提交请求体的顶层。language 目前适用于 POST /v1/videos/generations 和 POST /v1/images/generations,同样放在请求体顶层。

指定错误文案语言

language 是可选字符串参数,只影响失败回调中的 error.message。任务 ID、状态、进度、金额和结果 URL 等字段不会随语言变化。不传时,错误文案保持上游或平台返回的原文。

语言 参数值 语言 参数值
English en Русский ru
简体中文 zh Français fr
日本語 ja Deutsch de
한국어 ko Bahasa Indonesia id
Português pt Español es
  • 参数值不区分大小写,首尾空格会自动移除,例如 "ZH"、" zh " 都会按 zh 处理。
  • 请使用表格中的两位语言码。zh-CN、en-US、pt-BR 等带地区标签的值不会被识别。
  • 不支持的参数值不会导致任务提交失败,回调会保留原始错误文案。
  • 如果错误原文已经是目标语言,会直接返回原文,不会重复翻译。
  • 翻译失败时会回退到原始错误文案,不会影响回调投递。

轮询任务时,可通过任务状态接口的 language 查询参数指定相同的错误文案语言。Webhook 没有查询参数,因此必须在提交任务时指定 language。

POST /mj/submit/* 和 POST /v1/images/edits 不支持 webhook / language。官方 xAI 图片模型不支持 language,携带该参数会返回 400 parameter "language" is not supported;调用这些模型时请不要传入该参数。

地址规则

你填的 webhook 是基础地址(base),我们会自动在后面拼 /callback:

你填的 webhook 我们实际 POST 到
https://your-server.com https://your-server.com/callback
https://your-server.com/api https://your-server.com/api/callback
https://your-server.com/api/ https://your-server.com/api/callback

所以你的服务端需要准备一个接收 POST .../callback 的接口。

你会收到什么

推送内容和「获取任务状态」接口返回的完全一致——你用同一套解析逻辑处理即可。

成功(status:
{
  "id": "task_01KV7FXR8BEYS1BWHJCT3JMCJ5",
  "status": "completed",
  "progress": 100,
  "created": 1781589029,
  "completed": 1781589058,
  "actual_time": 29,
  "cost": 0.006,
  "credits_cost": 0.06,
  "result": {
    "images": [{ "url": ["https://.../result.png"], "expires_at": 1781675458 }]
  }
}
失败(status:
{
  "id": "task_xxx",
  "status": "failed",
  "progress": 100,
  "created": 1781589029,
  "completed": 1781589050,
  "error": {
    "message": "输入图片无法访问,请确认链接是公网可达的",
    "type": "task_failed",
    "param": "",
    "code": "task_failed"
  }
}

视频任务结果在 result.videos,音频在 result.audios。

上面的失败示例使用了 "language": "zh"。语言参数只改变 error.message,其他字段与不传时一致。

只有任务到达终态(completed / failed)才会推送;处理中不推。

重试与去重(重要)

  • 重试:如果你的服务端没在约 10 秒内返回 2xx,或返回了 5xx,我们会自动重试,最多 3 次,间隔约 10 秒、30 秒、60 秒。3 次都失败就放弃(约 2 分钟内结束)。
  • 不重试的情况:你的接口返回 4xx(视为地址 / 请求有问题),我们直接放弃,不重试。
  • 去重:正常情况下一个任务只推一次。但在极端情况下(如我们这边发送后、确认前发生重启)你可能收到重复推送。请务必按 id(task_id)做幂等去重,避免重复处理。

你的接收接口建议:

尽快返回 2xx

先收下、入队,再异步处理,别让我们等你处理完。

按 id 去重

以 id(task_id)作为幂等键,避免重复处理。

配置并校验签名

在生产环境对回调请求做来源校验,拒绝伪造请求。

对回调地址的要求

为安全起见,回调地址必须满足:

要求 说明
公网可访问 不能是内网 / 本地地址(如 127.0.0.1、10.x、192.168.x 等会被拒绝)
协议 http 或 https(推荐 https)
端口 用标准端口(80 / 443),非标端口可能被拦截
域名 不能指向我们自己的服务域名

不满足要求的地址会被直接丢弃(不会推送、也不会重试)。

常见问题

提交了带 webhook 的任务,但没收到推送?

逐项排查:

  1. 任务是否真的完成了?查一下任务详情,status 是不是 completed / failed(处理中不推)。
  2. 你的地址是不是公网可访问?我们能不能连上你的 /callback?
  3. 端口是不是标准端口(80 / 443)?非标端口可能被安全策略拦掉。
  4. 你的 /callback 是不是及时返回了 2xx?返回 4xx 会被直接放弃。
  5. 用 https 了吗?证书是否有效?
收到的 result 里 url 怎么是个数组?

部分模型一次会出多张图,images[].url 可能是数组,按数组处理即可。

结果链接有有效期吗?

result 里若带 expires_at(Unix 时间戳),表示该链接的过期时间,请及时转存。

会推送「处理中」的状态吗?

不会。只在任务最终成功或失败时推送一次。

最小接收端示例

Python
from http.server import BaseHTTPRequestHandler, HTTPServer
import json

class H(BaseHTTPRequestHandler):
    def do_POST(self):
        n = int(self.headers.get("Content-Length") or 0)
        body = self.rfile.read(n)
        data = json.loads(body)
        print("收到任务回调:", data["id"], data["status"])
        # TODO: 这里按 id 去重、校验签名、再处理
        self.send_response(200); self.end_headers()
        self.wfile.write(b'{"ok":true}')

HTTPServer(("0.0.0.0", 443), H).serve_forever()

收到后请尽快返回 200,处理逻辑放后台异步做。

This documentation is built and hosted on Mintlify, a developer documentation platform.

© 2026 26j.cn · AI 模型中转站