Open in
Webhook 端点
使用每个端点独立的密钥和事件筛选器管理多个 Webhook URL。
基于端点的 Webhook 系统允许您为每个组织注册多个目标地址,每个地址都拥有各自的密钥、状态,以及对部分事件类型的独立订阅。对于所有新集成,建议使用此模型。
与旧版单 URL Webhook相比,该方式支持每个组织配置多个 URL;旧版 Webhook 仅为向后兼容而保留,并且每个组织仅支持一个 URL。
端点
| 方法 | 路径 | 所需角色 | 描述 |
|---|---|---|---|
GET | /v1/developer/webhook-endpoints | admin+ | 列出端点 |
POST | /v1/developer/webhook-endpoints | admin+ | 创建端点 |
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-secret | admin+ | 替换签名密钥 |
POST | /v1/developer/webhook-endpoints/{endpoint_id}/test | admin+ | 发送已签名的测试投递 |
GET | /v1/developer/webhook-deliveries | admin+ | 检查近期端点和旧版投递结果 |
端点对象
{
"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"
}| 字段 | 类型 | 描述 |
|---|---|---|
id | UUID | 端点 ID |
label | string | 显示名称,1–120 个字符 |
url | string | HTTPS URL;开发环境允许使用 http://localhost |
events | array of string | 订阅的事件类型(请参阅有效值)。空数组会订阅除仅可显式订阅的逐轮事件(telephony.turn / web.turn)之外的所有事件 |
status | string | active、disabled(手动暂停)或 failing(当一次投递在 24 小时重试计划耗尽后仍未收到任何 2xx 响应时自动设置) |
agent_id | integer | null | 此端点限定到的智能体;null 表示组织范围 |
agent_name | string | null | 限定智能体的名称;组织范围端点则为 null |
secret_hint | string | 签名密钥的前 4 个和后 4 个字符,中间以省略号分隔(a1b2…9f0e)——足以让您与本地保存的密钥进行核对,同时不会暴露完整值 |
paused_at | timestamp | null | ThunderPhone 将端点设为 failing 的时间。当端点为 active 或 disabled 时为 null |
pause_last_error | string | 端点暂停时最后一次投递错误,例如 HTTP 503: Service Unavailable。除非状态为 failing,否则为空 |
pause_undelivered_count | integer | null | 自端点上次成功投递以来未投递的事件数,在端点暂停时统计 |
created_at, updated_at | timestamp |
有效事件类型
系统会根据以下精确集合验证 events——列表之外的值将返回
400。请参阅事件目录了解各类型的
负载结构。
telephony.incoming、telephony.complete、telephony.tool、telephony.turnweb.incoming、web.complete、web.tool、web.turnsms.sent、sms.failedsms.received(保留;尚未触发)call.graded、call.data_extracted、call.transfer_completedcampaign.completedissue.reported、issue.escalatedtest-call.completedalert.triggered
issue.escalated 没有智能体上下文,仅会投递至
组织范围端点。
无法显式选择 voice.ready 和 voice.failed。如需接收
这些事件,请创建一个包含 events: [] 的组织范围端点。空事件
列表会接收除 telephony.turn 和 web.turn 之外的所有受支持事件,
这两个事件必须显式选择。
端点状态
active——投递正常进行。disabled——通过PATCH手动暂停。不发送任何请求。我们绝不会更改disabled端点的状态;是否将其恢复为active始终由您决定。failing——当向该端点的投递耗尽整个重试计划(24 小时内尝试 8 次)且始终未获得 2xx 响应时自动设置。处于失败状态的端点不会再接收流量。发生这种情况时,我们会向您组织的所有者和管理员发送电子邮件,控制台会显示已暂停的端点及“重新激活”按钮。端点修复后,通过PATCH将其状态改回active;重试计划尚未耗尽的投递将从中断处继续。
列出端点
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 -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"]
}'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"]请求字段
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
label | string | 是 | 1–120 个字符 |
url | string | 是 | HTTPS URL(仅允许对 localhost / 127.0.0.1 使用 http) |
events | array | 否 | 留空或省略时订阅除 telephony.turn / web.turn 之外的所有事件,后两者需要显式订阅。必须使用有效事件类型中列出的值;重复项会被移除 |
agent_id | integer | 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 -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"]
}'| 字段 | 类型 | 说明 |
|---|---|---|
label | string | |
url | string | |
events | array | |
status | string | active 或 disabled。将服务器标记为 failing 的端点重新启用时,请设置为 active |
agent_id | integer | null | 设置智能体 ID 以限定端点范围,或设为 null 以创建组织级端点 |
返回 200 OK,其中包含更新后的端点对象。
轮换签名密钥
替换端点的签名密钥,例如在密钥丢失或可能泄露时。对于智能体范围的端点,您也可以使用控制台:打开该智能体的 Webhook 部分,并在端点上选择 重新生成密钥。组织范围的端点通过 API 轮换。
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_ids | UUID 数组 | 现在使用新密钥的每个端点 |
发送测试投递
使用常规投递管道向一个端点发送合成的 webhook.test 事件,包括规范 JSON 序列化、两个签名标头、投递记录和重试记录。
无论所选端点的 events 过滤条件为何,测试都会以该端点为目标。
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 -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 错误表示证书链、主机名或到期时间存在问题。