---
title: xAI Grok
description: Learn how to use xAI with AI Gateway and the direct provider.
url: "https://ai-sdk.dev/providers/ai-sdk-providers/xai"
docs_index: /llms.txt
---

> For an index of all documentation, see [/llms.txt](/llms.txt).

The [xAI Grok](https://x.ai) provider contains language model support for the [xAI API](https://x.ai/api).
You can use xAI models through [AI Gateway](/providers/ai-sdk-providers/ai-gateway) (recommended) or connect directly with `@ai-sdk/xai`.

```ts provider="xai" model="spacexai/grok-4.7"
import { generateText } from 'ai';

const { text } = await generateText({
  model: "spacexai/grok-4.7",
  prompt: 'Write a vegetarian lasagna recipe for 4 people.',
});

console.log(text);
```

## Using AI Gateway

The AI SDK uses AI Gateway by default for model strings. Gateway provides access to models across providers through a single API key, with usage and cost tracking. Install `ai`:

```bash
pnpm add ai
```

Set an [AI Gateway API key](https://vercel.com/docs/ai-gateway/getting-started) in your environment:

```bash
export AI_GATEWAY_API_KEY=your_api_key_here
```

Vercel deployments can also use [OIDC authentication](/providers/ai-sdk-providers/ai-gateway#oidc-authentication-vercel-deployments).
See the [AI Gateway provider documentation](/providers/ai-sdk-providers/ai-gateway) for configuration and the [model catalog](https://vercel.com/ai-gateway/models) for available models.

Gateway feature and provider-option support depends on the model and the provider serving the request. See [Gateway provider options](https://vercel.com/docs/ai-gateway/models-and-providers/provider-options).

## Using `@ai-sdk/xai`

For direct access to xAI, install `ai` and `@ai-sdk/xai`:

```bash
pnpm add ai @ai-sdk/xai
```

Set your xAI API credential in the `XAI_API_KEY` environment variable:

```bash
export XAI_API_KEY=your_api_key_here
```

AI Gateway does not expose every API in `@ai-sdk/xai`. Use the direct provider for provider-specific APIs or custom connection settings.

The following sections document the direct `@ai-sdk/xai` provider, including
its model factories and settings. Gateway model and feature availability can
differ.

## Provider Instance

You can import the default provider instance `xai` from `@ai-sdk/xai`:

```ts
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:

```ts
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 `Authorization` header. It defaults to
  the `XAI_API_KEY` environment variable.

- **headers** *Record\<string,string>*

  Custom headers to include in the requests.

- **fetch** *(input: RequestInfo, init?: RequestInit) => Promise\<Response>*

  Custom [fetch](https://developer.mozilla.org/en-US/docs/Web/API/fetch) implementation.
  Defaults to the global `fetch` function.
  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](https://console.x.ai) using a provider instance. The
first argument is the model id, e.g. `grok-4.7`.

```ts
const model = xai('grok-4.7');
```

### Example

You can use xAI language models to generate text with the `generateText` function:

```ts
import { xai } from '@ai-sdk/xai';
import { generateText } from 'ai';

const { text } = await generateText({
  model: xai('grok-4.7'),
  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`](/docs/reference/ai-sdk-core/output)
(see [AI SDK Core](/docs/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`.

```ts
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 by `grok-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](https://docs.x.ai/developers/model-capabilities/text/reasoning) and
[Grok 4.6 model page](https://docs.x.ai/developers/models/grok-4.6) 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.

```ts
import { xai } from '@ai-sdk/xai';
import { generateText } from 'ai';

const { providerMetadata } = await generateText({
  model: xai('grok-4.7'),
  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](https://docs.x.ai/developers/advanced-api-usage/priority-processing).

## Realtime Models

Realtime is an experimental feature.

You can create models that call the [xAI Realtime API](https://docs.x.ai/docs/guides/realtime)
using the `.experimental_realtime()` factory method.

```ts
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()`:

```ts
const token = await xai.experimental_realtime.getToken({
  model: 'grok-voice-latest',
});
```

See [Realtime](/docs/ai-sdk-core/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.

```ts
const model = xai.responses('grok-4.7');
```

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:

```ts
import { xai } from '@ai-sdk/xai';
import { generateText } from 'ai';

const { text } = await generateText({
  model: xai.responses('grok-4.7'),
  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:

```ts
import { xai } from '@ai-sdk/xai';
import { generateText } from 'ai';

const { text } = await generateText({
  model: xai('grok-4.7'),
  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:

```ts
import { xai } from '@ai-sdk/xai';
import { generateText } from 'ai';

const { text, sources } = await generateText({
  model: xai.responses('grok-4.7'),
  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);
```

Each citation is returned as one `source`. With `streamText`, each citation is emitted once as a `source` stream part, as soon as it is added.

#### 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:

```ts
const { text, sources } = await generateText({
  model: xai.responses('grok-4.7'),
  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 20). Cannot be used with `excludedXHandles`.

- **excludedXHandles** *string\[]*

  Exclude posts from specified X handles (max 20). 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:

```ts
const { text } = await generateText({
  model: xai.responses('grok-4.7'),
  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:

```ts
const { text } = await generateText({
  model: xai.responses('grok-4.7'),
  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:

```ts
const { text } = await generateText({
  model: xai.responses('grok-4.7'),
  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:

```ts
import { xai } from '@ai-sdk/xai';
import { generateText } from 'ai';

const result = await generateText({
  model: xai.responses('grok-4.7'),
  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)](https://modelcontextprotocol.io/) servers and use their tools:

```ts
const { text } = await generateText({
  model: xai.responses('grok-4.7'),
  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):

```ts
import { xai, type XaiLanguageModelResponsesOptions } from '@ai-sdk/xai';
import { streamText } from 'ai';

const result = streamText({
  model: xai.responses('grok-4.7'),
  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](https://docs.x.ai/docs/guides/using-collections/api).

### Multiple Tools

You can combine multiple server-side tools for comprehensive research:

```ts
import { xai } from '@ai-sdk/xai';
import { streamText } from 'ai';

const { stream } = streamText({
  model: xai.responses('grok-4.7'),
  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:

```ts
import { xai, type XaiLanguageModelResponsesOptions } from '@ai-sdk/xai';
import { generateText } from 'ai';

const result = await generateText({
  model: xai.responses('grok-4.7'),
  providerOptions: {
    xai: {
      reasoningEffort: 'high',
    } satisfies XaiLanguageModelResponsesOptions,
  },
  // ...
});
```

The following provider options are available:

- **reasoningEffort** *'none' | 'low' | 'medium' | 'high' | 'xhigh'*

  Control the reasoning effort for supported models. See [Reasoning Effort](#reasoning-effort) for model-specific values and defaults.

- **logprobs** *boolean*

  Return log probabilities for output tokens. This is silently ignored by `grok-4.20` and newer models.

- **topLogprobs** *number*

  Number of most likely tokens to return per token position (0-8). When set, `logprobs` is automatically enabled. This is silently ignored by `grok-4.20` and newer models.

- **minP** *number*

  Set the min-p sampling threshold between 0 and 1. Tokens whose probability is below `minP` times the most likely token's probability are excluded. Unlike the standard AI SDK `topK` option, `minP` is xAI-specific and must be set in `providerOptions.xai`.

- **maxTurns** *number*

  Set the maximum number of assistant/server-side tool turns xAI may perform within one API request. This limits xAI's internal loop for provider-executed tools such as web search; it is separate from AI SDK's `stopWhen`, which limits the outer loop of AI SDK steps and API requests.

- **parallelToolCalls** *boolean*

  Allow the model to call tools in parallel. Defaults to `true`.

- **promptCacheKey** *string*

  Route requests with shared prompt prefixes to improve cache reuse.

- **safetyIdentifier** *string*

  Provide a stable, preferably hashed end-user identifier for safety monitoring.

- **user** *string*

  Provide an end-user identifier for abuse monitoring.

- **include** *Array\<'file\_search\_call.results' | 'web\_search\_call.action.sources' | 'code\_interpreter\_call.outputs' | 'reasoning.encrypted\_content' | 'no\_inline\_citations'>*

  Include file-search results, web-search sources, code-interpreter outputs, or encrypted reasoning content, or disable inline citations.

- **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 on `providerMetadata.xai.serviceTier`, and is `'default'` when priority capacity was unavailable. See [Priority Processing](https://docs.x.ai/developers/advanced-api-usage/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.

## Batch

Batch support is experimental and the API may change in patch releases.

The xAI provider supports asynchronous text generation through the [Batch
API](https://docs.x.ai/developers/advanced-api-usage/batch-api). Pass the xAI
provider to the AI SDK's [Batch](/docs/ai-sdk-core/batch) API
for the complete workflow, including polling, persistence, and result handling.

Each request specifies its `type` and `model`. xAI supports using different
text models within the same batch.

The xAI Batch API does not support per-batch webhooks. When you provide a
`webhookUrl`, the provider returns an unsupported warning and starts the batch
without a webhook.

## 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](https://docs.x.ai/docs#models) 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](https://docs.x.ai/developers/model-capabilities/audio/text-to-speech)
using the `.speech()` factory method. xAI's text-to-speech endpoint does not
require a model identifier.

```ts
const model = xai.speech();
```

Use xAI speech models with the `generateSpeech` function:

```ts
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.7` to `1.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`:

```ts
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 `outputFormat` is
  `'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.

- **withTimestamps** *boolean*

  Return character-level timing metadata alongside the audio. The timing data
  and total duration are exposed via `providerMetadata.xai` (see below).

- **replace** *Record\<string, string>*

  Map of phrases to spoken substitutions applied before synthesis. Values may
  be respellings (`{ 'Acme Mobile': 'Acme Mobull' }`) or IPA phonetics
  (`{ nginx: '/ˈɛndʒɪn ˈɛks/' }`).

### Provider Metadata

xAI speech results include provider-specific metadata under
`providerMetadata.xai`:

- **traceId** *string* — the xAI trace ID for the request, useful for
  debugging with xAI support.
- **duration** *number* — total audio duration in seconds (only with
  `withTimestamps`).
- **contentType** *string* — MIME type of the decoded audio, e.g.
  `'audio/mpeg'` (only with `withTimestamps`).
- **audioTimestamps** `{ graphChars: string[]; graphTimes: [number, number][] }` —
  per-character alignment data (only with `withTimestamps`). `graphChars[i]`
  is the character spoken during the `[start, end]` interval
  `graphTimes[i]`, in seconds.

```ts
const result = await generateSpeech({
  model: xai.speech(),
  text: 'Hello world.',
  providerOptions: {
    xai: { withTimestamps: true } satisfies XaiSpeechModelOptions,
  },
});

const { traceId, duration, audioTimestamps } = result.providerMetadata.xai;
```

### 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](https://docs.x.ai/developers/model-capabilities/audio/speech-to-text)
using the `.transcription()` factory method. The model identifier is optional:
pass `grok-voice-transcribe-2.0` to pin a model, or omit it to use xAI's
default transcription model. `grok-voice-transcribe-1.0` is retired, and
requests to it are routed to `grok-voice-transcribe-2.0`.

```ts
const model = xai.transcription('grok-voice-transcribe-2.0');
```

Use xAI transcription models with the `transcribe` function:

```ts
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`:

```ts
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` | `alaw` | `opus`*

  Input audio encoding for raw, headerless audio (`pcm`, `mulaw`, `alaw`).
  Container formats such as Ogg/Opus are auto-detected, so do not set
  `audioFormat` for them. `opus` is supported for streaming transcription only:
  each audio chunk must be exactly one raw Opus packet (not Ogg), and an
  `audio/opus` input audio type maps to `opus` automatically.

- **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 `uh` and `um` in the transcript.

- **vadThreshold** *number*

  Voice activity detection threshold. Range: 0.0-1.0. Defaults to `0.5` for
  `transcribe` and `0.08` for streaming. `0` disables the filter.

- **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`                   | ✓                | ✓         | ✓               | ✓           | ✓            |
| `grok-voice-transcribe-2.0` | ✓                | ✓         | ✓               | ✓           | ✓            |

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()](/docs/reference/ai-sdk-core/generate-image).

```ts
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:

```ts
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:

```ts
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:

```ts
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`:

```ts
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' | '1.5k' | '2k'*

  Output resolution: `1k` (default, \~1024×1024), `1.5k` (\~1408×1408), or `2k`
  (\~2048×2048). Actual dimensions vary based on aspect ratio.
  `grok-imagine-image` does not support `1.5k`.

- **quality** *'low' | 'medium' | 'high' | 'auto'*

  Image quality level. Only supported by `grok-imagine-image-2.0`, which accepts
  `low`, `medium`, and `auto`. `auto` is the default when omitted: it serves
  `low` for generation and `medium` for editing, billed at the quality served.
  `high` is not documented by xAI but is still accepted by older models, and is
  kept for backward compatibility.

### Image Model Capabilities

| Model                    | Resolution         | Aspect Ratios                                                                                                              | Image Editing |
| ------------------------ | ------------------ | -------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `grok-imagine-image-2.0` | `1k`, `1.5k`, `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`, `21:9`, `5:2`, `auto` | ✓             |
| `grok-imagine-image-pro` | `1k`, `1.5k`, `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`                | ✓             |

`grok-imagine-image-2.0` is xAI's latest image model.

## Video Models

You can create xAI video models using the `.video()` factory method.
For more on video generation with the AI SDK see [generateVideo()](/docs/reference/ai-sdk-core/generate-video).

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:

```ts
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: '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:

```ts
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: {
    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:

```ts
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-1.5'),
  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,
  },
});
```

`grok-imagine-video-1.5` supports first-last-frame interpolation. Earlier
models ignore a `last_frame` entry with a warning. Use `extend-video` when you
want to continue an existing video rather than pin its final frame.

### Video Editing

Edit an existing video using a text prompt by providing a source video URL via provider options:

```ts
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: '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`:

```ts
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 edit
const step1 = await generateVideo({
  model: xai.video('grok-imagine-video-1.5'),
  prompt: 'Add a party hat to the person',
  providerOptions,
});

// Get the xAI-hosted URL from provider metadata
const step1VideoUrl = step1.providerMetadata?.xai?.videoUrl as string;

// Step 2: Apply two more edits concurrently, building on step 1
const [withSunglasses, withScarf] = await Promise.all([
  generateVideo({
    model: xai.video('grok-imagine-video-1.5'),
    prompt: 'Add sunglasses',
    providerOptions: {
      xai: {
        mode: 'edit-video',
        videoUrl: step1VideoUrl,
        pollTimeoutMs: 600000,
      },
    },
  }),
  generateVideo({
    model: xai.video('grok-imagine-video-1.5'),
    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.

```ts
import { xai, type XaiVideoModelOptions } from '@ai-sdk/xai';
import { experimental_generateVideo as generateVideo } from 'ai';

// Step 1: Generate a source video
const source = await generateVideo({
  model: xai.video('grok-imagine-video-1.5'),
  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 scene
const extended = await generateVideo({
  model: xai.video('grok-imagine-video-1.5'),
  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.

```ts
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 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:

```ts
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-1.5'),
  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 and audio references. Audio references must
declare an audio media type and can be supplied alone or together with images;
they are sent through `reference_audios`. A reference with no media type is
treated as an image. Video references are ignored with a warning.

#### Reference Audio

Reference-to-video can also give the subject a voice. Use `inputReferences` for
caller-supplied audio clips, or `referenceVoiceIds` for up to 3 xAI preset voice
ids. Reference them from the prompt with `<AUDIO_0>`, `<AUDIO_1>`, and
`<AUDIO_2>`, in the order they are passed.

```ts
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](https://docs.x.ai/developers/model-capabilities/audio/text-to-speech#voices).
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.

Preset voices are generally available. Caller-supplied voice clips are
available to trusted partners on request. xAI accepts at most three audio
references per request.

Reference-to-video supports `duration`, `aspectRatio`, and `resolution`. Use
`mode` to select the operation — each mode is mutually exclusive.
`inputReferences` takes precedence over the legacy `referenceImageUrls`
provider option and can be combined with pinned frames. 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 `resolution` parameter,
  `1920x1080` maps to `1080p`, `1280x720` maps to `720p`, and `854x480` maps
  to `480p`. Use this provider option to pass the native format directly.
  `1080p` requires the `grok-imagine-video-1.5` model and is available for
  text-to-video and image-to-video; reference-to-video is capped at `720p`
  (a `1080p` request 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 (requires `videoUrl`)
  - `'extend-video'` — extend a video from its last frame (requires `videoUrl`)
  - `'reference-to-video'` — generate from reference images (requires `referenceImageUrls`)

  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
  and `mode: '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 with `mode: '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](https://docs.x.ai/developers/model-capabilities/audio/text-to-speech#voices);
  an unknown id returns a `400` listing 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.

- **storageOptions** *object*

  Stores the generated video in the xAI Files API. Set `filename` and
  optionally `expiresAfter` (up to 30 days) and `publicUrl`. Stored-file
  details and storage errors are returned in `providerMetadata.xai.fileOutput`
  and `providerMetadata.xai.storageError`.

- **keyframes** *Array\<\{ imageUrl: string; timestampSeconds: number }>*

  Up to four mid-video image anchors. Each timestamp must fall strictly inside
  the video duration. Keyframes are supported by `grok-imagine-video-1.5` and
  are ignored with a warning for editing and extension operations.

### Audio and Frame Controls

Use the provider-neutral `generateAudio` option to request or disable generated
audio. Use `frameImages` for exact endpoint frames:

```ts
const { video } = await generateVideo({
  model: xai.video('grok-imagine-video-1.5'),
  prompt: 'A paper boat drifting down a rain-soaked street',
  generateAudio: false,
  frameImages: [
    {
      frameType: 'last_frame',
      image: 'https://example.com/final-frame.png',
    },
  ],
});
```

`last_frame` is supported only by `grok-imagine-video-1.5`. The provider emits
an unsupported-feature warning and omits the field for other model IDs. A
`first_frame` is sent as xAI's standard `image` input.

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.

---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)