ДокументацияВебхуки
Вебхуки
Уведомление о завершении запроса без опроса.
Передайте в теле запроса webhook_url — адрес https на вашем сервере. Когда запрос завершится (completed, failed или nsfw), туда придёт POST:
{ "event": "request.completed", "delivery_id": "1842", "created_at": "2026-09-26T10:01:13.000Z", "data": { "id": "d7e6c0f3-…", "status": "completed", "output": { "video": { "url": "https://outsee.io/f/…" } } }}
События: request.completed и request.failed (включает nsfw). В data — то же, что отдаёт GET /requests/{id}.
Заголовки
| Заголовок | Значение |
|---|---|
Outsee-Event | Тип события |
Outsee-Request-Id | id запроса |
Outsee-Delivery-Id | id доставки — одинаковый у повторов |
Outsee-Signature | t=<unix-время>,v1=<подпись> |
Проверка подписи
Подпись — HMAC-SHA256 от строки <t>.<тело запроса> секретом из раздела «Ключи API». Считайте её от тела как оно пришло, до разбора JSON. Отклоняйте уведомления старше 5 минут.
import crypto from "node:crypto";function verifyOutseeSignature(rawBody, header, secret) { const parts = Object.fromEntries(header.split(",").map((p) => p.split("="))); const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex"); const fresh = Math.abs(Date.now() / 1000 - Number(parts.t)) < 300; const given = Buffer.from(parts.v1 || ""); return fresh && given.length === expected.length && crypto.timingSafeEqual(Buffer.from(expected), given);}
Доставка и повторы
- Ответьте любым
2xxв течение 10 секунд — доставка засчитана. - Сеть,
5xx,408,409,425,429— повторим: через 30 секунд, 2 и 10 минут, 30 минут, 1, 2, 4 и 8 часов. - Остальные
4xxи переадресации3xx— постоянный отказ, повторов не будет. Указывайте конечный адрес без переадресаций. - Кнопка проверки адреса в разделе «Ключи API» шлёт подписанное событие с полем
"test": trueи нулевым id запроса — такие события не обрабатывайте как настоящие. - Возможны повторные доставки одного события — отсеивайте дубли по id запроса и статусу.
- Историю доставок видно в карточке запроса в разделе «Запросы».