Pipelines3 min read

Async Webhooks for GPT Image 2 Batches on fal.ai

Fire a thousand renders, walk away, and pick up the results when the webhook fires. The production-grade batch pattern.


If you need to render a thousand images without blocking your request worker, the fal.ai webhook pattern is the answer. Submit the job, hand fal.ai a URL, walk away, and pick up the result when fal.ai posts to your endpoint. This is how you run a bulk catalog update without paying for a compute instance that sits idle for hours.

The submit call

example.tsTS
1const { request_id } = await fal.queue.submit("fal-ai/gpt-image-2", {
2 input: {
3 prompt: "...",
4 image_size: "1024x1024",
5 quality: "medium",
6 num_images: 1,
7 output_format: "png",
8 },
9 webhookUrl: "https://your-app.com/api/fal-webhook?sku=ABC123",
10});
11
12await persistPending(request_id, { sku: "ABC123" });

You get a request_id immediately. Store it alongside your business key (sku, campaign, asset slug). The worker moves on.

The webhook handler

example.tsTS
1export async function POST(request: Request) {
2 const body = await request.json();
3 const { request_id, status, data } = body;
4 if (status !== "OK") return new Response(null, { status: 204 });
5 const asset = await lookupPending(request_id);
6 await persistResult(asset.sku, data.images[0].url);
7 return new Response(null, { status: 204 });
8}

fal.ai signs the webhook with an HMAC header. Verify the signature before you trust the payload.

Throughput

A single submit takes about 100ms. You can push a thousand jobs into the queue in under two minutes, then let fal.ai run them at its own concurrency and post results as they complete. Your worker never blocks.

A sequence diagram showing submit, queue, and webhook steps
A sequence diagram showing submit, queue, and webhook steps

Also reading