Veo 3.1
Generate Veo 3.1 video clips through one task API: three models priced per 8-second clip and two priced per second, with frames, audio and GIF output.
Veo 3.1 is Google's video generation model. SeedRouter offers it as five model IDs on one endpoint: three priced per clip, every clip 8 seconds long, and two priced per second with more controls (duration, audio, seed, negative prompt, first and last frame). Send the request, keep the returned task ID, and read the finished video from the task. Images go in as URLs.
Model IDs
| Model ID | Billing | Length | Images | Audio |
|---|---|---|---|---|
veo-3.1-fast | per clip | 8 seconds | up to 3, frame or reference mode | no switch |
veo-3.1-quality | per clip | 8 seconds | up to 3, frame mode | no switch |
veo-3.1-lite | per clip | 8 seconds | none (text to video) | no switch |
veo-3.1-fast-official | per second | 4, 6 or 8 seconds | first and last frame | generate_audio |
veo-3.1-quality-official | per second | 4, 6 or 8 seconds | first and last frame | generate_audio |
See the model page for current prices.
Quick example
curl https://api.seedrouter.ai/v1/videos/generations \
-H "Authorization: Bearer $SEEDROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "veo-3.1-fast",
"prompt": "A red paper boat drifts across a calm pond at sunrise, soft mist on the water, slow push-in on a 35mm lens, no text, no logos.",
"resolution": "720p",
"aspect_ratio": "16:9"
}'Endpoint
POST https://api.seedrouter.ai/v1/videos/generations| Header | Value |
|---|---|
| Authorization | Bearer YOUR_API_KEY |
| Content-Type | application/json |
The response is a task ({"id": "task_...", "status": "processing"}), not the finished video. Poll GET /v1/tasks/{task_id} for the result. Keep API keys in server-side code.
Parameters: per-clip models
veo-3.1-fast, veo-3.1-quality and veo-3.1-lite.
| Field | Type | Default | Notes |
|---|---|---|---|
model | string | required | One of the three IDs above. |
prompt | string | required | Describes the shot. |
duration | integer | 8 | Only 8 is accepted. |
aspect_ratio | enum | 16:9 or 9:16. | |
resolution | enum | 720p | 720p, 1080p or 4k (any case). veo-3.1-lite has no 4k. |
enable_gif | boolean | false | Return the clip as an animated GIF instead of MP4. 720p only. |
nsfw_check | boolean | false | Check the prompt and images for unsafe content before generating. |
image_urls | array | Fast and Quality only. Up to 3 public image URLs. | |
generation_type | enum | by image count | Fast and Quality only. frame or reference; Quality takes frame only. |
Parameters: per-second models
veo-3.1-fast-official and veo-3.1-quality-official.
| Field | Type | Default | Notes |
|---|---|---|---|
model | string | required | One of the two IDs above. |
prompt | string | required | Describes the shot. |
negative_prompt | string | What to keep out of the clip. | |
duration | integer | 8 | 4, 6 or 8 seconds. |
aspect_ratio | enum | 16:9 | 16:9 or 9:16. |
resolution | enum | 720p | 720p, 1080p or 4k (any case). |
first_frame_image | string | Public image URL. The clip opens on it. | |
last_frame_image | string | Public image URL. Needs first_frame_image. | |
seed | integer | random | 0 to 4294967295. |
generate_audio | boolean | false | Add an audio track. Billed at a higher per-second rate. |
person_generation | enum | allow_adult | allow_adult or disallow. |
resize_mode | enum | pad | pad or crop. Needs first_frame_image. |
enhance_prompt | boolean | true | Only true is accepted; omit the field otherwise. |
nsfw_check | boolean | false | Check the prompt and images for unsafe content before generating. |
The schema is strict: unknown fields are rejected rather than ignored, and each model takes only its own fields. Callbacks are not available; poll the task instead.
Image modes
On veo-3.1-fast and veo-3.1-quality, generation_type sets how image_urls are used:
generation_type | Images | Effect |
|---|---|---|
frame | 1 or 2 | The first image is the first frame, the second the last frame. |
reference | up to 3 | The images are references for the subject and style. Fast only. |
| omitted | 2 or 3 | Two images use frame mode, three use reference mode. |
veo-3.1-quality does not run reference mode, so it refuses generation_type: "reference" and three images without a generation_type. veo-3.1-lite takes no images.
On the per-second models, set first_frame_image and, optionally, last_frame_image. resize_mode chooses whether an image of another shape is padded or cropped.
Media inputs
Images are public HTTP(S) URLs:
{ "image_urls": ["https://example.com/first.jpg", "https://example.com/last.jpg"] }On the per-clip models each image is JPEG, PNG or WebP and at most 10 MB; a file that breaks these rules fails the task without a charge. Base64 data is not accepted: upload the file to your own storage and pass its URL.
Pricing dimensions
Check the model pricing section for current rates.
per-clip models: cost = price of one clip at the output resolution (720p and 1080p cost the same)
per-second models: cost = duration × rate for the resolution and audio settingThe charge is fixed when the request is accepted, so the amount reserved is the amount charged. View final charges in your account usage history. Failed tasks are not charged.
Output schema
Submission returns the task:
{"id": "task_...", "model": "veo-3.1-fast", "status": "processing", "created_at": 1789689600}Get the task
GET https://api.seedrouter.ai/v1/tasks/{task_id}Poll every 10–20 seconds until status is completed or failed. A network timeout while polling does not mean generation failed: keep the task ID and resume checking it. Do not create another task to check progress.
Completed task
{
"id": "task_...",
"model": "veo-3.1-fast",
"status": "completed",
"created_at": 1789689600,
"finished_at": 1789689720,
"output": {
"video_url": "https://static.seedrouter.ai/media/tasks/task_example/0.mp4"
}
}video_url is an MP4, or a GIF when the request set enable_gif. The link is on SeedRouter's storage.
What our test runs returned (one run each, 2026-10-04):
| Request | File |
|---|---|
veo-3.1-fast, 9:16, frame mode | MP4, H.264, 720 × 1280, 24 fps, 8 s, with a stereo AAC audio track |
veo-3.1-fast-official, 16:9, 720p, 4 s, no generate_audio | MP4, H.264, 1280 × 720, 24 fps, 4 s, no audio track |
veo-3.1-lite, enable_gif | GIF, 480 × 270, 16 fps, 8 s |
The per-clip models have no audio switch; the per-second models add an audio track only with generate_audio.
Errors
Requests rejected before a task is created return an HTTP error with an error object and are not charged. A task that fails after acceptance returns HTTP 200 when queried, with status: "failed" and an error object.
See the shared error catalog for codes, HTTP statuses, and retry guidance.
{
"id": "task_...",
"model": "veo-3.1-fast",
"status": "failed",
"error": {
"code": 60001,
"message": "The request was rejected by the content policy. Please revise the prompt or input images."
}
}If submission itself times out, check your tasks before submitting again: the first request may have been accepted.
Tips
- Start on
veo-3.1-liteorveo-3.1-fastat 720p to try a prompt, then move to Quality or 4k for the final render. - Name the camera and the light: a lens and a camera move change the shot more than adjectives do.
- Add
no text, no logosto keep invented lettering and marks out of the frame. - For a shot that must start and end on known images, use frame mode with two images, or the per-second models with
first_frame_imageandlast_frame_image. - Fix
seedon the per-second models and change one clause at a time to iterate on a shot.
