Webhooks
Ein Webhook teilt deinem Server mit, wenn etwas passiert, zum Beispiel ein Video, das endet. Er spart dir das Abfragen GET /v1/job/{id}. Webhooks werden mit demselben API-Schlüssel verwaltet wie der Rest der API, unter https://reigniter.ai/api/webhooks.
Veranstaltungen
Abschnitt betitelt „Veranstaltungen“| Veranstaltung | Gesendet, wann |
|---|---|
video.completed |
Ein Rendering abgeschlossen. Die Nutzlast hat download_url, eine Verbindung, die 7 Tage lang funktioniert. |
video.failed |
Ein Rendering ist fehlgeschlagen. Ein Render, den du abbrechen kannst, sendet dies nicht. |
training.invited |
Ein Lernender erhielt ein Modul zugewiesen und erhielt seine Schulungsseite. |
training.completed |
Ein benannter Lernender hat ein Modul abgeschlossen. Die Nutzlast enthält die Punktzahl (vom Server markiert), passed, und deren Ergebnisseite. |
training.passed / training.failed |
Gesendet mit training.completed, gegen die Bestehensmarke des Moduls. Wenn die Zeit knapp wird, ist das Nichtbestehen. |
training.overdue |
Ein Lernender hat bis zum Abgabetermin noch nicht abgeschlossen. Einmal auf Einladung. |
training.certificate_expiring |
Ein Zertifikat verfällt innerhalb von 30 Tagen. Einmal pro Zertifikat. |
post.published |
Ein Beitrag wurde auf YouTube, TikTok, LinkedIn, Facebook oder Instagramveröffentlicht. Die Nutzlast enthält die Plattform, das Konto und url, den Link zum Beitrag, wenn die Plattform einen anbietet. |
post.failed |
Ein Beitrag konnte nicht veröffentlicht werden. reason ist die Antwort der Plattform in klaren Worten. |
credits.low |
Der Saldo sank auf 10 Credits oder weniger. Einmal pro Drop. |
credits.purchased |
Guthaben wurden dem Konto hinzugefügt. |
subscription.created |
Ein Abonnement wurde gestartet. |
subscription.canceled |
Ein Abonnement wurde gekündigt. |
user.signup |
Das Konto wurde erstellt. |
user.onboarded |
Das Konto hat das Onboarding abgeschlossen. |
GET /api/webhooks/events gibt diese Liste zurück.
Richte einen Webhook ein
Abschnitt betitelt „Richte einen Webhook ein“-
Baue auf deinem Server einen Endpunkt, der
POSTAnfragen mit einem JSON Body entgegennimmt und2xxschnell beantwortet. Er muss im öffentlichen Internet erreichbar sein. Private und lokale Netzwerkadressen werden abgelehnt. -
Abonniere es für ein Event. Ein Webhook hört ein Event; erstelle pro benötigtes Ereignis eines.
Terminal-Fenster 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"] -
Speichern Sie die
secretaus der201Antwort. Sie brauchen sie, um Unterschriften zu überprüfen. -
Senden Sie einen Test.
POST /api/webhooks/hooks/{id}/testsendet ein signiertesping-Ereignis an Ihre URL und teilt Ihnen mit, was Ihr Endpunkt beantwortet hat:{ "delivered": true, "status": 200 }
Das erneute Abonnement desselben Ereignisses und derselben URL erzeugt kein Duplikat. Der vorhandene Webhook wird mit reused: true zurückgegeben und wieder eingeschaltet.
Wie eine Lieferung aussieht
Abschnitt betitelt „Wie eine Lieferung aussieht“Jede Lieferung ist ein POST mit einem JSON Körper:
{ "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 führt job_id, user_id, canvas_id und ein reason.
Gleiche payload.job_id dem job_id ab, das du von POST /v1/render bekommen hast.
Und diese Überschriften:
| Header | Wert |
|---|---|
X-Reigniter-Event |
Der Name der Veranstaltung. |
X-Reigniter-Delivery |
Eine eindeutige ID für diese Lieferung. Sie bleibt gleich, wenn eine Lieferung erneut versucht wird. |
X-Reigniter-Timestamp |
Unix-Zeit, in Sekunden, als die Lieferung unterschrieben wurde. |
X-Reigniter-Signature |
sha256= und das Hex HMAC-SHA256 von {timestamp}.{raw body}, verbunden mit deinem Geheimnis. |
Überprüfen Sie die Unterschrift
Abschnitt betitelt „Überprüfen Sie die Unterschrift“Überprüfe jede Lieferung, bevor du ihr vertraust:
- Lies den rohen Request-Body, bevor du JSON Parsing machst.
- Baue die Schnur
{X-Reigniter-Timestamp}.{raw body}. - Berechnen Sie HMAC-SHA256 davon mit Ihrem Geheimnis als Hex und fügen Sie
sha256=davor hinzu. - Vergleichen Sie es mit
X-Reigniter-Signaturemit einem konstanten Zeitvergleich. - Lehnen Sie die Lieferung ab, wenn der Zeitstempel älter als 5 Minuten ist.
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)Lieferung und Nachversuche
Abschnitt betitelt „Lieferung und Nachversuche“- Jede Lieferung wartet bis zu 10 Sekunden, bis dein Endpunkt antwortet.
- Ein
5xx, ein429, ein Timeout oder ein Netzwerkfehler wird erneut versucht, insgesamt bis zu 3 Versuche, etwa eine Sekunde auseinander. - Jede andere
4xxwird nicht erneut versucht. - Wiederholte Versuche behalten das gleiche
X-Reigniter-Delivery. Nutze es, um eine Lieferung zu ignorieren, die du bereits erledigt hast. - Nach 20 fehlgeschlagenen Lieferungen in Folge wird der Webhook abgeschaltet.
GET /api/webhooks/hookszeigtactive: falseund den letzten Fehler inlast_statusan. Repariere deinen Endpunkt und schalte ihn dann mitPATCH /api/webhooks/hooks/{id}und{ "active": true }wieder ein.
Beantworte 2xx, sobald du die Lieferung aufbewahrt hast, und arbeite danach langsam.
Webhooks verwalten
Abschnitt betitelt „Webhooks verwalten“| Methode | Verlauf | Was es bewirkt |
|---|---|---|
GET |
/api/webhooks/events |
Listen Sie Ereignisnamen und das Signaturschema auf |
GET |
/api/webhooks/hooks |
Listen Sie Ihre Webhooks auf |
POST |
/api/webhooks/hooks |
Erstellen Sie einen Webhook |
PATCH |
/api/webhooks/hooks/{id} |
Pausieren, fortsetzen oder URL oder Beschreibung ändern |
DELETE |
/api/webhooks/hooks/{id} |
Lösche einen Webhook |
POST |
/api/webhooks/hooks/{id}/test |
Senden Sie ein unterschriebenes ping |
Ein Konto kann bis zu 25 Webhooks haben. Vollständige Anfrage- und Antwortformen befinden sich in der Endpunkt-Referenz.