ThunderPhone 2.0 正式上线。全程自助,低至2美分/分钟。查看发布公告

Webhooks

Webhook 端点

使用每个端点独立的密钥和事件筛选器管理多个 Webhook URL。

基于端点的 Webhook 系统允许您为每个组织注册多个目标地址,每个地址都拥有各自的密钥、状态,以及对部分事件类型的独立订阅。对于所有新集成,建议使用此模型。

与旧版单 URL Webhook相比,该方式支持每个组织配置多个 URL;旧版 Webhook 仅为向后兼容而保留,并且每个组织仅支持一个 URL。

端点

方法路径所需角色描述
GET/v1/developer/webhook-endpointsadmin+列出端点
POST/v1/developer/webhook-endpointsadmin+创建端点
PATCH/v1/developer/webhook-endpoints/{endpoint_id}admin+更新标签 / URL / 事件 / 状态
DELETE/v1/developer/webhook-endpoints/{endpoint_id}admin+删除端点
POST/v1/developer/webhook-endpoints/{endpoint_id}/rotate-secretadmin+替换签名密钥
POST/v1/developer/webhook-endpoints/{endpoint_id}/testadmin+发送已签名的测试投递
GET/v1/developer/webhook-deliveriesadmin+检查近期端点和旧版投递结果

端点对象

{
  "id": "c4d5e6f7-...",
  "label": "Production — Call events",
  "url": "https://example.com/thunderphone/hook",
  "events": ["telephony.incoming", "telephony.complete"],
  "status": "active",
  "agent_id": 42,
  "agent_name": "Support Agent",
  "secret_hint": "a1b2…9f0e",
  "paused_at": null,
  "pause_last_error": "",
  "pause_undelivered_count": null,
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z"
}
字段类型描述
idUUID端点 ID
labelstring显示名称,1–120 个字符
urlstringHTTPS URL;开发环境允许使用 http://localhost
eventsarray of string订阅的事件类型(请参阅有效值)。空数组会订阅除仅可显式订阅的逐轮事件(telephony.turn / web.turn)之外的所有事件
statusstringactive、disabled(手动暂停)或 failing(当一次投递在 24 小时重试计划耗尽后仍未收到任何 2xx 响应时自动设置)
agent_idinteger | null此端点限定到的智能体;null 表示组织范围
agent_namestring | null限定智能体的名称;组织范围端点则为 null
secret_hintstring签名密钥的前 4 个和后 4 个字符,中间以省略号分隔(a1b2…9f0e)——足以让您与本地保存的密钥进行核对,同时不会暴露完整值
paused_attimestamp | nullThunderPhone 将端点设为 failing 的时间。当端点为 active 或 disabled 时为 null
pause_last_errorstring端点暂停时最后一次投递错误,例如 HTTP 503: Service Unavailable。除非状态为 failing,否则为空
pause_undelivered_countinteger | null自端点上次成功投递以来未投递的事件数,在端点暂停时统计
created_at, updated_attimestamp

有效事件类型

系统会根据以下精确集合验证 events——列表之外的值将返回 400。请参阅事件目录了解各类型的 负载结构。

  • telephony.incoming、telephony.complete、telephony.tool、telephony.turn
  • web.incoming、web.complete、web.tool、web.turn
  • sms.sent、sms.failed
  • sms.received(保留;尚未触发)
  • call.graded、call.data_extracted、call.transfer_completed
  • campaign.completed
  • issue.reported、issue.escalated
  • test-call.completed
  • alert.triggered

issue.escalated 没有智能体上下文,仅会投递至 组织范围端点。

无法显式选择 voice.ready 和 voice.failed。如需接收 这些事件,请创建一个包含 events: [] 的组织范围端点。空事件 列表会接收除 telephony.turn 和 web.turn 之外的所有受支持事件, 这两个事件必须显式选择。

端点状态

  • active ——投递正常进行。
  • disabled ——通过 PATCH 手动暂停。不发送任何请求。我们绝不会更改 disabled 端点的状态;是否将其恢复为 active 始终由您决定。
  • failing ——当向该端点的投递耗尽整个重试计划(24 小时内尝试 8 次)且始终未获得 2xx 响应时自动设置。处于失败状态的端点不会再接收流量。发生这种情况时,我们会向您组织的所有者和管理员发送电子邮件,控制台会显示已暂停的端点及“重新激活”按钮。端点修复后,通过 PATCH 将其状态改回 active;重试计划尚未耗尽的投递将从中断处继续。

列出端点

cURL
curl https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"

返回一个端点对象数组。 传入 ?agent_id=42 以仅返回限定为该智能体的端点。

智能体限定端点

组织范围端点会接收所有匹配事件。带有 agent_id 的端点仅接收由该智能体处理的通话的匹配事件; 没有智能体上下文的事件(例如 alert.triggered)永远不会到达该端点。您 还可以通过智能体构建器的 Webhook 部分创建和管理这些端点。


创建端点

cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label":  "Production — Call events",
    "url":    "https://example.com/thunderphone/hook",
    "events": ["telephony.incoming", "telephony.complete"]
  }'
Python
result = requests.post(
    "https://api.thunderphone.com/v1/developer/webhook-endpoints",
    headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
    json={
        "label":  "Production — Call events",
        "url":    "https://example.com/thunderphone/hook",
        "events": ["telephony.incoming", "telephony.complete"],
    },
).json()
secret = result["secret"]
endpoint_id = result["id"]

请求字段

字段类型必填说明
labelstring是1–120 个字符
urlstring是HTTPS URL(仅允许对 localhost / 127.0.0.1 使用 http)
eventsarray否留空或省略时订阅除 telephony.turn / web.turn 之外的所有事件,后两者需要显式订阅。必须使用有效事件类型中列出的值;重复项会被移除
agent_idinteger | null否将投递范围限定为此组织中的某个智能体;省略或使用 null 则创建组织级端点

返回 201 Created,其中包含端点对象,以及额外的顶级 secret 字段,其中包含原始签名密钥——一个 48 个字符的十六进制字符串:

{
  "id": "c4d5e6f7-…",
  "label": "Production — Call events",
  "url": "https://example.com/thunderphone/hook",
  "events": ["telephony.incoming", "telephony.complete"],
  "status": "active",
  "secret_hint": "a1b2…9f0e",
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z",
  "secret": "a1b2c37e08d94f5b16a2c8d90e7f3a4b5c6d7e8f90a19f0e"
}

更新端点

cURL
curl -X PATCH https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label":  "Production — Call + Grade events",
    "events": ["telephony.incoming", "telephony.complete", "call.graded"]
  }'
字段类型说明
labelstring
urlstring
eventsarray
statusstringactive 或 disabled。将服务器标记为 failing 的端点重新启用时,请设置为 active
agent_idinteger | null设置智能体 ID 以限定端点范围,或设为 null 以创建组织级端点

返回 200 OK,其中包含更新后的端点对象。


轮换签名密钥

替换端点的签名密钥,例如在密钥丢失或可能泄露时。对于智能体范围的端点,您也可以使用控制台:打开该智能体的 Webhook 部分,并在端点上选择 重新生成密钥。组织范围的端点通过 API 轮换。

cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../rotate-secret \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
字段类型必填描述
include_copies布尔值否默认为 true。还会将新密钥分配给您组织中具有相同 URL 和相同当前密钥的其他端点,例如其他智能体上此端点的副本,以便同一接收方持续使用一个密钥进行验证

返回 200 OK:

{
  "endpoint": { "id": "c4d5e6f7-...", "secret_hint": "7f3a…c21d", "...": "..." },
  "secret": "7f3a90b2c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5c21d",
  "rotated_endpoint_ids": ["c4d5e6f7-..."]
}
字段类型描述
endpoint对象带有新 secret_hint 的端点对象
secret字符串新的签名密钥。仅在此响应中返回
rotated_endpoint_idsUUID 数组现在使用新密钥的每个端点

发送测试投递

使用常规投递管道向一个端点发送合成的 webhook.test 事件,包括规范 JSON 序列化、两个签名标头、投递记录和重试记录。 无论所选端点的 events 过滤条件为何,测试都会以该端点为目标。

cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"

端点会收到如下信封:

{
  "data": {
    "message": "ThunderPhone webhook test",
    "sent_at": "2026-07-17T20:12:34.567890+00:00"
  },
  "event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
  "type": "webhook.test"
}

首次尝试后,API 会返回 200 OK,即使目标地址返回错误也是如此。 请检查 success、status、response_code 和 error 以了解投递结果:

{
  "success": true,
  "event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
  "event_type": "webhook.test",
  "status": "delivered",
  "response_code": 204,
  "error": ""
}

webhook.test 是合成事件,不能添加到端点的 events 订阅中。如果首次尝试失败,ThunderPhone 会在约一分钟后重试一次, 随后停止;该投递随后会在调试投递下显示 status: "failed"。测试投递永远不会将端点标记为 failing。

要根据真实事件结构配置触发器,请传入可选的 event_type。投递仍然是合成的,并包含 "sample": true; 与通话相关的示例使用 call_id: 0 和 agent_id: 0。

curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_type":"call.graded"}'

event_type 接受有效事件类型中的任意值。 省略该参数会保留通用的 webhook.test 行为。


删除端点

cURL
curl -X DELETE https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"

返回 204 No Content。向该 URL 的投递会立即停止; 正在进行的重试将被放弃。


调试投递

在断定 webhook 未发送之前,请检查 GET /v1/developer/webhook-deliveries。 它会显示两个 webhook 系统的近期尝试,包括通话 ID、 URL 来源、HTTP 状态、尝试次数、允许列表中的失败类别以及下次重试时间。 它绝不会返回事件负载、转写文本、存储的错误文本、 响应正文或 URL 路径。

您也可以在 智能体 → 选择一个智能体 → Webhooks → 近期投递 中查看相同的近期历史记录。每一行会显示端点标签以及最新 尝试所使用的 URL 来源。这是运行状态,而非不可变的审计日志:删除端点 也会删除其投递行。

对于 n8n 404,请先确认工作流处于活动状态、接受 POST,并且使用 生产 webhook URL 而非测试 URL。401 或 403 表示 身份验证或签名验证问题;超时表示目标地址延迟 或不可用;TLS 错误表示证书链、主机名或到期时间存在问题。


相关内容