Skip to Content

Webhooks

Übergeben Sie beim Erstellen einer Aufgabe eine callback_url, und ofox liefert das Ergebnis per Webhook, statt dass Sie es per Polling abfragen. Wenn die Aufgabe einen terminalen Zustand erreicht, sendet ofox ein POST an Ihre URL, mit dem vollständigen Aufgabenobjekt im Body (eine fehlgeschlagene Zustellung wird erneut versucht — siehe Abschnitt Wiederholungen unten).

callback_url muss HTTPS verwenden und die SSRF-Prüfung bestehen (private, Loopback- und Cloud-Metadata-Adressen werden abgelehnt). Eine ungültige URL wird beim Erstellen mit 400 invalid_callback_url abgelehnt — siehe Video erstellen.

Ereignisse

Pro Aufgabe wird ein Ereignis zugestellt, passend zu dem terminalen Status, in dem sie gelandet ist (derselbe Wert erscheint in data.status).

EreignisAusgelöst wenn
video.generation.completedDie Aufgabe erfolgreich war
video.generation.failedDie Aufgabe fehlgeschlagen ist
video.generation.cancelledDie Aufgabe abgebrochen wurde
video.generation.expiredDie Aufgabe abgelaufen ist

Zustellungs-Payload

Jede Zustellung ist ein POST an Ihre callback_url mit diesen Headern:

POST https://your-app.example/webhooks/ofox-video Content-Type: application/json X-Ofox-Idempotency-Key: 9bcf3c60-7db2-4e1a-a1b2-c3d4e5f60718-completed X-Ofox-Signature: <HMAC-SHA256, base64url>

Der Body ist ein Envelope. Sein Feld data ist identisch mit dem Response Body von Videostatus abrufen für dieselbe Aufgabe:

{ "event": "video.generation.completed", "id": "9bcf3c60-7db2-4e1a-a1b2-c3d4e5f60718", "created_at": 1776211400, "data": { "id": "9bcf3c60-7db2-4e1a-a1b2-c3d4e5f60718", "status": "completed", "model": "google/veo-3.1", "prompt": "A golden retriever running on the beach at sunset", "unsigned_urls": ["https://upstream.example/out.mp4"], "mirror_urls": ["https://cdn.ofox.ai/videos/vgen_xxx.mp4?sig=..."], "usage": { "video_seconds": 5, "video_cost": "0.4000000000" }, "created_at": 1776211362, "updated_at": 1776211400 } }
FeldTypBeschreibung
eventstringEiner der oben aufgeführten Ereignistypen
idstringAufgaben-ID (UUID)
created_atintegerEreigniszeitpunkt, Unix-Sekunden
dataobjectDas vollständige Aufgabenobjekt — dieselbe Form wie GET /v1/videos/{id}

Idempotenz

Dasselbe Ereignis kann mehr als einmal zugestellt werden — ein Retry kann ausgelöst werden, nachdem Ihr Endpunkt die erste Zustellung bereits verarbeitet hat. Deduplizieren Sie über den Header X-Ofox-Idempotency-Key, der <id>-<status> ist (zum Beispiel 9bcf3c60-7db2-4e1a-a1b2-c3d4e5f60718-completed), und verarbeiten Sie jeden Key höchstens einmal.

Antworten Sie mit einem beliebigen 2xx-Status, um den Empfang zu bestätigen. Eine Nicht-2xx-Antwort oder ein Timeout wird als fehlgeschlagene Zustellung behandelt und löst einen Retry aus; geben Sie daher zügig 2xx zurück und erledigen Sie schwere Arbeit asynchron.

Signaturprüfung

Jede Zustellung enthält einen X-Ofox-Signature-Header: HMAC-SHA256(raw request body, your webhook secret), base64url-kodiert. Berechnen Sie ihn mit Ihrem Secret neu und vergleichen Sie ihn in konstanter Zeit, bevor Sie der Payload vertrauen.

verify-webhook.js
import crypto from 'node:crypto' // X-Ofox-Signature = HMAC-SHA256(raw request body, your webhook secret), // base64url-encoded. function verifyOfoxSignature(rawBody, signatureHeader, secret) { if (typeof signatureHeader !== 'string') return false const expected = crypto .createHmac('sha256', secret) .update(rawBody) .digest('base64url') const a = Buffer.from(expected) const b = Buffer.from(signatureHeader) // Constant-time compare; guard length first (timingSafeEqual throws on mismatch). return a.length === b.length && crypto.timingSafeEqual(a, b) }

Berechnen Sie den HMAC über die Rohbytes exakt so, wie sie empfangen wurden, vor jedem JSON-Parsing oder erneuter Serialisierung — sonst stimmt die Signatur nicht überein. In Express erfassen Sie den Body mit express.raw({ type: 'application/json' }).

Wiederholungen

Eine fehlgeschlagene Zustellung (Nicht-2xx oder Timeout) wird automatisch mit gekapptem exponentiellem Backoff plus Jitter wiederholt — bis zu 10 Wiederholungen über ein Zeitfenster von etwa 40 Minuten. Die Verzögerung vor Retry n beträgt min(5·2^(n-1), 600) Sekunden plus zufälligem Jitter.

WiederholungVerzögerungKumulativ
15s5s
210s15s
320s35s
440s1m15s
580s2m35s
6160s5m15s
7320s10m35s
8600s (capped)20m35s
9600s30m35s
10600s40m35s

Fallback

Wenn alle Wiederholungen ausgeschöpft sind, beendet ofox die Zustellversuche. Das Aufgabenergebnis geht nie verloren — Sie können jederzeit GET /v1/videos/{id} per Polling abfragen, um den finalen Zustand abzurufen (vorbehaltlich der Ratenbegrenzung dieses Endpunkts).

Last updated on