---
title: "Конечные точки вебхуков"
description: "Управляйте несколькими 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}/rotate-secret` | `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",
  "paused_at": null,
  "pause_last_error": "",
  "pause_undelivered_count": null,
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z"
}
```

| Поле | Тип | Описание |
|-------|------|-------------|
| `id` | UUID | Идентификатор конечной точки |
| `label` | string | Отображаемое имя, 1–120 символов |
| `url` | string | URL HTTPS; для разработки разрешён `http://localhost` |
| `events` | array of 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`) — достаточно, чтобы сопоставить его с секретом, сохранённым локально, не раскрывая полное значение |
| `paused_at` | timestamp \| null | Время, когда ThunderPhone установил для конечной точки статус `failing`. `null`, пока её статус — `active` или `disabled` |
| `pause_last_error` | string | Последняя ошибка доставки при приостановке конечной точки, например `HTTP 503: Service Unavailable`. Пусто, если статус не `failing` |
| `pause_undelivered_count` | integer \| null | События, не доставленные с момента последней успешной доставки конечной точки, подсчитанные при её приостановке |
| `created_at`, `updated_at` | timestamp | |

<Note>
  Полный `secret` конечной точки возвращается **один раз** при создании и
  больше никогда. Храните его в безопасности: если вы его потеряете,
  [смените его](#rotate-the-signing-secret), чтобы получить новый.
</Note>

### Допустимые типы событий

`events` проверяется по этому точному набору — значения вне списка
возвращают `400`. Формат полезной нагрузки каждого типа см. в [каталоге событий](/ru/webhooks/events).

- `telephony.incoming`, `telephony.complete`, `telephony.tool`, `telephony.turn`
- `web.incoming`, `web.complete`, `web.tool`, `web.turn`
- `sms.sent`, `sms.failed`
- `sms.received` (зарезервировано; пока не отправляется)
- `call.graded`, `call.data_extracted`, `call.transfer_completed`
- `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` — устанавливается автоматически, когда доставка в конечную точку
  исчерпывает весь график повторных попыток (8 попыток за 24 часа), так и не
  получив 2xx. Конечная точка в состоянии сбоя больше не получает трафик.
  В этом случае мы отправляем письмо по email владельцам и администраторам
  вашей организации, а на панели управления отображается приостановленная
  конечная точка с кнопкой «Повторно активировать».
  После исправления конечной точки верните её статус в `active` через `PATCH`;
  доставки, график повторных попыток которых ещё не исчерпан, продолжатся с
  того места, на котором остановились.

---

## Список конечных точек

<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`, никогда не поступают на неё. Вы
также можете создавать эти конечные точки и управлять ими в конструкторе агентов,
в разделе **Вебхуки**.

---

## Создайте эндпоинт

<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` | string | да | 1–120 символов |
| `url` | string | да | HTTPS URL (`http` разрешён только для `localhost` / `127.0.0.1`) |
| `events` | array | нет | Пустое или отсутствующее значение подписывает на все события, кроме `telephony.turn` / `web.turn`, для которых требуется явная подписка. Необходимо использовать значения из списка [Допустимые типы событий](#valid-event-types); дубликаты удаляются |
| `agent_id` | integer \| 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` | string | |
| `url` | string | |
| `events` | array | |
| `status` | string | `active` или `disabled`. Укажите `active`, чтобы повторно включить эндпоинт, который сервер пометил как `failing` |
| `agent_id` | integer \| null | Укажите идентификатор агента, чтобы ограничить область действия эндпоинта, или `null`, чтобы сделать его доступным для всей организации |

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

---

## Смена секрета подписи

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

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../rotate-secret \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```
</CodeGroup>

| Поле | Тип | Обязательное | Описание |
|-------|------|----------|-------------|
| `include_copies` | логическое значение | нет | По умолчанию `true`. Также передаёт новый секрет другим конечным точкам вашей организации с тем же URL и тем же текущим секретом, например копиям этой конечной точки у других агентов, чтобы один получатель продолжал проверять подписи с помощью одного секрета |

Возвращает `200 OK`:

```json
{
  "endpoint": { "id": "c4d5e6f7-...", "secret_hint": "7f3a…c21d", "...": "..." },
  "secret": "7f3a90b2c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5c21d",
  "rotated_endpoint_ids": ["c4d5e6f7-..."]
}
```

| Поле | Тип | Описание |
|-------|------|-------------|
| `endpoint` | объект | [Объект конечной точки](#endpoint-object) с новым `secret_hint` |
| `secret` | строка | Новый секрет подписи. Возвращается только в этом ответе |
| `rotated_endpoint_ids` | массив UUID | Все конечные точки, которые теперь используют новый секрет |

<Warning>
  Старый секрет перестаёт использоваться немедленно: следующая доставка,
  включая повторные попытки, подписывается новым секретом. Пока у вашего получателя нет
  нового секрета, доставки не проходят проверку подписи; если он отвечает
  на них статусом, отличным от 2xx, они повторяются по обычному расписанию
  на 24 ч, поэтому оперативно обновите получателя. Если развёртывание вашего получателя
  проходит поэтапно, настройте его на приём обоих секретов во время развёртывания — вспомогательные
  функции проверки SDK принимают список секретов (см.
  [Проверка подписей вебхуков](/ru/guides/verify-webhook-signatures)).
</Warning>

---

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

Отправьте синтетическое событие `webhook.test` на один эндпоинт через стандартный
конвейер доставки, включая каноническую сериализацию JSON, оба
заголовка подписи, запись доставки и учёт повторных попыток.
Тест нацелен на выбранный эндпоинт независимо от его фильтра `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` конечной точки. Если первая попытка завершится неудачей,
ThunderPhone повторит её один раз примерно через минуту, а затем остановится;
после этого доставка будет иметь `status: "failed"` в разделе
[Отладка доставок](#debug-deliveries). Тестовая доставка никогда не переводит
конечную точку в состояние `failing`.

Чтобы настроить триггер для структуры реального события, передайте необязательный
`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 немедленно прекращается;
уже запущенные повторные попытки отменяются.

---

## Отладка доставок

Прежде чем сделать вывод, что вебхук не был отправлен, проверьте
[`GET /v1/developer/webhook-deliveries`](/api-reference/webhook-deliveries).
Он показывает недавние попытки из обеих систем вебхуков, включая идентификатор звонка,
источник URL, HTTP-статус, число попыток, категорию сбоя из разрешённого списка и время
следующей повторной попытки. Он никогда не возвращает полезную нагрузку события, расшифровку,
сохранённый текст ошибки, тело ответа или путь URL.

Ту же недавнюю историю можно посмотреть в **Агенты → выберите агента → Вебхуки →
Недавние доставки**. В строках отображаются метка конечной точки и источник URL, использованный
в последней попытке. Это операционное состояние, а не неизменяемый журнал аудита: удаление конечной точки
также удаляет её строки доставок.

При `404` от n8n сначала убедитесь, что рабочий процесс активен, принимает `POST` и использует
URL вебхука для продакшена, а не тестовый URL. Ошибки `401` или `403` указывают на
аутентификацию или проверку подписи; тайм-ауты — на задержки или доступность целевого сервера;
ошибки TLS — на цепочку сертификатов, имя хоста или срок действия.

---

## Связанные материалы

<CardGroup cols={2}>
  <Card title="Каталог событий" icon="list" href="/ru/webhooks/events">
    Полный список значений `events`, на которые можно подписаться.
  </Card>
  <Card title="Обзор вебхуков" icon="bolt" href="/ru/webhooks/overview">
    Проверка подписи и семантика доставки.
  </Card>
</CardGroup>
