> ## 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.

# Điểm cuối webhook

> Quản lý nhiều URL webhook với secret và bộ lọc sự kiện cho từng điểm cuối.

Hệ thống webhook dựa trên điểm cuối cho phép bạn đăng ký **nhiều**
đích đến cho mỗi tổ chức, mỗi đích có secret riêng, trạng thái riêng
và gói đăng ký riêng cho một tập hợp con các loại sự kiện. Đây là mô
hình được khuyến nghị cho mọi tích hợp mới.

So sánh với [webhook một URL cũ](/api-reference/organizations#legacy-single-url-webhook),
được duy trì để tương thích ngược nhưng chỉ hỗ trợ một URL cho mỗi
tổ chức.

## Điểm cuối

| Phương thức | Đường dẫn                                            | Vai trò bắt buộc | Mô tả                                      |
| ----------- | ---------------------------------------------------- | ---------------- | ------------------------------------------ |
| `GET`       | `/v1/developer/webhook-endpoints`                    | `admin+`         | Liệt kê điểm cuối                          |
| `POST`      | `/v1/developer/webhook-endpoints`                    | `admin+`         | Tạo điểm cuối                              |
| `PATCH`     | `/v1/developer/webhook-endpoints/{endpoint_id}`      | `admin+`         | Cập nhật nhãn / URL / sự kiện / trạng thái |
| `DELETE`    | `/v1/developer/webhook-endpoints/{endpoint_id}`      | `admin+`         | Xóa điểm cuối                              |
| `POST`      | `/v1/developer/webhook-endpoints/{endpoint_id}/test` | `admin+`         | Gửi bản phân phối kiểm thử đã ký           |

## Đối tượng điểm cuối

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

| Trường                     | Loại          | Mô tả                                                                                                                                                      |
| -------------------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                       | UUID          | ID điểm cuối                                                                                                                                               |
| `label`                    | string        | Tên hiển thị, 1–120 ký tự                                                                                                                                  |
| `url`                      | string        | URL HTTPS; cho phép `http://localhost` để phát triển                                                                                                       |
| `events`                   | mảng string   | Các loại sự kiện đã đăng ký (xem [giá trị hợp lệ](#valid-event-types)). Mảng rỗng đăng ký tất cả sự kiện                                                   |
| `status`                   | string        | `active`, `disabled` (tạm dừng thủ công), hoặc `failing` (tự động đặt khi một lần phân phối dùng hết lịch thử lại 24 giờ mà không có một phản hồi 2xx nào) |
| `secret_hint`              | string        | 4 ký tự đầu và 4 ký tự cuối của secret ký với dấu ba chấm (`a1b2…9f0e`) — đủ để đối chiếu với secret bạn đã lưu cục bộ mà không làm lộ toàn bộ giá trị     |
| `created_at`, `updated_at` | dấu thời gian |                                                                                                                                                            |

<Note>
  `secret` đầy đủ của điểm cuối chỉ được trả về **một lần** khi tạo và
  sẽ không bao giờ được trả về lại. Lưu trữ an toàn — nếu làm mất, hãy xóa điểm cuối
  và tạo lại.
</Note>

### Các loại sự kiện hợp lệ

`events` được xác thực theo đúng tập hợp này — các giá trị ngoài danh sách
sẽ trả về `400`. Xem [Danh mục sự kiện](/vi/webhooks/events) để biết cấu
trúc payload của từng loại.

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

### Trạng thái điểm cuối

* `active` — các bản phân phối diễn ra bình thường.
* `disabled` — tạm dừng thủ công qua `PATCH`. Không có yêu cầu nào được gửi. Chúng tôi
  không bao giờ thay đổi trạng thái của một điểm cuối `disabled`; việc chuyển lại thành
  `active` luôn do bạn quyết định.
* `failing` — được đặt tự động khi một lần phân phối đến điểm cuối dùng
  hết toàn bộ lịch thử lại (8 lần thử trong 24 giờ) mà không
  từng nhận được phản hồi 2xx. Điểm cuối gặp lỗi sẽ không nhận thêm lưu lượng nào.
  Sau khi sửa điểm cuối, hãy `PATCH` trạng thái của nó trở lại `active`;
  các bản phân phối có lịch thử lại chưa hết sẽ tiếp tục từ vị trí
  đã dừng.

***

## Liệt kê điểm cuối

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

Trả về một mảng [đối tượng Điểm cuối](#endpoint-object).

***

## Tạo endpoint

<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>

### Trường yêu cầu

| Trường   | Kiểu   | Bắt buộc | Mô tả                                                                                                                                                              |
| -------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `label`  | string | có       | 1–120 ký tự                                                                                                                                                        |
| `url`    | string | có       | URL HTTPS (`http` chỉ được phép cho `localhost` / `127.0.0.1`)                                                                                                     |
| `events` | array  | không    | Để trống hoặc bỏ qua sẽ đăng ký tất cả sự kiện. Phải dùng các giá trị liệt kê trong [Loại sự kiện hợp lệ](#valid-event-types); các giá trị trùng lặp sẽ bị loại bỏ |

Trả về `201 Created` cùng [đối tượng Endpoint](#endpoint-object) và
một trường `secret` cấp cao nhất bổ sung chứa khóa ký thô — một
chuỗi hex gồm 48 ký tự:

```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` chỉ được trả về **khi tạo**. Các phản hồi `GET` tiếp theo
  chỉ bao gồm `secret_hint`. Sao chép toàn bộ giá trị vào trình quản lý
  secret của bạn trước khi đóng phản hồi.
</Warning>

***

## Cập nhật endpoint

<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>

| Trường   | Kiểu   | Mô tả                                                                                                |
| -------- | ------ | ---------------------------------------------------------------------------------------------------- |
| `label`  | string |                                                                                                      |
| `url`    | string |                                                                                                      |
| `events` | array  |                                                                                                      |
| `status` | string | `active` hoặc `disabled`. Đặt thành `active` để bật lại endpoint mà máy chủ đã đánh dấu là `failing` |

Trả về `200 OK` cùng [đối tượng Endpoint](#endpoint-object) đã cập nhật.

***

## Gửi một lần phân phối kiểm thử

Gửi sự kiện `webhook.test` tổng hợp đến một endpoint bằng pipeline
phân phối thông thường, bao gồm tuần tự hóa JSON chuẩn,
`X-ThunderPhone-Signature`, ghi nhận lần phân phối và theo dõi thử lại.
Lần kiểm thử nhắm đến endpoint đã chọn bất kể bộ lọc `events` của endpoint đó.

<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>

Endpoint nhận được một envelope như sau:

```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 trả về `200 OK` sau lần thử đầu tiên, ngay cả khi đích đến
trả về lỗi. Kiểm tra `success`, `status`, `response_code` và `error`
để biết kết quả phân phối:

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

`webhook.test` là sự kiện tổng hợp và không thể được thêm vào gói đăng ký
`events` của endpoint. Nếu lần thử đầu tiên thất bại, lần phân phối sẽ tuân theo
cùng lịch thử lại như các lần phân phối sự kiện thông thường.

***

## Xóa endpoint

<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>

Trả về `204 No Content`. Việc gửi đến URL dừng ngay lập tức;
các lần thử lại đang diễn ra sẽ bị hủy.

***

## Liên quan

<CardGroup cols={2}>
  <Card title="Danh mục sự kiện" icon="list" href="/vi/webhooks/events">
    Danh sách đầy đủ các giá trị `events` mà bạn có thể đăng ký nhận.
  </Card>

  <Card title="Tổng quan về webhook" icon="bolt" href="/vi/webhooks/overview">
    Xác minh chữ ký và ngữ nghĩa phân phối.
  </Card>
</CardGroup>
