Ganchos de red
Un webhook avisa a tu servidor cuando ocurre algo, como que termine un vídeo. Te ahorra la encuesta GET /v1/job/{id}. Los webhooks se gestionan con la misma API clave que el resto del API, bajo https://reigniter.ai/api/webhooks.
Eventos
Sección titulada «Eventos»| Evento | Enviado cuando |
|---|---|
video.completed |
Un render terminado. La carga útil ha download_url, un enlace que funciona durante 7 días. |
video.failed |
Un render falló. Un render que cancelas no envía esto. |
training.invited |
A un alumno se le asignaba un módulo y se le enviaba su página de formación. |
training.completed |
Un aprendiz con nombre terminó un módulo. La carga útil tiene la puntuación (marcada por el servidor), passed, y su página de resultados. |
training.passed / training.failed |
Enviado con training.completed, contra la nota de aprobado del módulo. Se acaba el tiempo es un suspenso. |
training.overdue |
Un alumno no ha terminado antes de la fecha límite. Una vez por invitación. |
training.certificate_expiring |
Un certificado caduca en 30 días. Una vez por certificado. |
post.published |
Una publicación se publicó en YouTube, TikTok, LinkedIn, Facebook o Instagram. La carga útil tiene la plataforma, la cuenta y url, el enlace a la publicación cuando la plataforma lo proporciona. |
post.failed |
No se podía publicar una publicación. reason es la respuesta de la plataforma en palabras claras. |
credits.low |
El saldo bajó a 10 créditos o menos. Una vez por entrega. |
credits.purchased |
Se añadieron créditos a la cuenta. |
subscription.created |
Se inició una suscripción al plan. |
subscription.canceled |
Se canceló una suscripción al plan. |
user.signup |
La cuenta fue creada. |
user.onboarded |
La cuenta terminó de incorporarse. |
GET /api/webhooks/events devuelve esta lista.
Crea un webhook
Sección titulada «Crea un webhook»-
Crea un endpoint en tu servidor que acepte
POSTsolicitudes con un cuerpo JSON y responda2xxrápidamente. Debe ser accesible en internet público. Se rechazan las direcciones de red privadas y locales. -
Suscríbete a un evento. Un webhook escucha un evento; crea uno por cada evento que necesites.
Ventana de terminal curl https://reigniter.ai/api/webhooks/hooks \-H "Authorization: Bearer $REIGNITER_API_KEY" \-H "Content-Type: application/json" \-d '{"event": "video.completed","webhook_url": "https://hooks.example.com/reignitor","description": "Post finished videos to our CMS"}'const res = await fetch('https://reigniter.ai/api/webhooks/hooks', {method: 'POST',headers: {Authorization: `Bearer ${process.env.REIGNITER_API_KEY}`,'Content-Type': 'application/json',},body: JSON.stringify({event: 'video.completed',webhook_url: 'https://hooks.example.com/reignitor',description: 'Post finished videos to our CMS',}),});const { hook, secret } = await res.json();res = requests.post("https://reigniter.ai/api/webhooks/hooks",headers={"Authorization": f"Bearer {os.environ['REIGNITER_API_KEY']}"},json={"event": "video.completed","webhook_url": "https://hooks.example.com/reignitor","description": "Post finished videos to our CMS",},)data = res.json()hook, secret = data["hook"], data["secret"] -
Guarda el
secretde la respuesta201. Lo necesitas para comprobar firmas. -
Envía una prueba.
POST /api/webhooks/hooks/{id}/testenvía un evento depingfirmado a tu URL y te dice qué ha respondido tu endpoint:{ "delivered": true, "status": 200 }
Suscribir el mismo evento y URL de nuevo no crea un duplicado. Devuelve el webhook existente con reused: true y lo vuelve a activar.
Cómo es una entrega
Sección titulada «Cómo es una entrega»Cada entrega es una POST con un cuerpo JSON:
{ "event": "video.completed", "payload": { "job_id": "7d2e4b10-5c3a-4f8e-a1b2-9c0d8e7f6a54", "user_id": "3f1c2a9e-8b7d-4c1e-9f0a-2d6b5e4c3a21", "output_url": "https://cdn.example.com/exports/7d2e4b10.mp4", "canvas_id": null, "scene_count": 4, "scenes_failed": 0, "credits_charged": 12 }, "emitted_at": "2026-09-25T10:15:00.000Z", "delivery_id": "1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed"}video.failed lleva job_id, user_id, canvas_id y un reason.
Compara payload.job_id con el job_id que obtuviste de POST /v1/render.
Y estos encabezados:
| Cabecera | Valor |
|---|---|
X-Reigniter-Event |
El nombre del evento. |
X-Reigniter-Delivery |
Un ID único para esta entrega. Se mantiene igual cuando se vuelve a intentar una entrega. |
X-Reigniter-Timestamp |
Hora Unix, en segundos, cuando se firmó la entrega. |
X-Reigniter-Signature |
sha256= y el hexágono HMAC-SHA256 de {timestamp}.{raw body}, vinculado a tu secreto. |
Verifica la firma
Sección titulada «Verifica la firma»Revisa cada entrega antes de confiar en ella:
- Lee el cuerpo de la petición en bruto antes de JSON analizar.
- Construye la cadena
{X-Reigniter-Timestamp}.{raw body}. - Calcula HMAC-SHA256 con tu secreto, como hexadecimal, y añade
sha256=delante. - Compáralo con
X-Reigniter-Signatureusando una comparación en tiempo constante. - Rechaza la entrega si la marca de tiempo tiene más de 5 minutos.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyReigniterWebhook(rawBody, headers, secret) { const timestamp = headers['x-banshea-timestamp']; const received = headers['x-banshea-signature'] ?? ''; if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = 'sha256=' + createHmac('sha256', secret) .update(`${timestamp}.${rawBody}`) .digest('hex');
const a = Buffer.from(expected); const b = Buffer.from(received); return a.length === b.length && timingSafeEqual(a, b);}import hashlib, hmac, time
def verify_reignitor_webhook(raw_body: bytes, headers, secret: str) -> bool: timestamp = headers.get("X-Reigniter-Timestamp") received = headers.get("X-Reigniter-Signature", "") if not timestamp or abs(time.time() - int(timestamp)) > 300: return False
signed = f"{timestamp}.".encode() + raw_body expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, received)Entrega y repeticiones
Sección titulada «Entrega y repeticiones»- Cada entrega espera hasta 10 segundos para que tu endpoint responda.
- Se vuelve a intentar un
5xx, un429, un tiempo de espera o un error de red, hasta 3 intentos en total, con aproximadamente un segundo de diferencia. - Cualquier otro
4xxno se vuelve a intentar. - Los intentos mantienen el mismo
X-Reigniter-Delivery. Úsalo para ignorar una entrega que ya has manejado. - Después de 20 entregas fallidas seguidas, el webhook se apaga.
GET /api/webhooks/hooksmuestraactive: falsey el último error enlast_status. Arregla tu endpoint y luego vuelve a encenderlo conPATCH /api/webhooks/hooks/{id}y{ "active": true }.
Responde 2xx tan pronto como hayas guardado la entrega y haz un trabajo lento después.
Gestionar los webhooks
Sección titulada «Gestionar los webhooks»| Método | Camino | Qué hace |
|---|---|---|
GET |
/api/webhooks/events |
Nombres de eventos de lista y esquema de firma |
GET |
/api/webhooks/hooks |
Haz una lista de tus webhooks |
POST |
/api/webhooks/hooks |
Crea un gancho web |
PATCH |
/api/webhooks/hooks/{id} |
Pausa, reanuda o cambia la URL o descripción |
DELETE |
/api/webhooks/hooks/{id} |
Eliminar un webhook |
POST |
/api/webhooks/hooks/{id}/test |
Envía un ping firmado |
Una cuenta puede tener hasta 25 webhooks. Las formas completas de petición y respuesta están en la referencia del endpoint.