События вебхуков
Список событий вебхуков run.succeeded, run.failed, batch.completed и balance.low с форматом тела и заголовков.
Справочник по формату доставки вебхуков: заголовки и подпись, повторы и отключение, видимость секрета конечной точки — и четыре события, на которые можно подписаться. Как подключить приём и проверить подпись на Node.js, Python и PHP — «Приём вебхуков».
Заголовки и подпись
Каждая доставка подписана по соглашению Standard Webhooks и несёт три заголовка:
webhook-id— идентификатор события (evt_…); одинаковый во всех попытках одной и той же доставки — по нему и делается дедупликация на стороне получателя (повторная попытка — не новое событие);webhook-timestamp— время отправки, целые секунды Unix;webhook-signature— может содержать несколько подписей через пробел, каждая в форматеv1,<base64>(Standard Webhooks разрешает несколько, не объясняя зачем — проверяйте каждую: действительной считается любая совпавшая).
Подпись — HMAC-SHA256 от строки {webhook-id}.{webhook-timestamp}.{тело запроса} (тело — ровно те
байты, что были отправлены, без повторной сериализации на вашей стороне) на ключе — секрете
конечной точки. Секрет имеет вид whsec_ + base64; HMAC-ключ — результат base64-декодирования
части после whsec_.
Кроме самой подписи, проверяющая сторона обязана отклонять запрос, если webhook-timestamp
отличается от текущего времени больше чем на 5 минут (300 секунд) — в любую сторону. Это
защита от повторного использования перехваченного тела запроса (replay): без проверки времени
когда-то действительная подпись оставалась бы действительной вечно.
Секрет конечной точки
Секрет виден в поле secret всюду, где ключ или сессия несёт скоуп runs:write: в ответе на
создание конечной точки, в GET /v1/webhook_endpoints/{id} и в списке
GET /v1/webhook_endpoints — не только сразу после создания. Без этого скоупа поле всегда null.
Отдельный случай — повтор запроса на создание с тем же Idempotency-Key: такой ответ всегда несёт
secret: null, даже у принципала с runs:write (секрет не повторяется в ответах-повторах). Если
конечная точка была создана автоматически для webhook_url прогона, прочитайте её секрет позже
через GET /v1/webhook_endpoints (с runs:write) — отдельного уведомления с ним не присылается.
На сервере секрет хранится зашифрованным.
Отдельного маршрута для смены (ротации) секрета нет. Чтобы заменить секрет, создайте новую конечную точку и удалите старую — повторно использовать тот же URL можно только после удаления предыдущей записи с ним (один URL — одна конечная точка организации, активная или отключённая).
Повторы и отключение
Неудачная попытка повторяется ещё 6 раз — итого до 7 попыток (с 0 по 6) на одну доставку — с
увеличивающейся задержкой: 5 секунд, 5 минут, 30 минут, 2 часа, 5 часов, 10 часов. Если и последняя
попытка не удалась, доставка помечается failed и дальше не повторяется автоматически; её можно
повторить вручную — каждый такой повтор добавляет одну попытку сверх автоматической серии и сам не
планирует следующую. Если и он не удался, доставка снова failed, и вы можете повторить её вручную
ещё раз, и так далее, пока не добьётесь успеха или не откажетесь от доставки.
Конечная точка, у которой 72 часа подряд не было ни одной успешной доставки, отключается
автоматически (status: "disabled") — владельцам и администраторам организации приходит письмо.
Отключённую точку можно включить обратно вручную; пока она отключена, она ничего не получает.
Если в настройках организации срок хранения результата — «не хранить» (retention: "none"), то к
моменту повторной отправки output и fields в сохранённом теле события уже могли быть обнулены
— ручной повтор в этом случае придёт с "output": null и "fields": null под тем же
webhook-id, что и первая попытка.
События
Четыре типа событий, в этом же порядке в списке events конечной точки:
run.succeeded,run.failed— прогон завершился, успешно или с ошибкой;batch.completed— пакетная обработка завершена;balance.low— баланс организации опустился ниже порога.
Тело запроса — JSON-объект одной формы для всех событий:
{
"id": "evt_01J…",
"type": "run.succeeded",
"created_at": "2026-10-31T12:00:00.000Z",
"data": { "object": { "…": "…" } }
}data.object для run.succeeded/run.failed — тот же объект Run, что отдаёт REST API, с одним
отличием: поле file в нём всегда null — имя файла по вебхуку не передаётся, даже когда в самом
API оно видно. Для batch.completed — объект Batch. Форма data.object для balance.low этой
страницей не документируется.
Объект data.object по событиям
run.succeeded,run.failed—data.object— тот же объектRun, что отдаёт REST API (id,status,typizer_id,typizer_version,mode,format,pages,output,fields,error,metadata,created_at,completed_atи другие поля), с одним отличием:fileв нём всегдаnull— имя файла по вебхуку не передаётся. Структураoutput/fields— та же, что уGET /v1/runs/{id}в форматеjson, см. «Форматы результата».batch.completed—data.object— объектBatch(id,typizer_id,status,total,succeeded,failed,created_at,completed_at); сами результаты батча вебхук не несёт — заберите ихGET /v1/batches/{id}/export.balance.low— формаdata.objectэтой страницей не документируется.
Что дальше
- «Приём вебхуков» — настройка конечной точки и проверенные примеры проверки подписи на трёх языках.
- «Форматы результата» — структура
output/fieldsв телеrun.succeeded/run.failed. - «Обработка ошибок и повторов» —
Idempotency-Keyна вызовах к API (у вебхуков своя, отдельная схема повторов — выше).