# Generate videos with AI SDK

**Author:** Ben Sabic

---

With the AI SDK, you can generate a video from a text prompt or an input image using the `experimental_generateVideo` function and a video model, then read the result as base64 or a `Uint8Array`. Video generation runs asynchronously and can take from a few seconds to several minutes, so plan for longer timeouts than you'd use for text or images. Providers, including Google Veo, FAL, Kling AI, Replicate, and xAI, expose video models through the AI SDK.

> **Note:** Video generation is experimental, and the API may change in a future release.

## Overview

In this guide, you'll learn how to:

- Generate a video from a text prompt with `experimental_generateVideo`
  
- Control the output with aspect ratio, resolution, duration, FPS, and seed
  
- Generate a video from an input image
  
- Generate multiple videos in one call with `n`
  
- Handle long-running generation with timeouts and polling configuration
  

## Prerequisites

Before you begin, make sure you have:

- The `ai` package
  
- Access to video model through the AI Gateway , or a provider package such as `@ai-sdk/fal` with provider credentials
  

## Generate a video from a prompt

Call `experimental_generateVideo` with a model and a prompt. It returns a `video` that you can read as base64 or a `Uint8Array`.

`import { experimental_generateVideo as generateVideo } from 'ai'; const { video } = await generateVideo({ model: 'google/veo-3.1-generate-001', prompt: 'A cat walking on a treadmill', }); const base64 = video.base64; // base64 video data const uint8Array = video.uint8Array; // Uint8Array video data`

Use `video.uint8Array` to write the file to storage, or `video.base64` to embed it or return it from a route. The model name above is an AI Gateway string. To call a provider directly instead, pass a provider model such as `fal.video('luma-dream-machine/ray-2')`.

## Control the output

Pass settings as top-level properties to shape the output. Support varies by model and provider, and any unsupported setting comes back in the response's `warnings` array.

| Setting       | Type     | Example      | Description                                         |
| ------------- | -------- | ------------ | --------------------------------------------------- |
| `aspectRatio` | `string` | `'16:9'`     | Width-to-height ratio, in `{width}:{height}` format |
| `resolution`  | `string` | `'1280x720'` | Output resolution, in `{width}x{height}` format     |
| `duration`    | `number` | `5`          | Length in seconds, when the model supports it       |
| `fps`         | `number` | `24`         | Frames per second, when the model supports it       |
| `seed`        | `number` | `1234567890` | Reproducible output, when the model supports it     |

`const { video, warnings } = await generateVideo({ model: 'google/veo-3.1-generate-001', prompt: 'A serene mountain landscape at sunset', aspectRatio: '16:9', duration: 5, });`

## Generate a video from an image

To animate an image, pass a prompt object with an `image` and `text`. The image can be a URL, a base64 string, or a `Uint8Array`.

`import { experimental_generateVideo as generateVideo } from 'ai'; import { fal } from '@ai-sdk/fal'; const { video } = await generateVideo({ model: fal.video('luma-dream-machine/ray-2'), prompt: { image: 'https://example.com/my-image.png', text: 'Animate this image with gentle motion', }, });`

Check the [models table](#video-models) for which models support image-to-video.

## Generate multiple videos

Set `n` to generate more than one video in a single call. The result has a `videos` array instead of a single `video`. Most video models produce one video per call, so the SDK makes the needed calls in parallel to reach `n`. To change the batch size, set `maxVideosPerCall`.

`const { videos } = await generateVideo({ model: 'google/veo-3.1-generate-001', prompt: 'A rocket launching into space', n: 3, });`

## Handle long-running generation

Video generation can take several minutes, and most providers poll for the result, so set generous timeouts. Use `abortSignal` to cap the total wait:

`const { video } = await generateVideo({ model: 'google/veo-3.1-generate-001', prompt: 'A cat walking on a treadmill', abortSignal: AbortSignal.timeout(60000), // abort after 60 seconds });`

For longer videos, raise the provider's polling timeout through `providerOptions`. Each provider exports an options type you can apply with `satisfies` for type safety:

`import { experimental_generateVideo as generateVideo } from 'ai'; import { fal, type FalVideoModelOptions } from '@ai-sdk/fal'; const { video } = await generateVideo({ model: fal.video('luma-dream-machine/ray-2'), prompt: 'A cinematic timelapse of a city from dawn to dusk', duration: 10, providerOptions: { fal: { pollTimeoutMs: 600000, // 10 minutes } satisfies FalVideoModelOptions, }, });`

For production, set `pollTimeoutMs` to at least 10 minutes (600000ms) to cover varying generation times across models and video lengths. `providerOptions` also passes model-specific settings, where each key becomes a request body property, such as fal's `loop` or `motionStrength`.

## Handle errors

`experimental_generateVideo` throws `NoVideoGeneratedError` when the provider can't return a valid video, for example when the model fails to respond or returns a response the SDK can't parse. Check for it with `NoVideoGeneratedError.isInstance`, and read `cause` and `responses` for detail.

`import { experimental_generateVideo as generateVideo, NoVideoGeneratedError, } from 'ai'; try { await generateVideo({ model: 'google/veo-3.1-generate-001', prompt: 'A cat walking on a treadmill', }); } catch (error) { if (NoVideoGeneratedError.isInstance(error)) { console.log('Cause:', error.cause); console.log('Responses:', error.responses); } }`

## Video models

These are some of the video models available through the AI SDK. Each provider's documentation lists the full set and any model-specific settings.

| Provider      | Model                       | Features                                              |
| ------------- | --------------------------- | ----------------------------------------------------- |
| Google Vertex | `veo-3.1-generate-001`      | Text-to-video, audio generation                       |
| Google Vertex | `veo-3.1-fast-generate-001` | Text-to-video, audio generation                       |
| Google        | `veo-2.0-generate-001`      | Text-to-video, up to 4 videos per call                |
| FAL           | `luma-dream-machine/ray-2`  | Text-to-video, image-to-video                         |
| FAL           | `minimax-video`             | Text-to-video                                         |
| Kling AI      | `kling-v2.6-t2v`            | Text-to-video                                         |
| Kling AI      | `kling-v2.6-i2v`            | Image-to-video                                        |
| Replicate     | `minimax/video-01`          | Text-to-video                                         |
| xAI           | `grok-imagine-video`        | Text-to-video, image-to-video, editing, and extension |

## Next steps

- Read the [`experimental_generateVideo`](https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-video) [reference](https://ai-sdk.dev/docs/reference/ai-sdk-core/generate-video) for every option and return field.
  
- See [Image generation](https://ai-sdk.dev/docs/ai-sdk-core/image-generation) for the matching `experimental_generateImage` workflow.
  
- Browse [Providers and models](https://ai-sdk.dev/docs/foundations/providers-and-models) to choose a video model and provider.
  
- Check provider pages such as [FAL video models](https://ai-sdk.dev/providers/ai-sdk-providers/fal#video-models) for model-specific settings and limits.

---

[View full KB sitemap](/kb/sitemap.md)
