# WhatsApp 消息状态事件

Bird 为入站和出站 WhatsApp 消息记录**事件**。出站时间线展示发送返回 `202` 后发生的情况：接受、移交至 WhatsApp、投递、已读或失败。入站时间线记录 Bird 收到消息的时间。

本页介绍如何通过 API 读取该时间线。如需 Bird 在每个事件发生时将其推送到您的端点，请参阅[消息状态 Webhook](/docs/guides/whatsapp/webhooks/message-status)。回应（Reaction）有独立的历史记录，详见[回应事件](/docs/guides/whatsapp/events/reactions)。

## 生命周期事件

事件按时间顺序排列。出站消息可能终止于 [`whatsapp.failed` 或 `whatsapp.rejected`](#失败事件)，其 `whatsapp.read` 事件仅在收件人打开消息时才出现。入站时间线从 `whatsapp.received` 开始，并可在您的工作区将消息标记为已读后记录 `whatsapp.read`。

| 事件                 | 含义                                         |
| -------------------- | -------------------------------------------- |
| `whatsapp.accepted`  | Bird 接受了发送请求。这是 `202` 报告的结果。 |
| `whatsapp.sent`      | Bird 已将消息移交至 WhatsApp 网络。          |
| `whatsapp.delivered` | WhatsApp 确认消息已投递至收件人的设备。      |
| `whatsapp.read`      | 收件人打开了消息。                           |
| `whatsapp.failed`    | 消息未能投递。`error.code` 说明了阻止原因。  |
| `whatsapp.rejected`  | Bird 在发送前拒绝了消息，未产生费用。        |
| `whatsapp.received`  | Bird 收到了来自联系人的入站消息。            |

适用的 `delivered` 或 `read` 回调可触发 Meta 的费用分成。WhatsApp 事件载荷不包含费用信息。使用 [`GET /v1/whatsapp/messages/{message_id}`](/docs/api/reference/get-whatsapp-message) 回读消息以查看其费用。请参阅[费用与计费](/docs/guides/whatsapp/sending-whatsapp#cost-and-billing)。

[将入站消息标记为已读](/docs/guides/whatsapp/mark-message-as-read)会在其时间线中记录 `whatsapp.read`，但不会触发已读确认 webhook。入站消息保持其 `received` 状态，并在 WhatsApp 接受确认后记录 `read_at`。

`whatsapp.read` **不会**更改消息的 `status`。已投递的消息仍保持 `delivered`；消息同时在 `read_at` 中记录已读。

**`whatsapp.delivered` 可能被完全跳过。** 当收件人的设备上已打开聊天窗口时，Meta 会报告已读而不报告投递，因此时间线显示为 `whatsapp.accepted` → `whatsapp.sent` → `whatsapp.read`，中间没有 `whatsapp.delivered`。应将 `read` 视为投递证明：等待 `delivered` 后才认为消息送达的消费者，恰好会卡在最快看到消息的收件人上；而仅根据 `delivered` 计算投递率会导致低估。在这种情况下，消息 `status` 保持 `sent`，因为只有投递回执才会推进状态。

仅已读的回调仍可触发适用的 Meta 费用。Bird 在投递和已读路径上使用同一个费用标识；缺少投递事件并不意味着 Meta 部分免费。请参阅[费用与计费](/docs/guides/whatsapp/sending-whatsapp#cost-and-billing)。

事件类型列表是开放的：新类型可能随时添加，因此请将未识别的值视为未来事件而非错误。

## 失败事件

`whatsapp.failed` 和 `whatsapp.rejected` 是终态。**拒绝**表示 Bird 在将消息发送至 WhatsApp 之前阻止了它，因此不会产生费用。原因包括[被屏蔽或已退订的收件人](/docs/guides/whatsapp/opt-outs)、钱包余额不足或目标地址未配置价格。**失败**表示消息未能投递，`error.code` 说明了决策方。大多数错误码携带的是 WhatsApp 的判定，映射自其报告的代码。`internal_error` 是例外：它记录缺少可用的发送方凭据或处理重试已耗尽。不确定的传输尝试并不能证明 Meta 从未收到请求。`meta_error_code` 在可用时包含 WhatsApp 的代码，而 `internal_error` 类型的失败在设计上不包含代码。

两种事件都包含一个 `error` 对象，该对象带有稳定的 Bird `code`、可读的 `description`、可选的 `meta_error_code` 以及 `occurred_at`。该对象仅在这些事件类型的 API 记录和 webhook 载荷中出现。

## 从 API 读取事件

`GET /v1/whatsapp/messages/{message_id}/events` 按时间顺序返回时间线。有界列表不分页。读取事件需要具有 `whatsapp:read` 的 API 密钥：

**TypeScript**

```typescript
const { data } = await bird.whatsapp.listEvents("wa_abc123");
for (const event of data) console.log(event.type, event.occurred_at);
```

Examples: [TypeScript](/zh-sg/wendang/guides/whatsapp/events/message-status.ts.md) · [Python](/zh-sg/wendang/guides/whatsapp/events/message-status.py.md) · [Go](/zh-sg/wendang/guides/whatsapp/events/message-status.go.md) · [PHP](/zh-sg/wendang/guides/whatsapp/events/message-status.php.md) · [CLI](/zh-sg/wendang/guides/whatsapp/events/message-status.cli.md) · [MCP](/zh-sg/wendang/guides/whatsapp/events/message-status.mcp.md) · [cURL](/zh-sg/wendang/guides/whatsapp/events/message-status.curl.md)

一条经历了接受、发送、投递和已读的消息会返回四个事件：

```json
{
  "data": [
    {
      "id": "ev_01ky7q6a1fejfbvs0myn41hj41",
      "occurred_at": "2026-07-23T14:48:34.71Z",
      "type": "whatsapp.accepted"
    },
    {
      "id": "ev_01ky7q6a2denvtd6jg1vqwmg13",
      "occurred_at": "2026-07-23T14:48:35.671Z",
      "type": "whatsapp.sent"
    },
    {
      "id": "ev_01ky7q6a2zff9r2qm74mmg1g6z",
      "occurred_at": "2026-07-23T14:48:36.642Z",
      "type": "whatsapp.delivered"
    },
    {
      "id": "ev_01ky7q6c21frssf0vj8h50qysw",
      "occurred_at": "2026-07-23T14:48:38.65Z",
      "type": "whatsapp.read"
    }
  ]
}
```

传入 `type` 可返回一种精确的公共事件类型，例如 `?type=whatsapp.failed` 或 `?type=whatsapp.read`。省略该参数则返回完整时间线。

该时间线与您在 [WhatsApp 日志](/docs/guides/whatsapp/message-log)页面打开消息时看到的内容相同。

![Bird 仪表板中的 WhatsApp 消息详情面板，打开了一条已投递的 bird_delivery_update 消息：Events 标签页显示每条消息的生命周期时间线，包含 Accepted、Sent、Delivered 和 Read，各附有经过时间和时间戳，消息列表在背景中变暗](/images/docs/dashboard-whatsapp-detail.png)

## 后续步骤

- [消息状态 Webhook](/docs/guides/whatsapp/webhooks/message-status)：在每个事件发生时接收它
- [回应事件](/docs/guides/whatsapp/events/reactions)：读取当前回应和回应日志
- [标记消息为已读](/docs/guides/whatsapp/mark-message-as-read)：确认入站消息并显示输入状态
- [WhatsApp 日志](/docs/guides/whatsapp/message-log)：呈现此时间线的每条消息视图
- [发送 WhatsApp 消息](/docs/guides/whatsapp/sending-whatsapp)：消息生命周期的起点

## Related resources

- [Connecting WhatsApp to Bird: from buying a number to a live channel](/learn/whatsapp/connecting-whatsapp-to-bird) (video)
- [What is the 24-hour customer service window on WhatsApp?](/explained/whatsapp/what-is-the-24-hour-customer-service-window) (answer)
- [WhatsApp message builder](/tools/whatsapp-message-builder) (tool)
- [WhatsApp](/whatsapp-api) (product)

[Get an implementation brief](/learn/workspace?topic=whatsapp)
