async-video-job-orchestrationlisted
Install: claude install-skill apimageorg/apimage-skills
# Async Video Jobs
**Video generation on APImage is always asynchronous.** `generate_video` returns a job ID immediately, not a video. This is the single most common source of double-billing, because the natural reaction to "no video came back" is to call it again.
Don't. Poll.
## The correct sequence
```
1. generate_video(...) → returns job_id, immediately
2. get_video_generation(id=...) → status: pending / processing
3. wait → a few seconds
4. get_video_generation(id=...) → status: completed, plus the URL
```
`get_video_generation` and `list_video_generations` are **free**. There is no cost reason to avoid polling and every reason to avoid regenerating.
```python
import time
job = generate_video(
mode="image-to-video",
model="flux-3-video-draft",
reference_images=[still],
prompt=prompt,
aspect_ratio="9:16",
duration=5,
seed=4271,
)
deadline = time.monotonic() + 600 # cap the wait
while time.monotonic() < deadline:
r = get_video_generation(id=job["id"])
if r["status"] == "completed":
break
if r["status"] == "failed":
break # already refunded. Read the error
time.sleep(5)
```
Three things in there matter:
- **A deadline.** An unbounded poll loop on a stuck job runs forever.
- **Handle `failed` explicitly.** Failed renders are already refunded — you don't need to reconcile credits, but you do need to read the error and fix the input