Webhooks
Получайте уведомления о завершении задач без polling'а
Webhooks — это HTTP POST-запросы, которые IskraGen отправляет на ваш URL, когда задача завершается (успехом или неудачей). Полезно для длинных генераций — видео, музыка, аудио — чтобы не опрашивать GET /v1/generations/:id в цикле.
Зачем использовать
Три основных use case'а:
- Уведомление пользователя о завершении. Запустили рендер видео на 30 секунд → ушли по своим делам → webhook прилетел → отправили push / email / in-app сообщение «готово».
- Запись результата в свою БД. При
generation.succeededполучаете финальный URL медиа из payload, сохраняете в свою таблицу или копируете на свой S3 для долговременного хранения. - Триггер пайплайна пост-обработки. Сразу после генерации запускаете апскейл, лицензирование, водяной знак, монтаж в общий ролик — без задержки на polling.
Как создать webhook
Управление endpoint'ами происходит через API. UI в личном кабинете пока в разработке.
1. Создать endpoint
curl https://api.iskragen.ru/v1/webhook-endpoints \
-H "Authorization: Bearer $ISKRAGEN_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/iskragen",
"eventTypes": ["generation.succeeded", "generation.failed"]
}'
Ответ 201:
{
"id": "01HQ...uuid",
"url": "https://your-app.com/webhooks/iskragen",
"secret": "whsec_BASE64SECRET...",
"eventTypes": ["generation.succeeded", "generation.failed"]
}
Сохраните secret сразу — он показывается только один раз. Им вы будете проверять подпись входящих запросов.
2. Список endpoint'ов
curl https://api.iskragen.ru/v1/webhook-endpoints \
-H "Authorization: Bearer $ISKRAGEN_KEY"
3. Ротация секрета
curl -X POST https://api.iskragen.ru/v1/webhook-endpoints/<id>/rotate-secret \
-H "Authorization: Bearer $ISKRAGEN_KEY"
Старый секрет инвалидируется немедленно — переключите проверку в коде до ротации или сразу после.
4. Удаление
curl -X DELETE https://api.iskragen.ru/v1/webhook-endpoints/<id> \
-H "Authorization: Bearer $ISKRAGEN_KEY"
События
generation.succeeded— задача завершилась успешно. В payload — финальный URL результата.generation.failed— задача провалилась окончательно (после всех retry). Списанные средства возвращены на баланс автоматически.
Подпись
Каждый запрос подписан по схеме Standard Webhooks. Заголовки:
| Заголовок | Что внутри |
|---|---|
webhook-id | Уникальный ID сообщения (UUID), для идемпотентности на вашей стороне. |
webhook-timestamp | Unix-время (секунды), когда подпись посчитана. |
webhook-signature | v1,<base64-hmac-sha256> — HMAC от ${msgId}.${timestamp}.${body} с вашим секретом. |
Проверьте, что webhook-timestamp отличается от текущего не более чем на 5 минут — иначе считайте подпись невалидной (защита от replay-атак).
Пример обработчика (Node.js + Express)
import crypto from 'node:crypto';
import express from 'express';
const SECRET = process.env.ISKRAGEN_WEBHOOK_SECRET; // "whsec_..."
const app = express();
// raw body нужен для побайтовой подписи — НЕ используйте express.json() до проверки
app.post('/webhooks/iskragen', express.raw({ type: 'application/json' }), (req, res) => {
const msgId = req.header('webhook-id');
const timestamp = req.header('webhook-timestamp');
const signatureHeader = req.header('webhook-signature');
const body = req.body.toString('utf8');
if (!msgId || !timestamp || !signatureHeader) return res.status(400).end();
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return res.status(400).end();
const key = Buffer.from(SECRET.replace(/^whsec_/, ''), 'base64');
const expected = crypto.createHmac('sha256', key)
.update(`${msgId}.${timestamp}.${body}`)
.digest('base64');
const valid = signatureHeader.split(' ').some((sig) => {
const [scheme, sigB64] = sig.split(',');
return scheme === 'v1' && crypto.timingSafeEqual(
Buffer.from(sigB64), Buffer.from(expected),
);
});
if (!valid) return res.status(401).end();
const event = JSON.parse(body);
// event.type === "generation.succeeded" | "generation.failed"
// event.data.generation — финальный объект генерации с URL результата
// Ответьте 2xx как можно быстрее, тяжёлую работу делайте в фоне
res.status(204).end();
});
app.listen(3000);
Ретраи
При ошибке (HTTP ≥ 400, кроме 410, или таймаут 10 секунд) IskraGen ретраит до 15 раз с экспоненциальным бэк-оффом — от 5 секунд до 3 суток. Если ваш endpoint вернёт HTTP 410 Gone, он будет автоматически отключён. После 30 × 24 подряд неудач endpoint также деактивируется.
Идемпотентность
При ретраях один и тот же webhook-id будет повторяться. Сохраняйте обработанные msgId (например, в Redis с TTL 24 часа) и сразу отвечайте 2xx без обработки на дубликат — иначе рискуете дважды сохранить результат или дважды дёрнуть пост-обработку.
См. также Interactive API Reference → раздел Webhook Endpoints.