Async & Polling
All Fluxpool generations are asynchronous — the initial POST returns immediately with a generation id and a presigned S3 URL. This page covers how to check when your generation is ready.
Webhooks are coming soon
Webhook delivery is on the roadmap. Until then, please poll — either the shared generation-status endpoint, or the presigned S3 URL that the initial response hands you.
If you were expecting a webhook_url parameter on the generation endpoints: the ingestion Lambda currently accepts the field but does not deliver callbacks. Don't rely on it.
Two polling patterns
The initial POST response looks like this:
{
"created": 1785845810,
"id": "6dcc89ce-964e-466e-8100-ba2bdfb6d07c",
"status": "pending",
"model": "flux-2-pro",
"type": "image",
"data": [
{
"url": "https://fluxpool-output.s3.ap-southeast-1.amazonaws.com/...?X-Amz-...",
"generation_id": "6dcc89ce-964e-466e-8100-ba2bdfb6d07c",
"status": "pending",
"model": "flux-2-pro",
"revised_prompt": null
}
]
} You have two ways to know when it's done:
Option 1 — Poll the generation-status endpoint
Best for structured status information (progress, errors, model name).
curl https://api.fluxpool.ai/v1/generations/6dcc89ce-964e-466e-8100-ba2bdfb6d07c \
-H "Authorization: Bearer fp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" Poll every 3 seconds until status is "completed". Possible values: pending, processing, completed, failed.
Option 2 — Poll the presigned S3 URL directly
Cheaper — bypasses the Fluxpool API entirely. Best for image workloads where you just want the bytes.
curl -I --range 0-0 "https://fluxpool-output.s3.ap-southeast-1.amazonaws.com/...?X-Amz-..." Important: S3 presigned GET URLs reject HEAD requests with a 403. Use GET with Range: bytes=0-0 for a cheap readiness probe — you'll get a 200 and one byte when the file is available.
Presigned URL expiry
Every presigned URL is valid for 1 hour from the moment the generation was submitted (controlled by the PRESIGNED_URL_EXPIRY environment setting, currently 3600 seconds).
Persist the file to your own storage promptly once it's ready — after the URL expires you'll need a fresh one from GET /v1/generations/{id}.
Complete Python example
import time
import requests
API_KEY = "fp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
headers = {"Authorization": f"Bearer {API_KEY}"}
# 1. Submit
submit = requests.post(
"https://api.fluxpool.ai/v1/videos/generations",
headers=headers,
json={
"model": "seedance-v2",
"prompt": "A drone shot over a coral reef",
"duration": 5,
"resolution": "720p",
},
).json()
gen_id = submit["id"]
# 2. Poll status
while True:
status = requests.get(
f"https://api.fluxpool.ai/v1/generations/{gen_id}",
headers=headers,
).json()
if status["status"] == "completed":
video_url = status["data"][0]["url"]
break
if status["status"] == "failed":
raise RuntimeError(status.get("error", "generation failed"))
time.sleep(3)
# 3. Persist to your own storage before the URL expires (1 hour).
open("video.mp4", "wb").write(requests.get(video_url).content)