Pick a model
| Model | Strong for | Max duration | Notes |
|---|---|---|---|
veo-3-1 (Google) | Photorealism, motion coherence | 8 s | Slower, higher cost |
veo-3-1-fast | Iteration | 4 s | Default for prototyping |
sora-2 (OpenAI) | Long, narrative scenes | 20 s | Limited availability |
wan-2-1 (Alibaba) | Text-to-video | 6 s | PRC opt-in required |
grok-video | Realistic, low refusal | 6 s | xAI |
GET /v1/models?modality=video. Check allowedParams for supported resolution, aspect_ratio, duration_seconds.
Sample output
4-second clip fromveo-3.0-fast-generate-001, 16:9, prompt: “A vibrant tropical coral reef in crystal-clear turquoise water, colorful fish darting between coral, soft golden sunlight streaming down, slow cinematic dolly-in, rich saturated colors.”
Submit + poll pattern
The minimum viable client:python
Async with progress
In a UI, surfaceprogress (0–100) so users see motion:
node
job_id onto a queue and let a worker poll. Never block an HTTP request handler waiting for a video — the request will time out long before the video is ready.
Image-to-video
Animate a still image. Pass the source viaimage_url or inline base64:
python
Persistence
Theresult.url is already mirrored to our storage — it’s a signed URL pointing at GCS, not the upstream provider’s ephemeral URL. It survives upstream URL expiry.
To download or pin permanently:
python
result.mirror_status: "failed" so you can retry from your side.
Prompting
Video models reward physical coherence over visual fidelity:- Describe motion, not just appearance: “camera tracks left as the cyclist rides past” beats “a cyclist”.
- Specify subject continuity: “the same red car remains in frame throughout”.
- Limit complexity: 1–2 subjects, 1 camera move, 1 lighting condition.
- For people: shorter clips and specific actions (“nodding”, “turning to look at camera”) avoid the “wandering eyes” failure mode.
Cost ballpark
Per 4-second 720p clip:- Veo 3.1 fast: ~80 credits
- Veo 3.1: ~180 credits
- Sora 2: ~200 credits
- Wan 2.1: ~40 credits
When jobs fail
Common reasons:- Safety refusal from the provider — 400-class, won’t be retried by fallback. Reword and resubmit.
- Provider quota — 429 on the upstream. Configure a fallback chain and let a different model take it.
- Upstream timeout — rare; your job is auto-cancelled at 1 hour with
status: "failed"anderror: "timeout". Resubmit.
job_id is logged in Settings → Usage → Recent requests for traceability.
