xAI Grok Provider
The xAI Grok provider contains language model support for the xAI API.
Setup
The xAI Grok provider is available via the @ai-sdk/xai module. You can
install it with
pnpm add @ai-sdk/xai
Provider Instance
You can import the default provider instance xai from @ai-sdk/xai:
import { xai } from '@ai-sdk/xai';If you need a customized setup, you can import createXai from @ai-sdk/xai
and create a provider instance with your settings:
import { createXai } from '@ai-sdk/xai';
const xai = createXai({ apiKey: 'your-api-key',});You can use the following optional settings to customize the xAI provider instance:
-
baseURL string
Use a different URL prefix for API calls, e.g. to use proxy servers. The default prefix is
https://api.x.ai/v1. -
apiKey string
API key that is being sent using the
Authorizationheader. It defaults to theXAI_API_KEYenvironment variable. -
headers Record<string,string>
Custom headers to include in the requests.
-
fetch (input: RequestInfo, init?: RequestInit) => Promise<Response>
Custom fetch implementation. Defaults to the global
fetchfunction. You can use it as a middleware to intercept requests, or to provide a custom fetch implementation for e.g. testing.
Language Models
You can create xAI models using a provider instance. The
first argument is the model id, e.g. grok-4.6.
const model = xai('grok-4.6');Since AI SDK 7, xai(modelId) uses the xAI Responses API by default. To use
the Chat Completions
API (legacy), use
xai.chat(modelId).
Example
You can use xAI language models to generate text with the generateText function:
import { xai } from '@ai-sdk/xai';import { generateText } from 'ai';
const { text } = await generateText({ model: xai('grok-4.6'), prompt: 'Write a vegetarian lasagna recipe for 4 people.',});xAI language models can also be used in the streamText function
and support structured data generation with Output
(see AI SDK Core).
Reasoning Effort
For models with configurable reasoning, you can control how much effort the
model spends thinking before responding via
providerOptions.xai.reasoningEffort. This works for both the Responses API
(default) and the Chat Completions API (xai.chat()).
import { xai } from '@ai-sdk/xai';import { generateText } from 'ai';
const { text } = await generateText({ model: xai('grok-4.3'), prompt: 'Explain quantum entanglement.', providerOptions: { xai: { reasoningEffort: 'medium' }, },});The AI SDK option accepts these values, but each xAI model supports a subset:
'none'— Disables reasoning entirely; no thinking tokens are used. Best for simple use cases that need a near-instant response.'low'— Uses some reasoning tokens, but still fast. Good for general agentic use and tool calling.'medium'— More thinking for less-latency-sensitive applications such as complex data analysis and long-context reasoning.'high'— More reasoning tokens for deeper thinking. Suited for very challenging problems, complex math, multi-step logic, and competition-level tasks.'xhigh'— Uses the most reasoning tokens for the most challenging tasks. This level is only supported bygrok-4.6.
Support and defaults are model-specific. grok-4.3 supports 'none',
'low', 'medium', and 'high'. grok-4.5 supports 'low', 'medium',
and 'high', defaults to 'high', and cannot disable reasoning. grok-4.6
supports 'low', 'medium', 'high', and 'xhigh', and defaults to
'high'. The grok-4.20-reasoning and grok-4.20-non-reasoning variants do
not accept this option. For grok-4.20-multi-agent, 'low', 'medium', and
'high' control the number of agents instead of reasoning depth. See xAI's
reasoning
docs and
Grok 4.6 model page for
current details.
Priority Processing
providerOptions.xai.serviceTier requests higher scheduling priority, which
typically lowers time-to-first-token and speeds up inter-token latency. This
works for both the Responses API (default) and the Chat Completions API
(xai.chat()).
import { xai } from '@ai-sdk/xai';import { generateText } from 'ai';
const { providerMetadata } = await generateText({ model: xai('grok-4.6'), prompt: 'Explain quantum entanglement.', providerOptions: { xai: { serviceTier: 'priority' }, },});
// 'priority' when the request was served at the priority tier,// 'default' when priority capacity was unavailable.console.log(providerMetadata?.xai?.serviceTier);Priority requests are billed at a premium per-token rate, and xAI only charges
that rate when the response confirms the priority tier — so read the applied
tier back from providerMetadata.xai.serviceTier rather than assuming the
request you sent is the tier you got. Omitting the option is equivalent to
'default'. See xAI's priority processing
docs.
Realtime Models
You can create models that call the xAI Realtime API
using the .experimental_realtime() factory method.
import { xai } from '@ai-sdk/xai';
const model = xai.experimental_realtime('grok-voice-latest');Realtime sessions run in the browser and require a short-lived token created on
your server with xai.experimental_realtime.getToken():
const token = await xai.experimental_realtime.getToken({ model: 'grok-voice-latest',});See Realtime for the complete setup and tool calling pattern.
Responses API (Agentic Tools)
The xAI Responses API is the default when using xai(modelId) (since AI SDK 7). You can also use xai.responses(modelId) explicitly. This enables the model to autonomously orchestrate tool calls and research on xAI's servers.
const model = xai.responses('grok-4.6');The Responses API provides server-side tools that the model can autonomously execute during its reasoning process:
- web_search: Real-time web search and page browsing
- x_search: Search X (Twitter) posts, users, and threads
- code_execution: Execute Python code for calculations and data analysis
- view_image: View and analyze images
- view_x_video: View and analyze videos from X posts
- mcp_server: Connect to remote MCP servers and use their tools
- file_search: Search through documents in vector stores (collections)
Vision
The Responses API supports image input with vision models:
import { xai } from '@ai-sdk/xai';import { generateText } from 'ai';
const { text } = await generateText({ model: xai.responses('grok-4.6'), messages: [ { role: 'user', content: [ { type: 'text', text: 'What do you see in this image?' }, { type: 'file', mediaType: 'image', data: fs.readFileSync('./image.png'), }, ], }, ],});You can control the resolution at which the model processes an image with
the imageDetail provider option on the image part:
import { xai } from '@ai-sdk/xai';import { generateText } from 'ai';
const { text } = await generateText({ model: xai('grok-4.6'), messages: [ { role: 'user', content: [ { type: 'text', text: 'What do you see in this image?' }, { type: 'file', mediaType: 'image/png', data: fs.readFileSync('./image.png'), providerOptions: { xai: { imageDetail: 'low' }, }, }, ], }, ],});The following image detail values are supported:
- low: processes the image at reduced resolution and consumes fewer input tokens.
- high: processes the image at full resolution.
- auto: lets the xAI API decide.
When not set, the image is processed at full resolution.
Web Search Tool
The web search tool enables autonomous web research with optional domain filtering and image understanding:
import { xai } from '@ai-sdk/xai';import { generateText } from 'ai';
const { text, sources } = await generateText({ model: xai.responses('grok-4.6'), prompt: 'What are the latest developments in AI?', tools: { web_search: xai.tools.webSearch({ allowedDomains: ['arxiv.org', 'openai.com'], enableImageUnderstanding: true, }), },});
console.log(text);console.log('Citations:', sources);Web Search Parameters
-
allowedDomains string[]
Only search within specified domains (max 5). Cannot be used with
excludedDomains. -
excludedDomains string[]
Exclude specified domains from search (max 5). Cannot be used with
allowedDomains. -
enableImageSearch boolean
Allow the model to perform image search as a separate Web Search mode when images are useful for the answer. The model can choose between regular web search and image search; responses can include Markdown image embeds when relevant.
-
enableImageUnderstanding boolean
Enable the model to view and analyze images found during search. Increases token usage. To allow explicitly searching for images, use
enableImageSearch.
X Search Tool
The X search tool enables searching X (Twitter) for posts, with filtering by handles and date ranges:
const { text, sources } = await generateText({ model: xai.responses('grok-4.6'), prompt: 'What are people saying about AI on X this week?', tools: { x_search: xai.tools.xSearch({ allowedXHandles: ['elonmusk', 'xai'], fromDate: '2025-10-23', toDate: '2025-10-30', enableImageUnderstanding: true, enableVideoUnderstanding: true, }), },});X Search Parameters
-
allowedXHandles string[]
Only search posts from specified X handles (max 10). Cannot be used with
excludedXHandles. -
excludedXHandles string[]
Exclude posts from specified X handles (max 10). Cannot be used with
allowedXHandles. -
fromDate string
Start date for posts in ISO8601 format (
YYYY-MM-DD). -
toDate string
End date for posts in ISO8601 format (
YYYY-MM-DD). -
enableImageUnderstanding boolean
Enable the model to view and analyze images in X posts.
-
enableVideoUnderstanding boolean
Enable the model to view and analyze videos in X posts.
Code Execution Tool
The code execution tool enables the model to write and execute Python code for calculations and data analysis:
const { text } = await generateText({ model: xai.responses('grok-4.6'), prompt: 'Calculate the compound interest for $10,000 at 5% annually for 10 years', tools: { code_execution: xai.tools.codeExecution(), },});View Image Tool
The view image tool enables the model to view and analyze images:
const { text } = await generateText({ model: xai.responses('grok-4.6'), prompt: 'Describe what you see in the image', tools: { view_image: xai.tools.viewImage(), },});View X Video Tool
The view X video tool enables the model to view and analyze videos from X (Twitter) posts:
const { text } = await generateText({ model: xai.responses('grok-4.6'), prompt: 'Summarize the content of this X video', tools: { view_x_video: xai.tools.viewXVideo(), },});Image Generation Tool
The image generation tool lets the model create and edit images with Grok Imagine as part of a conversation. The model decides when to call the tool, writes the image prompt, and returns the finished image alongside its text response:
import { xai } from '@ai-sdk/xai';import { generateText } from 'ai';
const result = await generateText({ model: xai.responses('grok-4.6'), prompt: 'Generate an image of a corgi surfing a big wave, in the style of a Japanese woodblock print', tools: { image_generation: xai.tools.imageGeneration(), },});
for (const toolResult of result.staticToolResults) { if (toolResult.toolName === 'image_generation') { const base64Image = toolResult.output.result; }}The tool result also contains the prompt that the model wrote for the image model, which is useful for understanding and debugging what was generated.
Image Generation Parameters
-
action 'auto' | 'generate' | 'edit'
Restricts what the tool can do. Defaults to
'auto'.'auto': the model can generate and edit images.'generate': text-to-image generation only.'edit': image editing only (edits images already in the conversation, including images the model generated earlier).
The tool takes no size or format parameters; the model picks an aspect ratio for each call. To control it, ask in your prompt (e.g. "in a 9:16 vertical aspect ratio").
MCP Server Tool
The MCP server tool enables the model to connect to remote Model Context Protocol (MCP) servers and use their tools:
const { text } = await generateText({ model: xai.responses('grok-4.6'), prompt: 'Use the weather tool to check conditions in San Francisco', tools: { weather_server: xai.tools.mcpServer({ serverUrl: 'https://example.com/mcp', serverLabel: 'weather-service', serverDescription: 'Weather data provider', allowedTools: ['get_weather', 'get_forecast'], }), },});MCP Server Parameters
-
serverUrl string (required)
The URL of the remote MCP server.
-
serverLabel string
A label to identify the MCP server.
-
serverDescription string
A description of what the MCP server provides.
-
allowedTools string[]
List of tool names that the model is allowed to use from the MCP server. If not specified, all tools are allowed.
-
headers Record<string, string>
Custom headers to include when connecting to the MCP server.
-
authorization string
Authorization header value for authenticating with the MCP server (e.g.,
'Bearer token123').
File Search Tool
The file search tool enables searching through documents stored in xAI vector stores (collections):
import { xai, type XaiLanguageModelResponsesOptions } from '@ai-sdk/xai';import { streamText } from 'ai';
const result = streamText({ model: xai.responses('grok-4.6'), prompt: 'What documents do you have access to?', tools: { file_search: xai.tools.fileSearch({ vectorStoreIds: ['collection_your-collection-id'], maxNumResults: 10, }), }, providerOptions: { xai: { include: ['file_search_call.results'], } satisfies XaiLanguageModelResponsesOptions, },});File Search Parameters
-
vectorStoreIds string[] (required)
The IDs of the vector stores (collections) to search.
-
maxNumResults number
The maximum number of results to return from the search.
Provider Options for File Search
-
include Array<'file_search_call.results'>
Include file search results in the response. When set to
['file_search_call.results'], the response will contain the actual search results with file content and scores.
File search requires grok-4 family models (including grok-4.20) and the Responses API. Vector stores can be created using the xAI API.
Multiple Tools
You can combine multiple server-side tools for comprehensive research:
import { xai } from '@ai-sdk/xai';import { streamText } from 'ai';
const { stream } = streamText({ model: xai.responses('grok-4.6'), prompt: 'Research AI safety developments and calculate risk metrics', tools: { web_search: xai.tools.webSearch(), x_search: xai.tools.xSearch(), code_execution: xai.tools.codeExecution(), file_search: xai.tools.fileSearch({ vectorStoreIds: ['collection_your-documents'], }), data_service: xai.tools.mcpServer({ serverUrl: 'https://data.example.com/mcp', serverLabel: 'data-service', }), },});
for await (const part of stream) { if (part.type === 'text-delta') { process.stdout.write(part.text); } else if (part.type === 'source' && part.sourceType === 'url') { console.log('\nSource:', part.url); }}Provider Options
The Responses API supports the following provider options:
import { xai, type XaiLanguageModelResponsesOptions } from '@ai-sdk/xai';import { generateText } from 'ai';
const result = await generateText({ model: xai.responses('grok-4.6'), providerOptions: { xai: { reasoningEffort: 'high', } satisfies XaiLanguageModelResponsesOptions, }, // ...});The following provider options are available:
-
reasoningEffort 'none' | 'low' | 'medium' | 'high'
Control the reasoning effort for supported models. See Reasoning Effort for model-specific values and defaults.
-
logprobs boolean
Return log probabilities for output tokens.
-
topLogprobs number
Number of most likely tokens to return per token position (0-8). When set,
logprobsis automatically enabled. -
include Array<'file_search_call.results'>
Specify additional output data to include in the model response. Use
['file_search_call.results']to include file search results with scores and content. -
store boolean
Whether to store the input message(s) and model response for later retrieval. Defaults to
true. -
previousResponseId string
The ID of the previous response from the model. You can use it to continue a conversation.
-
serviceTier 'default' | 'priority'
Scheduling priority for the request.
'priority'buys lower time-to-first-token and faster inter-token latency at a premium per-token price. The tier xAI actually applied comes back onproviderMetadata.xai.serviceTier, and is'default'when priority capacity was unavailable. See Priority Processing.
The Responses API only supports server-side tools. You cannot mix server-side tools with client-side function tools in the same request.
Model Capabilities
| Model | Image Input | Object Generation | Tool Usage | Tool Streaming | Reasoning |
|---|---|---|---|---|---|
grok-4.6 | |||||
grok-4.5 | |||||
grok-4.20-reasoning | |||||
grok-4.20-non-reasoning | |||||
grok-4-1-fast-reasoning | |||||
grok-4-1-fast-non-reasoning | |||||
grok-4-1 | |||||
grok-4-fast-reasoning | |||||
grok-4-fast-non-reasoning | |||||
grok-code-fast-1 | |||||
grok-3 | |||||
grok-3-mini |
The table above lists popular models. Please see the xAI docs for a full list of available models. You can also pass any available provider model ID as a string if needed.
Speech Models
You can create models that call the xAI Text to Speech API
using the .speech() factory method. xAI's text-to-speech endpoint does not
require a model identifier.
const model = xai.speech();Use xAI speech models with the generateSpeech function:
import { xai } from '@ai-sdk/xai';import { generateSpeech } from 'ai';
const result = await generateSpeech({ model: xai.speech(), text: 'Hello from the AI SDK!', voice: 'ara', language: 'en', outputFormat: 'mp3', speed: 1.1,});Supported Parameters
-
text string (required)
Text to synthesize. You can include xAI speech tags such as
[pause],[laugh], or<whisper>...</whisper>directly in the text. -
voice string
The xAI voice ID. Defaults to
'eve'. Built-in voice IDs are'eve','ara','rex','sal', and'leo'; custom voice IDs are also accepted. -
language string
A BCP-47 language code or
'auto'for automatic detection. Defaults to'auto'when omitted. -
speed number
Speech rate multiplier from
0.7to1.5. -
outputFormat string
The audio codec to generate. Supported values are
'mp3','wav','pcm','mulaw', and'alaw'. Defaults to'mp3'.
xAI does not expose a separate instructions field for text-to-speech. Use
speech tags in text to control expressive delivery.
Provider Options
You can pass xAI-specific controls using providerOptions.xai:
import { xai, type XaiSpeechModelOptions } from '@ai-sdk/xai';import { generateSpeech } from 'ai';
const result = await generateSpeech({ model: xai.speech(), text: 'A high fidelity narration sample.', outputFormat: 'mp3', providerOptions: { xai: { sampleRate: 44100, bitRate: 192000, optimizeStreamingLatency: 1, textNormalization: true, } satisfies XaiSpeechModelOptions, },});-
sampleRate 8000 | 16000 | 22050 | 24000 | 44100 | 48000
Sample rate of the output audio in Hz.
-
bitRate 32000 | 64000 | 96000 | 128000 | 192000
MP3 bit rate in bits per second. Only applies when
outputFormatis'mp3'. -
optimizeStreamingLatency 0 | 1 | 2
Latency optimization level. Higher values reduce time to first audio with a quality tradeoff at chunk boundaries.
-
textNormalization boolean
Whether to normalize written-form input text before synthesizing speech.
Model Capabilities
| Model | Language | Speed | Output Formats |
|---|---|---|---|
default | mp3, wav, pcm, mulaw, alaw |
Transcription Models
You can create models that call the xAI Speech to Text API
using the .transcription() factory method. xAI's batch transcription endpoint
does not require a model identifier.
const model = xai.transcription();Use xAI transcription models with the transcribe function:
import { xai } from '@ai-sdk/xai';import { transcribe } from 'ai';import { readFile } from 'fs/promises';
const result = await transcribe({ model: xai.transcription(), audio: await readFile('meeting.mp3'),});Provider Options
You can pass xAI-specific controls using providerOptions.xai:
import { xai, type XaiTranscriptionModelOptions } from '@ai-sdk/xai';import { transcribe } from 'ai';import { readFile } from 'fs/promises';
const result = await transcribe({ model: xai.transcription(), audio: await readFile('meeting.mp3'), providerOptions: { xai: { language: 'en', format: true, keyterm: ['AI SDK', 'Grok'], diarize: true, } satisfies XaiTranscriptionModelOptions, },});-
audioFormat
pcm|mulaw|alawAudio encoding for raw, headerless input audio.
-
sampleRate 8000 | 16000 | 22050 | 24000 | 44100 | 48000
Sample rate of the input audio in Hz.
-
language string
Language code used for inverse text normalization.
-
format boolean
Enables inverse text normalization. Requires
language. -
multichannel boolean
Enables per-channel transcription for interleaved multichannel audio.
-
channels 2 | 3 | 4 | 5 | 6 | 7 | 8
Number of interleaved audio channels.
-
diarize boolean
Enables speaker diarization.
-
keyterm string | string[]
One or more terms to bias transcription toward.
-
fillerWords boolean
Includes filler words such as
uhandumin the transcript. -
streaming object
Options for streaming speech-to-text over WebSocket. Use with
experimental_streamTranscribe.-
interimResults boolean
Emits partial transcripts while speech is being processed.
-
endpointing number
Silence duration in milliseconds before an utterance-final event. Range: 0-5000.
-
smartTurn number
End-of-turn detection threshold. When set, enables Smart Turn. Range: 0.0-1.0.
-
smartTurnTimeout number
Maximum silence duration in milliseconds before forcing
speech_final. Range: 1-5000.
-
Model Capabilities
| Model | Request/Response | Streaming | Word Timestamps | Diarization | Multichannel |
|---|---|---|---|---|---|
default |
Word timestamps, diarization results, and segments are only returned on the
request/response path (transcribe). Streaming transcription
(experimental_streamTranscribe) emits partial and final transcript text with
utterance-level timing, but does not surface per-word timestamps, speaker
labels, or segments.
Image Models
You can create xAI image models using the .image() factory method. For more on image generation with the AI SDK see generateImage().
import { xai } from '@ai-sdk/xai';import { generateImage } from 'ai';
const { image } = await generateImage({ model: xai.image('grok-imagine-image'), prompt: 'A futuristic cityscape at sunset',});The xAI image model does not support the size parameter. Use aspectRatio
instead. Supported aspect ratios: 1:1, 16:9, 9:16, 4:3, 3:4, 3:2,
2:3, 2:1, 1:2, 19.5:9, 9:19.5, 20:9, 9:20, and auto.
Image Editing
xAI supports image editing through the grok-imagine-image model. Pass input images via prompt.images to transform or edit existing images.
xAI image editing does not support masks. Editing is prompt-driven - describe what you want to change in the text prompt.
Basic Image Editing
Transform an existing image using text prompts:
import { xai } from '@ai-sdk/xai';import { generateImage } from 'ai';import { readFileSync } from 'fs';
const imageBuffer = readFileSync('./input-image.png');
const { images } = await generateImage({ model: xai.image('grok-imagine-image'), prompt: { text: 'Turn the cat into a golden retriever dog', images: [imageBuffer], },});Multi-Image Editing
Combine or reference multiple input images in the prompt:
import { xai } from '@ai-sdk/xai';import { generateImage } from 'ai';import { readFileSync } from 'fs';
const cat = readFileSync('./cat.png');const dog = readFileSync('./dog.png');
const { images } = await generateImage({ model: xai.image('grok-imagine-image'), prompt: { text: 'Combine these two animals into a group photo', images: [cat, dog], },});Style Transfer
Apply artistic styles to an image:
const imageBuffer = readFileSync('./input-image.png');
const { images } = await generateImage({ model: xai.image('grok-imagine-image'), prompt: { text: 'Transform this into a watercolor painting style', images: [imageBuffer], }, aspectRatio: '1:1',});Input images can be provided as Buffer, ArrayBuffer, Uint8Array, or
base64-encoded strings.
Image Provider Options
You can customize the image generation behavior with provider-specific settings via providerOptions.xai:
import { xai, type XaiImageModelOptions } from '@ai-sdk/xai';import { generateImage } from 'ai';
const { images } = await generateImage({ model: xai.image('grok-imagine-image-pro'), prompt: 'A futuristic cityscape at sunset', aspectRatio: '16:9', providerOptions: { xai: { resolution: '2k', quality: 'high', } satisfies XaiImageModelOptions, },});-
resolution '1k' | '2k'
Output resolution.
1kproduces ~1024×1024 images,2kproduces ~2048×2048 images (actual dimensions vary based on aspect ratio). Available forgrok-imagine-image-pro. -
quality 'low' | 'medium' | 'high'
Image quality level. Higher quality may increase generation time.
Image Model Capabilities
| Model | Resolution | Aspect Ratios | Image Editing |
|---|---|---|---|
grok-imagine-image-pro | 1k, 2k | 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 2:1, 1:2, 19.5:9, 9:19.5, 20:9, 9:20, auto | |
grok-imagine-image | 1k | 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 2:1, 1:2, 19.5:9, 9:19.5, 20:9, 9:20, auto |
Video Models
You can create xAI video models using the .video() factory method.
For more on video generation with the AI SDK see generateVideo().
This provider supports standard video generation from text prompts or image input, plus explicit video editing, video extension, and reference-to-video (R2V) operations.
Text-to-Video
Generate videos from text prompts:
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';
const { video } = await generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'A chicken flying into the sunset in the style of 90s anime.', aspectRatio: '16:9', duration: 5, providerOptions: { xai: { user: 'user-123', pollTimeoutMs: 600000, // 10 minutes } satisfies XaiVideoModelOptions, },});Generation with Image Input
Generate videos using an image as the starting frame with an optional text prompt. This uses the standard generation path rather than a separate provider mode:
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';
const { video } = await generateVideo({ model: xai.video('grok-imagine-video'), prompt: { image: 'https://example.com/start-frame.png', text: 'The cat slowly turns its head and blinks', }, duration: 5, providerOptions: { xai: { pollTimeoutMs: 600000, // 10 minutes } satisfies XaiVideoModelOptions, },});You can also pass the starting frame via the top-level frameImages option using the first_frame role. This is provider-agnostic and accepts file data (e.g. a Buffer) or a { type: 'url', url } object:
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';import fs from 'node:fs';
const { video } = await generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'The cat slowly turns its head and blinks', frameImages: [ { image: fs.readFileSync('./start-frame.png'), frameType: 'first_frame', }, ], duration: 5, providerOptions: { xai: { pollTimeoutMs: 600000, // 10 minutes } satisfies XaiVideoModelOptions, },});xAI does not support first-last-frame interpolation. A last_frame entry in
frameImages is ignored with a warning — use the extend-video mode to
continue from a video's last frame instead.
Video Editing
Edit an existing video using a text prompt by providing a source video URL via provider options:
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';
const { video } = await generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'Give the person sunglasses and a hat', providerOptions: { xai: { mode: 'edit-video', videoUrl: 'https://example.com/source-video.mp4', pollTimeoutMs: 600000, // 10 minutes } satisfies XaiVideoModelOptions, },});Video editing accepts input videos up to 8.7 seconds long. The duration,
aspectRatio, and resolution parameters are not supported for editing - the
output matches the input video's properties (capped at 720p).
Chaining and Concurrent Edits
The xAI-hosted video URL is available in providerMetadata.xai.videoUrl.
You can use it to chain sequential edits or branch into concurrent edits
using Promise.all:
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';
const providerOptions = { xai: { mode: 'edit-video', videoUrl: 'https://example.com/source-video.mp4', pollTimeoutMs: 600000, } satisfies XaiVideoModelOptions,};
// Step 1: Apply an initial editconst step1 = await generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'Add a party hat to the person', providerOptions,});
// Get the xAI-hosted URL from provider metadataconst step1VideoUrl = step1.providerMetadata?.xai?.videoUrl as string;
// Step 2: Apply two more edits concurrently, building on step 1const [withSunglasses, withScarf] = await Promise.all([ generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'Add sunglasses', providerOptions: { xai: { mode: 'edit-video', videoUrl: step1VideoUrl, pollTimeoutMs: 600000, }, }, }), generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'Add a scarf', providerOptions: { xai: { mode: 'edit-video', videoUrl: step1VideoUrl, pollTimeoutMs: 600000, }, }, }),]);Video Extension
Extend an existing video from its last frame. The duration controls the length of the extension only, not the total output. The output inherits aspectRatio and resolution from the source video.
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';
// Step 1: Generate a source videoconst source = await generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'A cat sitting on a sunlit windowsill, tail gently swishing.', duration: 5, aspectRatio: '16:9', providerOptions: { xai: { pollTimeoutMs: 600000, } satisfies XaiVideoModelOptions, },});
const sourceUrl = source.providerMetadata?.xai?.videoUrl as string;
// Step 2: Extend the video with a new sceneconst extended = await generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'The cat turns its head, notices a butterfly, and leaps off.', duration: 6, providerOptions: { xai: { mode: 'extend-video', videoUrl: sourceUrl, pollTimeoutMs: 600000, } satisfies XaiVideoModelOptions, },});Video extension does not support custom aspectRatio or resolution — the
output inherits those from the source video. duration is supported and
controls how long the extension is (not the total video length).
Reference-to-Video (R2V)
Provide reference images to guide the video's style and content. Unlike image-to-video, reference images are not used as the first frame — the model incorporates their visual elements into the generated video. Each reference image can be a public HTTPS URL or a base64 data URI.
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';
const { video } = await generateVideo({ model: xai.video('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.', duration: 8, aspectRatio: '16:9', providerOptions: { xai: { mode: 'reference-to-video', referenceImageUrls: [ 'https://example.com/comic-cat.png', 'https://example.com/comic-dog.png', ], pollTimeoutMs: 600000, } satisfies XaiVideoModelOptions, },});Use <IMAGE_1>, <IMAGE_2>, etc. in your prompt to reference specific images. Up to 7 reference images are supported per request.
Alternatively, use the provider-agnostic top-level inputReferences option. Providing it automatically selects reference-to-video mode, and it accepts file data (e.g. a Buffer) or { type: 'url', url } objects:
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';import fs from 'node:fs';
const { video } = await generateVideo({ model: xai.video('grok-imagine-video'), prompt: 'The comic cat and the comic dog are having a playful chase ' + 'through a sunlit park. Cinematic slow-motion, warm afternoon light.', inputReferences: [ fs.readFileSync('./comic-cat.png'), fs.readFileSync('./comic-dog.png'), ], duration: 8, aspectRatio: '16:9', providerOptions: { xai: { pollTimeoutMs: 600000, } satisfies XaiVideoModelOptions, },});inputReferences accepts image references only. A reference with a non-image
media type (for example a video or audio clip) is ignored with a warning, and a
reference with no media type is treated as an image. If no image reference
remains, reference-to-video is not selected and no reference images are sent.
Reference Audio
Reference-to-video can also give the subject a voice. referenceVoiceIds takes
up to 3 xAI preset voice ids — you cannot upload your own audio clips.
Reference the voices from the prompt with <AUDIO_0>, <AUDIO_1>, and
<AUDIO_2>, in the order the voices are passed.
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';import { experimental_generateVideo as generateVideo } from 'ai';
const { video } = await generateVideo({ model: xai.video('grok-imagine-video-1.5'), prompt: 'The person from <IMAGE_0> stands in the room from <IMAGE_1> and speaks ' + 'to the camera with the voice from <AUDIO_0>.', aspectRatio: '9:16', duration: 10, providerOptions: { xai: { mode: 'reference-to-video', referenceImageUrls: [ 'https://example.com/person.png', 'https://example.com/room.png', ], referenceVoiceIds: ['eve'], resolution: '720p', pollTimeoutMs: 600000, } satisfies XaiVideoModelOptions, },});Valid voice ids come from the xAI
text-to-speech voice roster.
Ids are case-insensitive, and an unknown id returns a 400 response listing the
available voices. referenceVoiceIds is ignored with a warning when the
resolved operation is not reference-to-video.
xAI documents reference audio as available in the United States only, for trusted partners. Requests from accounts without access are rejected by the xAI API.
Reference-to-video supports duration, aspectRatio, and resolution. Use
mode to select the operation — each mode is mutually exclusive. When both
are provided, frameImages takes precedence over inputReferences, and
inputReferences takes precedence over the legacy referenceImageUrls
provider option. Reference-to-video is supported by the grok-imagine-video
and grok-imagine-video-1.5 models; native 1080p requires
grok-imagine-video-1.5.
Video Provider Options
The following provider options are available via providerOptions.xai.
You can validate the provider options using the XaiVideoModelOptions type.
-
pollIntervalMs number
Polling interval in milliseconds for checking task status. Defaults to 5000.
-
pollTimeoutMs number
Maximum wait time in milliseconds for video generation. Defaults to 600000 (10 minutes).
-
resolution '480p' | '720p' | '1080p'
Video resolution. When using the SDK's standard
resolutionparameter,1920x1080maps to1080p,1280x720maps to720p, and854x480maps to480p. Use this provider option to pass the native format directly.1080prequires thegrok-imagine-video-1.5model and is available for text-to-video and image-to-video; reference-to-video is capped at720p(a1080prequest is downgraded with a warning). -
user string
Optional identifier for the end user responsible for the request. xAI uses this value for abuse monitoring. It is sent unchanged for video generation (including reference-to-video) and video editing requests, and is omitted when not configured. It is not sent for video extension requests. Use an opaque stable identifier and avoid sending unnecessary personal information.
-
mode 'edit-video' | 'extend-video' | 'reference-to-video'
Selects the explicit video operation. Each mode is mutually exclusive:
'edit-video'— edit an existing video (requiresvideoUrl)'extend-video'— extend a video from its last frame (requiresvideoUrl)'reference-to-video'— generate from reference images (requiresreferenceImageUrls)
When omitted, standard generation is used. Legacy inputs are still auto-detected from fields for backward compatibility.
-
videoUrl string
URL of a source video. Used with
mode: 'edit-video'for video editing andmode: 'extend-video'for video extension. -
referenceImageUrls string[]
Array of reference image URLs (1–7 images) or base64 data URIs for reference-to-video (R2V) generation. The model incorporates visual elements from these images without using them as the first frame. Use
<IMAGE_1>,<IMAGE_2>, etc. in the prompt to reference specific images. Used withmode: 'reference-to-video'. -
referenceVoiceIds string[]
Up to 3 xAI preset voice ids that give the subject a voice in reference-to-video (R2V) generation. Preset voices only — audio clips cannot be uploaded. Ids are case-insensitive and come from the text-to-speech voice roster; an unknown id returns a
400listing the available voices. Use<AUDIO_0>,<AUDIO_1>, and<AUDIO_2>tags in the prompt to reference the voices. Ignored with a warning outside reference-to-video. Reference audio is documented as US-only and limited to trusted partners.
Video generation is an asynchronous process that can take several minutes.
Consider setting pollTimeoutMs to at least 10 minutes (600000ms) for
reliable operation. Generated video URLs are ephemeral and should be
downloaded promptly.
Aspect Ratio and Resolution
For text-to-video, you can specify both aspectRatio and resolution.
The default aspect ratio is 16:9 and the default resolution is 480p. The
grok-imagine-video-1.5 model additionally supports native 1080p for
text-to-video and image-to-video.
For image-to-video, the output defaults to the input image's aspect ratio.
If you specify aspectRatio, it will override this and stretch the image to the
desired ratio.
For video editing, the output matches the input video's aspect ratio and
resolution. Custom duration, aspectRatio, and resolution are not
supported — the output resolution is capped at 720p (e.g., a 1080p input
will be downsized to 720p).
For video extension, the output inherits aspectRatio and resolution
from the source video. duration is supported and controls only the
extension length.
For reference-to-video (R2V), you can specify duration, aspectRatio,
and resolution. Unlike text-to-video, R2V is capped at 720p — a 1080p
request is downgraded to 720p with a warning.
Video Model Capabilities
| Model | Duration | Aspect Ratios | Resolution | Image-to-Video | Editing | Extension | R2V |
|---|---|---|---|---|---|---|---|
grok-imagine-video | 1–15s | 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3 | 480p, 720p | ||||
grok-imagine-video-1.5 | 1–15s | 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3 | 480p, 720p, 1080p* |
* Native 1080p applies to text-to-video and image-to-video. Reference-to-video
is capped at 720p — a 1080p request is downgraded with a warning.
You can also pass any available provider model ID as a string if needed.