Webhooks 与投递
每次通话结束后,Hanc.AI 可以将通话内容——摘要、转录文本、提取的字段——发送到您自己的系统:工单系统、CRM、ERP 或任意 HTTPS 端点。本页说明这一投递过程的确切行为:您的服务器不可用时会发生什么、我们重试多少次、您的防火墙需要放行什么,以及请求是什么样子。
带重试和投递日志的通话后投递在所有套餐中均可使用,包括 Free 套餐。
发送什么,何时发送
请求会在通话结束且其分析完成后(摘要、情感、您的提取字段)发出——通常在挂断后几秒内。
| 来源 | 在哪里设置 |
|---|---|
| API 调用动作 | 代理 → 动作 → Post call → API 调用 |
| 工作流步骤 | 工作流构建器 → 设置为运行时机:通话后的 API 调用工具步骤 |
| 代理 webhook | 代理的 webhook_url 字段(API 参考) |
代理在对话进行中发出的请求(实时工具)不在本页范围内:它们在当下那一刻就需要结果,之后绝不会重发。
当您的服务器不可用时
不会丢失任何内容。请求在第一次尝试之前就已存入投递队列,并一直保留到您的服务器接收它或重试计划用完为止。
- 您的端点在 30 秒内以任意
2xx状态响应,即视为投递成功。 - 其他情况一律重试:连接被拒绝、DNS 或 TLS 错误、超时,以及任何其他状态——
5xx、429,也包括4xx。如果 API 密钥过期而您更新了它,等待中的通话会自行送达。 - 每次尝试发送的都是带有相同投递 ID 的同一个请求。
重试计划
| 尝试 | 之前的间隔 | 距通话结束的时间 |
|---|---|---|
| 1 | —(立即) | ~0 |
| 2 | 1 分钟 | ~1 分钟 |
| 3 | 5 分钟 | ~6 分钟 |
| 4 | 30 分钟 | ~36 分钟 |
| 5 | 2 小时 | ~2 小时 36 分钟 |
| 6 | 6 小时 | ~8 小时 36 分钟 |
| 7 | 24 小时 | ~1 天 8 小时 |
| 8 | 48 小时 | ~3 天 8 小时 |
即约 3.4 天内共 8 次尝试——足以覆盖周末期间的故障。
自定义计划
在 API 调用动作中(以及在通话后运行的工作流 API 调用步骤中),您可以在失败时重试下替换该计划:
- 最多 10 次重试,
- 每个间隔从 1 分钟到 7 天,
- 删除所有行则只发送一次,不重试。
您从未改动过的动作沿用上面的默认计划。
最后一次尝试之后
该投递会被标记为未送达,您会收到邮件通知(除非您已关闭该通知),请求会保留 30 天。在此期间您可以重新发送——在投递日志中点击一下,或调用一次 API。已经成功的投递同样可以重新发送,例如在您一方恢复数据之后。
与任何 webhook 无关,通话本身始终保留在您的 Hanc.AI 账户中——转录文本、摘要、录音和提取的字段可在通话中查看,也可通过 API 获取。长时间的故障只会推迟向您的系统交付,不会删除对话。
投递为至少一次。在少数情况下——例如您的服务器已处理请求,但响应未能及时到达我们——同一通话会到达两次。请使用 X-Hanc-Delivery-Id 识别并跳过重复请求。
失败通知
您不必盯着日志:当动作的请求未能送达时,它可以通过邮件通知您。请在动作(或工作流步骤)的失败通知下选择:
| 设置 | 何时发送邮件 |
|---|---|
| 最后一次尝试之后 (默认) | 一次,在重试计划用完、请求被标记为未送达时 |
| 每次尝试失败之后 | 每次尝试失败后发送,并附下次尝试的时间——最后一次失败后同样发送 |
| 不通知 | 从不;失败仅在日志中可见 |
邮件会写明动作和代理的名称、您服务器的主机名、服务器的响应(例如 HTTP 503 或 timeout after 30s)、这是总共几次尝试中的第几次,并附上投递日志的链接。最后一封邮件还会说明请求保留到何时,以及可以重新发送。
发送至用于设置收件人——通常是负责运维接收系统的人。留空时,邮件发送给账户所有者。邮件使用账户的语言撰写。
为避免故障期间邮件塞满您的收件箱,通知按动作限制为每小时 10 封、每天 30 封;暂停前的最后一封会说明暂停持续到何时。每次失败仍会记录在日志中。您手动重新发送的请求不会触发通知。
投递日志
每次尝试都会被记录:时间、HTTP 状态或网络错误、耗时,以及您服务器响应的开头部分。
在应用中:CRM → 通讯 → 打开一条 API 调用记录。您可以看到状态(已送达、重试中、未送达)、所有尝试、下次尝试的时间以及重新发送按钮。
通过 API(使用 x-api-key 请求头中的 API 密钥进行身份验证):
| 请求 | 结果 |
|---|---|
GET /v1/webhook-deliveries | 您的投递记录,最新的在前。筛选条件:status(pending、delivered、failed)、agent_id、call_id、limit、offset |
GET /v1/webhook-deliveries/{id} | 单条投递,含所有尝试和请求体 |
POST /v1/webhook-deliveries/{id}/resend | 立即重新发送并返回结果 |
{
"id": "6ac71fb82e4f72e709a4a566",
"delivery_id": "0b0f2f0e-6c0f-4f0b-9c55-3c6a3a1f8a11",
"kind": "api_call",
"name": "Create ticket",
"call_id": "6ac71f9d2e4f72e709a4a4f0",
"status": "pending",
"attempts_made": 2,
"attempts_max": 8,
"next_attempt_at": "2026-10-09T11:36:04.000Z",
"attempts": [
{ "n": 1, "at": "2026-10-09T11:30:03.512Z", "duration_ms": 212, "error": "connection refused" },
{ "n": 2, "at": "2026-10-09T11:31:04.007Z", "duration_ms": 187, "status_code": 503, "error": "HTTP 503", "response_preview": "Service Unavailable" }
]
}
已存储请求的请求头值(您的密钥)永远不会返回。
网络与防火墙
Hanc.AI 调用的是您的端点——连接始终由我们一方向您一方发起。
| 方向 | 从 Hanc.AI 出站 → 您一方入站 |
| 源 IP 地址 | 178.104.10.47(投递服务)和 128.140.65.92(通话服务,用作备用路径) |
| 协议 | HTTPS(TLS 1.2 或更高版本)。明文 HTTP 可以使用,但不建议 |
| 端口 | 443,或您的 URL 中指定的端口 |
| IP 版本 | IPv4 |
| 证书 | 必须有效,并由公共证书颁发机构签发;自签名证书会被拒绝 |
| 响应时间 | 请在 30 秒内响应——最好立即确认,然后在后台处理 |
| 重定向 | 会跟随,最多 5 次 |
加入白名单:如果您的防火墙或 WAF 按源地址过滤,请为您的 webhook 路径放行上述两个地址。这些地址如有变更,我们会提前通知。
不可行:私有网络内的地址(10.x、172.16–31.x、192.168.x、localhost)。端点必须能从互联网访问——直接访问,或通过您的反向代理 / API 网关。
浏览器:webhooks 在服务器之间运行,不涉及浏览器设置、扩展程序或员工工作站上的开放端口。
请求格式
POST、PUT 和 PATCH 携带 JSON 请求体(Content-Type: application/json,UTF-8)。
{
"call_from": "+431234567890",
"call_to": "+439876543210",
"direction": "inbound",
"call_type": "phone",
"call_status": "ended",
"start_timestamp": 1730000000000,
"end_timestamp": 1730000187000,
"duration": 187000,
"call_summary": "Customer reports a broken router and asks for a callback…",
"transcription": [
{ "speaker": "agent", "content": "Hello…", "timestamp": 1730000001000 },
{ "speaker": "user", "content": "Hi…", "timestamp": 1730000003000 }
],
"task_achieved": true,
"sentiment": { "sentiment": "neutral", "explanation": "…" },
"custom_analysis_data": {
"customer_number": "K-20417",
"ticket_category": "Hardware",
"priority": "high"
},
"collected_data": { },
"transfer_history": [ ],
"recording_url": "https://…",
"disconnection_reason": "user_hangup"
}
| 字段 | 内容 |
|---|---|
call_summary | 对话摘要 |
transcription | 完整对话,逐轮记录,带时间戳 |
call_from、call_to、direction | 主叫号码、被叫号码、呼入或呼出 |
start_timestamp、end_timestamp、duration | Unix 时间和时长,单位为毫秒 |
custom_analysis_data | 从对话中提取的您自己的字段——参见检索变量 |
collected_data | 代理在通话中收集的数据 |
sentiment、task_achieved | 对话的情感,以及是否达成目标 |
recording_url | 录音链接(如已开启录音) |
transfer_history | 通话中发生的转接 |
对于 GET 和 DELETE,相同的字段通过查询字符串传递;transcription 等嵌套值会被省略。
请求头
| 请求头 | 含义 |
|---|---|
X-Hanc-Delivery-Id | 标识一次投递。每次尝试都相同——可用它跳过重复请求 |
X-Hanc-Attempt | 尝试序号,从 1 开始 |
X-Correlation-Id | 内部追踪 ID;联系支持团队时请提供 |
User-Agent | HANC-Webhooks/1.0 |
| 您的请求头 | 您在动作中配置的所有内容 |
身份验证
由您决定您的端点如何识别我们:
- API 密钥或令牌——在动作中添加请求头,例如
Authorization: Bearer <token>或X-API-Key: <key>。请求头会随每次尝试一并发送。 - Basic 认证——
Authorization: Basic <base64(user:password)>。 - 查询参数——适用于要求将密钥放在 URL 中的系统。
- 源地址——仅放行上面列出的 IP 地址。
这些方式可以组合使用;常见做法是密钥加 IP 白名单。
按您的系统定制请求
默认情况下,请求携带整个通话(参见请求格式)。对于要求自有结构的系统——大多数工单系统都是如此——您可以自行描述该结构,并用通话数据填充。
变量
在通话后的 API 调用动作和工作流的 API 调用步骤中,URL、请求头、查询参数和请求体都可以使用双花括号变量。它们会在请求发出前用通话数据填入。
| 变量 | 值 |
|---|---|
{{call_id}} | 通话 ID |
{{call_from}}、{{call_to}} | 主叫号码和被叫号码 |
{{customer_phone}}、{{customer_email}} | 对方的号码和邮箱,与通话方向无关 |
{{call_direction}}、{{call_type}} | inbound / outbound,phone / web |
{{call_start}}、{{call_end}} | 开始和结束时间,ISO 8601(UTC) |
{{call_duration}} | 时长,单位为秒 |
{{call_summary}} | 对话摘要 |
{{call_transcription}} | 文本形式的完整对话 |
{{call_sentiment}}、{{call_task_achieved}} | 情感,以及是否达成目标 |
{{call_recording_url}} | 录音链接 |
{{agent_id}} | 代理 ID |
| 您的字段 | 每个检索变量均可按其名称使用,例如 {{customer_number}}、{{priority}}——以及工作流在通话中收集的每个变量 |
值得了解的规则:
- 仅由一个变量构成的请求体字段会保留该变量的类型:
"priority": "{{priority}}"会作为数字3发送,"urgent": "{{urgent}}"会作为true发送。变量周围有文本时,它就变成文本。 - 放在 URL 中的值会自动进行百分号编码(
+43…变为%2B43…)。 - 通话中没有值的变量会以空值发送——绝不会原样发送
{{name}}。
在应用中,字段里的 {x} 按钮会列出可用变量;在请求体中输入 {{ 时会给出建议。
请求体
在动作的 请求体 (JSON) 中,您可以写入您的系统所要求的 JSON 对象,嵌套层级不限:
{
"ticket": {
"subject": "Call from {{customer_phone}}: {{ticket_category}}",
"comment": { "body": "{{call_summary}}" },
"priority": "{{priority}}",
"custom_fields": [
{ "id": 360001, "value": "{{customer_number}}" },
{ "id": 360002, "value": "{{call_recording_url}}" }
],
"tags": ["phone-agent"]
}
}
仅您的字段
开启仅发送我的字段后,请求只携带您的请求体和查询参数——不会附加通话数据。保持关闭时,您的字段会与完整通话数据一并发送。
选择性发送
用自然语言写的条件(“仅当来电者报告故障时”)决定哪些通话会触发请求。多个动作可以指向不同的系统或端点。
接入工单系统
任何提供 HTTP API 或入站 webhook 的工单系统都可以接收通话——直接接收,无需中间软件。您一方需要准备:
- 一个端点,可从互联网通过 HTTPS 访问,并接受 JSON。
- 该端点的凭据(API 密钥、令牌或 Basic 认证),在动作中作为请求头填入。
- 如果您按地址过滤——将上述两个 IP 地址加入白名单。
然后,在动作中:
- 定义您的字段。添加检索变量,例如客户编号、工单类别、优先级、要求回电。代理会根据对话填写它们。
- 按照您的工单 API 的结构编写请求体,并将变量放到相应位置。
- 开启仅发送我的字段。
- 点击测试 API 配置,然后拨打一次测试通话。
我们很乐意与您一起为您的系统准备请求体。
测试
连接测试。动作中的测试 API 配置按钮会立即发送一个示例请求,并显示是否已到达您的端点。
重试测试——亲眼看看该机制如何工作:
- 在动作的失败时重试下设置一个较短的计划,例如三个 1 分钟的间隔。
- 停止您的端点,或在防火墙中屏蔽我们的地址。
- 向代理拨打一次测试通话。
- 打开 CRM → 通讯:该记录显示重试中、失败的尝试及其错误,以及下次尝试的时间。
- 重新启动端点(或解除屏蔽)。下一次尝试会送达该通话,记录变为已送达——您也可以点击重新发送立即投递。
端点检查清单
- 请求一经保存即以
2xx响应;耗时的处理放到之后进行。 - 将
X-Hanc-Delivery-Id视为幂等键。 - 无法接收请求时,请以
4xx/5xx响应——我们会再次发送。 - 保持证书有效,并保持两个源地址处于放行状态。