语音事件
Bird 在通话开始、被接听和结束时发出 webhook 事件。使用这些事件来更新你的系统,无需轮询。订阅、签名、重试和重放的详情请参阅 Webhooks。
一次通话经历的事件类型路径:
- voice_call.initiated:Bird 接受了通话建立请求(一个 SIP INVITE)并开始路由通话
- voice_call.answered:你呼叫的号码已接听。只有被接听的通话才会产生此事件
- voice_call.ended:通话已结束,事件携带结果
voice_call.initiated 确认通话已存在,而 voice_call.ended 报告其结果。在接受 INVITE 之后被拒绝的通话 Bird 仍会发出带有 status: "failed" 和 sip_response_code: 503 的 voice_call.ended。
事件 type 是一个开放枚举:Bird 可能会随时间添加新类型,因此请匹配你需要处理的类型并忽略其余类型,而不是将不认识的类型视为错误。
事件信封
语音事件与其他所有 Bird 事件使用相同的嵌套信封,详见 Webhooks 指南:type、timestamp,以及一个特定类型的 data 对象。事件的标识位于 webhook-id HTTP 请求头中,而非正文中。
| 字段 | 说明 |
|---|---|
| type | 本页三种类型之一,例如 voice_call.ended |
| timestamp | 事件发生的时间(RFC 3339)。按此字段排序,不要按到达顺序排序 |
| data | 特定于事件的载荷,始终携带相同的通话标识字段 |
每个语音事件的 data 包含相同的标识字段,用于关联。两个号码均使用 E.164 格式:前导 +、国家代码和国内号码。
| 字段 | 说明 |
|---|---|
| call_id | 通话记录的 id(vcl_…),与通话日志中显示的相同 |
| session_id | 由转接或多方通话的每个分支共享(vcs_…)。无会话关联时为 null |
| workspace_id | 通话所属的工作区 |
| direction | 你的设备发起的通话为 outbound |
| from | 主叫号码 |
| to | 被叫号码 |
voice_call.initiated
Bird 收到 INVITE 并开始路由。
代码示例
{
"type": "voice_call.initiated",
"timestamp": "2026-06-10T14:30:00Z",
"data": {
"call_id": "vcl_01krdgeqcxet5s7t44vh8rt9mg",
"session_id": "vcs_01krdgeqcxet5s7t44vh8rt9mh",
"workspace_id": "wsp_01krdgeqcxet5s7t44vh8rt9mj",
"direction": "outbound",
"from": "+14155551234",
"to": "+16505559876"
}
}voice_call.answered
对方已接听,计费时间开始。未接听的通话不会产生此事件。
载荷是每个语音事件都携带的通话标识字段,其中 timestamp 设置为接听时刻。
voice_call.ended
通话已结束。此事件附加了结果:
| 字段 | 说明 |
|---|---|
| status | 结束方式:answered、no_answer、failed、rejected 或 unknown(见状态) |
| sip_response_code | 通话的最终 SIP 代码,例如 200 或 486。被 Bird 拒绝的通话携带 503;未记录最终代码时为 null |
| duration_ms | 通话总时长(毫秒),从 Bird 收到通话到挂断 |
| billable_ms | 接听时长(毫秒),未被接听的通话报告为零 |
代码示例
{
"type": "voice_call.ended",
"timestamp": "2026-06-10T14:31:05Z",
"data": {
"call_id": "vcl_01krdgeqcxet5s7t44vh8rt9mg",
"session_id": "vcs_01krdgeqcxet5s7t44vh8rt9mh",
"workspace_id": "wsp_01krdgeqcxet5s7t44vh8rt9mj",
"direction": "outbound",
"from": "+14155551234",
"to": "+16505559876",
"status": "answered",
"sip_response_code": 200,
"duration_ms": 65000,
"billable_ms": 60000
}
}通话记录包含此事件未提供的两项详情:拒绝原因和费用。在通话日志中打开该通话,以区分 Bird 拒绝与运营商故障。费用在计费完成后显示。
安全消费事件
- 基于 webhook-id 去重。 Bird 至少投递一次,当信令重试重放时,通话的 initiated 事件可能被发布多次。相同通话、相同阶段、相同 webhook-id,因此以此为键即可合并重复项。
- 不要依赖顺序。 投递不保证有序,因此 answered 可能在 ended 之后到达。按 timestamp 排序,让后到达但时间戳更早的事件被丢弃。
- 将 ended 视为唯一可靠的结果。 它是携带状态和时长的事件,也是你自己的记录应以此为键的事件。
- 与通话记录核对。 事件提供及时更新,而通话日志保存通话记录。导出 CSV 进行核对。
后续步骤
| 页面 | 涵盖内容 |
|---|---|
| Webhooks 与事件 | 端点设置、签名验证、重试和重放 |
| 通话日志 | 通话记录的所有字段及 CSV 导出 |