Webhook 回调
任务终态异步推送、签名验证、重试策略
API 配置
保存后下方「Try It」面板会自动携带此 API Key 发送真实请求。
Base: api.xrtoken.net
视频生成等异步任务可通过 callback_url 注册回调,任务进入终态(succeeded / failed)时 XRToken 会向你的 URL 推送一次 POST 请求,无需轮询。
启用回调
在 POST /v1/videos/generations 请求体中加 callback_url:
{
"model": "doubao-seedance-2-0-260128",
"content": [{ "type": "text", "text": "..." }],
"callback_url": "https://your.app/webhooks/xrtoken"
}载荷格式
{
"task_id": "5e1f2c8a-...",
"status": "succeeded",
"model": "doubao-seedance-2-0-260128",
"video_url": "https://tos.../video.mp4",
"created_at": "2026-04-15T10:00:00Z",
"finished_at": "2026-04-15T10:01:32Z"
}失败时:
{
"task_id": "5e1f2c8a-...",
"status": "failed",
"model": "doubao-seedance-2-0-260128",
"error": { "code": "task_failed", "message": "..." },
"created_at": "...",
"finished_at": "..."
}请求头
| Header | 含义 |
|---|---|
Content-Type | application/json |
X-XRToken-Timestamp | 发送时间戳(Unix 秒) |
X-XRToken-Signature | sha256=<hex>,HMAC-SHA256 签名 |
验证签名
签名计算:
HMAC_SHA256(secret, timestamp + "." + raw_body)secret 是账号专属的 Webhook Secret(Dashboard → 设置 → Webhook 查看 / 轮换;以 whsec_ 开头)。
Node.js 示例:
import crypto from 'node:crypto'
function verify(req, secret) {
const ts = req.headers['x-xrtoken-timestamp']
const sig = req.headers['x-xrtoken-signature'] // 'sha256=...'
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(ts + '.' + req.rawBody) // 注意:使用原始未解析的 body
.digest('hex')
return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))
}Python 示例:
import hmac, hashlib
def verify(headers, raw_body, secret):
ts = headers['x-xrtoken-timestamp']
sig = headers['x-xrtoken-signature'].split('=', 1)[1]
expected = hmac.new(
secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(sig, expected)校验完签名后,建议同时检查 timestamp 与当前时间相差不超过 5 分钟,防止重放。
响应与重试
- 接收方需在 10 秒内返回
2xx,否则视为失败 - 失败/超时最多重试 3 次,间隔
5s / 30s / 5min - 4 次仍失败的回调会标记为
dropped,不再投递;任务结果仍可通过GET /v1/videos/generations/{taskId}查询
幂等
同一 task_id 的回调在重试期间可能重复抵达。接收方应当用 task_id 做幂等。