> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thunderphone.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook 端點

> 使用各端點專屬的密鑰與事件篩選條件管理多個 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+` | 傳送已簽署的測試傳遞           |

## 端點物件

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

| 欄位                         | 類型        | 說明                                                                                  |
| -------------------------- | --------- | ----------------------------------------------------------------------------------- |
| `id`                       | UUID      | 端點 ID                                                                               |
| `label`                    | string    | 顯示名稱，1–120 個字元                                                                      |
| `url`                      | string    | HTTPS URL；開發環境可使用 `http://localhost`                                                |
| `events`                   | string 陣列 | 訂閱的事件類型（請參閱[有效值](#valid-event-types)）。空陣列會訂閱所有事件                                    |
| `status`                   | string    | `active`、`disabled`（手動暫停）或 `failing`（當傳遞在 24 小時的重試排程中用盡所有嘗試次數，且未取得任何單一 2xx 回應時自動設定） |
| `secret_hint`              | string    | 簽署密鑰的前 4 個與後 4 個字元，並以省略號表示（`a1b2…9f0e`）——足以讓你與本機儲存的密鑰交叉比對，同時不會揭露完整值                 |
| `created_at`, `updated_at` | timestamp |                                                                                     |

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

### 有效事件類型

`events` 會依照此精確集合進行驗證——清單外的值
會傳回 `400`。請參閱[事件目錄](/zh-Hant/webhooks/events)以瞭解各類型的
酬載格式。

* `telephony.incoming`, `telephony.complete`, `telephony.tool`
* `web.incoming`, `web.complete`, `web.tool`
* `call.graded`
* `issue.reported`
* `test-call.completed`
* `alert.triggered`

### 端點狀態

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

***

## 列出端點

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

傳回一個[端點物件](#endpoint-object)陣列。

***

## 建立端點

<CodeGroup>
  ```bash cURL theme={null}
  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 theme={null}
  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`  | string | 是  | 1–120 個字元                                                   |
| `url`    | string | 是  | HTTPS URL（僅 `localhost` / `127.0.0.1` 允許使用 `http`）          |
| `events` | array  | 否  | 留空或省略即訂閱所有事件。必須使用[有效事件類型](#valid-event-types)中列出的值；重複項目會被移除 |

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

```json theme={null}
{
  "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 theme={null}
  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`  | string |                                                               |
| `url`    | string |                                                               |
| `events` | array  |                                                               |
| `status` | string | `active` 或 `disabled`。將伺服器標記為 `failing` 的端點設為 `active`，即可重新啟用 |

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

***

## 傳送測試傳遞

使用一般傳遞管線，將合成的 `webhook.test` 事件傳送至一個端點，包括正規 JSON 序列化、`X-ThunderPhone-Signature`、傳遞記錄與重試管理。無論端點的 `events` 篩選條件為何，測試都會傳送至所選端點。

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

端點會收到如下的封套：

```json theme={null}
{
  "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 theme={null}
{
  "success": true,
  "event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
  "event_type": "webhook.test",
  "status": "delivered",
  "response_code": 204,
  "error": ""
}
```

`webhook.test` 為合成事件，無法加入端點的 `events` 訂閱。如果首次嘗試失敗，傳遞會依照一般事件傳遞相同的重試排程執行。

***

## 刪除端點

<CodeGroup>
  ```bash cURL theme={null}
  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；
捨棄進行中的重試。

***

## 相關內容

<CardGroup cols={2}>
  <Card title="事件目錄" icon="list" href="/zh-Hant/webhooks/events">
    你可以訂閱的完整 `events` 值清單。
  </Card>

  <Card title="Webhook 概覽" icon="bolt" href="/zh-Hant/webhooks/overview">
    簽章驗證與傳送語意。
  </Card>
</CardGroup>
