Veo 3.1 is one model behind two doors: the Gemini API on Google AI, Vertex AI on Google Cloud. Same video, different model ids and a different invoice. Most confusion around Veo 3.1 API pricing comes from mixing those surfaces.

What the Veo 3.1 API actually returns

Veo 3.1 generates 8-second clips at 720p, 1080p or 4k, with audio produced by the model rather than dubbed on afterwards. Four controls matter when you plan work: landscape 16:9 or portrait 9:16, first and last frames for interpolation, up to three reference images, and extension that continues a clip you already generated.

Two limits shape a pipeline more than they look. The prompt is capped at 1,024 tokens, and the parameter table lists one video per request, so four variants of one shot means four requests. Every output carries a SynthID watermark. If this is your first Google media API, the Gemini API getting started guide covers the plumbing this path reuses.

Two surfaces, two sets of model ids

Gemini API model ids

The Gemini API lists three Veo 3.1 ids, all in preview: veo-3.1-generate-preview, veo-3.1-fast-generate-preview and veo-3.1-lite-generate-preview. The previous generation stays documented but marked deprecated: veo-3.0-generate-001 and veo-3.0-fast-generate-001.

Vertex AI model ids and region

Vertex AI names the same three models differently: veo-3.1-generate-001, veo-3.1-fast-generate-001 and veo-3.1-lite-generate-001. The first two are generally available; Lite is still preview.

The model card lists availability in the United States, in us-central1, and a quota of 50 regional online prediction requests per minute per base model.

Your first request: REST against the Gemini API

A Google collage of Veo 3.1 video stills — balloons spilling through a workshop window, a dancer in silhouette, a candle-lit figure, a cowboy on horseback and a woman in a gilded hallway — with the white Veo 3.1 wordmark across the centre
Google

Veo is a long-running operation, so the call has two halves: submit, then poll.

# Requires curl and jq.
BASE_URL="https://generativelanguage.googleapis.com/v1beta"
VEO_MODEL="veo-3.1-generate-preview"

# 1. Submit the job and keep the operation name.
operation_name=$(curl -s "${BASE_URL}/models/${VEO_MODEL}:predictLongRunning" \
  -H "x-goog-api-key: ${GEMINI_API_KEY}" \
  -H "Content-Type: application/json" \
  -X POST \
  -d '{
    "instances": [
      {
        "prompt": "A slow dolly shot through a rain-soaked neon alley at night, reflections on wet asphalt, distant traffic and light rain."
      }
    ],
    "parameters": {
      "aspectRatio": "16:9",
      "resolution": "1080p",
      "durationSeconds": "8"
    }
  }' | jq -r .name)

# 2. Poll until the operation reports done.
while true; do
  status=$(curl -s -H "x-goog-api-key: ${GEMINI_API_KEY}" "${BASE_URL}/${operation_name}")
  if [ "$(echo "${status}" | jq .done)" = "true" ]; then
    video_uri=$(echo "${status}" | jq -r '.response.generateVideoResponse.generatedSamples[0].video.uri')

    # 3. Download in the same run: the server keeps the file for two days.
    curl -L -o out.mp4 -H "x-goog-api-key: ${GEMINI_API_KEY}" "${video_uri}"
    break
  fi
  sleep 10
done

Three details carry the weight. The verb is predictLongRunning, not generateContent. The submit call returns only an operation name, which is why the loop exists. And the video is addressed by a URI that expires.

durationSeconds accepts "4", "6" or "8", but 1080p and 4k output has to be 8 seconds. A 4-second 4k request is rejected, not shortened.

The same call through the Python SDK

import time

from google import genai
from google.genai import types

client = genai.Client()  # reads GEMINI_API_KEY from the environment

operation = client.models.generate_videos(
    model="veo-3.1-fast-generate-preview",
    prompt=(
        "A macro shot of espresso pouring into a glass cup, steam rising, "
        "warm window light, quiet cafe ambience, no dialogue."
    ),
    config=types.GenerateVideosConfig(
        aspect_ratio="9:16",
        number_of_videos=1,
        resolution="720p",
    ),
)

while not operation.done:
    time.sleep(10)
    operation = client.operations.get(operation)

video = operation.response.generated_videos[0].video
client.files.download(file=video, destination="espresso.mp4")

The SDK wraps the identical operation, polling loop included. Two habits matter: keep the model id in the environment, and log the operation name, which is your only handle if the process dies mid-poll.

Generating on Vertex AI

Vertex AI needs more scaffolding before the first frame: a Cloud project, application credentials, and a Cloud Storage bucket, because video comes back as a gs:// URI instead of inline bytes.

import time

from google import genai
from google.genai.types import GenerateVideosConfig

# export GOOGLE_CLOUD_PROJECT=<project>
# export GOOGLE_CLOUD_LOCATION=<location>
# export GOOGLE_GENAI_USE_ENTERPRISE=True
client = genai.Client()

output_gcs_uri = "gs://your-bucket/veo/"  # must already exist

operation = client.models.generate_videos(
    model="veo-3.1-generate-001",
    prompt="A heron standing perfectly still in shallow water at dawn, mist on the surface.",
    config=GenerateVideosConfig(
        aspect_ratio="16:9",
        output_gcs_uri=output_gcs_uri,
    ),
)

while not operation.done:
    time.sleep(15)
    operation = client.operations.get(operation)

if operation.response:
    print(operation.result.generated_videos[0].video.uri)

Three differences bite when code moves between the surfaces. The model id loses its -preview suffix and gains a version. output_gcs_uri is how you keep a durable file. And Vertex adds negativePrompt, seed, a personGeneration setting accepting "allow_adult" or "disallow", and sampleCount from 1 to 4.

What the official pricing pages publish

Both pages list Veo 3.1, in different units. The Gemini API quotes a rate per second. Vertex AI quotes a rate per count, and splits audio generation from silent generation.

ModelGemini API, paid tier per secondVertex AI, per count
Veo 3.1$0.40 at 720p and 1080p, $0.60 at 4kVideo with audio $0.40, video only $0.20, 4k $0.60 / $0.40
Veo 3.1 Fast$0.10 at 720p, $0.12 at 1080p, $0.30 at 4kVideo with audio $0.10 / $0.12 / $0.30, video only $0.08 / $0.10 / $0.25
Veo 3.1 Lite$0.05 at 720p, $0.08 at 1080p, no 4k outputVideo with audio $0.05 / $0.08, video only $0.03 / $0.05

Three things those pages state plainly. Veo 3.1 has no free tier on the Gemini API, where the row reads “Not available”. Audio sits inside the per-second price. And a blocked generation is not billed: you are charged only when generation succeeds.

Costing a batch before you commit

One 8-second clip at 1080p on the standard model is 8 × $0.40, so $3.20. On Fast it is $0.96, on Lite $0.64. Multiply by your retry rate rather than your shot list, because a generation stopped by a safety filter costs nothing while one that succeeds and is unusable costs full price.

Quota, retention and retries

Vertex AI publishes one hard number: 50 regional online prediction requests per minute per base model. The Gemini API publishes a 1,024-token input cap and a latency range of 11 seconds to 6 minutes at peak. That spread will time out any synchronous design, so poll with a ceiling and a retry budget.

Generated videos are deleted from the server after two days, and extended videos count as new generations, which restarts the clock.

Before you paste a key into a front-end file, read how Google expects API keys to be handled. A key a browser can read is a public key. If you also generate stills, our Nano Banana Pro API walkthrough covers the same habits on the image side.

Frequently asked questions

Is there a free tier for the Veo 3.1 API? The Gemini API pricing table says “Not available”. Vertex AI has none either, and trial credits on a new Cloud account are a separate thing.

Should I use the Gemini API or Vertex AI? Gemini API for the shortest path to a running request. Vertex AI when you already run on Google Cloud, want the model inside your own IAM and quotas, or want output written to a bucket you control.

Why do the two pages quote different prices for the same model? They price different units. The Gemini API publishes one rate per second of video. Vertex AI publishes a per-count rate and charges audio and silent generation separately.

Does the API cost more than using Veo in the Gemini app? They are different products: the app is a subscription, the API is metered per second. Our comparison of the app and the API covers when the subscription is the cheaper answer.

How long does one generation take? Google publishes 11 seconds as the minimum and 6 minutes at peak. Size the polling loop for the maximum, not the average.

Wire up the submit-and-poll loop, keep the model id in configuration, and fold your retry rate into the price. Those three decisions settle whether the Veo 3.1 API fits your pipeline.