Grok Imagine
import { experimental_generateVideo as generateVideo } from 'ai';
const result = await generateVideo({ model: 'xai/grok-imagine-video', prompt: 'A serene mountain lake at sunrise.'});Getting started
Generate videos with Grok Imagine using the experimental_generateVideo function from AI SDK 6 or later. AI Gateway handles routing and polls until the video is ready.
Install the AI SDK (pnpm add ai dotenv), create an API key from the API Keys page, and set it as AI_GATEWAY_API_KEY in your environment. Full setup is covered in the video generation quickstart.
import { experimental_generateVideo as generateVideo } from 'ai';import fs from 'node:fs';import 'dotenv/config';
async function main() { const result = await generateVideo({ model: 'xai/grok-imagine-video', prompt: 'A chicken flying into the sunset in the style of 90s anime', });
// Save the generated video fs.writeFileSync('output.mp4', result.videos[0].uint8Array);
console.log('Video saved to output.mp4');}
main().catch(console.error);Top-level parameters
Load the supported top-level parameters: prompt, aspectRatio, duration, and resolution.
import { experimental_generateVideo as generateVideo } from 'ai';import fs from 'node:fs';import 'dotenv/config';
async function main() { const result = await generateVideo({ model: 'xai/grok-imagine-video', prompt: 'A chicken flying into the sunset in the style of 90s anime', aspectRatio: '16:9', duration: 5, resolution: '1280x720', });
// Save the generated video fs.writeFileSync('output.mp4', result.videos[0].uint8Array);
console.log('Video saved to output.mp4');}
main().catch(console.error);| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | No | Text description of the video to generate. |
duration | number | No | Video length in seconds. 1-15 seconds. |
resolution | string | No | Resolution ('854x480', '1280x720'). |
aspectRatio | string | No | Aspect ratio ('1:1', '16:9', '9:16', '4:3', '3:4', '3:2', '2:3'). |
frameImages | Array<{ image: string | Buffer; frameType: 'first_frame' }> | No | Opening frame of the clip, as a single first_frame entry. Replaces prompt.image and wins when both are set. Grok does not interpolate to an ending image, so a last_frame entry is ignored with a warning. |
inputReferences | Array<string | Buffer> | No | One to seven reference images that Grok builds a new scene from rather than animating. Passing them selects reference-to-video mode automatically. Images only — a video reference is ignored with a warning, so use mode: 'extend-video' to continue from a video. |
Input limits
| Input | Formats | Sources | Max count | Max size | Limits |
|---|---|---|---|---|---|
| Image | jpg, jpeg, png, webp, gif, avif | url, base64, buffer | 5 | — | — |
| Video | — | url | 1 | — | 2-8.7s |
Provider options
Pass Grok-specific options under providerOptions.xai. videoUrl switches the call into video-editing mode (where duration, aspectRatio, and resolution are ignored), so it has its own example below.
import { experimental_generateVideo as generateVideo } from 'ai';import fs from 'node:fs';import 'dotenv/config';
async function main() { const result = await generateVideo({ model: 'xai/grok-imagine-video', prompt: 'A chicken flying into the sunset in the style of 90s anime', duration: 5, providerOptions: { xai: { resolution: '720p', pollIntervalMs: 5000, pollTimeoutMs: 600000, }, }, });
// Save the generated video fs.writeFileSync('output.mp4', result.videos[0].uint8Array);
console.log('Video saved to output.mp4');}
main().catch(console.error);Pass Grok-specific options under providerOptions.xai in your generateVideo call.
| Parameter | Type | Required | Description |
|---|---|---|---|
resolution | '480p' | '720p' | No | Native resolution format. Alternative to the standard resolution parameter. |
videoUrl | string | No | URL of a source video. With mode: 'edit-video' (or no mode) the call edits it; with mode: 'extend-video' the clip continues from its last frame. Either way duration, aspectRatio, and resolution are ignored. See the video-editing quirk below. |
mode | 'edit-video' | 'extend-video' | 'reference-to-video' | No | Selects the operation explicitly. Omit it for standard generation from a text prompt, prompt.image, or frameImages. Leaving it out while passing videoUrl or inputReferences still works, and is treated as editing or reference-to-video respectively. |
referenceImageUrls | string[] | No | One to seven reference image URLs for reference-to-video, which generates a new scene from the references rather than animating them. Legacy alternative to the top-level inputReferences, used only when inputReferences is omitted. |
pollIntervalMs | number | No | How often to check task status. Defaults to 5000. |
pollTimeoutMs | number | No | Maximum wait time. Defaults to 600000 (10 minutes). |
Resolution: two ways
You can set the output resolution two ways: the top-level resolution parameter accepts 854x480 (480p) or 1280x720 (720p), while providerOptions.xai.resolution accepts the native 480p or 720p form. They map to the same two resolutions.
The docs do not specify precedence if you set both, so set only one to avoid ambiguity. providerOptions.xai.resolution is the provider-native control; prefer it when you want to be explicit, or use the top-level resolution for parity with other video models.
Because the top-level resolution is a pixel dimension and aspectRatio is an independent shape control, avoid pairing values that disagree (for example aspectRatio: '1:1' with resolution: '1280x720'). Match the resolution to the ratio, or set the native providerOptions.xai.resolution tier so only aspectRatio controls the shape.
Video editing
Pass providerOptions.xai.videoUrl with a source video URL to edit an existing video instead of generating a new one. The prompt then describes the edits to apply.
The maximum input duration is listed in the Input limits table. The output matches the input video's aspect ratio and resolution, up to 720p (a 1080p input is downsized to 720p).
When editing, the duration, aspectRatio, and resolution parameters are not supported and are ignored.
Mode selection and frames
Editing, extension, and reference-to-video are mutually exclusive. Passing providerOptions.xai.videoUrl selects editing, and passing inputReferences selects reference-to-video; set providerOptions.xai.mode to choose explicitly.
The top-level parameters win over their provider-option equivalents: a first_frame in frameImages overrides prompt.image, and inputReferences overrides providerOptions.xai.referenceImageUrls.
Grok does not interpolate between a first and last frame. A last_frame entry in frameImages is ignored with a warning — use mode: 'extend-video' to continue from the end of an existing clip instead.
frameImages takes priority over references: when it is set, reference-to-video is not auto-selected.
Image to video
Animate a static image by passing prompt.image (a URL) with an optional prompt.text describing the motion. The output defaults to the input image’s aspect ratio; setting aspectRatio overrides it and stretches the image.
import { experimental_generateVideo as generateVideo } from 'ai';import fs from 'node:fs';import 'dotenv/config';
async function main() { const result = await generateVideo({ model: 'xai/grok-imagine-video', prompt: { image: 'https://example.com/cat.png', text: 'The cat slowly turns its head and blinks', }, duration: 5, providerOptions: { xai: { pollTimeoutMs: 600000, }, }, });
// Save the generated video fs.writeFileSync('output.mp4', result.videos[0].uint8Array);
console.log('Video saved to output.mp4');}
main().catch(console.error);Reference to video
Generate a new scene from reference images passed through the top-level inputReferences. The references guide visual elements in the output rather than becoming the first frame, and passing them selects reference-to-video mode automatically. Refer to each one in the prompt with <IMAGE_1>, <IMAGE_2>, and so on.
import { experimental_generateVideo as generateVideo } from 'ai';import fs from 'node:fs';import 'dotenv/config';
async function main() { const result = await generateVideo({ model: 'xai/grok-imagine-video', prompt: 'The comic cat from <IMAGE_1> and the comic dog from <IMAGE_2> ' + 'are having a playful chase through a sunlit park. ' + 'Cinematic slow-motion, warm afternoon light.', inputReferences: [ 'https://example.com/comic-cat.png', 'https://example.com/comic-dog.png', ], duration: 8, aspectRatio: '16:9', providerOptions: { xai: { pollTimeoutMs: 600000, }, }, });
// Save the generated video fs.writeFileSync('output.mp4', result.videos[0].uint8Array);
console.log('Video saved to output.mp4');}
main().catch(console.error);Video editing
Edit an existing video with a text prompt. Provide the source video as providerOptions.xai.videoUrl (input duration limits are in the Input limits table); output matches the input video’s aspect ratio and resolution, up to 720p. The duration, aspectRatio, and resolution parameters are not supported when editing.
import { experimental_generateVideo as generateVideo } from 'ai';import fs from 'node:fs';import 'dotenv/config';
async function main() { const result = await generateVideo({ model: 'xai/grok-imagine-video', prompt: 'Give the person sunglasses and a hat', providerOptions: { xai: { videoUrl: 'https://example.com/source-video.mp4', pollTimeoutMs: 600000, }, }, });
// Save the generated video fs.writeFileSync('output.mp4', result.videos[0].uint8Array);
console.log('Video saved to output.mp4');}
main().catch(console.error);