Plattform
Callbacks (Webhooks)
Statt den Status abzufragen, gib bei einer Bild- oder Videoanfrage eine callback_url an. Sobald das Ergebnis bereit ist oder ein Fehler auftritt, sendet Zurelay es per POST an diese URL – mit einer Signatur, an der du erkennst, dass es von uns kommt.
Callback anfordern
Füge einer dieser Anfragen callback_url hinzu. Die URL muss öffentlich erreichbar sein und https verwenden.
curl https://api.zurelay.com/v1/videos \ -H "Authorization: Bearer $ZURELAY_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "seedance-2.0", "prompt": "A fox running through fresh snow at dawn", "seconds": 5, "callback_url": "https://example.com/hooks/zurelay" }'Bildanfragen mit Callback
Ohne callback_url wartet eine Bildanfrage, bis die Bilder fertig sind, und gibt sie dann zurück – wie bei der API von OpenAI. Mit dieser Option wird die Anfrage sofort angenommen und der Job zurückgegeben. Kosten fallen nur an, wenn Bilder erstellt werden:
HTTP/1.1 202 Acceptedx-request-id: req_6fJd0kQ3pW9xT2mB7cZ1hR4u{ "id": "req_6fJd0kQ3pW9xT2mB7cZ1hR4u", "object": "image.generation", "model": "nano-banana-pro", "status": "in_progress", "created_at": 1791000000, "completed_at": null, "data": [], "url_expires_at": null, "cost": null, "error": null, "callback_url": "https://example.com/hooks/zurelay"}/v1/images/{id}Du kannst den Status auch abfragen: GET /v1/images/{id} gibt dasselbe Objekt zurück, mit aktuellen Links in data, sobald status den Wert completed hat. Callbacks enthalten immer Links, nie base64 – unabhängig vom Wert von response_format.
Was wir senden
Ein POST pro Ereignis mit einem JSON-Body: type, timestamp und data. Der Auftrag entspricht genau der API-Antwort (das Video-Objekt oder die obige Bildanfrage) und enthält Download-Links, die 24 Stunden gültig sind.
POST /hooks/zurelay HTTP/1.1content-type: application/jsonuser-agent: Zurelay-Webhooks/1.0 (+https://zurelay.com/docs/webhooks)webhook-id: msg_2c1f9e0b7a4d4f6e8b3a91c05d7e6f42webhook-timestamp: 1791000094webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4={ "type": "video.completed", "timestamp": "2026-10-03T03:21:34.000Z", "data": { "id": "video_Qm3v8Rk2Lx7Pa1Zt9Ws4Yn6B", "object": "video", "model": "seedance-2.0", "status": "completed", "progress": 100, "created_at": 1791000000, "completed_at": 1791000093, "expires_at": 1793592000, "seconds": 5, "resolution": "720p", "aspect_ratio": "16:9", "size": "1280x720", "generate_audio": true, "url": "https://…/video_Qm3v8Rk2Lx7Pa1Zt9Ws4Yn6B.mp4?token=…", "url_expires_at": 1791086494, "cost": 0.45, "error": null, "callback_url": "https://example.com/hooks/zurelay" }}{ "type": "image.completed", "timestamp": "2026-10-03T03:20:41.000Z", "data": { "id": "req_6fJd0kQ3pW9xT2mB7cZ1hR4u", "object": "image.generation", "model": "nano-banana-pro", "status": "completed", "created_at": 1791000000, "completed_at": 1791000041, "data": [{ "url": "https://…/req_6fJd0kQ3pW9xT2mB7cZ1hR4u-1.png?token=…" }], "url_expires_at": 1791086441, "cost": 0.07, "error": null, "callback_url": "https://example.com/hooks/zurelay" }}Signatur prüfen
Callbacks folgen dem Format Standard Webhooks, das auch die Webhooks von OpenAI verwenden. Die Signatur ist ein HMAC-SHA256 über <webhook-id>.<webhook-timestamp>.<body> mit dem Signatur-Secret deines Workspaces als Schlüssel, codiert in base64. Du findest das Secret (es beginnt mit whsec_) im Dashboard unter API-Schlüssel. Bewahre es nur auf deinem Server auf.
import osfrom fastapi import FastAPI, HTTPException, Requestfrom standardwebhooks.webhooks import Webhook # pip install standardwebhookswebhook = Webhook(os.environ["ZURELAY_WEBHOOK_SECRET"]) # whsec_…app = FastAPI()@app.post("/hooks/zurelay")async def zurelay_hook(request: Request): body = await request.body() # the raw bytes: the signature covers exactly these try: event = webhook.verify(body, dict(request.headers)) except Exception: raise HTTPException(status_code=400) handle(event) # event["type"], event["data"]; keep it quick, or queue it return {"ok": True}- Prüfe den unveränderten Body: Wenn du das JSON einliest und neu serialisierst, ändern sich die Bytes – und damit die Signatur.
- Lehne einen
webhook-timestampab, der älter als fünf Minuten ist. So kann niemand einen abgefangenen Callback erneut senden. Die Bibliotheken übernehmen das für dich. - Wenn du das Secret wechselst (als Owner oder Admin auf der Seite für API-Schlüssel), erhältst du sofort ein neues. Das alte signiert noch 24 Stunden lang mit. Stelle deinen Server innerhalb dieser Zeit um.
Erst antworten, dann verarbeiten
Antworte innerhalb von 15 Sekunden mit einem beliebigen 2xx, dann gilt der Callback als zugestellt. Speichere zuerst das Ereignis und antworte; lade das Video oder die Bilder danach herunter. Ein Callback kann mehrfach eintreffen, etwa wenn deine Antwort unterwegs verloren geht. Verwende webhook-id, um ihn nur einmal zu verarbeiten.
Erneute Versuche
Bei jeder anderen Antwort (Fehlerstatus, Weiterleitung, keine Antwort innerhalb von 15 Sekunden oder nicht erreichbarer Server) versuchen wir es erneut – insgesamt sechsmal:
Jeder Callback erscheint zusammen mit der zugehörigen Anfrage unter Anfragen im Dashboard: wohin er gesendet wurde, die Antwort auf jeden Versuch und wann der nächste Versuch ansteht. Mit Retry callback sendest du ihn dort sofort erneut – unabhängig davon, ob er bereits zugestellt wurde. Die enthaltenen Links werden bei jedem Versuch neu erstellt.
Fragen oder fehlt etwas? Frag unser Support-Team und wir antworten per E-Mail, meist innerhalb einer Minute.