Gemini video generation — Veo 3.1 via predictLongRunning
Status: DOCUMENTED · PREVIEW (all three Veo 3.1 ids are previews) · validation / error shapes LIVE_VERIFIED (no paid generation was run: $0.05–0.60 per second) · generatedFiles list LIVE_VERIFIED (200 {}) · Veo 3.0 / 2.0 DEPRECATED (shutdown 2026-06-30, absent from models.list).
Sources: Veo guide · Video overview (Omni vs Veo) · Pricing #veo-3.1 · Deprecations · Files guide · discovery v1beta rev. 20260918 (models.predictLongRunning, models.operations.*, generatedFiles.*) · python-genai types (GenerateVideosConfig, GenerateVideosResponse, VideoGenerationReferenceImage).
Last verified: 2026-09-18. Twins: generated/fragments/endpoints/gemini-media-batch-tuning.json (api_family video-generation, operations, files), generated/fragments/parameters/gemini-video-generation.json, generated/fragments/status-lifecycles/gemini-lifecycles.json.
Google now recommends Gemini Omni Flash (Interactions API,
gemini-omni-1.1-flash, conversational video editing) as the default video model; Veo 3.1 stays for extension, first/last-frame control and legacy pipelines. Omni is out of scope here (interactions agent).
1. Models (live list)
| Model id | supportedGenerationMethods |
Input limit | Status | Extension | Reference images | 4k |
|---|---|---|---|---|---|---|
veo-3.1-generate-preview |
predictLongRunning only |
480 tokens (guide: 1,024) | Preview (since 2025-10-15) | yes | yes (≤ 3) | yes |
veo-3.1-fast-generate-preview |
same | same | Preview | yes | yes | yes |
veo-3.1-lite-generate-preview |
same | same | Preview (2026-03-31) | no | no | no |
veo-3.0-generate-001, veo-3.0-fast-generate-001, veo-2.0-generate-001 |
— | — | deprecated 2025-09-09, shut down 2026-06-30 |
All Veo 3.x output: 24 fps, native audio always on, 1 video per request, SynthID watermark.
2. Lifecycle (long-running operation)
POST /v1beta/models/veo-3.1-generate-preview:predictLongRunning → 200 Operation {name:"models/veo-3.1-generate-preview/operations/<id>", done:false}
GET /v1beta/models/veo-3.1-generate-preview/operations/<id> → poll every ~10 s (11 s … 6 min)
done:true, response.generateVideoResponse.generatedSamples[0].video.uri
GET <uri> (https://generativelanguage.googleapis.com/v1beta/files/<id>:download?alt=media) -H x-goog-api-key -L → MP4done:true+error(google.rpc.Status) = blocked by safety/audio filters or invalid input; not billed.- Videos are stored 2 days (timer resets when a video is referenced for extension). They also surface in
GET /v1beta/generatedFiles(state GENERATING → GENERATED | FAILED). - No
:cancelexists for model operations (onlybatches/*:cancel). Webhooks can replace polling (docs/gemini/long-running-operations.md). - Request latency: min 11 s, max 6 min at peak.
3. Request body (PredictLongRunningRequest)
{
"instances": [{
"prompt": "Drone shot following a red convertible along a coastal road at sunset; engine roars.",
"image": {"inlineData": {"mimeType": "image/png", "data": "<base64>"}},
"lastFrame": {"inlineData": {"mimeType": "image/png", "data": "<base64>"}},
"referenceImages": [{"image": {"inlineData": {...}}, "referenceType": "asset"}],
"video": {"inlineData": {"mimeType": "video/mp4", "data": "<base64 of a previous Veo output>"}}
}],
"parameters": {"aspectRatio": "16:9", "resolution": "720p", "durationSeconds": "8", "personGeneration": "allow_all", "negativePrompt": "…", "seed": 42, "numberOfVideos": 1}
}| Field | Veo 3.1 / 3.1 Fast | Veo 3.1 Lite | Rules |
|---|---|---|---|
instances[].prompt |
string | string | Audio cues: quoted dialogue, SFX, ambience. English fully supported. |
instances[].image |
Image | Image | Image-to-video first frame. Not with video. |
instances[].lastFrame |
Image | Image | Interpolation; requires image. |
instances[].referenceImages[] |
≤ 3 {image, referenceType: asset|style} |
n/a | Requires prompt; not with image/video; durationSeconds must be 8; personGeneration allow_adult only. |
instances[].video |
Veo-generated video | n/a | Extension: +7 s per call, ≤ 20 times, input ≤ 141 s, output ≤ 148 s, 720p, 9:16/16:9, generated/referenced ≤ 2 days ago. Voice only extends if present in the last second. |
parameters.aspectRatio |
16:9 (default), 9:16 |
same | |
parameters.durationSeconds |
"4", "6", "8" |
same | Must be "8" with extension, reference images, 1080p or 4k. |
parameters.resolution |
720p (default), 1080p, 4k |
720p, 1080p |
1080p/4k → 8 s only; extension → 720p only. |
parameters.personGeneration |
text-to-video & extension allow_all; image/interpolation/reference allow_adult |
same minus extension | EU/UK/CH/MENA: allow_adult only. SDK also lists dont_allow. |
parameters.seed |
int | int | Improves, does not guarantee, determinism. |
parameters.negativePrompt, enhancePrompt, generateAudio, fps, compressionQuality, webhookConfig |
SDK GenerateVideosConfig fields |
UNVERIFIED at REST level; generateAudio is effectively always on. |
Only instances is required. Live validation (free): empty body → 400 INVALID_ARGUMENT "No instances in the request."; {"instances":[{}]} → 400 "Unsupported video generation request. Please check the documentation for supported usage: https://ai.google.dev/gemini-api/docs/video"; unknown model → 404 "models/veo-9-generate is not found for API version v1beta, or is not supported for predictLongRunning".
4. Response objects
- REST:
Operation.response = {"@type": "…PredictLongRunningResponse", "generateVideoResponse": {"generatedSamples": [{"video": {"uri": "…files/<id>:download?alt=media"}}], "raiMediaFilteredCount", "raiMediaFilteredReasons"}}(path used by the officialjqsamples). - SDK (
GenerateVideosOperation.response→GenerateVideosResponse):generated_videos[].video.{uri, video_bytes, mime_type},rai_media_filtered_count,rai_media_filtered_reasons[].client.files.download(file=video)fetches the bytes; the sameVideoobject is what you pass back asinstances[].videofor extension.
5. Pricing (paid tier only; per second of generated video, billed only on success)
| Model | 720p | 1080p | 4k |
|---|---|---|---|
veo-3.1-generate-preview |
$0.40 | $0.40 | $0.60 |
veo-3.1-fast-generate-preview |
$0.10 | $0.12 | $0.30 |
veo-3.1-lite-generate-preview |
$0.05 | $0.08 | not supported |
An 8-second 720p clip therefore costs $0.40 (Lite) to $3.20 (Standard). Free tier: not available. Rate limits: see AI Studio rate-limit page (not documented per model in the crawled pages).
6. generatedFiles and download
| Method | Path | Live 2026-09-18 |
|---|---|---|
| list | GET /v1beta/generatedFiles?pageSize=&pageToken= → {generatedFiles[]: {name, state, mimeType, error}, nextPageToken} |
200 {} (nothing generated) |
| operation | GET /v1beta/generatedFiles/{id}/operations/{op} |
bogus ids → 400 INVALID_ARGUMENT "Request contains an invalid argument." |
| download | GET https://generativelanguage.googleapis.com/v1beta/files/{id}:download?alt=media with x-goog-api-key, follow redirects |
Only model-generated files can be downloaded (files.download); user uploads cannot. |
7. Live log
| Call | Status |
|---|---|
POST …veo-3.1-lite-generate-preview:predictLongRunning {} |
400 No instances in the request. |
same, {"instances":[{}]} |
400 Unsupported video generation request… |
POST …veo-9-generate:predictLongRunning |
404 |
GET /v1beta/models/veo-3.1-lite-generate-preview/operations |
200 {} |
GET /v1beta/models/veo-3.1-lite-generate-preview/operations/bogus-op |
403 PERMISSION_DENIED You do not have permission to access the Operation with ID bogus-op or it may not exist. |
GET /v1beta/generatedFiles?pageSize=10 |
200 {} |
Cost: $0. Examples (examples/gemini/video-generation/) are UNVERIFIED end-to-end; they implement the documented flow and stop before paying unless ATLAS_ALLOW_PAID=1.