Перейти к содержимому
LegalStack
Основы API

Вебхуки

Подписка на события платформы и проверка подписи доставки.

LegalStack доставляет события платформы на ваши HTTPS-эндпоинты. Подписками управляют через раздел API «Безопасность и доступ» — вебхуки, нужен scope webhooks:write.

Регистрация эндпоинта

Запрос
POST /api/v1/webhooks HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{ "url": "https://example.com/hooks/legalstack", "events": ["task.created", "signature.signed"] }

В ответе придёт секрет эндпоинта с префиксом whsec_ — он нужен для проверки подписи. Все операции с подписками — в справочнике API.

Секрет показывается один раз

Сохраните секрет сразу после создания эндпоинта. Платформа хранит его зашифрованным и повторно не покажет, можно только сгенерировать новый.

Доставка

Каждое событие приходит POST-запросом с JSON-телом { id, type, teamId, timestamp, data } и четырьмя заголовками:

ЗаголовокЗначение
x-legalstack-signatureподпись v1=<hex>
x-legalstack-timestampunix-время отправки в секундах
x-legalstack-event-idидентификатор события
x-legalstack-event-typeтип события

Пример реальной доставки (подпись вычислена боевым кодом платформы):

POST /ваш-endpoint HTTP/1.1
content-type: application/json
x-legalstack-signature: v1=29e7075a454efa9d2fdb5b5d15e1e4e93bfd2b635717bda86931b63566f71c16
x-legalstack-timestamp: 1752307200
x-legalstack-event-id: evt_01hzxamp1e
x-legalstack-event-type: task.created

{"id":"evt_01hzxamp1e","type":"task.created","teamId":"team_01hzxamp1e","timestamp":"2026-07-12T08:00:00.000Z","data":{"taskId":"task_01hzxamp1e","teamId":"team_01hzxamp1e","data":{"title":"Проверить договор"}}}

Проверка подписи

Подпись — HMAC-SHA256 в hex от строки timestamp + "." + payload, ключ — секрет эндпоинта как обычная UTF-8-строка (без декодирования):

secret    = "whsec_2b7e151628aed2a6abf7158809cf4f3c2b7e151628aed2a6abf7158809cf4f3c"
timestamp = "1752307200"  // значение заголовка x-legalstack-timestamp
payload   = тело запроса (сырые байты)

signature = "v1=" + hex(hmac_sha256(secret, timestamp + "." + payload))
          = "v1=29e7075a454efa9d2fdb5b5d15e1e4e93bfd2b635717bda86931b63566f71c16"

Сравнивайте подписи константным по времени сравнением и отклоняйте доставки со старым timestamp (например, старше 5 минут) для защиты от replay.

Повторные доставки

Неуспешные доставки (не-2xx ответ) повторяются с экспоненциальной задержкой. Обрабатывайте события идемпотентно по x-legalstack-event-id — одно событие может прийти более одного раза.

Каталог всех типов событий — на странице События вебхуков.

Вебхук формы

Форма может сама отправлять каждый ответ на ваш сервер. Включите Webhook на вкладке «Каналы» конструктора формы и укажите адрес, который начинается с https://. Секрет для подписи создаётся автоматически. Он хранится зашифрованным отдельно от настроек формы, поэтому его не видят те, кто может только просматривать форму.

В меню рядом с кнопкой «Проверить» пункт «Копировать секрет» получает действующий секрет с сервера, а «Перевыпустить секрет» выпускает новый: прежний перестаёт подходить сразу. То же доступно через API: GET /api/v1/interfaces/{id}/webhook/secret возвращает секрет, POST по тому же адресу перевыпускает его. Нужно право редактировать форму и scope interfaces:write.

Ответ приходит POST-запросом с теми же заголовками и той же подписью v1, что и события платформы. Тип события interface.submitted, а x-legalstack-event-id совпадает с submissionId ответа.

Тело
{
  "event": "interface.submitted",
  "interfaceId": "6f1c2e84-3b7a-4d0e-9c51-2a7f0b9e1d43",
  "submissionId": "a93e07c4-58d2-4f1b-b6e0-7c3d9a1f2e85",
  "data": {
    "_interfaceId": "6f1c2e84-3b7a-4d0e-9c51-2a7f0b9e1d43",
    "_source": "web",
    "_submittedAt": "2026-10-06T12:00:00.000Z",
    "_ipAddress": "203.0.113.24",
    "_userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)",
    "licensee_name": "Иванов Иван Иванович",
    "licensee_email": "ivanov@example.ru"
  },
  "channel": "web",
  "submittedAt": "2026-10-06T12:00:00.000Z"
}

В data лежат ответы по ключам полей формы и служебные значения с префиксом _: канал, из которого пришёл ответ (web, embed, telegram или api), время отправки, IP-адрес и User-Agent отправителя. Для ответов из Telegram добавляется _telegramUserId. Поле channel повторяет _source.

Кнопка «Проверить» отправляет на адрес тестовый ответ с полем "test": true и показывает код и время ответа вашего сервера. Если сервер ответил не 2xx, доставка повторяется с нарастающей задержкой, каждый раз с текущими адресом и секретом формы. Если выключить вебхук, недоставленные ответы больше не отправляются.

Секрет, заданный вручную

Если секрет вебхука формы вводили вручную, подпись остаётся в прежнем формате: HMAC-SHA256 в hex от тела запроса, без v1= и без timestamp. Перевыпустите секрет, чтобы перейти на общий формат подписи.

На этой странице