Webhooks API

訂閱事件,透過 webhook 即時接收通知。

Webhooks API 讓你能以程式設計方式訂閱事件。適合用來實作 Zapier 式的即時觸發器,或需要即時通知的自訂整合。

注意:Webhooks API 需要Hobby 方案以上,且帳單狀態為有效

端點

端點方法說明
/api/v1/webhooks/subscribePOST建立 webhook 訂閱
/api/v1/webhooks/subscribe/[id]DELETE移除訂閱
/api/v1/chatbotsGET列出可訂閱的代理程式

建立訂閱

POST /api/v1/webhooks/subscribe

請求主體

{
  "event": "form_submission",
  "targetUrl": "https://your-server.com/webhook",
  "chatbotId": "123e4567-e89b-12d3-a456-426614174000"
}

參數

欄位類型是否必填說明
eventstringlead_createdform_submissioncustom_form_submittedconversation_startedconversation_endedescalation_created
targetUrlstring接收事件的 URL——正式環境必須使用 HTTPS,正式環境以外也接受 HTTP
chatbotIdstring(UUID)要訂閱的代理程式

回應

成功(201)

{
  "id": "subscription-uuid"
}

範例

curl -X POST 'https://your-domain.com/api/v1/webhooks/subscribe' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "event": "form_submission",
    "targetUrl": "https://hooks.zapier.com/hooks/catch/123456/abcdef",
    "chatbotId": "123e4567-e89b-12d3-a456-426614174000"
  }'

刪除訂閱

DELETE /api/v1/webhooks/subscribe/[id]

回應

成功(200) 回傳狀態碼 200 的空回應。

範例

curl -X DELETE 'https://your-domain.com/api/v1/webhooks/subscribe/sub_abc123' \
  -H 'Authorization: Bearer YOUR_API_KEY'

列出代理程式

取得可訂閱的代理程式清單:

GET /api/v1/chatbots

回應

{
  "chatbots": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "Support Bot",
      "url": "https://your-domain.com/chat/support-bot"
    }
  ]
}

Webhook 酬載

事件發生時,我們會以 POST 請求傳送至你的目標 URL:

表單提交事件

{
  "event": "form_submission",
  "eventId": "evt_91d0a3ce-5a9d-4b67-a454-bafb9484281a",
  "data": {
    "id": "lead-uuid",
    "chatbotId": "123e4567-e89b-12d3-a456-426614174000",
    "name": "John Smith",
    "email": "[email protected]",
    "phone": "+1234567890",
    "conversationId": "conv_abc123",
    "createdAt": "2025-01-10T12:00:00Z"
  },
  "timestamp": "2025-01-10T12:00:00Z"
}

標頭

每次傳送都會包含以下標頭:

Content-Type: application/json
User-Agent: AgentkitWebhook/2.0
X-Agentkit-Event: form_submission
X-Agentkit-Event-Id: evt_91d0a3ce-5a9d-4b67-a454-bafb9484281a
X-Agentkit-Signature: t=<unix-seconds>,v1=<hex-hmac-sha256>

請先針對原始 UTF-8 請求主體驗證簽章,再解析 JSON。簽署流程與完整酬載目錄請參閱 Webhook 安全性

URL 規範

安全性

在正式環境中,訂閱 URL 必須使用 HTTPS。正式環境以外則也接受 HTTP——但一律只允許 http:https: 這兩種 URL,且每個 URL 都必須額外通過針對 URL 本身的公開目的地檢查,該檢查會拒絕 localhost 及類似的迴路(loopback)主機名稱、以字面形式寫出的私有與連結本地(link-local)位址,以及雲端中繼資料端點。

完整的目的地限制清單請參閱 Webhook 安全性;該文件是這項規則的權威說明。

驗證

建立訂閱時系統會檢查 URL;未通過上述檢查的 URL 會以 400 錯誤拒絕,錯誤訊息中會註明正式環境的要求。此檢查是依照 URL 的原始寫法來檢視——它不會解析主機名稱,因此請將訂閱指向你實際想要接收事件的公開端點。投遞時,系統只會解析一次主機名稱,所有解析出的位址都必須是公開位址,且連線會固定使用這些位址——解析到私有或內部位址的主機名稱(包括在解析與連線之間改變的情況)永遠不會被連線;該次嘗試會記錄為 target_blocked

可靠性

回應要求

你的端點應:

  • 在 10 秒內回傳 2xx 狀態
  • 處理重複傳送(冪等)

失敗處理

  • 傳送失敗會在初次請求後再重試五次
  • 一次耗盡的事件會讓連續失敗次數累加一次
  • 7 天內累積至少 10 次耗盡事件,訂閱會自動停用
  • 帳戶擁有者可從 Webhook 設定中修復並重新啟用訂閱
  • 傳送保證至少送達一次;請使用 eventId 做冪等處理,且不要假設送達順序

錯誤回應

狀態碼訊息原因
400Invalid JSON bodyJSON 格式錯誤
400Invalid request body欄位缺漏或無效(包含不支援的事件類型)
400Target URL must be a public HTTPS endpoint (localhost and private IPs are not allowed)URL 未通過 SSRF 驗證
401Missing or invalid Authorization header未提供標頭或格式錯誤
401Invalid API key金鑰無法辨識
403Webhook subscriptions require a Hobby plan or above with active billing方案或帳單狀態不允許使用整合功能
403Chatbot does not belong to this account該代理程式屬於其他帳戶
403Subscription does not belong to this account該訂閱屬於其他帳戶
404Chatbot not found代理程式 ID 無效
404Webhook subscription not found訂閱 ID 無效
409Webhook subscription already exists for this event and URL訂閱重複

Zapier 整合

以上端點正是我們 Zapier 整合背後的支撐。當你將 Agentkit 連接到 Zapier 時:

  1. Zapier 會呼叫 /api/v1/auth 驗證你的 API 金鑰
  2. Zapier 會呼叫 /api/v1/chatbots 列出你的代理程式
  3. 當你啟用觸發器時,Zapier 會呼叫 /api/v1/webhooks/subscribe
  4. 事件會被傳送至 Zapier 的 webhook URL
  5. 當你停用時,Zapier 會對該訂閱呼叫 DELETE

如果你想要不寫程式碼就完成整合,直接使用 Zapier 即可,不需要呼叫這些 API。

設定 Zapier →

程式碼範例

Node.js 訂閱管理器

class WebhookManager {
  constructor(apiKey, baseUrl) {
    this.apiKey = apiKey;
    this.baseUrl = baseUrl;
  }

  async subscribe(chatbotId, targetUrl, event = 'form_submission') {
    const response = await fetch(`${this.baseUrl}/api/v1/webhooks/subscribe`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.apiKey}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ event, targetUrl, chatbotId }),
    });

    if (!response.ok) {
      throw new Error(`Subscribe failed: ${response.status}`);
    }

    return response.json();
  }

  async unsubscribe(subscriptionId) {
    const response = await fetch(
      `${this.baseUrl}/api/v1/webhooks/subscribe/${subscriptionId}`,
      {
        method: 'DELETE',
        headers: { 'Authorization': `Bearer ${this.apiKey}` },
      },
    );

    return response.ok;
  }
}

後續步驟