Mindket

Veo tutorial: make an AI video with the Gemini API

A black banner titled "AI video" over the line "Sora, Veo, video prompts and open models".

To make a video with Veo in code, install Google's google-genai package, create a client with a Gemini API key and call generate_videos with a prompt. Then poll the job until it finishes and save the MP4. Veo 3.1 makes 4, 6 or 8 second clips at 720p or 1080p, with sound, and Google lists it as a paid feature.

In this lesson

  • Call generate_videos with a prompt, then poll the operation and save the file.
  • Put aspect ratio, resolution and a negative prompt in the config object.
  • Start from a picture, pin an end frame or pass up to three references to hold a look.
  • Switch to Gemini Omni when you want to edit a clip by talking to it.
All courses
On this page
  1. Before you start: three model IDs and a paid feature
  2. Make your first clip
  3. The settings you can add
  4. Describe the sound in the prompt
  5. Start from a picture, then pin the ending
  6. References, and making a clip longer
  7. Gemini Omni, the other video model in the cookbook
  8. Common mistakes
  9. Try it yourself
  10. Next: write better video prompts
  11. Check yourself
  12. Frequently asked questions
  13. Sources

Before you start: three model IDs and a paid feature

Veo is Google's video model. You reach it through the Gemini API, which lets your own code send a request to Google's servers and get a video back. A package called google-genai, the SDK, wraps those requests. Google's Veo notebook marks Veo as paid, so its sample code stays switched off until you set a flag yourself.

You need a Gemini API key from Google AI Studio and SDK version 2.9.0 or newer. Veo 3 and later make sound along with the picture. Veo 2 is still available for a while but makes silent video. If you would rather not write code, Mindket's lesson on making AI videos with Gemini and Flow walks through Google's apps and their menus.

Google Cloud Tech, one of Google's own channels, has an introduction to Veo of under five minutes, published in November 2025. Its chapter list covers prompt optimization, configurable parameters and image-to-video generation, the same ground as the sections below. Its description speaks of Google Cloud's Veo model and links Vertex AI Studio, so expect Google Cloud's screens rather than this lesson's Gemini API code. Take the code from the notebook.

From Google's Get started with Veo notebook, read on 6 November 2026.
Model IDWhat the notebook says
veo-3.1-generate-previewThe full Veo 3.1. The only one the notebook uses for reference images
veo-3.1-fast-generate-previewA faster, more accessible version, suggested for ads, A/B tests and social content
veo-3.1-lite-generate-previewThe notebook's default. Called cost-effective, built for high-throughput 720p and 1080p
Google Cloud Tech on YouTube, November 2025: an introduction to Veo on Google Cloud.

Make your first clip

A video takes about a minute to make, according to the notebook, so generate_videos, the SDK's function for asking for one, does not return a finished video. It returns an operation, which is a job still running. You ask for its state every 20 seconds until it reports done, then download the files and save them.

The code below is the notebook's text-to-video cell. The one change is the key: the notebook reads it from a Colab secret named GEMINI_API_KEY, and this version reads an environment variable of the same name.

import os
import time

from google import genai
from google.genai import types

client = genai.Client(api_key=os.environ["GEMINI_API_KEY"])
VEO_MODEL_ID = "veo-3.1-lite-generate-preview"

operation = client.models.generate_videos(
    model=VEO_MODEL_ID,
    prompt="a close-up shot of a golden retriever playing in a field of sunflowers",
    config=types.GenerateVideosConfig(
        aspect_ratio="16:9",
        resolution="1080p",
    ),
)

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

for n, generated_video in enumerate(operation.result.generated_videos):
    client.files.download(file=generated_video.video)
    generated_video.video.save(f"video{n}.mp4")
  1. Install the SDK with pip install -U "google-genai>=2.9.0".
  2. Create a Gemini API key in Google AI Studio and keep it out of your code, in an environment variable named GEMINI_API_KEY.
  3. Pick a model ID. The notebook starts with veo-3.1-lite-generate-preview.
  4. Call generate_videos with a prompt and a config. aspect_ratio takes "16:9" or "9:16", and resolution takes "720p" or "1080p".
  5. Check client.operations.get on a timer until operation.done is true.
  6. Download each generated video and save it as an MP4.

The notebook skips the paid calls unless a flag at the top is set to True. Add your own guard before you loop over many prompts.

The settings you can add

The prompt is the only required argument. Everything else is optional and goes in the config object. A negative prompt is a short list of things you do not want to see, such as the notebook's "airplanes" in its unicorn example.

For the wording of the prompt, the notebook points to shot composition ("single shot", "over-the-shoulder shot") and camera position and movement ("eye level", "dolly shot", "tracking shot"). It adds focus and lens effects ("shallow focus", "macro lens") and overall style.

The notebook's list of optional parameters.
SettingWhat it takes
negative_promptText describing what you do not want in the video
person_generationWhether adults may appear. Children are always blocked
duration_seconds4, 6 or 8 with Veo 3.1. Always 8 with Veo 3, and 7 when extending
aspect_ratio"16:9" for widescreen or "9:16" for vertical
resolution"720p" or "1080p"

Describe the sound in the prompt

Veo 3 makes audio from the same prompt, so sound goes into the sentence like any other detail. The notebook's audio example is below. It names the sights and the sounds together and says where the listener stands.

For speech, the notebook writes each line in quotes inside the prompt and adds a negative prompt of "texts, captions, subtitles" to the call. Both use the same generate_videos code as before.

fireworks at a beautiful city skyline scene with many different fireworks colors and sounds. sounds from excited people enjoying the show surrounding the camera POV can be heard too.

Start from a picture, then pin the ending

An image argument makes the picture the first frame, and the prompt says what moves. The prompt may even be empty. The notebook says that with no prompt the model decides what to generate from the picture.

To control where the clip ends, add last_frame to the config. The notebook is clear that an ending image never works alone: you always pass a starting image too. In the cell below, gemini_image and ending_image are pictures the notebook made earlier with a Gemini image model, and you can load your own instead. The image editing lesson covers making them.

operation = client.models.generate_videos(
    model=VEO_MODEL_ID,
    prompt="",
    image=gemini_image,
    config=types.GenerateVideosConfig(
        aspect_ratio="16:9",
        resolution="1080p",
        negative_prompt="ugly, low quality, static, weird physics",
        last_frame=ending_image,
    ),
)

References, and making a clip longer

Reference images hold a character, a prop or a style across a clip without making any of them the first frame. Each goes in as a reference image marked as an asset. The notebook limits this to Veo 3.1 but not the Fast model, at 720p and in widescreen.

Extending is a separate argument. You pass an earlier Veo video as video, with an optional prompt, and Veo adds 7 more seconds.

backpack_reference = types.VideoGenerationReferenceImage(
    image=backpack_image,
    reference_type="asset",
)
actor_reference = types.VideoGenerationReferenceImage(
    image=actor_image,
    reference_type="asset",
)

operation = client.models.generate_videos(
    model="veo-3.1-generate-preview",
    prompt="A caricatural commercial video for this backpack. The actor puts on the backpack, jumps on his motorbike and starts off with a bang and an epic music",
    config=types.GenerateVideosConfig(
        aspect_ratio="16:9",
        resolution="720p",
        reference_images=[backpack_reference, actor_reference],
    ),
)
  • A clip you extend must come from Veo, be 720p and be under 141 seconds long.
  • The finished video can reach 148 seconds, which the notebook puts at about 20 extensions of a first 8 second clip.
  • Extension runs with the same call as before, passing video instead of image.

Gemini Omni, the other video model in the cookbook

Google's Omni notebook covers Gemini Omni 1.2 Flash, which uses a different call, the Interactions API, and needs google-genai 2.21.0 or newer. An interaction keeps state: you name an earlier one with previous_interaction_id and the model edits or extends that clip.

The notebook's multi-turn cells are below. The first makes a clip from a prompt with a timecode, and the second changes only the car color. Google advises short, surgical edit prompts, and its example ends with "Keep everything else the same."

The notebook's own advice is to prefer Omni for conversational editing, complex prompts and many references, and Veo for standalone batch jobs. The table sets the two side by side.

Limits the notebooks state

148 s

longest Veo video after extending

Source: GitHub: google-gemini/cookbook, Get started with Veo notebook (read November 6, 2026)

3

reference images in Veo 3.1

Source: GitHub: google-gemini/cookbook, Get started with Veo notebook (read November 6, 2026)

15 s

longest Omni clip

Source: GitHub: google-gemini/cookbook, Gemini Omni notebook (read November 6, 2026)

6

reference images in Omni

Source: GitHub: google-gemini/cookbook, Gemini Omni notebook (read November 6, 2026)

turn1 = client.interactions.create(
    model="gemini-omni-1.2-flash",
    input="[0-10s] Single unbroken continuous camera shot from a locked perspective gliding forward along a scenic coastal road at sunset. A sleek silver sports car cruises smoothly in front of the camera. Completely continuous unbroken take.",
    response_format={"type": "video"},
)

turn2 = client.interactions.create(
    model="gemini-omni-1.2-flash",
    previous_interaction_id=turn1.id,
    input="Change the car color to metallic blue. Keep everything else the same.",
)
From the two Google notebooks, read on 6 November 2026. Mindket put the rows side by side.
Veo 3.1Gemini Omni 1.2 Flash
Callclient.models.generate_videosclient.interactions.create
Clip length4, 6 or 8 seconds3 to 15 seconds, 10 by default
Resolution720p or 1080p360p draft, 720p, 1080p or 4k
EditingNone, each call stands aloneFollow-up turns with previous_interaction_id
Reference imagesUp to 3, in Veo 3.1 but not FastUp to 6 images, also on the longest clips
Extending7 seconds a step3 to 10 seconds a turn, up to 30 seconds in total for generated clips
SDKgoogle-genai 2.9.0 or newergoogle-genai 2.21.0 or newer

Common mistakes

  • Running the sample without a paid plan. Every paid cell in the notebook checks a flag first for this reason.
  • Pinning only an end frame. The notebook says a start image is always needed with it.
  • Asking for reference images with the Fast model, at 1080p or in a vertical shape. The notebook allows them only with Veo 3.1 and not the Fast model, in a horizontal 720p video.
  • Extending a clip that did not come from Veo, or one over the length limit above.
  • Polling with no pause. The notebook waits between checks and points to webhooks for being told when a job ends.
  • Pasting the API key into the script. Keep it in a secret or an environment variable.

Try it yourself

  • Run the first clip with the dog prompt, then switch aspect_ratio to the vertical option to get a vertical video.
  • Add the notebook's negative prompt "airplanes" to a sky scene and compare the two clips.
  • Make a picture, pass it as image, then add an end frame that shows the next moment.
  • Make the same clip with the Lite and the full Veo 3.1 model at 720p and compare the detail.
  • Check what a call costs before a batch run.

Judge a clip on what you asked for: the subject holds its look, the camera does what you wrote and any speech matches the lines.

Next: write better video prompts

A call is only as good as its prompt, and OpenAI, Google, Lightricks and Tencent each publish their own advice for writing one. Write better video prompts lines that advice up and adds how to keep one character the same from shot to shot.

Check yourself

  1. Your generate_videos call returned at once with no video. What does the notebook do next?

    Show answer

    B. It checks client.operations.get every 20 seconds until operation.done is true generate_videos returns an operation, a job still running, so the code polls it and downloads the files when it is done.

  2. You want a clip that ends on a particular picture. What else must you pass?

    Show answer

    A. A starting image, because an ending image never works alone The notebook says you cannot use only an ending image and always need a starting one too.

  3. Which settings does the notebook give for reference images in Veo?

    Show answer

    C. Veo 3.1 but not Fast, 720p, widescreen The notebook limits reference images to Veo 3.1 but not the Fast model, at 720p and in widescreen.

  4. Which call edits a generated Gemini Omni clip in a follow-up turn?

    Show answer

    B. client.interactions.create with previous_interaction_id An interaction keeps state, so naming an earlier one with previous_interaction_id lets the model edit that clip.

Frequently asked questions

Is Veo free to use?

No. Google's notebook says Veo will not run on the Free Tier, so a paid account is the starting point.

Are Veo videos watermarked?

Yes. According to the notebook, every generated video is digitally watermarked with Google DeepMind's SynthID.

Can I try the Veo code without installing Python?

Yes. A Colab badge at the top of the notebook opens it in your browser, with the key stored as a Colab Secret. The paid cells stay off until you switch the flag on.

Can Veo make a vertical video?

Yes, ask for the tall 9:16 shape. Reference images are the exception, which the notebook takes only in the widescreen shape.

Can I extend a clip I filmed myself?

Not with Veo, which extends only videos it made, according to the notebook. Gemini Omni accepts an uploaded clip of 10 seconds or less, except for users in the European Economic Area, Switzerland and the United Kingdom.

Sources

  1. GitHub: google-gemini/cookbook, Get started with Veo notebook (read November 6, 2026)https://github.com/google-gemini/cookbook/blob/main/quickstarts/Get_started_Veo.ipynb
  2. GitHub: google-gemini/cookbook, Gemini Omni notebook (read November 6, 2026)https://github.com/google-gemini/cookbook/blob/main/quickstarts/Get_started_Omni.ipynb
  3. YouTube (Google Cloud Tech): Bringing ideas to life: An intro to AI video generation (read November 6, 2026)https://www.youtube.com/watch?v=5NlXA7A8IKg

Share this lesson

Let an agent call video tools for you

An MCP server lets an AI agent use a tool on your behalf. Browse the servers Mindket lists and read each one before you connect it.

Browse MCP servers

This lesson as Markdown · AI video: Sora, Veo, video prompts and open models · All courses