---
title: "Webhook 端點"
description: "以各端點專屬密鑰及事件篩選器管理多個 webhook URL。"
---

以端點為基礎的 webhook 系統讓你可為每個機構登記**多個**目的地，每個目的地均有獨立的密鑰、狀態，以及對部分事件類型的個別訂閱。此為所有新整合項目的建議模式。

你可與[舊版單一 URL webhook](/api-reference/organizations#legacy-single-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}/test` | `admin+` | 傳送已簽署的測試傳遞 |
| `GET` | `/v1/developer/webhook-deliveries` | `admin+` | 檢視最近的端點及舊版傳遞結果 |

## 端點物件

```json
{
  "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",
  "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` | string 陣列 | 已訂閱的事件類型（請參閱[有效值](#valid-event-types)）。空陣列會訂閱除僅限明確選取的逐輪事件（`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`）——足以讓你與本機儲存的密鑰核對，同時不會暴露完整值 |
| `created_at`, `updated_at` | timestamp | |

<Note>
  端點完整的 `secret` 只會在建立時**一次性**傳回，
  其後不會再次提供。請安全儲存——如遺失密鑰，請刪除端點
  並重新建立。
</Note>

### 有效事件類型

`events` 會根據以下確切集合驗證——清單以外的值會
傳回 `400`。請參閱[事件目錄](/yue/webhooks/events)，了解每種類型的
payload 格式。

- `telephony.incoming`, `telephony.complete`, `telephony.tool`, `telephony.turn`
- `web.incoming`, `web.complete`, `web.tool`, `web.turn`
- `call.graded`, `call.data_extracted`
- `campaign.completed`
- `issue.reported`, `issue.escalated`
- `test-call.completed`
- `alert.triggered`

`issue.escalated` 沒有智能體內容，只會傳送至
機構範圍端點。

無法明確選取 `voice.ready` 和 `voice.failed`。如要接收
這些事件，請建立 `events: []` 的機構範圍端點。空事件
清單會接收所有支援的事件，惟 `telephony.turn` 和 `web.turn`
必須明確選取。

### 端點狀態

- `active` ——傳送會正常進行。
- `disabled` ——透過 `PATCH` 手動暫停。不會發送任何請求。我們
  絕不會變更 `disabled` 端點的狀態；是否將其切換回
  `active` 始終由你決定。
- `failing` ——當傳送至端點的請求在整個重試排程內
  （24 小時內 8 次嘗試）從未取得 2xx 時，系統會自動設定此狀態。失敗中的端點不會再接收任何流量。
  修復端點後，透過 `PATCH` 將其狀態改回 `active`；
  尚未用盡重試排程的傳送會從中斷處繼續。

---

## 列出端點

<CodeGroup>
```bash cURL
curl https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

傳回一個[端點物件](#endpoint-object)陣列。
傳入 `?agent_id=42`，只傳回所屬於該智能體的端點。

### 智能體範圍端點

機構範圍端點會接收所有相符事件。設有
`agent_id` 的端點只會接收由該智能體處理的通話之相符事件；
沒有智能體內容的事件，例如 `alert.triggered`，絕不會傳送至該端點。你
亦可在智能體建立工具的
**Webhooks** 區段建立及管理這些端點。

---

## 建立端點

<CodeGroup>
```bash cURL
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"]
  }'
```

```python Python
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"]
```
</CodeGroup>

### 請求欄位

| 欄位 | 類型 | 必填 | 說明 |
|-------|------|----------|-------------|
| `label` | 字串 | 是 | 1–120 個字元 |
| `url` | 字串 | 是 | HTTPS URL（僅 `localhost` / `127.0.0.1` 可使用 `http`） |
| `events` | 陣列 | 否 | 留空／省略即訂閱除 `telephony.turn` / `web.turn` 外的所有事件，兩者必須明確訂閱。必須使用[有效事件類型](#valid-event-types)所列的值；重複項目會被移除 |
| `agent_id` | 整數 \| null | 否 | 將傳送範圍限定至此組織內的智能體；省略或使用 `null` 則建立組織層級端點 |

回傳 `201 Created`，包括[端點物件](#endpoint-object)，以及一個額外頂層 `secret` 欄位，當中包含原始簽署金鑰——一個 48 字元的十六進位字串：

```json
{
  "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"
}
```

<Warning>
  `secret` **僅會於建立時**回傳。其後的 `GET` 回應只會包含 `secret_hint`。關閉回應前，請將完整值複製至你的密鑰管理工具。
</Warning>

---

## 更新端點

<CodeGroup>
```bash cURL
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"]
  }'
```
</CodeGroup>

| 欄位 | 類型 | 說明 |
|-------|------|-------------|
| `label` | 字串 | |
| `url` | 字串 | |
| `events` | 陣列 | |
| `status` | 字串 | `active` 或 `disabled`。將伺服器標記為 `failing` 的端點設為 `active`，即可重新啟用 |
| `agent_id` | 整數 \| null | 設定智能體 ID 以限定端點範圍，或設為 `null` 以建立組織層級端點 |

回傳 `200 OK`，包括已更新的[端點物件](#endpoint-object)。

---

## 傳送測試遞送

使用正常的遞送流程，向一個端點傳送合成的 `webhook.test` 事件，包括標準 JSON 序列化、
`X-ThunderPhone-Signature`、遞送記錄及重試追蹤。
無論所選端點的 `events` 篩選條件為何，測試均會以該端點為目標。

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

端點會收到以下信封格式：

```json
{
  "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`，以了解遞送結果：

```json
{
  "success": true,
  "event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
  "event_type": "webhook.test",
  "status": "delivered",
  "response_code": 204,
  "error": ""
}
```

`webhook.test` 為合成事件，無法加入端點的 `events`
訂閱。如首次嘗試失敗，遞送會遵循與一般事件遞送相同的重試時間表。

如要針對真實事件結構設定觸發條件，請傳入可選的
`event_type`。遞送仍然是合成的，並包含 `"sample": true`；
與通話相關的範例會使用 `call_id: 0` 及 `agent_id: 0`。

```bash
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` 可接受[有效事件類型](#valid-event-types)中的任何值。
省略此項會保留一般 `webhook.test` 行為。

---

## 刪除端點

<CodeGroup>
```bash cURL
curl -X DELETE https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

傳回 `204 No Content`。系統會立即停止向該 URL 遞送；
正在進行的重試會被捨棄。

---

## 偵錯遞送

在判定 Webhook 未有傳送前，請先檢查
[`GET /v1/developer/webhook-deliveries`](/api-reference/webhook-deliveries)。
此項會顯示兩個 Webhook 系統的最近嘗試記錄，包括通話 ID、
URL 來源、HTTP 狀態、嘗試次數、已列入許可清單的失敗類別，以及下次
重試時間。系統絕不會傳回事件內容、逐字稿、已儲存的錯誤文字、
回應內容或 URL 路徑。

你亦可在 **智能體 → 選擇智能體 → Webhooks →
最近遞送** 中查看相同的最近記錄。每列會顯示端點標籤，以及最新一次
嘗試所使用的 URL 來源。這是營運狀態，而非不可變更的稽核記錄：刪除端點
亦會刪除其遞送記錄列。

如 n8n 出現 `404`，請先確認工作流程已啟用、接受 `POST`，並使用
正式 Webhook URL 而非測試 URL。`401` 或 `403` 表示
驗證或簽名驗證出現問題；逾時表示目標位置的延遲
或可用性問題；TLS 錯誤則表示憑證鏈、主機名稱或到期日出現問題。

---

## 相關內容

<CardGroup cols={2}>
  <Card title="事件目錄" icon="list" href="/yue/webhooks/events">
    可供訂閱的完整 `events` 值清單。
  </Card>
  <Card title="Webhook 概覽" icon="bolt" href="/yue/webhooks/overview">
    簽名驗證及遞送語義。
  </Card>
</CardGroup>
