पोलिंग की ज़रूरत नहीं। जैसे ही कोई जनरेशन पूरा होता है, Flixly आपके URL पर एक साइन किया हुआ इवेंट POST कर देता है — चाहे रिक्वेस्ट sync रही हो (इमेज मॉडल) या async (वीडियो मॉडल, धीमी क़तारें)।
हर डिलीवरी पर `${timestamp}.${body}` का सिग्नेचर होता है, ताकि आप पुष्टि कर सकें कि वह वाकई हमारी ओर से आया है और उससे कोई छेड़छाड़ नहीं हुई।
X-Flixly-Timestamp हेडर से आप लगभग 5 मिनट से पुराने सिग्नेचर अस्वीकार कर सकते हैं — पकड़े गए रिक्वेस्ट के दोबारा भेजे जाने से बचाव।
एक्सपोनेंशियल बैकऑफ़ के साथ 3 प्रयास (तुरंत, +2s, +6s)। हर प्रयास पर 5 सेकंड का टाइमआउट। /generations/{id} को पोल करना आपका फ़ॉलबैक है।
हर API key का अपना webhook सीक्रेट होता है। उसे डैशबोर्ड से कभी भी रोटेट करें — पुराने सिग्नेचर तुरंत वेरिफ़िकेशन में फ़ेल होने लगते हैं।
Flixly को यह बताने के दो तरीके हैं कि आपके इवेंट कहाँ POST करने हैं:
हर API key पर एक डिफ़ॉल्ट webhook URL सेट करें और साइनिंग सीक्रेट जनरेट करें। उस key से भेजा गया हर जनरेशन उसी URL पर डिलीवर होगा।
POST बॉडी में webhook_url देकर हर रिक्वेस्ट पर key का डिफ़ॉल्ट ओवरराइड करें। एक-बार के डेस्टिनेशन या एनवायरनमेंट के हिसाब से रूटिंग के लिए उपयोगी।
POST /api/v1/generate
{
"model": "veo-3-fast",
"prompt": "...",
"webhook_url": "https://you/hook"
}हर पूरे हुए (या फ़ेल हुए) जनरेशन पर एक POST। JSON बॉडी, साइन किए हुए हेडर।
POST https://your-server.example.com/flixly-webhook
Content-Type: application/json
User-Agent: Flixly-Webhook/1.0
X-Flixly-Event: generation.completed
X-Flixly-Timestamp: 1781085600
X-Flixly-Signature: sha256=abc123...
X-Flixly-Delivery-Id: wh_a1b2c3d4e5f6g7h8{
"event": "generation.completed",
"id": "j5h2k9...",
"status": "completed",
"type": "TEXT_TO_IMAGE",
"model": "flux-dev",
"output_url": "https://cdn.flixly.ai/outputs/...",
"credits_charged": 1,
"error": null,
"created_at": "2026-06-06T12:00:00Z",
"completed_at": "2026-06-06T12:00:05Z"
}generation.completed या generation.failed।POST /api/v1/generate से मिला था और जिसे आप GET /api/v1/generations/{id} के साथ इस्तेमाल करते हैं।completed या failed।null।null। यह पहले से सैनिटाइज़ है — अपने यूज़र्स को सीधे दिखाना सुरक्षित है।हम हर डिलीवरी को `${timestamp}.${body}` पर HMAC-SHA256 से साइन करते हैं। आप उसी सीक्रेट से, जो जनरेट करते समय हमने आपको दिखाया था, अपने सर्वर पर HMAC दोबारा निकालते हैं और कॉन्स्टेंट टाइम में तुलना करते हैं।
JSON.parse → JSON.stringify से व्हाइटस्पेस और फ़ील्ड का क्रम बदल जाता है, जिससे सिग्नेचर टूट जाता है। Express में raw-body मिडलवेयर लगाएँ। Next.js App Router में await req.json() से पहले await req.text() कॉल करें।
import { Flixly } from "@flixly/sdk";
// In your webhook handler — Express, Hono, Next.js, etc.
export async function POST(req) {
const rawBody = await req.text(); // MUST be raw — re-stringifying breaks the signature
const signature = req.headers.get("x-flixly-signature");
const timestamp = req.headers.get("x-flixly-timestamp");
const valid = await Flixly.verifyWebhookSignature({
secret: process.env.FLIXLY_WEBHOOK_SECRET,
timestamp,
signature,
body: rawBody,
tolerance: 300, // optional — defaults to 300s replay window
});
if (!valid) {
return new Response("invalid signature", { status: 401 });
}
const event = JSON.parse(rawBody);
// event.event === "generation.completed" | "generation.failed"
// event.id, event.status, event.output_url, event.credits_charged, ...
await handleGenerationEvent(event);
return new Response("ok");
}sync हो या async, हर डिलीवरी एक ही पैटर्न पर चलती है:
2xx रिस्पॉन्स। कहने को कुछ न हो तो खाली बॉडी के साथ 200 OK लौटा दें।301, 302 और बाक़ी 3xx रिस्पॉन्स को फ़ेल्योर मानते हैं — वे अगले hop पर X-Flixly-Signature हेडर को चुपचाप हटा देंगे।हर डिलीवरी के साथ एक यूनीक X-Flixly-Delivery-Id हेडर आता है। अगर रीट्राई की वजह से वही इवेंट आपको दो बार मिल जाए (जैसे हमारा रीट्राई चल पड़ा हो, पर आपका पहला रिस्पॉन्स हम तक पहुँचने में बहुत देर लगा हो), तो अपनी तरफ़ डीडुप्लिकेशन के लिए उसी हेडर का इस्तेमाल करें।
इवेंट का id फ़ील्ड जनरेशन id है — एक ही डिलीवरी के सभी रीट्राई में वही रहता है। X-Flixly-Delivery-Id हर प्रयास पर तभी बदलेगा जब हम payload दोबारा बनाएँ (फ़िलहाल हम ऐसा नहीं करते)।