Kernleitfäden
Webhook-Management-API
Konfigurieren Sie Aufgabenbenachrichtigungen über das Dashboard, die API oder MCP, verifizieren Sie Signaturen und beheben Sie Probleme bei der Zustellung.
Webhooks benachrichtigen Ihre Anwendung, wenn eine asynchrone Aufgabe abgeschlossen wurde, fehlgeschlagen ist oder ein Timeout aufgetreten ist. Konfigurieren Sie diese im Dashboard → API → Webhooks, über die Management-API oder über das full-Profil von TokenLab MCP. Sie nutzen dieselben Workspace-Endpunkte und denselben Zustellungsverlauf.
Welche Anmeldedaten sind zu verwenden
| Anmeldedaten | Zweck | Verwendung |
|---|---|---|
Management Token mt-… | Webhooks erstellen, auflisten, aktualisieren, löschen, testen und rotieren | Authorization: Bearer mt-… unter /v1/management/webhooks* |
API-Key sk-… | Modellanfragen übermitteln und Aufgabenstatus abfragen | Modell-APIs und /v1/tasks/{id} |
Signing Secret whsec_… | Überprüfen, ob eine empfangene Benachrichtigung authentisch ist | Ihr Empfänger; niemals als API-Bearer-Token verwenden |
Erstellen Sie ein Management Token unter Dashboard → API → Management Tokens. Tokens sind auf den Workspace beschränkt: Wählen Sie denselben Workspace wie für den API-Key, der die Aufgaben übermittelt. Ein Token kann die Endpunkte eines anderen Workspaces weder lesen noch ändern. API-Keys und Signing Secrets werden von der Management-API abgelehnt. Die Dashboard-Konfiguration verwendet Ihre angemeldete Workspace-Admin-Sitzung.
Speichern Sie mt-… und whsec_… auf Ihrem Backend. Betten Sie diese nicht in Browser-Code, Prompts, Repository-Dateien oder URLs ein. Management Tokens autorisieren auch andere Workspace-Management-Operationen; es handelt sich nicht um reine Webhook-Anmeldedaten.
Einen Endpunkt konfigurieren
export TOKENLAB_MANAGEMENT_TOKEN="mt-your-management-token"
curl https://api.tokenlab.sh/v1/management/webhooks \
-H "Authorization: Bearer $TOKENLAB_MANAGEMENT_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"url":"https://your-app.example/webhooks/tokenlab","events":["task.completed","task.failed","task.timeout"],"description":"Production task results"}'Die 201-Antwort enthält eine id und ein einmaliges secret, das mit whsec_ beginnt. Speichern Sie das Secret, bevor Sie diesen Schritt verlassen. Antworten für List/Get/Update geben es niemals preis. Pro Workspace können bis zu 10 Endpunkte konfiguriert werden. URLs müssen öffentliches HTTPS verwenden und dürfen keine Anmeldedaten, Query-Strings oder Fragmente enthalten. Weiterleitungen werden nicht verfolgt.
| Operation | Endpunkt |
|---|---|
| Auflisten / Erstellen | GET / POST /v1/management/webhooks |
| Abrufen / Aktualisieren / Löschen | GET / PATCH / DELETE /v1/management/webhooks/{webhookId} |
| Signing Secret rotieren | POST /v1/management/webhooks/{webhookId}/rotate-secret |
| Test senden | POST /v1/management/webhooks/{webhookId}/test |
| Zustellungsverlauf | GET /v1/management/webhooks/{webhookId}/deliveries?page=1&limit=50 |
Pausieren Sie mit PATCH {"is_active":false}; setzen Sie die Aktivität mit PATCH {"is_active":true} fort. Das Fortsetzen setzt die Anzahl der aufeinanderfolgenden Fehler zurück. Die Rotation gibt einmalig ein neues Secret zurück; konfigurieren Sie dieses umgehend auf Ihrem Empfänger. Anfragen, die bereits unterwegs sind, können noch die vorherige Signatur tragen, akzeptieren Sie daher während der Rotation kurzzeitig beide Secrets. Die Rotation ist nicht umkehrbar.
Ereignisse und Payloads
Abonnements decken zukünftige terminale asynchrone Aufgabenereignisse ab; synchrone Ergebnisse und historische Aufgaben werden nicht erneut abgespielt. Empfangen Sie alle Workspace-Aufgaben für die ausgewählten Ereignistypen und gleichen Sie data.taskId mit der ID ab, die Sie beim Erstellen der Aufgabe erhalten haben. Callback-Felder verwenden camelCase; Management-Antwortfelder verwenden snake_case.
{
"id": "event-unique-id",
"type": "task.completed",
"created": 1790000000,
"data": {
"taskType": "video",
"taskId": "ldtask_0123456789abcdef0123456789abcdef",
"model": "your-selected-model",
"durationMs": 42000,
"resultUrls": ["https://api.tokenlab.sh/v1/media-results/7c9e6679-7425-40de-944b-e07fc1f90ae7.mp4?token=…"],
"settledCost": 0.12
}
}| Ereignis | Daten |
|---|---|
task.completed | taskType, taskId, optional model, durationMs, resultUrls, settledCost |
task.failed | taskType, taskId, error, errorCode, retryable, refundOutcome |
task.timeout | taskType, taskId, expectedTimeoutMs, actualWaitMs, refundIssued, resolutionSource, refundOutcome |
webhook.test | Testnachricht und konfigurierte Abonnements; wird nur durch die Test-Operation gesendet |
Jeder Eintrag in resultUrls ist eine TokenLab-Media-Result-URL, die 30 Tage gültig bleibt. Siehe Datenaufbewahrung.
Bei task.timeout ist expectedTimeoutMs der konfigurierte Timeout-Schwellenwert und actualWaitMs die verstrichene Wartezeit, beides in Millisekunden. refundIssued: true bedeutet, dass die Rückerstattung erfolgreich war oder bereits ausgestellt wurde; false schließt eine spätere Rückerstattung nicht aus. refundOutcome beschreibt das Ergebnis der Rückerstattungsabwicklung. Timeout-Ereignisse enthalten kein durationMs.
Felder hängen von der Aufgabe ab und können fehlen. Verwenden Sie GET /v1/tasks/{id} mit dem sk-…-Key des ursprünglichen Workspaces für das maßgebliche Ergebnis und den Abrechnungsstatus. Das Feld retryable eines Ereignisses beschreibt den Fehler bei der Generierung; es ist keine Anweisung, eine terminale Aufgabe unbegrenzt abzufragen oder automatisch eine neue kostenpflichtige Aufgabe einzureichen. In task.failed sind error, errorCode und retryable die öffentlichen error_details.message, code und retryable der Aufgabe – dieselben Werte, die ein Status-Read zurückgibt.
Vor der Verarbeitung verifizieren
Jeder POST enthält X-Webhook-ID, X-Webhook-Timestamp (Unix-Sekunden) und X-Webhook-Signature (sha256=<hex>). Berechnen Sie HMAC-SHA256 über den exakten Zeitstempel-String, einen Punkt und die rohen Request-Body-Bytes unter Verwendung des vollständigen whsec_…-Secrets. Parsen und serialisieren Sie JSON vor der Verifizierung nicht neu.
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verifyWebhook(rawBody, headers, secrets) {
const timestamp = headers['x-webhook-timestamp'];
const signature = headers['x-webhook-signature'];
if (typeof timestamp !== 'string' || !/^\d+$/.test(timestamp)) return false;
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
if (typeof signature !== 'string' || !/^sha256=[a-f0-9]{64}$/.test(signature)) return false;
const received = Buffer.from(signature.slice(7), 'hex');
return secrets.some(secret => {
const expected = createHmac('sha256', secret).update(timestamp + '.').update(rawBody).digest();
return timingSafeEqual(expected, received);
});
}Überprüfen Sie nach der Verifizierung, ob die id im Body mit X-Webhook-ID übereinstimmt, speichern Sie die Ereignis-ID atomar mit Ihrem Arbeitselement und geben Sie schnell 2xx zurück. Verarbeiten Sie rechenintensive Aufgaben aus Ihrer eigenen Warteschlange. Deduplizieren Sie anhand der Ereignis-ID innerhalb des empfangenden Endpunkts: Zustellungen können sich wiederholen und die Reihenfolge ist nicht garantiert. Eine Zeitstempel-Toleranz von fünf Minuten begrenzt das Alter von Replays; die ID-Deduplizierung verhindert eine wiederholte Verarbeitung innerhalb dieses Zeitfensters.
Wiederholungsversuche und Wiederherstellung
Jeder Zustellungszyklus unternimmt bis zu drei Versuche, wobei 1 Sekunde und dann 4 Sekunden gewartet wird. Jeder HTTP-Versuch hat ein Timeout von 10 Sekunden sowie einen neuen Zeitstempel/Signatur. Netzwerkfehler, 429 und 5xx sind wiederholbar. Andere 4xx-Fehler, Weiterleitungen und ungültige Netzwerkziele beenden den Zyklus ohne Wiederholung. Vorübergehende Fehler können spätere Ereignis-Wiederholungen mit derselben Zustellungs-ID auslösen. Zehn aufeinanderfolgende fehlgeschlagene Zyklen pausieren den Endpunkt automatisch.
Verwenden Sie die Test-Operation und den Zustellungsverlauf, um outcome, http_status, attempts und delivered_at einzusehen. Eine erfolgreiche Test-API-Antwort (200) bedeutet nur, dass der Versuch aufgezeichnet wurde: Prüfen Sie outcome == "delivered". Reparieren Sie den Empfänger, setzen Sie den Endpunkt fort und senden Sie dann einen weiteren Test. Der Verlauf enthält Zustellungs-Metadaten, keine Payloads; ein manuelles Replay alter Ereignisse ist nicht verfügbar. Behalten Sie Aufgaben-IDs bei und gleichen Sie diese mit dem Aufgabenstatus ab, falls Ihr Empfänger pausiert oder nicht verfügbar war.
MCP-Konfiguration
Webhook-Management-Tools sind im full-Profil verfügbar. Die Management-Anmeldedaten sind vom Inference-Key getrennt; Katalog- und Webhook-Management können ohne Inference-Key funktionieren.
{
"mcpServers": {
"tokenlab": {
"command": "npx",
"args": ["-y", "@tokenlabai/mcp-server@latest"],
"env": {
"TOKENLAB_MCP_TOOL_PROFILE": "full",
"TOKENLAB_MANAGEMENT_TOKEN": "mt-your-management-token",
"TOKENLAB_API_KEY": "sk-your-inference-key"
}
}
}
}Tools: list_webhooks, create_webhook, get_webhook, update_webhook, delete_webhook, rotate_webhook_secret, test_webhook, list_webhook_deliveries. Fügen Sie niemals Anmeldedaten in ein Tool-Argument ein. Gewähren Sie nur vertrauenswürdigen MCP-Clients Management-Zugriff.
Polling-Fallback
Webhooks entfernen nicht den Zugriff auf Statusabfragen und legen kein neues Polling-Limit fest. Wenn Sie Polling verwenden, nutzen Sie die poll_url aus der Erstellungsantwort, warten Sie bei ausstehenden Aufgaben ab und stoppen Sie bei terminalen Zuständen. Stoppen Sie bei 401, 403, 404 oder error.retryable == false; wiederholen Sie vorübergehende 503 async_task_owner_unavailable-Fehler mit Backoff. Eine fehlende oder abgelaufene Aufgabe gibt 404 async_task_not_found zurück. Das wiederholte Abfragen einer fehlenden Aufgabe kann diese nicht neu erstellen.
Die callback_url der Seedance-Kompatibilitäts-API ist ein separater Callback-Vertrag pro Anfrage. Sie kann beim Erstellen der Aufgabe festgelegt werden; sie verwendet nicht diese Workspace-Ereignis-Payloads oder HMAC-Header.