Your AI Connector Docs

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_enabledretries_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"
  }
}

更新订阅

提供至少一个 urlsubscribed_tonamesubscribed_to_tagsretries_enabledenabledapply_to_sub_accounts。省略的字段将保留其当前值。subscribed_tosubscribed_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 标志报告结果——测试失败不会返回错误状态。当 deliveredfalse 时,响应中会包含失败详情。

字段 必需 描述
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_typepermanenttemporarytimeoutnetworkunknown 之一。


检查交付健康状况

返回订阅 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_disabledtrue 时,表示由于重复失败,向该 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-DeliveryX-Webhook-AttemptX-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_enabledfalsesigning_secretnull

生成或轮换签名密钥

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 /webhooksPUT /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。请参阅 错误 获取完整列表。


后续步骤