Skip to main content
在任务上提供 webhook.url,当任务进入终止状态(COMPLETED 或 FAILED)时,我们会把结果 POST 到该地址。

投递负载

我们以 Content-Type: application/json POST 如下正文:
object
必填
与提交时拿到的任务元数据相同,此时带有终止 status,并回传你的 idempotencyKey。
object
必填
按引擎计算的额度消耗,例如 Perplexity 为 2、ChatGPT 为 3(视引擎为 1–3 额度)。任务失败时 creditsCharged 为 0。与始终报告零的提交和轮询响应不同,这个字段是非零的。
object
必填
引擎特定的结果,参见引擎。失败任务中,这里是 { "error": "<reason>" },而不是引擎结果。
失败的任务同样会投递:

重试

返回任意 2xx 即表示确认。其他任何情况(包括超时)都算失败,我们会以指数退避重试: 第五次尝试后,投递会被放弃并记录日志。没有可供读取的死信队列。如需通过任务 API 获取结果,请在 24 小时公开 轮询窗口内轮询。该窗口并不决定底层记录的存储期限。 每次尝试的请求超时为 30 秒。
从任务的角度看,投递是发出即不管的。任务已完成但 webhook 始终无法投递时,GET /v1/async/task/{id} 仍显示 COMPLETED。状态描述的是引擎工作,而不是通知。

编写安全的处理程序

1

快速确认

一旦把负载持久化入队,立即返回 200。解析和数据库写入放在之后。处理缓慢会耗尽 30 秒超时,招来你不想要的重试。
2

按 idempotencyKey 去重

由于存在重试,处理程序多次收到同一任务是正常的。按 task.idempotencyKey(或 task.id)匹配,并让写入幂等。
3

按状态分支,而非按字段是否存在

显式检查 task.status === "FAILED"。失败的任务同样会投递 webhook。
Webhook 请求不带签名或共享密钥。如果你的端点是公开的,请将负载视为不可信,使用难以猜测的 URL 路径, 或将处理程序置于网络层访问限制之后。