Platform

Geri çağrılar (webhook'lar)

Durumu sürekli sorgulamak yerine, görsel veya video isteğinize bir callback_url ekleyin. İşlem tamamlandığında veya başarısız olduğunda Zurelay, sonucu bu URL'ye POST ile gönderir. İmza sayesinde isteğin bizden geldiğini doğrulayabilirsiniz.

Geri çağrı isteyin

Bu isteklerden herhangi birine callback_url ekleyin. Bu, internet üzerinden herkese açık bir https URL'si olmalıdır.

Uç noktaNe olur
POST /v1/videosVideo üretimini her zamanki gibi başlatır. İşlem bittiğinde geri çağrı, tamamlanan videoyu (veya neden başarısız olduğunu) iletir. Durumu sorgulamanıza gerek kalmaz.
POST /v1/images/generationsGörselleri beklemek yerine hemen 202 ve isteğin kimliğiyle yanıt verir, görselleri arka planda üretir ve ardından geri çağrı gönderir.
POST /v1/images/editsDüzenlemeler için de aynısı geçerlidir: JSON alanı veya multipart istekte bir form alanı olarak ekleyin.
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"
}'

Geri çağrılı görsel istekleri

callback_url olmadan görsel isteği, OpenAI API'sinde olduğu gibi görseller hazır olana kadar bekler ve bunları yanıt olarak döndürür. Bu alan eklendiğinde istek hemen kabul edilir ve yanıt olarak iş nesnesi döndürülür. Yalnızca görseller üretilirse ücretlendirilir:

Yanıt
HTTP/1.1 202 Accepted
x-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"
}
GET/v1/images/{id}

Durumu sorgulamanız da mümkündür: GET /v1/images/{id} aynı nesneyi döndürür; status değeri completed olduğunda data içinde yeni bağlantılar yer alır. response_format ne olursa olsun, geri çağrılar her zaman bağlantı içerir, asla base64 içermez.

Ne gönderiyoruz

Her olay için JSON gövdeli bir POST gönderilir: type, timestamp ve API'nin döndürdüğü haliyle iş nesnesini içeren data (video nesnesi veya yukarıdaki görsel isteği). İndirme bağlantıları 24 saat geçerlidir.

OlayNe zaman
video.completedVideo hazır: data.url ile indirebilirsiniz.
video.failedÜretilemedi: data.error nedenini belirtir. Ücret alınmadı.
image.completedGörseller hazır: data.data her biri için bir bağlantı içerir.
image.failedGörsel üretilmedi: data.error nedenini belirtir. Ücret alınmadı.
Video geri çağrısı
POST /hooks/zurelay HTTP/1.1
content-type: application/json
user-agent: Zurelay-Webhooks/1.0 (+https://zurelay.com/docs/webhooks)
webhook-id: msg_2c1f9e0b7a4d4f6e8b3a91c05d7e6f42
webhook-timestamp: 1791000094
webhook-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"
}
}
Görsel geri çağrısı (gövde)
{
"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"
}
}
BaşlıkDeğer
webhook-idmsg_…: bu geri çağrının her yeniden denemesinde aynıdır. Daha önce işlediğiniz bir geri çağrıyı atlamak için kullanın.
webhook-timestampBu denemenin gönderildiği zaman, Unix saniyesi cinsinden.
webhook-signaturev1, ardından imza (aşağıya bakın). Gizli anahtarınızı yeniledikten sonraki bir gün boyunca, boşlukla ayrılmış iki imza gönderilir.
user-agentZurelay-Webhooks/1.0

İmzayı doğrulayın

Geri çağrılar, OpenAI webhook'larının da kullandığı Standard Webhooks biçimine uyar. İmza, çalışma alanınızın imzalama anahtarıyla <webhook-id>.<webhook-timestamp>.<body> üzerinden hesaplanan, base64 kodlu bir HMAC-SHA256 değeridir. Gizli anahtarı (whsec_ ile başlar) paneldeki API anahtarları sayfasında bulabilirsiniz. Yalnızca sunucunuzda saklayın.

import os
from fastapi import FastAPI, HTTPException, Request
from standardwebhooks.webhooks import Webhook # pip install standardwebhooks
webhook = 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}
  • Ham gövdeyi kontrol edin: JSON'u ayrıştırıp yeniden serileştirmek baytları, dolayısıyla imzayı değiştirir.
  • Beş dakikadan eski bir webhook-timestamp değerini reddedin: bu, birinin ele geçirdiği geri çağrıyı yeniden göndermesini engeller. Kütüphaneler bunu sizin için yapar.
  • Gizli anahtarı yenilediğinizde (sahipler ve yöneticiler, API anahtarları sayfasından) hemen yeni bir anahtar alırsınız. Eski anahtar 24 saat boyunca yenisiyle birlikte imzalamaya devam eder; bu süre içinde sunucunuzu yeni anahtara geçirin.

Önce yanıtlayın, sonra işleyin

15 saniye içinde herhangi bir 2xx ile yanıt verirseniz geri çağrı teslim edilmiş sayılır. Önce olayı kaydedip yanıt verin; video veya görselleri daha sonra indirin. Bir geri çağrı birden fazla kez gelebilir (örneğin yanıtınız yolda kaybolduysa). Bu yüzden her birini yalnızca bir kez işlemek için webhook-id kullanın.

Yeniden denemeler

Diğer tüm durumlarda (hata durumu, yönlendirme, 15 saniye içinde yanıt alınamaması veya sunucuya ulaşılamaması) yeniden denenir. Toplam altı deneme yapılır:

DenemeGönderim zamanı
1İşlem biter bitmez
21 dakika sonra
3Bundan 5 dakika sonra
4Bundan 30 dakika sonra
5Bundan 2 saat sonra
6Bundan 8 saat sonra, ardından başarısız olarak işaretlenir

Her geri çağrı, paneldeki İstekler bölümünde ilgili istekle birlikte görünür: nereye gönderildiği, her denemede alınan yanıt ve sonraki denemenin zamanı. Buradaki Geri çağrıyı yeniden dene, teslim edilmiş olsa da olmasa da geri çağrıyı hemen yeniden gönderir. İçindeki bağlantılar her denemede yenilenir.

Geri çağrılar yalnızca herkese açık internetteki https URL'lerine gönderilir: localhost, özel adresler veya bunlara çözümlenen adresler kullanılamaz. Yönlendirmeler takip edilmez, bu yüzden nihai URL'yi kullanın. Geliştirme sırasında denemek için bir tünel (ngrok, Cloudflare Tunnel) veya istek inceleme aracı kullanın.

Sorunuz mu var, yoksa bir şey mi eksik? Destek ekibimize sorun, genellikle bir dakika içinde e-postayla yanıtlayalım.