Webhooks API
Webhooks(网络钩子)允许平台在发生特定事件(如新增联系人、收到回复、预约成功等)时立即通知您的其他系统。此 API 用于管理订阅本身:即哪些 URL 接收哪些事件。关于如何接收和验证端点收到的负载,请参阅 Webhooks。
以下所有路径均相对于 API 基础 URL:
https://api.youraiconnector.com/v1
每个请求都必须经过身份验证。请参阅 身份验证 以了解四种支持的方法。此处的示例使用 X-API-Key 标头(以及一种用于 cURL 的查询参数形式)。
注意: 您的账户必须启用 Webhooks。如果未启用,这些端点将返回 403。
如何寻址订阅
每个订阅都有一个 id 和一个可选的 name。两者均可用作路径中的 {webhookId},用于更新、删除、测试、健康检查和重新启用操作。
建议优先使用名称。 订阅 ID 是位置性的,因此在删除其他订阅后可能会发生变动。如果您在创建订阅时设置了稳定的
name,请通过名称进行寻址以避免意外情况。
列出订阅
GET /webhooks
cURL
curl "https://api.youraiconnector.com/v1/webhooks?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/webhooks",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
响应
{
"success": true,
"webhooks": [
{
"id": "0",
"name": "Order updates hook",
"url": "https://hooks.example.com/incoming",
"subscribed_to": ["Contact Created", "Replies"],
"subscribed_to_tags": [],
"created_at": "2026-06-09T12:00:00.000Z",
"signing_enabled": true,
"signing_secret_created_at": "2026-07-15T09:30:00.000Z",
"retries_enabled": true,
"enabled": true,
"apply_to_sub_accounts": false
}
]
}
signing_enabled 和 retries_enabled 是针对每个订阅的可选功能,默认均为关闭状态,除非您手动开启。请参阅 签名负载 和 重试机制。
apply_to_sub_accounts 是代理机构继承的启用选项 — 请参阅 一个订阅适用于所有客户账户。默认情况下处于关闭状态,且在没有客户账户的账户上无效。
enabled 是订阅的开关 —— 请参阅 关闭订阅。已关闭的订阅仍会在此处列出。
签名密钥本身不会包含在此处 —— 请从 GET /webhooks/{id}/signing-secret 中读取。
列出可订阅的事件类型
返回您可以在 subscribed_to 中使用的确切字符串。请使用此接口来发现有效的事件名称,而不是对其进行硬编码。
GET /webhooks/events
cURL
curl "https://api.youraiconnector.com/v1/webhooks/events" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/events", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/webhooks/events",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
响应
响应为 {"success": true, "events": [...]},其中 events 目前包含 22 个确切字符串:Contact Created、Human Alerted、Appointment Booked、Replies、Reads、Deliveries、Credits Spent、Credits Recharged、Low Credit Balance、Contact Paused、Contact Do Not Disturb、Contact Unarchived、New Message、Contact Resumed、Chat Concluded、Task Created、Task Updated、Task Completed、Daily Summary Created、Channel Connected、Broadcast Started 和 Broadcast Completed(subscribed_to 接受 Channel Connected,但目前没有任何内容会触发它,因此请勿基于此进行开发)。
有关每个事件的含义及其在有效负载中发送的 event 代码,请参阅 22 个 Webhook 事件。此端点是任何时刻的权威列表 — 请实时读取它,而不是硬编码名称。
创建订阅
POST /webhooks
| 字段 | 必填 | 说明 |
|---|---|---|
url |
是 | 将通过 POST 接收事件有效负载的 HTTPS URL。必须是可公开访问的。 |
subscribed_to |
是 | 一个非空的事件名称数组(请参阅 /webhooks/events)。 |
name |
否 | 显示名称。稍后也可用作 {webhookId}。默认为带时间戳的名称。 |
subscribed_to_tags |
否 | 用于缩小哪些标签会产生对话摘要通知的标签 ID。它不会将订阅的事件范围限定为这些标签 — 若要在应用特定标签时获取请求,请在代理(或活动)的 标签 选项卡中设置 Webhook URL。 |
retries_enabled |
否 | 布尔值,默认为 false。选择加入失败投递的 重试 功能。 |
generate_signing_secret |
否 | 布尔值,默认为 false。随订阅一起生成 HMAC 签名密钥。该密钥仅返回一次,作为响应中的顶级 signing_secret。 |
enabled |
否 | 布尔值,默认为 true。传递 false 以在创建时关闭订阅。请参阅 关闭订阅。 |
apply_to_sub_accounts |
否 | 布尔值,默认为 false。在代理机构账户上,true 会使此订阅同时接收来自每个客户账户的事件 — 请参阅 一个订阅适用于所有客户账户。 |
URL 规则: URL 必须使用
https://且必须是公开可访问的。普通的http://、localhost、私有网络地址以及平台内部地址将被拒绝,并返回400。
cURL
curl -X POST "https://api.youraiconnector.com/v1/webhooks?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/incoming",
"subscribed_to": ["Contact Created", "Replies"],
"name": "Order updates hook"
}'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://hooks.example.com/incoming",
subscribed_to: ["Contact Created", "Replies"],
name: "Order updates hook",
}),
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/webhooks",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"url": "https://hooks.example.com/incoming",
"subscribed_to": ["Contact Created", "Replies"],
"name": "Order updates hook",
},
)
data = res.json()
响应
{
"success": true,
"webhook_id": "1",
"webhook": {
"id": "1",
"name": "Order updates hook",
"url": "https://hooks.example.com/incoming",
"subscribed_to": ["Contact Created", "Replies"],
"subscribed_to_tags": [],
"created_at": "2026-06-09T12:00:00.000Z"
}
}
更新订阅
提供至少一个 url、subscribed_to、name、subscribed_to_tags、retries_enabled、enabled 或 apply_to_sub_accounts。省略的字段将保留其当前值。subscribed_to 和 subscribed_to_tags 是替换项,而非合并项。
PUT /webhooks/{webhookId}
更新订阅不会影响其签名密钥——请通过签名密钥路由进行管理。
当 URL 更改时,新 URL 的投递功能会自动重新启用,从而使之前失败的端点获得一个新的开始。
cURL
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/Order%20updates%20hook" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://hooks.example.com/v2/incoming",
"subscribed_to": ["Replies", "Chat Concluded"]
}'
JavaScript
const res = await fetch(
`https://api.youraiconnector.com/v1/webhooks/${encodeURIComponent("Order updates hook")}`,
{
method: "PUT",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://hooks.example.com/v2/incoming",
subscribed_to: ["Replies", "Chat Concluded"],
}),
}
);
const data = await res.json();
Python
import requests
res = requests.put(
"https://api.youraiconnector.com/v1/webhooks/Order updates hook",
headers={"X-API-Key": "YOUR_API_KEY"},
json={
"url": "https://hooks.example.com/v2/incoming",
"subscribed_to": ["Replies", "Chat Concluded"],
},
)
data = res.json()
响应
{
"success": true,
"webhook_id": "0",
"webhook": {
"id": "0",
"name": "Order updates hook",
"url": "https://hooks.example.com/v2/incoming",
"subscribed_to": ["Replies", "Chat Concluded"],
"subscribed_to_tags": [],
"created_at": "2026-06-09T12:00:00.000Z"
}
}
未知的 id 或名称将返回 404 以及 { "success": false, "error": "Webhook not found" }。
删除订阅
移除订阅,使其 URL 停止接收负载。其投递健康计数器会被重置,因此稍后重新添加相同的 URL 时将从零开始记录。
DELETE /webhooks/{webhookId}
cURL
curl -X DELETE "https://api.youraiconnector.com/v1/webhooks/0" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0", {
method: "DELETE",
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
Python
import requests
res = requests.delete(
"https://api.youraiconnector.com/v1/webhooks/0",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
响应
{
"success": true
}
发送测试负载
向订阅的 URL 发送示例负载,以便您可以端到端地验证您的接收端。您可以选择传入一个 event 来控制示例模拟的事件类型。测试交付绝不会影响订阅的健康计数器。
POST /webhooks/{webhookId}/test
响应总是返回 200 并通过 delivered 标志报告结果——测试失败不会返回错误状态。当 delivered 为 false 时,响应中会包含失败详情。
| 字段 | 必需 | 描述 |
|---|---|---|
event |
否 | 要模拟的事件类型(必须是 /webhooks/events 之一)。默认为交付事件。 |
cURL
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/test?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "event": "Contact Created" }'
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/test", {
method: "POST",
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ event: "Contact Created" }),
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/webhooks/0/test",
headers={"X-API-Key": "YOUR_API_KEY"},
json={"event": "Contact Created"},
)
data = res.json()
响应(已交付)
{
"success": true,
"webhook_id": "0",
"delivered": true
}
响应(已失败)
{
"success": true,
"webhook_id": "0",
"delivered": false,
"failure_type": "permanent",
"status_code": 404,
"error_message": "Request failed with status code 404"
}
failure_type 是 permanent、temporary、timeout、network 或 unknown 之一。
检查交付健康状况
返回订阅 URL 的交付健康记录:已成功和失败的交付次数、交付是否因重复失败而暂停,以及最近一次失败的详情。当尚未尝试任何交付时,返回 "health": null。
GET /webhooks/{webhookId}/health
cURL
curl "https://api.youraiconnector.com/v1/webhooks/0/health" \
-H "X-API-Key: YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/health", {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
Python
import requests
res = requests.get(
"https://api.youraiconnector.com/v1/webhooks/0/health",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
响应
{
"success": true,
"webhook_id": "0",
"url": "https://hooks.example.com/incoming",
"health": {
"consecutive_failures": 0,
"total_failures": 2,
"total_successes": 120,
"is_disabled": false,
"disabled_at": null,
"disabled_reason": null,
"last_failure": null,
"last_success_at": "2026-06-09T12:00:00.000Z",
"created_at": "2026-05-01T08:00:00.000Z",
"updated_at": "2026-06-09T12:00:00.000Z"
}
}
当 is_disabled 为 true 时,表示由于重复失败,向该 URL 的交付已被自动暂停。请修复您的接收端,然后重新启用它(见下文)。
重新启用交付
恢复因重复失败而被自动暂停 URL 的 Webhook 交付。这会重置暂停标志和失败计数器,但不会尝试进行交付——请在之后使用测试端点来确认您的接收端已恢复正常。
POST /webhooks/{webhookId}/reenable
cURL
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/reenable?apiKey=YOUR_API_KEY"
JavaScript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/reenable", {
method: "POST",
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
Python
import requests
res = requests.post(
"https://api.youraiconnector.com/v1/webhooks/0/reenable",
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
响应
{
"success": true,
"webhook_id": "0"
}
关闭订阅
enabled 是订阅自身的开关。将其关闭会停止投递,同时保持 URL、事件列表和签名密钥不变。
# Off
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'
# Back on
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": true}'
- 缺失即表示开启。 在此字段存在之前创建的订阅没有存储
enabled值,并且会正常投递。GET /webhooks总是返回一个具体的布尔值。 - 已关闭的订阅仍然会被
GET /webhooks列出 —— 这就是你找到它们并重新开启的方式。 - 在关闭开关之前排队的 重试 不会恢复:重试会在发送时重新读取订阅,如果订阅已关闭,则会丢弃该重试。
- 在关闭期间被抑制的任何内容在重新开启时都不会被重放。
这与重复失败后的自动禁用不同,后者由
GET /webhooks/{id}/health报告为is_disabled,并可通过POST /webhooks/{id}/reenable清除。enabled是账户的开关;is_disabled是我们的开关。两者互不覆盖 —— 订阅必须同时处于开启状态且未被自动禁用才能进行投递。
一个订阅适用于所有客户账户(代理机构)
在代理机构账户上,在订阅上设置 apply_to_sub_accounts: true(在创建时或通过 PUT),它也会接收发生在每个客户账户上的事件 — 一个端点覆盖整个代理机构,无需在每个客户账户上重新创建订阅。
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"apply_to_sub_accounts": true}'
其工作方式如下:
user块用于区分账户。 每个有效负载的user块都会标识事件实际发生的账户,因此您的接收器可以按客户进行路由。- 代理机构订阅自身的设置适用于所有地方。 其事件列表、签名密钥 和 重试 选项也用于继承的投递。
- 客户账户自身对同一 URL 的订阅优先。 如果客户账户有自己的订阅指向同一个 URL,则该订阅将用于该账户的事件 — 同一个事件永远不会被投递到同一个端点两次。
- 客户账户看不到它。 继承的订阅不会出现在客户账户自己的 Webhook 列表中,且客户无法将其关闭 — 只有代理机构可以管理它们。
- 投递健康状况按客户账户跟踪。 持续失败的端点会自动为投递失败的账户禁用,而不是为整个代理机构禁用。
subscribed_to_tags不会继承。 标签列表引用的是代理机构自己的标签,这些标签在客户账户上不存在 — 对话摘要缩小范围仅适用于代理机构自己的事件。- 在其他地方无效。 在没有客户账户的账户上,该标志可以正常存储但不起作用。
每次投递的标头
无论订阅是否已签名,每次投递都会发送以下三个标头:
| 标头 | 含义 |
|---|---|
X-Webhook-Delivery |
逻辑事件的稳定 ID。在重试过程中保持不变——请据此进行去重。 |
X-Webhook-Attempt |
基于 1 的尝试次数。 |
X-Webhook-Event |
事件名称。 |
签名载荷
签名是可选的,默认关闭,并按订阅进行设置。当订阅拥有签名密钥时,每次投递除了发送所有投递都会包含的三个标头(X-Webhook-Delivery、X-Webhook-Attempt 和 X-Webhook-Event)外,还会额外携带两个标头:
| 标头 | 含义 |
|---|---|
X-Webhook-Signature |
v1=<hex> — 字符串 "<timestamp>.<raw request body>" 的 HMAC-SHA256 值,使用您在 GET/POST/DELETE /v1/webhooks/{webhookId}/signing-secret 处生成和轮换的每个 Webhook 的签名密钥进行加密。 |
X-Webhook-Timestamp |
发送时间,Unix 秒数。绑定到签名中,因此无法独立更改。 |
要进行验证,请使用您的密钥对原始正文重新计算 HMAC-SHA256,并将其与标头进行比较。请针对原始请求正文进行验证。重新序列化已解析的 JSON 会更改字节并导致比较失败。拒绝时间戳超出新鲜度窗口(300 秒是一个合理的默认值)的投递以防止重放攻击,并使用时间安全函数进行比较。
请参阅 签名载荷 以获取完整的 Node 和 Python 验证示例。
签名与 API 身份验证不同。 REST API 本身使用 API 密钥进行身份验证,而不是 OAuth(OAuth 2.1 确实存在于您注册为机器人工具的 MCP 服务器中),并且目前还没有官方的 npm 或 PyPI SDK 包——请使用任何 HTTP 客户端调用这些端点。
读取签名密钥
GET /webhooks/{id}/signing-secret
curl "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
响应
{
"success": true,
"webhook_id": "0",
"signing_enabled": true,
"signing_secret": "whsec_1a2b3c...",
"signing_secret_created_at": "2026-07-15T09:30:00.000Z"
}
当签名关闭时,signing_enabled 为 false,signing_secret 为 null。
生成或轮换签名密钥
POST /webhooks/{id}/signing-secret
创建一个密钥(开启签名)或替换现有密钥。返回新密钥。
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
响应
{
"success": true,
"webhook_id": "0",
"signing_enabled": true,
"signing_secret": "whsec_9f8e7d...",
"signing_secret_created_at": "2026-07-15T10:00:00.000Z"
}
轮换立即生效 —— 下一次投递仅使用新密钥进行签名。在您将更改部署到在线端点时,请短暂地同时接受两个密钥。
您也可以在创建时通过将 "generate_signing_secret": true 传递给 POST /webhooks 来铸造密钥;响应中随后会包含一个顶层的 signing_secret 字段。
关闭签名
DELETE /webhooks/{id}/signing-secret
curl -X DELETE "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
响应
{
"success": true,
"webhook_id": "0",
"signing_enabled": false
}
所有三个签名密钥路由都需要集成 edit(编辑)权限,包括
GET—— 密钥是一种可以伪造交付的凭据,因此它不会暴露给只读角色。
重试
可选,默认关闭,通过 POST /webhooks 或 PUT /webhooks/{id} 上的 retries_enabled 布尔值按订阅进行设置。
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"retries_enabled": true}'
启用后,失败的交付会在第一次尝试后的 1分钟、5分钟、30分钟和2小时 进行重试(总计约 2小时40分钟 的覆盖时间)。
- 重试: 5xx 响应、超时和连接失败。
- 不重试: 任何 4xx 错误。接收方拒绝了请求本身,因此原样重放只会再次导致拒绝。
重试可能会导致重复交付 —— 一个处理了事件但在响应前超时的端点会再次收到该事件。请根据 X-Webhook-Delivery 进行去重,该值在多次尝试中保持不变。这就是重试需要手动开启的原因。
delivery-health 计数器统计的是整个交付过程,而不是每次尝试:只有在所有重试都耗尽后才会记录一次失败,因此启用重试不会导致自动禁用触发得更快。
错误
所有错误都使用标准信封:
{
"success": false,
"error": "Webhook not found"
}
常见情况:不允许的 URL、空的/无效的 subscribed_to 或缺少字段会返回 400;未知的 ID 或名称会返回 404;而 403 表示您的账户未启用 Webhook。请参阅 错误 获取完整列表。
后续步骤
- Webhooks(接收负载) —— 设置您的接收器并了解负载格式。
- 身份验证 —— 对请求进行身份验证的四种方式。
- 错误与速率限制 —— 状态码和 300 次请求/分钟的限制。