平台
回调 (webhooks)
无需轮询,只需在图片或视频请求中添加 callback_url。生成完成或失败时,Zurelay 会向该 URL POST 结果,并附上签名,供你验证来源。
设置回调
在以下任一请求中添加 callback_url。它必须是可通过公网访问的 https URL。
curl https://api.zurelay.com/v1/videos \ -H "Authorization: Bearer $ZURELAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "seedance-2.0", "prompt": "A fox running through fresh snow at dawn", "seconds": 5, "callback_url": "https://example.com/hooks/zurelay" }'带回调的图片请求
不带 callback_url 时,图片请求会等待生成完成后返回图片,与 OpenAI 的 API 一致。添加后,请求会立即被接受并返回任务对象。仅在生成图片后计费:
HTTP/1.1 202 Acceptedx-request-id: req_6fJd0kQ3pW9xT2mB7cZ1hR4u{ "id": "req_6fJd0kQ3pW9xT2mB7cZ1hR4u", "object": "image.generation", "model": "nano-banana-pro", "status": "in_progress", "created_at": 1791000000, "completed_at": null, "data": [], "url_expires_at": null, "cost": null, "error": null, "callback_url": "https://example.com/hooks/zurelay"}/v1/images/{id}你也可以轮询:GET /v1/images/{id} 返回同一个对象,当其 status 为 completed 时,data 中会提供新的链接。无论 response_format 如何设置,回调始终返回链接,不返回 base64.
回调内容
每个事件发送一次 POST,JSON 请求体包含 type、timestamp 和 data。其中的任务对象与 API 返回的完全一致(视频对象或上面的图片请求对象),下载链接有效期为 24 小时。
POST /hooks/zurelay HTTP/1.1content-type: application/jsonuser-agent: Zurelay-Webhooks/1.0 (+https://zurelay.com/docs/webhooks)webhook-id: msg_2c1f9e0b7a4d4f6e8b3a91c05d7e6f42webhook-timestamp: 1791000094webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4={ "type": "video.completed", "timestamp": "2026-10-03T03:21:34.000Z", "data": { "id": "video_Qm3v8Rk2Lx7Pa1Zt9Ws4Yn6B", "object": "video", "model": "seedance-2.0", "status": "completed", "progress": 100, "created_at": 1791000000, "completed_at": 1791000093, "expires_at": 1793592000, "seconds": 5, "resolution": "720p", "aspect_ratio": "16:9", "size": "1280x720", "generate_audio": true, "url": "https://…/video_Qm3v8Rk2Lx7Pa1Zt9Ws4Yn6B.mp4?token=…", "url_expires_at": 1791086494, "cost": 0.45, "error": null, "callback_url": "https://example.com/hooks/zurelay" }}{ "type": "image.completed", "timestamp": "2026-10-03T03:20:41.000Z", "data": { "id": "req_6fJd0kQ3pW9xT2mB7cZ1hR4u", "object": "image.generation", "model": "nano-banana-pro", "status": "completed", "created_at": 1791000000, "completed_at": 1791000041, "data": [{ "url": "https://…/req_6fJd0kQ3pW9xT2mB7cZ1hR4u-1.png?token=…" }], "url_expires_at": 1791086441, "cost": 0.07, "error": null, "callback_url": "https://example.com/hooks/zurelay" }}验证签名
回调遵循 Standard Webhooks 格式,与 OpenAI 的 webhook 使用相同格式。签名以工作区的签名密钥对 <webhook-id>.<webhook-timestamp>.<body> 进行 HMAC-SHA256 计算,再以 base64 编码。你可以在控制台的 API 密钥页面找到该密钥(以 whsec_ 开头),请仅将其保存在服务端。
import osfrom fastapi import FastAPI, HTTPException, Requestfrom standardwebhooks.webhooks import Webhook # pip install standardwebhookswebhook = Webhook(os.environ["ZURELAY_WEBHOOK_SECRET"]) # whsec_…app = FastAPI()@app.post("/hooks/zurelay")async def zurelay_hook(request: Request): body = await request.body() # the raw bytes: the signature covers exactly these try: event = webhook.verify(body, dict(request.headers)) except Exception: raise HTTPException(status_code=400) handle(event) # event["type"], event["data"]; keep it quick, or queue it return {"ok": True}- 请使用原始请求体验证:解析并重新序列化 JSON 会改变字节内容,导致签名不匹配。
- 拒绝
webhook-timestamp早于当前时间五分钟以上的回调,防止有人截获回调后重放。相关库会自动完成这项检查。 - 所有者和管理员可在 API 密钥页面轮换密钥,新密钥会立即生成。旧密钥仍会与新密钥同时用于签名,持续 24 小时,因此请在一天内完成服务端切换。
先响应,再处理
在 15 秒内返回任意 2xx,即视为回调已送达。请先保存事件并响应,再下载视频或图片。回调可能重复送达(例如响应在传输途中丢失),因此请使用 webhook-id 确保每个事件只处理一次。
重试
其他情况(错误状态码、重定向、15 秒内未响应或服务器无法连接)都会触发重试,总共尝试六次:
每条回调都会随对应请求显示在控制台的请求中:包括发送地址、每次尝试的响应,以及下次重试时间。点击其中的重试回调即可立即重新发送,无论之前是否已送达。每次尝试都会更新回调中的链接。
有疑问,或发现内容缺失?联系我们的支持团队,我们会通过邮件回复,通常只需一分钟。