Platform

什么是 webhook?

Webhook 是一个 HTTP 请求,当某件事发生时,由一个系统发送到你的应用。

当 Bird 调用你的端点时,接收方必须在开始处理之前保存事件。Webhook 是一个 HTTP 请求,当某件事发生时,由一个系统发送到你的应用。发送方对发往你注册 URL 的 POST 进行签名。你的接收方决定何时持久化接受该事件。

Webhook 与轮询 API 有什么不同?

轮询是指你的应用按计划调用 API 并检查变更。Webhook 反转了这个方向:提供方在事件发生时调用你的端点,因此你可以避免空闲请求并更快地做出响应。

Webhook 需要一个公开的 HTTPS 端点,能够在事件投递期间接收请求。轮询可以从任何地方发起,让你的应用自行决定何时获取状态。对于即时通知,使用 webhook。当事件仅携带标识符时,使用 API 获取更多资源详情。

Webhook 请求是什么样的?

Webhook 请求是一个带有请求头和 JSON 事件信封的 HTTP POST。Bird 的邮件投递事件包含 type、一个事件 timestamp 以及特定类型的 data

{
  "type": "email.delivered",
  "timestamp": "2026-06-10T14:30:00Z",
  "data": {
    "email_id": "em_01krdgeqcxet5s7t44vh8rt9mg",
    "recipient_id": "er_01krdgeqcxet5s7t44vh8rt9mg",
    "workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
    "recipient": "user@example.com",
    "recipient_role": "to",
    "tags": [{ "name": "category", "value": "welcome" }],
    "metadata": { "order_id": "ord_123" },
    "broadcast_id": null
  }
}

消息 ID 是 data.email_id。投递标识是 webhook-id 请求头,当 Bird 重试或重放该事件时,它保持不变。正文中的 timestamp 记录事件发生的时间。webhook-timestamp 请求头记录本次投递尝试的时间,因此这两个时间戳回答的是不同的问题。有关特定事件的载荷,请参阅邮件事件字段

如何验证 webhook 签名?

在解析或存储事件之前,保留原始请求字节并验证签名。Bird 的 SDK 会检查 webhook-idwebhook-timestampwebhook-signature 请求头,并自动为你应用时间戳容差。请使用签名指南,而不是自行编写第二个验证器。

如果你需要了解签名输入,Bird 使用 {webhook-id}.{webhook-timestamp}.{raw request body}。端点密钥以 whsec_ 开头;去掉该前缀并对剩余部分进行 base64 解码,然后计算 HMAC-SHA256。在密钥轮换期间,签名请求头可以包含多个以空格分隔的 v1, 值,因此请从活跃密钥中接受任何匹配的值。

在存储之前拒绝格式错误、未经身份验证或过期的请求。先解析 JSON 可能改变空白或键的顺序,导致字节不再与签名消息匹配。

应如何存储和确认 webhook?

在返回成功之前,持久化已验证的事件及其持久工作项。以 webhook-id 为键插入事件。为新事件插入工作项。在一个事务中提交两者,或使用等效的持久收件箱与发件箱设计。

read raw bytes and headers
verify the signature and timestamp with the Bird SDK
begin a durable transaction
  insert the inbox event keyed by webhook-id, unless it already exists
  insert a durable work item for a new event
commit the transaction
return 204
worker processes the persisted event idempotently

已持久化存储的重复事件可以接收 204,而不会创建更多工作项。当持久提交失败时返回非 2xx 状态,以便 Bird 重试投递。一旦返回成功,请从你的持久记录中重试本地工作线程,而不是期望 Bird 再次发送该事件。

这种顺序是针对 Bird 的至少一次投递语义的应用设计。它不是 Bird 为你运行的队列。去重与幂等性指南更详细地介绍了去重决策。

Webhook 重试和重放如何工作?

Bird 为常规投递提供 15 秒的响应时间。任何 2xx 状态均视为成功。非 2xx 状态、重定向或超时视为失败,并按重试计划执行。

初始尝试后的重试次数距上一次尝试的基础延迟
15 秒
25 分钟
330 分钟
42 小时
55 小时
610 小时
710 小时

整个曲线包含 8 次尝试(含初始请求)。每次延迟会加减 20% 的抖动。429 或连接超时会将基础延迟提高到 60 秒。正的 Retry-After 值会被限制在该基础延迟与两倍基础延迟之间(抖动之前),因此表中描述的是基础延迟而非确切到达时间。请参阅失败的 webhook 如何重试了解失败路径。

投递是无序的,因此不要仅凭到达顺序更新当前应用状态。当事件可能乱序到达时,请使用事件 timestamp 和你的资源状态来判断。

当投递丢失时,检查 webhook 尝试记录。修复接收方。创建一个 webhook 重放。Bird 会跳过端点已成功接收的投递。重放复用原始的 webhook-id,因此相同的去重键可以保护它。

学习 webhook 基础知识后,接下来应该做什么?

创建一个端点。验证并持久化接受其签名投递。检查投递尝试记录重放遗漏的事件。然后使用密钥轮换部署新的签名密钥,而不中断投递。

基于同一网络构建。

测试 API 密钥即刻获取。添加付款方式并验证发送者身份后,即可解锁生产环境。

你的下一个创意。
随时连接。