Skip to content
Docs

Generate videos with AI SDK

Use experimental_generateVideo in the AI SDK to generate videos from a text prompt or an image, set aspect ratio, resolution, duration, FPS, and seed, and handle long-running generation with timeouts and polling.

4 min read
Last updated June 25, 2026

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.

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

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

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

app/api/video/route.ts
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').

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.

SettingTypeExampleDescription
aspectRatiostring'16:9'Width-to-height ratio, in {width}:{height} format
resolutionstring'1280x720'Output resolution, in {width}x{height} format
durationnumber5Length in seconds, when the model supports it
fpsnumber24Frames per second, when the model supports it
seednumber1234567890Reproducible 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,
});

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 for which models support image-to-video.

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,
});

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.

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);
}
}

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.

ProviderModelFeatures
Google Vertexveo-3.1-generate-001Text-to-video, audio generation
Google Vertexveo-3.1-fast-generate-001Text-to-video, audio generation
Googleveo-2.0-generate-001Text-to-video, up to 4 videos per call
FALluma-dream-machine/ray-2Text-to-video, image-to-video
FALminimax-videoText-to-video
Kling AIkling-v2.6-t2vText-to-video
Kling AIkling-v2.6-i2vImage-to-video
Replicateminimax/video-01Text-to-video
xAIgrok-imagine-videoText-to-video, image-to-video, editing, and extension

Was this helpful?

supported.