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

# Конечные точки вебхуков

> Управляйте несколькими URL-адресами вебхуков с секретами для каждой конечной точки и фильтрами событий.

Система вебхуков на основе конечных точек позволяет регистрировать **несколько**
получателей для каждой организации, у каждого из которых есть собственный секрет,
собственный статус и собственная подписка на подмножество типов событий. Это
рекомендуемая модель для всех новых интеграций.

Сравните с [устаревшим вебхуком с одним URL](/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         | Идентификатор конечной точки                                                                                                                                                       |
| `label`                    | string       | Отображаемое имя, 1–120 символов                                                                                                                                                   |
| `url`                      | string       | HTTPS URL; `http://localhost` разрешён для разработки                                                                                                                              |
| `events`                   | массив строк | Типы событий, на которые оформлена подписка (см. [допустимые значения](#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`. Формат полезной нагрузки каждого типа см. в [каталоге событий](/ru/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` — устанавливается автоматически, когда доставка в конечную точку
  исчерпывает всё расписание повторных попыток (8 попыток за 24 часа), так и не
  получив ответ 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).

***

## Создайте 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>

### Поля запроса

| Поле     | Тип    | Обязательно | Описание                                                                                                                                                                                   |
| -------- | ------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `label`  | string | да          | 1–120 символов                                                                                                                                                                             |
| `url`    | string | да          | HTTPS URL (`http` разрешён только для `localhost` / `127.0.0.1`)                                                                                                                           |
| `events` | array  | нет         | Пустое или отсутствующее значение подписывает на все события. Необходимо использовать значения, перечисленные в разделе [Допустимые типы событий](#valid-event-types); дубликаты удаляются |

Возвращает `201 Created` с [объектом endpoint](#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>

***

## Обновите 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>

| Поле     | Тип    | Описание                                                                                                             |
| -------- | ------ | -------------------------------------------------------------------------------------------------------------------- |
| `label`  | string |                                                                                                                      |
| `url`    | string |                                                                                                                      |
| `events` | array  |                                                                                                                      |
| `status` | string | `active` или `disabled`. Установите `active`, чтобы повторно включить endpoint, который сервер пометил как `failing` |

Возвращает `200 OK` с обновлённым [объектом endpoint](#endpoint-object).

***

## Отправьте тестовую доставку

Отправьте синтетическое событие `webhook.test` на один endpoint через обычный
конвейер доставки, включая каноническую сериализацию JSON,
`X-ThunderPhone-Signature`, запись доставки и учёт повторных попыток.
Тест нацелен на выбранный endpoint независимо от его фильтра `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>

Endpoint получает конверт следующего вида:

```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` является синтетическим и не может быть добавлен в подписку
endpoint `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="/ru/webhooks/events">
    Полный список значений `events`, на которые можно подписаться.
  </Card>

  <Card title="Обзор вебхуков" icon="bolt" href="/ru/webhooks/overview">
    Проверка подписей и семантика доставки.
  </Card>
</CardGroup>
