语音事件
Bird 在通话开始、被接听和结束时发出 webhook 事件。使用这些事件来更新你的系统,无需轮询。订阅、签名、重试和重放的详情请参阅 Webhooks。
一次通话经历的事件类型路径:
voice_call.initiated:Bird 接受了通话建立请求(一个 SIPINVITE)并开始路由通话voice_call.answered:你呼叫的号码已接听。只有被接听的通话才会产生此事件voice_call.ended:通话已结束,事件携带结果
voice_call.initiated 确认通话存在,而 voice_call.ended 报告其结果。对于被拒绝或失败的通话,请结合通话记录使用报告的状态和最终的 SIP 响应。不要仅凭某个事件的存在来推断完整的生命周期。
事件 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 | 呼入通话为 inbound;拨出通话为 outbound |
from | 主叫号码 |
to | 被叫号码 |
事件字段名与分支 API 不同:事件 call_id 标识分支,对应分支响应的 id;事件 session_id 对应分支响应的 call_id。在将 webhook 更新与 API 记录关联时请使用此映射。
这些生命周期事件使用共享的 webhook 投递和签名协议。序列的同步 webhook 步骤使用独立的、未签名的接收器协议;配置事件订阅不会对来自该步骤的请求进行身份验证。
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去重。 信令或投递重试可能导致更新重复。同一通话阶段的重复发布保留其投递标识,因此以该标识为键即可合并重复项。 - 不要依赖顺序。 投递不保证有序,因此
answered可能在ended之后到达。按timestamp排序,让后到达但时间戳更早的事件被丢弃。 - 使用
ended获取报告的结果。 它包含状态和时长。事件发布可能在投递排队之前失败,因此缺少某个事件并不意味着通话仍在进行中。 - 与通话记录核对。 事件提供及时更新,而通话日志保存通话记录。导出 CSV 进行核对。
后续步骤
| 页面 | 涵盖内容 |
|---|---|
| Webhooks 与事件 | 端点设置、签名验证、重试和重放 |
| 通话日志 | 通话记录的所有字段及 CSV 导出 |