Разработка и проверка webhook
Для существующего webhook-сценария используйте HTTP-туннель либо облачный webhook inbox. Inbox выдаёт постоянный публичный HTTPS-адрес и записывает входящие события в инспектор.
Описание
Общее описание функционала
Облачный webhook inbox — постоянный публичный HTTPS-адрес для приёма вебхуков от внешних провайдеров (платёжные системы, CRM, мессенджеры и т.д.) без обязательного подключения локального клиента туннеля. Каждый inbox привязан к вашему аккаунту, имеет собственный URL и режим доставки: только сохранение с подтверждением провайдеру, пересылка на локальный сервис через подключённый клиент или пересылка на внешний HTTPS-эндпоинт (при наличии соответствующей опции тарифа).
Входящие запросы фиксируются в инспекторе HTTP-трафика с меткой webhook inbox. При сбое доставки провайдер по-прежнему получает успешное подтверждение (HTTP 200), чтобы избежать лавины повторных отправок; детали ошибки видны вам в инспекторе.
Функция доступна на тарифах с возможностью webhook-inbox. Количество inbox на аккаунт ограничено лимитом тарифа. Пересылка на удалённый HTTPS-URL требует дополнительной опции webhook-inbox-remote-forward.
Как пользователь может использовать
- Разработчик нажимает Создать endpoint, получает публичный адрес без запущенного локального клиента и просматривает тестовые вебхуки в инспекторе.
- Интегратор даёт провайдеру стабильный URL inbox в режиме «только хранение», пока бэкенд ещё не готов к приёму трафика.
- Команда с подключённым клиентом туннеля пересылает вебхуки на
127.0.0.1:3000и видит реальный HTTP-код ответа локального сервиса. - Пользователь с опцией удалённой пересылки направляет вебхуки на staging-сервер по HTTPS без постоянного локального туннеля.
- QA ставит доставку на паузу, чтобы накопить события в инспекторе, не беспокоя downstream-сервис.
- Владелец аккаунта меняет режим или адрес назначения через API или дашборд — публичный URL inbox при этом не меняется.
- Оператор копирует
public_urlиз раздела Туннели → Webhook inbox и вставляет его в настройки провайдера. - Пользователь сравнивает повторные доставки через повтор запроса (Replay) после исправления обработчика на локальной стороне.
- Разработчик проверяет подпись или заголовки провайдера на сохранённых событиях в инспекторе до включения пересылки.
- Команда ограничена одним inbox на бесплатном тарифе — создаёт новый только после удаления старого туннеля или смены плана с большим лимитом.
- Владелец больше не использует endpoint и на странице
/dashboard/webhook-inboxвыбирает его, нажимает Удалить endpoint и подтверждает необратимое удаление. После подтверждения endpoint исчезает из списка, а его публичный URL перестаёт принимать webhook-запросы.
Как это реализовано в сервисе
1. Вы создаёте inbox в личном кабинете или через API POST /api/webhook-inboxes. Сервис выдаёт постоянный публичный URL и сохраняет настройки режима.
2. Провайдер отправляет HTTP-запрос (любой метод и путь) на этот URL. Запрос не требует входа на платформу.
3. Сервис распознаёт трафик как inbox, записывает событие в инспектор (тело, заголовки, метаданные) и в зависимости от режима:
- Только хранение — отвечает провайдеру HTTP 200;
- Локальная пересылка — при подключённом клиенте передаёт запрос на указанный локальный адрес и возвращает провайдеру код ответа upstream; если клиент недоступен — сохраняет событие и отвечает HTTP 200;
- HTTPS пересылка — при наличии опции тарифа отправляет запрос на настроенный HTTPS-URL и при успехе возвращает провайдеру код ответа удалённого сервиса; при ошибке доставки — HTTP 200 и запись об ошибке в инспекторе.
4. Флаг пауза доставки останавливает пересылку, но приём и запись в инспектор продолжаются; провайдер по-прежнему получает HTTP 200.
5. Изменения режима, адреса назначения и паузы применяются через PATCH /api/webhook-inboxes или кнопки в дашборде; публичный URL остаётся прежним.
6. Когда endpoint больше не нужен, его можно удалить в дашборде. После подтверждения действие нельзя отменить: endpoint удаляется из списка, а публичный URL навсегда перестаёт принимать webhook-запросы. Дашборд показывает подтверждение успешного удаления.
Подробности API — в справочнике API. Коды ошибок — в справочнике ошибок. Ограничения — в известных ограничениях.
Справочник API
Обзор
Управление облачными webhook inbox выполняется через REST API под префиксом /api/webhook-inboxes. Все методы требуют авторизованной сессии (кука) или эквивалентной аутентификации дашборда.
Приём вебхуков от внешних провайдеров идёт на публичный URL inbox (public_url из ответа API) — без авторизации, любым HTTP-методом и с любым путём после хоста.
| Метод | Путь | Назначение |
| --- | --- | --- |
| GET | /api/webhook-inboxes | Список inbox текущего пользователя |
| POST | /api/webhook-inboxes | Создать inbox |
| PATCH | /api/webhook-inboxes?id=<tunnel_id> | Изменить режим, назначение или паузу доставки |
Другие HTTP-методы на /api/webhook-inboxes возвращают 405 Method Not Allowed.
Удаление endpoint относится к общему жизненному циклу туннеля, а не к этому набору методов.
---
GET /api/webhook-inboxes
Список всех inbox, принадлежащих авторизованному пользователю.
Успешный ответ 200
Тело JSON:
| Поле | Тип | Описание |
| --- | --- | --- |
| inboxes | массив | Список объектов inbox (может быть пустым) |
Каждый элемент массива inboxes:
| Поле | Тип | Описание |
| --- | --- | --- |
| tunnel_id | строка | Идентификатор inbox (используется в PATCH ?id=) |
| public_url | строка | Публичный HTTPS-URL для провайдера |
| mode | строка | store_only, forward_local или forward_remote |
| remote_forward_url | строка | HTTPS-URL назначения (для forward_remote; иначе пусто) |
| target_addr | строка | Локальный адрес назначения (для forward_local; иначе служебное значение) |
| delivery_paused | boolean | true — пересылка отключена, приём и запись в инспектор продолжаются |
| created_at | строка (RFC3339) | Время создания |
| updated_at | строка (RFC3339) | Время последнего изменения |
---
POST /api/webhook-inboxes
Создаёт новый inbox и выдаёт публичный URL.
Требуется возможность тарифа webhook-inbox и свободная квота max_webhook_inboxes.
Тело запроса (JSON)
| Поле | Обязательность | Описание |
| --- | --- | --- |
| mode | необязательно | Режим доставки. По умолчанию store_only. Допустимые значения: store_only, forward_local, forward_remote |
| target_addr | необязательно | Для forward_local: адрес локального сервиса, например 127.0.0.1:3000 |
| remote_forward_url | обязательно для forward_remote | Полный HTTPS-URL внешнего эндпоинта, например https://api.example.com/hooks |
Для режима forward_remote требуется опция тарифа webhook-inbox-remote-forward. URL должен использовать схему HTTPS; адреса localhost, частных и служебных сетей отклоняются при создании.
Успешный ответ 201 Created
Тело — один объект inbox (те же поля, что в списке выше).
---
PATCH /api/webhook-inboxes?id=<tunnel_id>
Частичное обновление существующего inbox. Параметр id в query обязателен и равен tunnel_id.
Публичный URL (public_url) не меняется при обновлении.
Тело запроса (JSON)
Все поля необязательны; передаются только изменяемые:
| Поле | Описание |
| --- | --- |
| mode | Новый режим: store_only, forward_local, forward_remote |
| target_addr | Новый локальный адрес для forward_local |
| remote_forward_url | Новый HTTPS-URL для forward_remote |
| delivery_paused | true — приостановить пересылку; false — возобновить |
Те же правила тарифа и валидации HTTPS-URL, что при создании, применяются при смене режима или remote_forward_url.
Успешный ответ 200
Тело — обновлённый объект inbox.
---
DELETE /api/tunnels?id=<tunnel_id>
Удаляет endpoint через общий API жизненного цикла туннелей. Используйте tunnel_id из списка inbox. После успешного удаления его публичный URL навсегда перестаёт принимать webhook-запросы, а endpoint исчезает из списка.
Успешный ответ 204 No Content
Тело ответа отсутствует.
Для работы в интерфейсе откройте /dashboard/webhook-inbox, выберите endpoint, нажмите Удалить endpoint и подтвердите действие. Удаление необратимо.
DELETE /api/webhook-inboxes не поддерживается.
---
Публичный приём вебхуков (public_url)
Внешний провайдер отправляет запросы на public_url с любым путём и query, например:
POST https://<ваш-поддомен>/hooks/payment
Авторизация на платформе не требуется.
Поведение ответа провайдеру
| Режим | Успешная доставка | Сбой доставки или пауза |
| --- | --- | --- |
| store_only | HTTP 200, пустое тело | — |
| forward_local | HTTP-код ответа локального сервиса | HTTP 200; событие в инспекторе с пометкой об ошибке доставки |
| forward_remote | HTTP-код ответа удалённого HTTPS-сервиса (безопасные заголовки ответа могут быть переданы провайдеру) | HTTP 200; событие в инспекторе с пометкой об ошибке доставки |
При delivery_paused: true пересылка не выполняется; провайдер получает HTTP 200, событие сохраняется в инспекторе.
Если возможность webhook-inbox снята с тарифа владельца, публичный URL возвращает 404 Not Found.
События помечаются в инспекторе тегом webhook-inbox. Подробнее о просмотре — в документации инспектора HTTP-трафика.
---
Дашборд
На странице /dashboard/webhook-inbox (видна при наличии возможности webhook-inbox):
- Создать inbox — выбор режима и полей назначения;
- Копировать / открыть
public_url; - Пауза доставки / Возобновить доставку.
- Удалить endpoint — выбрать endpoint, подтвердить необратимое удаление и получить подтверждение об успехе.
Подписи режимов в интерфейсе: Только хранение, Локальная пересылка, HTTPS пересылка.
Ошибки
401 Unauthorized
Когда: запрос к /api/webhook-inboxes без действующей сессии или с недействительными учётными данными.
Что делать: войдите в личный кабинет или передайте корректную авторизацию, как для остальных API дашборда.
---
403 Forbidden — заблокированный аккаунт
Когда: попытка создать inbox при заблокированном аккаунте (POST /api/webhook-inboxes).
Тело ответа (JSON): code: "user_suspended", сообщение «Аккаунт заблокирован».
Что делать: обратитесь в поддержку для разблокировки аккаунта.
---
403 Forbidden — нет возможности на тарифе
Когда:
- создание или изменение inbox без возможности
webhook-inboxна тарифе; - создание или переключение в режим
forward_remoteбез опцииwebhook-inbox-remote-forward; - превышена квота
max_webhook_inboxesпри создании нового inbox.
Текст ответа: содержит forbidden и имя недоступной возможности или квоты (например feature webhook-inbox, feature webhook-inbox-remote-forward, quota max_webhook_inboxes).
Что делать: проверьте тариф и лимиты в разделе оплаты или обновите план. Удалите неиспользуемый inbox, если исчерпана квота количества.
---
400 Bad Request — некорректное тело
Когда: JSON в теле запроса не разбирается.
Текст ответа: invalid body.
Что делать: проверьте синтаксис JSON и заголовок Content-Type: application/json.
---
400 Bad Request — обязательный параметр
Когда: PATCH /api/webhook-inboxes без query-параметра id.
Текст ответа: id required.
Что делать: добавьте ?id=<tunnel_id> к URL.
---
400 Bad Request — недопустимый режим
Когда: в mode передано значение вне списка store_only, forward_local, forward_remote.
Текст ответа: invalid webhook inbox mode.
Что делать: используйте одно из допустимых значений режима.
---
400 Bad Request — недопустимый URL удалённой пересылки
Когда: для forward_remote указан URL не по HTTPS, адрес localhost, частной сети или иной запрещённый адрес.
Текст ответа: invalid remote forward URL.
Что делать: укажите публичный HTTPS-URL без частных IP и localhost. Если hostname указывает на частный адрес при фактическом соединении, доставка будет заблокирована; провайдер получит HTTP 200, а ошибка отобразится в инспекторе.
---
404 Not Found — inbox не найден
Когда:
PATCHдля чужого или несуществующегоtunnel_id;- внешний запрос на
public_urlinbox, если возможностьwebhook-inboxснята с тарифа владельца или запись inbox отсутствует.
Текст ответа (API): not found.
Что делать: проверьте tunnel_id и владельца inbox. Для публичного URL убедитесь, что inbox активен и тариф владельца включает функцию.
---
405 Method Not Allowed
Когда: на /api/webhook-inboxes вызван метод, отличный от GET, POST, PATCH (например DELETE).
Что делать: не отправляйте DELETE /api/webhook-inboxes: этот метод не поддерживается. Чтобы удалить endpoint, выберите его на /dashboard/webhook-inbox, нажмите Удалить endpoint и подтвердите действие. Для интеграции используйте общий API жизненного цикла туннелей: DELETE /api/tunnels?id=<tunnel_id>.
---
500 Internal Server Error / 503 Service Unavailable
Когда: внутренняя ошибка сервиса при создании, обновлении или чтении списка; сервис временно недоступен.
Что делать: повторите запрос позже. Если ошибка сохраняется — обратитесь в поддержку.
---
Ошибки доставки (видны в инспекторе, не в HTTP-ответе провайдеру)
Когда: пересылка на локальный клиент или удалённый HTTPS-эндпоинт не удалась (клиент отключён, сеть, таймаут, отказ upstream, отсутствие опции удалённой пересылки после смены тарифа, пауза доставки с пересылкой и т.д.).
Поведение для провайдера: HTTP 200 (подтверждение приёма), чтобы провайдер не повторял отправку бесконечно.
Поведение для вас: событие в инспекторе HTTP-трафика с тегами webhook-inbox и при необходимости delivery_error или capture_error; в заметках события — текст причины (например «локальный клиент не подключён»).
Что делать: проверьте подключение клиента, URL назначения, опцию тарифа, снимите паузу доставки; при необходимости повторите обработку через Replay.
Ограничения
- Подтверждение провайдеру при сбое доставки. В режимах с пересылкой при недоступности назначения, паузе доставки или отсутствии опции удалённой пересылки внешний провайдер всё равно получает HTTP 200. Это сделано намеренно, чтобы остановить повторные отправки со стороны провайдера. Факт сбоя смотрите в инспекторе трафика.
- Режим «только хранение». Провайдер всегда получает HTTP 200 с пустым телом; код ответа вашего приложения не формируется.
- Локальная пересылка требует клиента. Без подключённого клиента туннеля запрос сохраняется в инспекторе, пересылка не выполняется, провайдер получает HTTP 200.
- Удалённая пересылка — только HTTPS. HTTP-URL, localhost, частные и служебные адреса отклоняются при настройке; hostname, резолвящийся в частный IP при соединении, блокируется при доставке.
- Опция удалённой пересылки. Режим
forward_remoteи полеremote_forward_urlдоступны только с опцией тарифаwebhook-inbox-remote-forward. После снятия опции существующий inbox в этом режиме продолжает принимать вебхуки, но пересылка не выполняется до восстановления опции или смены режима.
- Квота количества inbox. Лимит
max_webhook_inboxesзадаётся тарифом (на бесплатном плане по умолчанию — один inbox). Превышение блокирует только создание новых; существующие продолжают работать.
- Публичный URL неизменен. Смена режима, адреса назначения или паузы не меняет выданный
public_url; провайдеру не нужно обновлять endpoint.
- Удаление необратимо. Endpoint можно удалить в
/dashboard/webhook-inbox: выберите его, нажмите Удалить endpoint и подтвердите действие. После этого endpoint исчезает из списка, а его публичный URL навсегда перестаёт принимать webhook-запросы. Для интеграций доступен общий API жизненного цикла туннелейDELETE /api/tunnels?id=<tunnel_id>; отдельныйDELETE /api/webhook-inboxesне поддерживается.
- Трафик inbox и лимиты тарифа. Входящие запросы на публичный URL inbox не расходуют те же лимиты HTTP RPM и исходящего трафика, что обычный прокси-туннель; это не отменяет общие правила тарифа для остального трафика аккаунта.
- Гостевые и закрытые туннели. Публичный URL inbox доступен внешним провайдерам без входа на платформу и не блокируется теми же правилами гостевого доступа, что приватные туннели.
- Захват в инспекторе. Размер и полнота тела запроса зависят от настроек инспектора HTTP-трафика и тарифа; при ошибке подготовки захвата провайдер всё равно получает HTTP 200, в событии может быть тег
capture_error.
- Заголовки при удалённой пересылке. На внешний HTTPS-эндпоинт не пересылаются служебные hop-by-hop заголовки; в ответ провайдеру из upstream передаётся ограниченный набор безопасных заголовков.
- Снятие возможности с тарифа. Если у владельца inbox больше нет
webhook-inbox, публичный URL отвечает404 Not Found; API создания и изменения также возвращает отказ.
- Панель дашборда. Секция Webhook inbox скрыта, если возможность
webhook-inboxнедоступна на тарифе, даже если старые записи существуют в системе.