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

AnmeldedatenZweckVerwendung
Management Token mt-…Webhooks erstellen, auflisten, aktualisieren, löschen, testen und rotierenAuthorization: Bearer mt-… unter /v1/management/webhooks*
API-Key sk-…Modellanfragen übermitteln und Aufgabenstatus abfragenModell-APIs und /v1/tasks/{id}
Signing Secret whsec_…Überprüfen, ob eine empfangene Benachrichtigung authentisch istIhr 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.

OperationEndpunkt
Auflisten / ErstellenGET / POST /v1/management/webhooks
Abrufen / Aktualisieren / LöschenGET / PATCH / DELETE /v1/management/webhooks/{webhookId}
Signing Secret rotierenPOST /v1/management/webhooks/{webhookId}/rotate-secret
Test sendenPOST /v1/management/webhooks/{webhookId}/test
ZustellungsverlaufGET /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
  }
}
EreignisDaten
task.completedtaskType, taskId, optional model, durationMs, resultUrls, settledCost
task.failedtaskType, taskId, error, errorCode, retryable, refundOutcome
task.timeouttaskType, taskId, expectedTimeoutMs, actualWaitMs, refundIssued, resolutionSource, refundOutcome
webhook.testTestnachricht 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.

Auf dieser Seite