Den Auftrag abschließen, wenn die Anfrage längst weg ist.
Ein Medienauftrag überlebt den HTTP-Aufruf, der ihn erzeugt hat, die Seite, die ihn ausgelöst hat, und oft auch das Deployment, das gerade lief. Hier geht es darum, das zu überstehen.
Zwischen Absenden und fertiger Datei gibt es vier Stellen, an denen Arbeit verloren geht: ein blind wiederholter Erstellungsaufruf nach Timeout, ein nicht prüfbarer Callback, eine Abfrageschleife, die hämmert oder aufgibt, und eine Ergebnis-URL, die abgelaufen ist, während Sie noch überlegt haben.
01
Eine Wiederholung ohne Schlüssel ist eine zweite Rechnung
Mit Idempotency-Key liefert eine Wiederholung desselben Modells, derselben Eingabe und desselben Callbacks innerhalb von 24 Stunden den ursprünglichen Auftrag zurück, ohne erneut zu reservieren. Der Schlüssel gilt je API-Schlüssel; ein anderer Schlüssel mit demselben Wert erhält 409 ohne Task-ID.
02
Ein ungeprüfter Callback ist ein offener Endpunkt
Zustellungen tragen X-Webhook-Timestamp und eine Base64-HMAC-SHA256 in X-Webhook-Signature über taskId.timestamp.sha256(raw_body). Prüfen Sie gegen die Rohbytes in konstanter Zeit und weisen Sie alte Zeitstempel ab, bevor Sie Auftrags- oder Abrechnungszustand ändern.
03
Abfragen ohne Obergrenze führen zum Rate Limit
recordInfo ist Rückfallebene, kein Transport. Starten Sie bei etwa zwei Sekunden, erhöhen Sie um die Hälfte, deckeln Sie bei fünfzehn und hören Sie zu einer Frist auf, die Sie gewählt haben.
Der Ansatz
Ein dauerhafter Datensatz je Auftrag, geschrieben vor der Antwort
Speichern Sie Idempotenzschlüssel, taskId und Ihre eigene Korrelations-ID in derselben Transaktion, in der Sie dem Aufrufer antworten. Jedes spätere Ereignis – Callback, Abfrage, Wiederholung, Supportfrage – löst gegen diese Zeile auf, und eine doppelte Zustellung wird zur Aktualisierung statt zur zweiten Bestellung.
Erst prüfen, dann lesen. Die Signatur deckt die Rohbytes ab, also wird erst nach dem Vergleich geparst.
Verify the callback before you trust it
import { createHash, createHmac, timingSafeEqual } from "node:crypto";
// rawBody is the exact bytes that arrived. Parse only to read the task ID:
// the digest is always computed over those raw bytes, never over a re-encode.
export function verifyDelivery(rawBody, headers, webhookKey) {
const timestamp = headers["x-webhook-timestamp"];
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const taskId = JSON.parse(rawBody).data.taskId; // payload version 2
const digest = createHash("sha256").update(rawBody).digest("hex");
const expected = createHmac("sha256", webhookKey)
.update(`${taskId}.${timestamp}.${digest}`)
.digest("base64");
const sent = Buffer.from(headers["x-webhook-signature"] ?? "", "utf8");
const mine = Buffer.from(expected, "utf8");
return sent.length === mine.length && timingSafeEqual(sent, mine);
}
Asynchrone Medien-API: Aufträge und Webhooks — Was Sie früh festhalten sollten
Feld oder Header
Wert oder Grenze
Idempotency-Key
24 h · scoped to one API key
X-Webhook-Signature
base64(HMAC-SHA256)
signed string
taskId.timestamp.sha256(raw_body)
X-Webhook-Payload-Version
2 for new integrations
Horizontal wischen, um alle Spalten zu sehen.
Integration
Vom ersten Aufruf bis in die Produktion
01Idempotenzschlüssel erzeugen, speichern und damit createTask senden; callBackUrl auf einen HTTPS-Endpunkt an Port 80 oder 443 setzen.
02data.taskId in die Datenbank schreiben, bevor dem Aufrufer geantwortet wird; im 202 taucht sie zuerst auf.
03Callback annehmen, Signatur gegen den Rohkörper prüfen, über request_id deduplizieren und den Datensatz aktualisieren.
04Ersatzweise recordInfo mit exponentiellem Backoff abfragen und output.assets vor Ablauf der signierten URL kopieren.
Passung
Wann dieser Weg der richtige ist
Dafür geeignet
Alles, was Medien erzeugt. Bild-, Video- und Audio-Endpunkte sind konstruktionsbedingt asynchron.
Sie brauchen einen dauerhaften Nachweis darüber, was gesendet wurde, was es kosten sollte und wie es endete.
Dafür nicht geeignet
Sie rufen ein Textmodell auf. Das streamt innerhalb der Anfrage und rechnet nach gemessener Nutzung ab.
Der Browser soll den Auftrag besitzen. Schlüssel gehören auf Ihren Server, der Auftragsdatensatz ebenso.
Belege
Was Sie selbst prüfen können
Jede Antwort trägt eine request_id
Der Umschlag lautet auf allen /api/v1-Operationen {code, msg, data, request_id}. In Payload-Version 2 bleibt die request_id einer Zustellung über Wiederholungen stabil und ist damit der natürliche Deduplizierungsschlüssel.
Reservierungen sind im Datensatz sichtbar
cost mit settled: false ist der reservierte Schätzwert, settled: true die Endabrechnung. Ein Erfolg übersteigt die Reservierung nie, Fehler und Ablauf geben sie vollständig frei.
Fehler nutzen ein geschlossenes Vokabular
errorCode ist einer von neun stabilen Werten: invalid_request, unsupported_combination, content_rejected, rate_limited, upstream_unavailable, generation_failed, timeout, invalid_asset, upstream_failed. Alles andere behandeln Sie als upstream_failed.
Vor dem Start
Plattformverhalten zum Bestätigen
Idempotenzschlüssel beim Auftrag speichern, nicht im Prozessspeicher.
Callback-Verarbeitung idempotent machen; Zustellungen werden planmäßig wiederholt.
Eine Abfragefrist setzen und bei Überschreitung alarmieren.
Ergebnisse vor expiresAt kopieren und die URL neu anfordern, statt eine signierte zu cachen.
Häufige Fragen
Was auf dieser Seite gefragt wird
Dieselbe Anfrage mit demselben Idempotency-Key wiederholen. Innerhalb von 24 Stunden und mit demselben API-Schlüssel erhalten Sie den ursprünglichen Auftrag ohne zweite Reservierung. Nach einem Timeout niemals einen neuen Körper senden – das ist ein neuer, separat berechneter Auftrag.
Beides. Der Callback ist der schnelle Weg, eine begrenzte Abfrage das Sicherheitsnetz für die Zustellung, die nie ankam. Eine Abfrageschleife sollte nie Ihr Haupttransport sein.
HMAC-SHA256 über taskId.timestamp.sha256(raw_body) mit dem Webhook-Schlüssel des Kontos berechnen, Base64 kodieren und in konstanter Zeit vergleichen. In Payload-Version 2 stammt die Task-ID aus data.taskId.
Nein. Die Annahme ist endgültig. Der Zustand canceled existiert nur, damit historische Datensätze lesbar bleiben; auslösen lässt er sich nicht.
Modelle
Modelle, die Sie dafür aufrufen können
Jeder Link führt auf die Seite der jeweiligen Modellfamilie: Eingaben, Grenzen, Inhaltsrichtlinie und der aktuelle Preis je Einheit.