创建任务时传 callback_url,任务每次状态变化我们都会 POST 到该地址。协议与官方一致:先握手,后推送。
握手(创建任务时)
我们向 callback_url POST 一个 {"challenge": "…"},你的服务必须在 3 秒内原样返回同一个 challenge(JSON),否则创建任务失败并返回 400。
POST body
{
"challenge": "3b7f…"
}推送(状态变化时)
握手通过后,任务进入 running、succeeded、failed、cancelled 时各推送一次;推送体与「查询任务」的响应同形({"task": {...}})。
- 推送体里不带成片链接;收到 succeeded 后请调用查询接口拿签名链接。
- 你的服务返回 2xx 即视为送达;非 2xx 或超时会重试三次(立刻 / 5 秒 / 30 秒后),之后放弃。
- callback_url 必须是公网 http(s) 地址;指向内网的地址会被拒绝。
视频超分任务的 callback_url 用同一套握手与推送,推送体是 查询超分任务 返回的 task 对象。
推送只是通知,不是数据源。任务的最终状态请以查询接口为准;我们的推送不带签名,请不要仅凭推送体执行扣款之类的关键动作。
Callback server
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/maoska/callback")
async def callback(request: Request):
body = await request.json()
if "challenge" in body:
# verification handshake: echo the challenge unchanged within 3 seconds
return {"challenge": body["challenge"]}
task = body["task"] # same shape as the Query Task response
print(task["id"], task["status"])
return {"ok": True}Push body
{
"task": {
"id": "1789383217076969",
"model": "MiniMax-H3-Max",
"status": "succeeded",
"created_at": 1789383217,
"updated_at": 1789383412,
"resolution": "720P",
"duration": 5,
"ratio": "16:9",
"task_type": "generation",
"modality": "video",
"usage": {
"total_seconds": 5,
"input_seconds": 0,
"output_seconds": 5,
"input_image_count": 0,
"input_audio_seconds": 0
}
}
}