Completion: polling, not webhooks
There is no webhook_url parameter on POST /api/v1/generate today. When a video is ready, you learn it by polling GET /api/v1/status/{id} until the status is completed or failed.
Payment provider webhooks (Dodo, Mollie) exist for billing only. They do not notify you that a generation finished.
How long to wait
| Model family | Typical time | Suggested polling |
|---|---|---|
| FLUX 3 Max | ~12s | Every 3-5s |
| Seedance 2.0, Grok Imagine 1.5, LTX-2 | ~30s | Every 5-10s |
| Veo 3 Fast, Higgsfield, Wan 2.5 | 45-60s | Every 10s |
| MiniMax H3, Veo 2 | 90-110s | Every 15s |
| Seedance 2.5, Kling 3 | 150-250s | Every 15-20s |
These are catalogue averages; queue load and longer durations add time. A 10-minute timeout covers every model. Status checks do not count against generation rate limits.
Pattern 1: wait inline (scripts, CLIs)
For a script or a one-off job, submit and poll in the same process. The status page has a complete Python function, and the example script does the full round trip.
Pattern 2: background worker (web apps)
In a web app, do not keep the user's HTTP request open for minutes. Store the generation_id, return immediately, and let a worker resolve pending jobs:
# 1. Request handler: submit and persist
gen_id = submit_generation(prompt) # POST /api/v1/generate
db.insert(job_id=gen_id, status="in_progress", user_id=user.id)
# 2. Worker (cron every 15s, or a queue consumer)
for job in db.select(status="in_progress"):
data = get_status(job.job_id) # GET /api/v1/status/{id}
if data["status"] in ("completed", "failed"):
db.update(job.job_id, status=data["status"], video_url=data.get("video_url"))
notify(job.user_id) # websocket, email, push...
Your own notify() step is effectively the webhook: your front end listens to your backend, and your backend polls VideoGenAPI.
Pattern 3: no-code (n8n, Make, Zapier)
Use an HTTP node to submit, a Wait node of 15-30 seconds, then a status request inside a loop that exits on completed or failed. The n8n guide shows the full workflow.
Good practice
- Persist the generation_id as soon as you receive it, so a restart does not lose a paid generation.
- Do not resubmit on a slow job. A job still
in_progressafter a few minutes is usually queued, not lost; resubmitting doubles your usage. - Download the video to your own storage once completed if you need it long-term.
- Back off on errors. If the status call itself fails, wait longer before the next attempt (see error codes).