OpenAI Provider

The OpenAI provider contains language model support for the OpenAI responses, chat, and completion APIs, as well as embedding model support for the OpenAI embeddings API.

Setup

The OpenAI provider is available in the @ai-sdk/openai module. You can install it with

pnpm add @ai-sdk/openai

Provider Instance

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

import { openai } from '@ai-sdk/openai';

If you need a customized setup, you can import createOpenAI from @ai-sdk/openai and create a provider instance with your settings:

import { createOpenAI } from '@ai-sdk/openai';
const openai = createOpenAI({
// custom settings, e.g.
headers: {
'header-name': 'header-value',
},
});

You can use the following optional settings to customize the OpenAI provider instance:

  • baseURL string

    Use a different URL prefix for API calls, e.g. to use proxy servers. The default prefix is https://api.openai.com/v1.

  • apiKey string

    API key that is being sent using the Authorization header. It defaults to the OPENAI_API_KEY environment variable.

  • name string

    The provider name. You can set this when using OpenAI compatible providers to change the model provider property. Defaults to openai.

  • organization string

    OpenAI Organization.

  • project string

    OpenAI project.

  • 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 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

The OpenAI provider instance is a function that you can invoke to create a language model:

const model = openai('gpt-5');

It automatically selects the correct API based on the model id. You can also pass additional settings in the second argument:

const model = openai('gpt-5', {
// additional settings
});

The available options depend on the API that's automatically chosen for the model (see below). If you want to explicitly select a specific model API, you can use .responses, .chat, or .completion.

Since AI SDK 5, the OpenAI responses API is called by default (unless you specify e.g. 'openai.chat')

Example

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

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const { text } = await generateText({
model: openai('gpt-5'),
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
});

OpenAI language models can also be used in the streamText, generateObject, and streamObject functions (see AI SDK Core).

Responses Models

You can use the OpenAI responses API with the openai(modelId) or openai.responses(modelId) factory methods. It is the default API that is used by the OpenAI provider (since AI SDK 5).

const model = openai('gpt-5');

Further configuration can be done using OpenAI provider options. You can validate the provider options using the OpenAIResponsesProviderOptions type.

import { openai, OpenAIResponsesProviderOptions } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai('gpt-5'), // or openai.responses('gpt-5')
providerOptions: {
openai: {
parallelToolCalls: false,
store: false,
user: 'user_123',
// ...
} satisfies OpenAIResponsesProviderOptions,
},
// ...
});

The following provider options are available:

  • parallelToolCalls boolean Whether to use parallel tool calls. Defaults to true.

  • store boolean

    Whether to store the generation. Defaults to true.

  • maxToolCalls integer The maximum number of total calls to built-in tools that can be processed in a response. This maximum number applies across all built-in tool calls, not per individual tool. Any further attempts to call a tool by the model will be ignored.

  • metadata Record<string, string> Additional metadata to store with the generation.

  • conversation string The ID of the OpenAI Conversation to continue. You must create a conversation first via the OpenAI API. Cannot be used in conjunction with previousResponseId. Defaults to undefined.

  • previousResponseId string The ID of the previous response. You can use it to continue a conversation. Defaults to undefined.

  • instructions string Instructions for the model. They can be used to change the system or developer message when continuing a conversation using the previousResponseId option. Defaults to undefined.

  • user string A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. Defaults to undefined.

  • reasoningEffort 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' Reasoning effort for reasoning models. Defaults to medium. If you use providerOptions to set the reasoningEffort option, this model setting will be ignored.

Supported reasoning efforts vary by model. GPT-5.6 supports 'none', 'low', 'medium', 'high', 'xhigh', and 'max'. GPT-6 and later models support 'low', 'medium', 'high', 'xhigh', and 'max'.

GPT-6 and later models do not support temperature, topP, logprobs, or the legacy promptCacheRetention option. The provider removes these settings and returns a warning. Use the Responses API for GPT-6 tool calling.

  • reasoningEffortUpdate 'low' | 'medium' | 'high' | 'xhigh' | 'max' Updates the reasoning effort for GPT-6 and later models starting with the current response without changing the request-level effort. Use this with previousResponseId to preserve the original prompt prefix for caching. Configuration updates require standard, single-agent mode and cannot be combined with automatic truncation.

  • reasoningMode 'standard' | 'pro' Controls how much model work GPT-5.6 performs before returning a final answer. 'standard' is the default. Use 'pro' for difficult tasks where quality matters more than latency and token usage.

  • reasoningContext 'auto' | 'current_turn' | 'all_turns' Controls which available reasoning items GPT-5.6 can reuse. 'auto' uses the model default, 'current_turn' excludes reasoning from earlier turns, and 'all_turns' makes compatible earlier reasoning available. The effective context is returned as providerMetadata.openai.reasoningContext.

  • reasoningSummary 'auto' | 'detailed' Controls whether the model returns its reasoning process. Set to 'auto' for a condensed summary, 'detailed' for more comprehensive reasoning. Defaults to undefined (no reasoning summaries). When enabled, reasoning summaries appear in the stream as events with type 'reasoning' and in non-streaming responses within the reasoning field.

  • strictJsonSchema boolean Whether to use strict JSON schema validation. Defaults to false.

  • serviceTier 'auto' | 'flex' | 'priority' | 'default' Service tier for the request. Set to 'flex' for 50% cheaper processing at the cost of increased latency (available for o3, o4-mini, and gpt-5 models). Set to 'priority' for faster processing with Enterprise access (available for gpt-4, gpt-5, gpt-5-mini, o3, o4-mini; gpt-5-nano is not supported).

    Defaults to 'auto'.

  • textVerbosity 'low' | 'medium' | 'high' Controls the verbosity of the model's response. Lower values result in more concise responses, while higher values result in more verbose responses. Defaults to 'medium'.

  • include Array<string> Specifies additional content to include in the response. Supported values: ['file_search_call.results'] for including file search results in responses. ['message.output_text.logprobs'] for logprobs. Defaults to undefined.

  • truncation string The truncation strategy to use for the model response.

    • Auto: If the input to this Response exceeds the model's context window size, the model will truncate the response to fit the context window by dropping items from the beginning of the conversation.
    • disabled (default): If the input size will exceed the context window size for a model, the request will fail with a 400 error.
  • promptCacheKey string A cache key for manual prompt caching control. Used by OpenAI to cache responses for similar requests to optimize your cache hit rates.

  • promptCacheOptions object Configures prompt caching for GPT-5.6 and later models. mode can be 'implicit' or 'explicit', and ttl currently only supports '30m'. In explicit mode, only content blocks marked with a prompt cache breakpoint are cached.

  • promptCacheRetention 'in_memory' | '24h' The legacy retention policy for models before GPT-5.6. Set to '24h' to enable extended prompt caching on supported models. For GPT-5.6 and later models, use promptCacheOptions.ttl instead.

  • safetyIdentifier string A stable identifier used to help detect users of your application that may be violating OpenAI's usage policies. The IDs should be a string that uniquely identifies each user.

The OpenAI responses provider also returns provider-specific metadata:

const { usage, providerMetadata } = await generateText({
model: openai.responses('gpt-5'),
});
const openaiMetadata = providerMetadata?.openai as
| {
responseId?: string;
reasoningContext?: string;
usage?: { cacheWriteTokens?: number };
}
| undefined;
console.log('Cache reads:', usage.cachedInputTokens);
console.log('Reasoning tokens:', usage.reasoningTokens);
console.log('Cache writes:', openaiMetadata?.usage?.cacheWriteTokens);

The following OpenAI-specific metadata is returned:

  • responseId string The ID of the response. Can be used to continue a conversation.

  • reasoningContext string The effective persisted-reasoning context returned by GPT-5.6.

  • usage.cacheWriteTokens number The number of input tokens written to the prompt cache.

Changing Reasoning Effort Mid-Conversation

GPT-6 and later models can change reasoning effort between responses without changing the request-level reasoningEffort setting. The provider sends reasoningEffortUpdate as an OpenAI configuration_update input item before the next user message. Keeping the request-level effort unchanged preserves the original prompt prefix for prompt caching.

import { openai, type OpenAIResponsesProviderOptions } from '@ai-sdk/openai';
import { generateText } from 'ai';
const first = await generateText({
model: openai.responses('gpt-6-astra'),
prompt: 'Draft a database migration plan.',
providerOptions: {
openai: {
reasoningEffort: 'low',
} satisfies OpenAIResponsesProviderOptions,
},
});
const previousResponseId = first.providerMetadata?.openai.responseId as
| string
| undefined;
if (!previousResponseId) {
throw new Error('OpenAI did not return a response ID.');
}
const second = await generateText({
model: openai.responses('gpt-6-astra'),
prompt: 'Analyze the failure modes and propose rollback steps.',
providerOptions: {
openai: {
previousResponseId,
reasoningEffort: 'low',
reasoningEffortUpdate: 'high',
} satisfies OpenAIResponsesProviderOptions,
},
});

The response metadata continues to report the request-level reasoning effort, not the effective effort selected by reasoningEffortUpdate. Configuration updates are not supported with reasoningMode: 'pro' or truncation: 'auto'.

Reasoning Output

For reasoning models like gpt-5, you can enable reasoning summaries to see the model's thought process. Different models support different summarizers—for example, o4-mini supports detailed summaries. Set reasoningSummary: "auto" to automatically receive the richest level available.

import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
const result = streamText({
model: openai('gpt-5'),
prompt: 'Tell me about the Mission burrito debate in San Francisco.',
providerOptions: {
openai: {
reasoningSummary: 'detailed', // 'auto' for condensed or 'detailed' for comprehensive
},
},
});
for await (const part of result.fullStream) {
if (part.type === 'reasoning') {
console.log(`Reasoning: ${part.textDelta}`);
} else if (part.type === 'text-delta') {
process.stdout.write(part.textDelta);
}
}

For non-streaming calls with generateText, the reasoning summaries are available in the reasoning field of the response:

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai('gpt-5'),
prompt: 'Tell me about the Mission burrito debate in San Francisco.',
providerOptions: {
openai: {
reasoningSummary: 'auto',
},
},
});
console.log('Reasoning:', result.reasoning);

Learn more about reasoning summaries in the OpenAI documentation.

Verbosity Control

You can control the length and detail of model responses using the textVerbosity parameter:

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai('gpt-5-mini'),
prompt: 'Write a poem about a boy and his first pet dog.',
providerOptions: {
openai: {
textVerbosity: 'low', // 'low' for concise, 'medium' (default), or 'high' for verbose
},
},
});

The textVerbosity parameter scales output length without changing the underlying prompt:

  • 'low': Produces terse, minimal responses
  • 'medium': Balanced detail (default)
  • 'high': Verbose responses with comprehensive detail

Web Search Tool

The OpenAI responses API supports web search through the openai.tools.webSearch tool.

const result = await generateText({
model: openai('gpt-5'),
prompt: 'What happened in San Francisco last week?',
tools: {
web_search: openai.tools.webSearch({
// optional configuration:
externalWebAccess: true,
searchContextSize: 'high',
userLocation: {
type: 'approximate',
city: 'San Francisco',
region: 'California',
},
filters: {
allowedDomains: ['sfchronicle.com', 'sfgate.com'],
blockedDomains: ['example.com'],
},
}),
},
// Force web search tool (optional):
toolChoice: { type: 'tool', toolName: 'web_search' },
});
// URL sources
const sources = result.sources;

The web search tool supports the following configuration options:

  • externalWebAccess boolean - Whether to use external web access for fetching live content. Defaults to true.
  • searchContextSize 'low' | 'medium' | 'high' - Controls the amount of context used for the search. Higher values provide more comprehensive results but may have higher latency and cost.
  • userLocation - Optional location information to provide geographically relevant results. Includes type (always 'approximate'), country, city, region, and timezone.
  • filters - Optional filter configuration to restrict search results.
    • allowedDomains string[] - Up to 100 allowed domains for the search.
    • blockedDomains string[] - Up to 100 blocked domains for the search.

Omit the HTTP or HTTPS prefix from domain filters. Subdomains of configured domains are automatically included or excluded.

For detailed information on configuration options see the OpenAI Web Search Tool documentation.

File Search Tool

The OpenAI responses API supports file search through the openai.tools.fileSearch tool.

You can force the use of the file search tool by setting the toolChoice parameter to { type: 'tool', toolName: 'file_search' }.

const result = await generateText({
model: openai('gpt-5'),
prompt: 'What does the document say about user authentication?',
tools: {
file_search: openai.tools.fileSearch({
vectorStoreIds: ['vs_123'],
// configuration below is optional:
maxNumResults: 5,
filters: {
key: 'author',
type: 'eq',
value: 'Jane Smith',
},
ranking: {
ranker: 'auto',
scoreThreshold: 0.5,
},
}),
},
providerOptions: {
openai: {
// optional: include results
include: ['file_search_call.results'],
} satisfies OpenAIResponsesProviderOptions,
},
});

The tool must be named file_search when using OpenAI's file search functionality. This name is required by OpenAI's API specification and cannot be customized.

Image Generation Tool

OpenAI's Responses API supports multi-modal image generation as a provider-defined tool. Availability is restricted to specific models (for example, gpt-5 variants).

You can use the image tool with either generateText or streamText:

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai('gpt-5'),
prompt:
'Generate an image of an echidna swimming across the Mozambique channel.',
tools: {
image_generation: openai.tools.imageGeneration({ outputFormat: 'webp' }),
},
});
for (const toolResult of result.staticToolResults) {
if (toolResult.toolName === 'image_generation') {
const base64Image = toolResult.output.result;
}
}
import { openai } from '@ai-sdk/openai';
import { streamText } from 'ai';
const result = streamText({
model: openai('gpt-5'),
prompt:
'Generate an image of an echidna swimming across the Mozambique channel.',
tools: {
image_generation: openai.tools.imageGeneration({
outputFormat: 'webp',
quality: 'low',
}),
},
});
for await (const part of result.fullStream) {
if (part.type == 'tool-result' && !part.dynamic) {
const base64Image = part.output.result;
}
}

When you set store: false, then previously generated images will not be accessible by the model. We recommend using the image generation tool without setting store: false.

For complete details on model availability, image quality controls, supported sizes, and tool-specific parameters, refer to the OpenAI documentation:

Code Interpreter Tool

The OpenAI responses API supports the code interpreter tool through the openai.tools.codeInterpreter tool. This allows models to write and execute Python code.

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai('gpt-5'),
prompt: 'Write and run Python code to calculate the factorial of 10',
tools: {
code_interpreter: openai.tools.codeInterpreter({
// optional configuration:
container: {
fileIds: ['file-123', 'file-456'], // optional file IDs to make available
},
}),
},
});

The code interpreter tool can be configured with:

  • container: Either a container ID string or an object with fileIds to specify uploaded files that should be available to the code interpreter

The tool must be named code_interpreter when using OpenAI's code interpreter functionality. This name is required by OpenAI's API specification and cannot be customized.

Local Shell Tool

The OpenAI responses API support the local shell tool for Codex models through the openai.tools.localShell tool. Local shell is a tool that allows agents to run shell commands locally on a machine you or the user provides.

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai.responses('gpt-5-codex'),
tools: {
local_shell: openai.tools.localShell({
execute: async ({ action }) => {
// ... your implementation, e.g. sandbox access ...
return { output: stdout };
},
}),
},
prompt: 'List the files in my home directory.',
stopWhen: stepCountIs(2),
});

The tool must be named local_shell. This name is required by OpenAI's API specification and cannot be customized. The model can only be

Async Tool Calling

GPT-6 Astra and later Responses models support async tool calling. An async tool lets the model continue generating independent output after issuing the call instead of waiting for its result. Your application still executes the tool and sends its result in a later request using the original tool call ID.

Enable async calling on a function tool with providerOptions.openai.async:

import { openai, type OpenAIToolOptions } from '@ai-sdk/openai';
import { generateText, tool } from 'ai';
import { z } from 'zod';
const result = await generateText({
model: openai.responses('gpt-6-astra'),
tools: {
getWeather: tool({
description: 'Get the weather for a city.',
inputSchema: z.object({ city: z.string() }),
outputSchema: z.object({
city: z.string(),
temperatureC: z.number(),
}),
providerOptions: {
openai: { async: true } satisfies OpenAIToolOptions,
},
}),
},
prompt:
'Start the weather lookup for Paris, then list three general packing essentials without waiting.',
});

The generated tool call exposes the provider marker as providerMetadata.openai.async. Use providerMetadata.openai.responseId as the next request's previousResponseId, and submit the result in a tool message with the original toolCallId.

With streamText, OpenAI can continue streaming text after the completed tool-call part. Use the tool's onInputAvailable callback to start work as soon as that part arrives. If execute returns the same already-running promise, tool execution overlaps the rest of the model stream. Omit execute when the job should outlive the current generation and submit its result in a later request.

Async calling applies to directly called function tools. It does not apply to hosted tools such as web search or code interpreter.

Image Inputs

The OpenAI Responses API supports Image inputs for appropriate models. You can pass Image files as part of the message content using the 'image' type:

const result = await generateText({
model: openai('gpt-5'),
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: 'Please describe the image.',
},
{
type: 'image',
image: fs.readFileSync('./data/image.png'),
},
],
},
],
});

The model will have access to the image and will respond to questions about it. The image should be passed using the image field.

You can also pass a file-id from the OpenAI Files API.

{
type: 'image',
image: 'file-8EFBcWHsQxZV7YGezBC1fq'
}

You can also pass the URL of an image.

{
type: 'image',
image: 'https://sample.edu/image.png',
}

PDF Inputs

The OpenAI Responses API supports reading PDF files. You can pass PDF files as part of the message content using the file type:

const result = await generateText({
model: openai('gpt-5'),
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: 'What is an embedding model?',
},
{
type: 'file',
data: fs.readFileSync('./data/ai.pdf'),
mediaType: 'application/pdf',
filename: 'ai.pdf', // optional
},
],
},
],
});

You can also pass a file-id from the OpenAI Files API.

{
type: 'file',
data: 'file-8EFBcWHsQxZV7YGezBC1fq',
mediaType: 'application/pdf',
}

You can also pass the URL of a pdf.

{
type: 'file',
data: 'https://sample.edu/example.pdf',
mediaType: 'application/pdf',
filename: 'ai.pdf', // optional
}

The model will have access to the contents of the PDF file and respond to questions about it. The PDF file should be passed using the data field, and the mediaType should be set to 'application/pdf'.

Structured Outputs

The OpenAI Responses API supports structured outputs. You can enforce structured outputs using generateObject or streamObject, which expose a schema option. Additionally, you can pass a Zod or JSON Schema object to the experimental_output option when using generateText or streamText.

// Using generateObject
const result = await generateObject({
model: openai('gpt-4.1'),
schema: z.object({
recipe: z.object({
name: z.string(),
ingredients: z.array(
z.object({
name: z.string(),
amount: z.string(),
}),
),
steps: z.array(z.string()),
}),
}),
prompt: 'Generate a lasagna recipe.',
});
// Using generateText
const result = await generateText({
model: openai('gpt-4.1'),
prompt: 'How do I make a pizza?',
experimental_output: Output.object({
schema: z.object({
ingredients: z.array(z.string()),
steps: z.array(z.string()),
}),
}),
});

Chat Models

You can create models that call the OpenAI chat API using the .chat() factory method. The first argument is the model id, e.g. gpt-4. The OpenAI chat models support tool calls and some have multi-modal capabilities.

const model = openai.chat('gpt-5');

OpenAI chat models support also some model specific provider options that are not part of the standard call settings. You can pass them in the providerOptions argument:

import { openai, type OpenAIChatLanguageModelOptions } from '@ai-sdk/openai';
const model = openai.chat('gpt-5');
await generateText({
model,
providerOptions: {
openai: {
logitBias: {
// optional likelihood for specific tokens
'50256': -100,
},
user: 'test-user', // optional unique user identifier
} satisfies OpenAIChatLanguageModelOptions,
},
});

The following optional provider options are available for OpenAI chat models:

  • logitBias Record<number, number>

    Modifies the likelihood of specified tokens appearing in the completion.

    Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this tokenizer tool to convert text to token IDs. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 should result in a ban or exclusive selection of the relevant token.

    As an example, you can pass {"50256": -100} to prevent the token from being generated.

  • logprobs boolean | number

    Return the log probabilities of the tokens. Including logprobs will increase the response size and can slow down response times. However, it can be useful to better understand how the model is behaving.

    Setting to true will return the log probabilities of the tokens that were generated.

    Setting to a number will return the log probabilities of the top n tokens that were generated.

  • parallelToolCalls boolean

    Whether to enable parallel function calling during tool use. Defaults to true.

  • user string

    A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. Learn more.

  • reasoningEffort 'none' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'

    Reasoning effort for reasoning models. Defaults to medium. If you use providerOptions to set the reasoningEffort option, this model setting will be ignored.

    Supported reasoning efforts vary by model. GPT-5.6 supports 'none', 'low', 'medium', 'high', 'xhigh', and 'max'.

  • structuredOutputs boolean

    Whether to use structured outputs. Defaults to true.

    When enabled, tool calls and object generation will be strict and follow the provided schema.

  • maxCompletionTokens number

    Maximum number of completion tokens to generate. Useful for reasoning models.

  • store boolean

    Whether to enable persistence in Responses API.

  • metadata Record<string, string>

    Metadata to associate with the request.

  • prediction Record<string, any>

    Parameters for prediction mode.

  • serviceTier 'auto' | 'flex' | 'priority' | 'default'

    Service tier for the request. Set to 'flex' for 50% cheaper processing at the cost of increased latency (available for o3, o4-mini, and gpt-5 models). Set to 'priority' for faster processing with Enterprise access (available for gpt-4, gpt-5, gpt-5-mini, o3, o4-mini; gpt-5-nano is not supported).

    Defaults to 'auto'.

  • strictJsonSchema boolean

    Whether to use strict JSON schema validation. Defaults to false.

  • textVerbosity 'low' | 'medium' | 'high'

    Controls the verbosity of the model's responses. Lower values will result in more concise responses, while higher values will result in more verbose responses.

  • promptCacheKey string

    A cache key for manual prompt caching control. Used by OpenAI to cache responses for similar requests to optimize your cache hit rates.

  • promptCacheOptions object

    Configures prompt caching for GPT-5.6 and later models. mode can be 'implicit' or 'explicit', and ttl currently only supports '30m'. In explicit mode, only content blocks marked with a prompt cache breakpoint are cached.

  • promptCacheRetention 'in_memory' | '24h'

    The legacy retention policy for models before GPT-5.6. Set to '24h' to enable extended prompt caching on supported models. For GPT-5.6 and later models, use promptCacheOptions.ttl instead.

  • safetyIdentifier string

    A stable identifier used to help detect users of your application that may be violating OpenAI's usage policies. The IDs should be a string that uniquely identifies each user.

Reasoning

OpenAI has introduced the o1,o3, and o4 series of reasoning models. Currently, o4-mini, o3, o3-mini, and o1 are available via both the chat and responses APIs. The models codex-mini-latest and computer-use-preview are available only via the responses API.

Reasoning models currently only generate text, have several limitations, and are only supported using generateText and streamText.

They support additional settings and response metadata:

  • You can use providerOptions to set

    • the reasoningEffort option (or alternatively the reasoningEffort model setting), which determines the amount of reasoning the model performs.
  • You can use response usage.reasoningTokens to access the number of reasoning tokens that the model generated.

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const { text, usage } = await generateText({
model: openai.chat('gpt-5'),
prompt: 'Invent a new holiday and describe its traditions.',
providerOptions: {
openai: {
reasoningEffort: 'low',
},
},
});
console.log(text);
console.log('Usage:', {
...usage,
reasoningTokens: usage.reasoningTokens,
});

System messages are automatically converted to OpenAI developer messages for reasoning models when supported.

Reasoning models require additional runtime inference to complete their reasoning phase before generating a response. This introduces longer latency compared to other models.

maxOutputTokens is automatically mapped to max_completion_tokens for reasoning models.

Structured Outputs

Structured outputs are enabled by default. You can disable them by setting the structuredOutputs option to false.

import { openai } from '@ai-sdk/openai';
import { generateObject } from 'ai';
import { z } from 'zod';
const result = await generateObject({
model: openai.chat('gpt-4o-2024-08-06'),
providerOptions: {
openai: {
structuredOutputs: false,
},
},
schemaName: 'recipe',
schemaDescription: 'A recipe for lasagna.',
schema: z.object({
name: z.string(),
ingredients: z.array(
z.object({
name: z.string(),
amount: z.string(),
}),
),
steps: z.array(z.string()),
}),
prompt: 'Generate a lasagna recipe.',
});
console.log(JSON.stringify(result.object, null, 2));

OpenAI structured outputs have several limitations, in particular around the supported schemas, and are therefore opt-in.

For example, optional schema properties are not supported. You need to change Zod .nullish() and .optional() to .nullable().

Logprobs

OpenAI provides logprobs information for completion/chat models. You can access it in the providerMetadata object.

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai.chat('gpt-5'),
prompt: 'Write a vegetarian lasagna recipe for 4 people.',
providerOptions: {
openai: {
// this can also be a number,
// refer to logprobs provider options section for more
logprobs: true,
},
},
});
const openaiMetadata = (await result.providerMetadata)?.openai;
const logprobs = openaiMetadata?.logprobs;

Image Support

The OpenAI Chat API supports Image inputs for appropriate models. You can pass Image files as part of the message content using the 'image' type:

const result = await generateText({
model: openai.chat('gpt-5'),
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: 'Please describe the image.',
},
{
type: 'image',
image: fs.readFileSync('./data/image.png'),
},
],
},
],
});

The model will have access to the image and will respond to questions about it. The image should be passed using the image field.

You can also pass the URL of an image.

{
type: 'image',
image: 'https://sample.edu/image.png',
}

PDF support

The OpenAI Chat API supports reading PDF files. You can pass PDF files as part of the message content using the file type:

const result = await generateText({
model: openai.chat('gpt-5'),
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: 'What is an embedding model?',
},
{
type: 'file',
data: fs.readFileSync('./data/ai.pdf'),
mediaType: 'application/pdf',
filename: 'ai.pdf', // optional
},
],
},
],
});

The model will have access to the contents of the PDF file and respond to questions about it. The PDF file should be passed using the data field, and the mediaType should be set to 'application/pdf'.

You can also pass a file-id from the OpenAI Files API.

{
type: 'file',
data: 'file-8EFBcWHsQxZV7YGezBC1fq',
mediaType: 'application/pdf',
}

You can also pass the URL of a PDF.

{
type: 'file',
data: 'https://sample.edu/example.pdf',
mediaType: 'application/pdf',
filename: 'ai.pdf', // optional
}

Predicted Outputs

OpenAI supports predicted outputs for gpt-4o and gpt-4o-mini. Predicted outputs help you reduce latency by allowing you to specify a base text that the model should modify. You can enable predicted outputs by adding the prediction option to the providerOptions.openai object:

const result = streamText({
model: openai.chat('gpt-5'),
messages: [
{
role: 'user',
content: 'Replace the Username property with an Email property.',
},
{
role: 'user',
content: existingCode,
},
],
providerOptions: {
openai: {
prediction: {
type: 'content',
content: existingCode,
},
},
},
});

OpenAI provides usage information for predicted outputs (acceptedPredictionTokens and rejectedPredictionTokens). You can access it in the providerMetadata object.

const openaiMetadata = (await result.providerMetadata)?.openai;
const acceptedPredictionTokens = openaiMetadata?.acceptedPredictionTokens;
const rejectedPredictionTokens = openaiMetadata?.rejectedPredictionTokens;

OpenAI Predicted Outputs have several limitations, e.g. unsupported API parameters and no tool calling support.

Image Detail

You can use the openai provider option to set the image input detail to high, low, original, or auto:

const result = await generateText({
model: openai.chat('gpt-5'),
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'Describe the image in detail.' },
{
type: 'image',
image:
'https://github.com/vercel/ai/blob/main/examples/ai-core/data/comic-cat.png?raw=true',
// OpenAI specific options - image detail:
providerOptions: {
openai: { imageDetail: 'low' },
},
},
],
},
],
});

For GPT-5.6, original preserves the input dimensions without resizing to a patch budget or pixel-dimension limit. auto and an omitted detail setting use the same sizing behavior as original, which can increase input token usage for large images.

Because the UIMessage type (used by AI SDK UI hooks like useChat) does not support the providerOptions property, you can use convertToModelMessages first before passing the messages to functions like generateText or streamText. For more details on providerOptions usage, see here.

Distillation

OpenAI supports model distillation for some models. If you want to store a generation for use in the distillation process, you can add the store option to the providerOptions.openai object. This will save the generation to the OpenAI platform for later use in distillation.

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
import 'dotenv/config';
async function main() {
const { text, usage } = await generateText({
model: openai.chat('gpt-4o-mini'),
prompt: 'Who worked on the original macintosh?',
providerOptions: {
openai: {
store: true,
metadata: {
custom: 'value',
},
},
},
});
console.log(text);
console.log();
console.log('Usage:', usage);
}
main().catch(console.error);

Prompt Caching

OpenAI has introduced Prompt Caching for supported models including gpt-4o and gpt-4o-mini.

  • Prompt caching is automatically enabled for these models, when the prompt is 1024 tokens or longer. It does not need to be explicitly enabled.
  • Cache reads are reported in usage.cachedInputTokens.
  • For GPT-5.6 and later models, cache writes are reported in providerMetadata.openai.usage.cacheWriteTokens.
  • For GPT-5.6 and later models, promptCacheOptions.ttl sets a minimum cache lifetime of 30 minutes. Earlier models generally retain in-memory prefixes for 5-10 minutes of inactivity, up to one hour.
import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const { text, usage } = await generateText({
model: openai.chat('gpt-4o-mini'),
prompt: 'A 1024-token or longer prompt...',
});
console.log('Cache reads:', usage.cachedInputTokens);

To improve cache hit rates, you can manually control caching using the promptCacheKey option:

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const { usage } = await generateText({
model: openai.chat('gpt-5'),
prompt: 'A 1024-token or longer prompt...',
providerOptions: {
openai: {
promptCacheKey: 'my-custom-cache-key-123',
},
},
});
console.log('Cache reads:', usage.cachedInputTokens);

GPT-5.6 and later models support explicit cache breakpoints on system messages and supported text, image, and file content blocks. Set a request-level cache key and mark the end of each reusable prefix with promptCacheBreakpoint:

import {
openai,
type OpenAIResponsesProviderOptions,
} from '@ai-sdk/openai';
import { generateText } from 'ai';
const { text, usage, providerMetadata } = await generateText({
model: openai.responses('gpt-5.6'),
providerOptions: {
openai: {
promptCacheKey: 'tenant:acme:support-v1',
promptCacheOptions: { mode: 'explicit', ttl: '30m' },
} satisfies OpenAIResponsesProviderOptions,
},
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: 'A stable prefix of at least 1024 tokens...',
providerOptions: {
openai: {
promptCacheBreakpoint: { mode: 'explicit' },
},
},
},
{ type: 'text', text: 'What should I do next?' },
],
},
],
});
const openaiMetadata = providerMetadata?.openai as
| { usage?: { cacheWriteTokens?: number } }
| undefined;
console.log('Cache reads:', usage.cachedInputTokens);
console.log('Cache writes:', openaiMetadata?.usage?.cacheWriteTokens);

In 'implicit' mode, OpenAI places an automatic breakpoint on the latest message and also honors explicit breakpoints. In 'explicit' mode, only marked content blocks are eligible for caching; a request without any explicit breakpoint does not use prompt caching.

In AI SDK v5, a breakpoint on a tool-result part applies to the whole tool result. When the result contains multiple nested output parts, the OpenAI provider places the API breakpoint on the final nested part because the v5 provider interface does not carry provider options on each nested output item.

For models before GPT-5.6 that support extended caching, you can keep cached prefixes active for up to 24 hours:

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const { usage } = await generateText({
model: openai.chat('gpt-5.1'),
prompt: 'A 1024-token or longer prompt...',
providerOptions: {
openai: {
promptCacheKey: 'my-custom-cache-key-123',
promptCacheRetention: '24h',
},
},
});
console.log('Cache reads:', usage.cachedInputTokens);

Audio Input

With the gpt-4o-audio-preview model, you can pass audio files to the model.

The gpt-4o-audio-preview model is currently in preview and requires at least some audio inputs. It will not work with non-audio data.

import { openai } from '@ai-sdk/openai';
import { generateText } from 'ai';
const result = await generateText({
model: openai.chat('gpt-4o-audio-preview'),
messages: [
{
role: 'user',
content: [
{ type: 'text', text: 'What is the audio saying?' },
{
type: 'file',
mediaType: 'audio/mpeg',
data: fs.readFileSync('./data/galileo.mp3'),
},
],
},
],
});

Completion Models

You can create models that call the OpenAI completions API using the .completion() factory method. The first argument is the model id. Currently only gpt-3.5-turbo-instruct is supported.

const model = openai.completion('gpt-3.5-turbo-instruct');

OpenAI completion models support also some model specific settings that are not part of the standard call settings. You can pass them as an options argument:

const model = openai.completion('gpt-3.5-turbo-instruct');
await model.doGenerate({
providerOptions: {
openai: {
echo: true, // optional, echo the prompt in addition to the completion
logitBias: {
// optional likelihood for specific tokens
'50256': -100,
},
suffix: 'some text', // optional suffix that comes after a completion of inserted text
user: 'test-user', // optional unique user identifier
},
},
});

The following optional provider options are available for OpenAI completion models:

  • echo: boolean

    Echo back the prompt in addition to the completion.

  • logitBias Record<number, number>

    Modifies the likelihood of specified tokens appearing in the completion.

    Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this tokenizer tool to convert text to token IDs. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 should result in a ban or exclusive selection of the relevant token.

    As an example, you can pass {"50256": -100} to prevent the <|endoftext|> token from being generated.

  • logprobs boolean | number

    Return the log probabilities of the tokens. Including logprobs will increase the response size and can slow down response times. However, it can be useful to better understand how the model is behaving.

    Setting to true will return the log probabilities of the tokens that were generated.

    Setting to a number will return the log probabilities of the top n tokens that were generated.

  • suffix string

    The suffix that comes after a completion of inserted text.

  • user string

    A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. Learn more.

Model Capabilities

ModelImage InputAudio InputObject GenerationTool Usage
gpt-6-astra
gpt-5.6
gpt-5.6-luna
gpt-5.6-sol
gpt-5.6-terra
gpt-5.4-pro
gpt-5.4
gpt-5.4-mini
gpt-5.4-nano
gpt-5.3-chat-latest
gpt-5.2-pro
gpt-5.2-chat-latest
gpt-5.2
gpt-5.1-codex-mini
gpt-5.1-codex
gpt-5.1-chat-latest
gpt-5.1
gpt-5-pro
gpt-5
gpt-5-mini
gpt-5-nano
gpt-5-codex
gpt-5-chat-latest
gpt-4.1
gpt-4.1-mini
gpt-4.1-nano
gpt-4o
gpt-4o-mini

The table above lists popular models. Please see the OpenAI docs for a full list of available models. The table above lists popular models. You can also pass any available provider model ID as a string if needed.

Embedding Models

You can create models that call the OpenAI embeddings API using the .textEmbedding() factory method.

const model = openai.textEmbedding('text-embedding-3-large');

OpenAI embedding models support several additional provider options. You can pass them as an options argument:

import { openai } from '@ai-sdk/openai';
import { embed } from 'ai';
const { embedding } = await embed({
model: openai.textEmbedding('text-embedding-3-large'),
value: 'sunny day at the beach',
providerOptions: {
openai: {
dimensions: 512, // optional, number of dimensions for the embedding
user: 'test-user', // optional unique user identifier
},
},
});

The following optional provider options are available for OpenAI embedding models:

  • dimensions: number

    The number of dimensions the resulting output embeddings should have. Only supported in text-embedding-3 and later models.

  • user string

    A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. Learn more.

Model Capabilities

ModelDefault DimensionsCustom Dimensions
text-embedding-3-large3072
text-embedding-3-small1536
text-embedding-ada-0021536

Image Models

You can create models that call the OpenAI image generation API using the .image() factory method.

const model = openai.image('dall-e-3');

Dall-E models do not support the aspectRatio parameter. Use the size parameter instead.

Model Capabilities

ModelSizes
gpt-image-1.51024x1024, 1536x1024, 1024x1536
gpt-image-1-mini1024x1024, 1536x1024, 1024x1536
gpt-image-11024x1024, 1536x1024, 1024x1536
dall-e-31024x1024, 1792x1024, 1024x1792
dall-e-2256x256, 512x512, 1024x1024

You can pass optional providerOptions to the image model. These are prone to change by OpenAI and are model dependent. For example, the gpt-image-1 model supports the quality option:

const { image, providerMetadata } = await generateImage({
model: openai.image('gpt-image-1.5'),
prompt: 'A salamander at sunrise in a forest pond in the Seychelles.',
providerOptions: {
openai: { quality: 'high' },
},
});

For more on generateImage() see Image Generation.

OpenAI's image models return additional metadata in the response that can be accessed via providerMetadata.openai. The following OpenAI-specific metadata is available:

  • images Array<object>

    Array of image-specific metadata. Each image object may contain:

    • revisedPrompt string - The revised prompt that was actually used to generate the image (OpenAI may modify your prompt for safety or clarity)
    • created number - The Unix timestamp (in seconds) of when the image was created
    • size string - The size of the generated image. One of 1024x1024, 1024x1536, or 1536x1024
    • quality string - The quality of the generated image. One of low, medium, or high
    • background string - The background parameter used for the image generation. Either transparent or opaque
    • outputFormat string - The output format of the generated image. One of png, webp, or jpeg

For more information on the available OpenAI image model options, see the OpenAI API reference.

Transcription Models

You can create models that call the OpenAI transcription API using the .transcription() factory method.

The first argument is the model id e.g. whisper-1.

const model = openai.transcription('whisper-1');

You can also pass additional provider-specific options using the providerOptions argument. For example, supplying the input language in ISO-639-1 (e.g. en) format will improve accuracy and latency.

import { experimental_transcribe as transcribe } from 'ai';
import { openai } from '@ai-sdk/openai';
const result = await transcribe({
model: openai.transcription('whisper-1'),
audio: new Uint8Array([1, 2, 3, 4]),
providerOptions: { openai: { language: 'en' } },
});

To get word-level timestamps, specify the granularity:

import { experimental_transcribe as transcribe } from 'ai';
import { openai } from '@ai-sdk/openai';
const result = await transcribe({
model: openai.transcription('whisper-1'),
audio: new Uint8Array([1, 2, 3, 4]),
providerOptions: {
openai: {
//timestampGranularities: ['word'],
timestampGranularities: ['segment'],
},
},
});
// Access word-level timestamps
console.log(result.segments); // Array of segments with startSecond/endSecond

The following provider options are available:

  • timestampGranularities string[] The granularity of the timestamps in the transcription. Defaults to ['segment']. Possible values are ['word'], ['segment'], and ['word', 'segment']. Note: There is no additional latency for segment timestamps, but generating word timestamps incurs additional latency.

  • language string The language of the input audio. Supplying the input language in ISO-639-1 format (e.g. 'en') will improve accuracy and latency. Optional.

  • prompt string An optional text to guide the model's style or continue a previous audio segment. The prompt should match the audio language. Optional.

  • temperature number The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and deterministic. If set to 0, the model will use log probability to automatically increase the temperature until certain thresholds are hit. Defaults to 0. Optional.

  • include string[] Additional information to include in the transcription response.

Model Capabilities

ModelTranscriptionDurationSegmentsLanguage
whisper-1
gpt-4o-mini-transcribe
gpt-4o-transcribe

Speech Models

You can create models that call the OpenAI speech API using the .speech() factory method.

The first argument is the model id e.g. tts-1.

const model = openai.speech('tts-1');

You can also pass additional provider-specific options using the providerOptions argument. For example, supplying a voice to use for the generated audio.

import { experimental_generateSpeech as generateSpeech } from 'ai';
import { openai } from '@ai-sdk/openai';
const result = await generateSpeech({
model: openai.speech('tts-1'),
text: 'Hello, world!',
providerOptions: { openai: {} },
});
  • instructions string Control the voice of your generated audio with additional instructions e.g. "Speak in a slow and steady tone". Does not work with tts-1 or tts-1-hd. Optional.

  • response_format string The format to audio in. Supported formats are mp3, opus, aac, flac, wav, and pcm. Defaults to mp3. Optional.

  • speed number The speed of the generated audio. Select a value from 0.25 to 4.0. Defaults to 1.0. Optional.

Model Capabilities

ModelInstructions
tts-1
tts-1-hd
gpt-4o-mini-tts