streamObject()
Streams a typed, structured object for a given prompt and schema using a language model.
It can be used to force the language model to return structured data, e.g. for information extraction, synthetic data generation, or classification tasks.
Example: stream an object using a schema
import { openai } from '@ai-sdk/openai';
import { streamObject } from 'ai';
import { z } from 'zod';
const { partialObjectStream } = streamObject({
model: openai('gpt-4.1'),
schema: z.object({
recipe: z.object({
name: z.string(),
ingredients: z.array(z.string()),
steps: z.array(z.string()),
}),
}),
prompt: 'Generate a lasagna recipe.',
});
for await (const partialObject of partialObjectStream) {
console.clear();
console.log(partialObject);
}
Example: stream an array using a schema
For arrays, you specify the schema of the array items.
You can use elementStream to get the stream of complete array elements.
import { openai } from '@ai-sdk/openai';
import { streamObject } from 'ai';
import { z } from 'zod';
const { elementStream } = streamObject({
model: openai('gpt-4.1'),
output: 'array',
schema: z.object({
name: z.string(),
class: z
.string()
.describe('Character class, e.g. warrior, mage, or thief.'),
description: z.string(),
}),
prompt: 'Generate 3 hero descriptions for a fantasy role playing game.',
});
for await (const hero of elementStream) {
console.log(hero);
}
Example: generate JSON without a schema
import { openai } from '@ai-sdk/openai';
import { streamObject } from 'ai';
const { partialObjectStream } = streamObject({
model: openai('gpt-4.1'),
output: 'no-schema',
prompt: 'Generate a lasagna recipe.',
});
for await (const partialObject of partialObjectStream) {
console.clear();
console.log(partialObject);
}
Example: generate an enum
When you want to generate a specific enum value, you can set the output strategy to enum
and provide the list of possible values in the enum parameter.
import { streamObject } from 'ai';
const { partialObjectStream } = streamObject({
model: 'openai/gpt-4.1',
output: 'enum',
enum: ['action', 'comedy', 'drama', 'horror', 'sci-fi'],
prompt:
'Classify the genre of this movie plot: ' +
'"A group of astronauts travel through a wormhole in search of a ' +
'new habitable planet for humanity."',
});
To see streamObject in action, check out the additional examples.
Import
<Snippet text={import { streamObject } from "ai"} prompt={false} />
API Signature
Parameters
<PropertiesTable
content={[
{
name: 'model',
type: 'LanguageModel',
description: "The language model to use. Example: openai('gpt-4.1')",
},
{
name: 'output',
type: "'object' | 'array' | 'enum' | 'no-schema' | undefined",
description: "The type of output to generate. Defaults to 'object'.",
},
{
name: 'mode',
type: "'auto' | 'json' | 'tool'",
description:
"The mode to use for object generation. Not every model supports all modes.
Defaults to 'auto' for 'object' output and to 'json' for 'no-schema' output.
Must be 'json' for 'no-schema' output.",
},
{
name: 'schema',
type: 'Zod Schema | JSON Schema',
description:
"The schema that describes the shape of the object to generate.
It is sent to the model to generate the object and used to validate the output.
You can either pass in a Zod schema or a JSON schema (using the jsonSchema function).
In 'array' mode, the schema is used to describe an array element.
Not available with 'no-schema' or 'enum' output.",
},
{
name: 'schemaName',
type: 'string | undefined',
description:
"Optional name of the output that should be generated.
Used by some providers for additional LLM guidance, e.g. via tool or schema name.
Not available with 'no-schema' or 'enum' output.",
},
{
name: 'schemaDescription',
type: 'string | undefined',
description:
"Optional description of the output that should be generated.
Used by some providers for additional LLM guidance, e.g. via tool or schema name.
Not available with 'no-schema' or 'enum' output.",
},
{
name: 'system',
type: 'string',
description:
'The system prompt to use that specifies the behavior of the model.',
},
{
name: 'prompt',
type: 'string | Array<SystemModelMessage | UserModelMessage | AssistantModelMessage | ToolModelMessage>',
description: 'The input prompt to generate the text from.',
},
{
name: 'messages',
type: 'Array<SystemModelMessage | UserModelMessage | AssistantModelMessage | ToolModelMessage>',
description:
'A list of messages that represent a conversation. Automatically converts UI messages from the useChat hook.',
properties: [
{
type: 'SystemModelMessage',
parameters: [
{
name: 'role',
type: "'system'",
description: 'The role for the system message.',
},
{
name: 'content',
type: 'string',
description: 'The content of the message.',
},
],
},
{
type: 'UserModelMessage',
parameters: [
{
name: 'role',
type: "'user'",
description: 'The role for the user message.',
},
{
name: 'content',
type: 'string | Array<TextPart | ImagePart | FilePart>',
description: 'The content of the message.',
properties: [
{
type: 'TextPart',
parameters: [
{
name: 'type',
type: "'text'",
description: 'The type of the message part.',
},
{
name: 'text',
type: 'string',
description: 'The text content of the message part.',
},
],
},
{
type: 'ImagePart',
parameters: [
{
name: 'type',
type: "'image'",
description: 'The type of the message part.',
},
{
name: 'image',
type: 'string | Uint8Array | Buffer | ArrayBuffer | URL',
description:
'The image content of the message part. String are either base64 encoded content, base64 data URLs, or http(s) URLs.',
},
{
name: 'mediaType',
type: 'string',
isOptional: true,
description:
'The IANA media type of the image. Optional.',
},
],
},
{
type: 'FilePart',
parameters: [
{
name: 'type',
type: "'file'",
description: 'The type of the message part.',
},
{
name: 'data',
type: 'string | Uint8Array | Buffer | ArrayBuffer | URL',
description:
'The file content of the message part. String are either base64 encoded content, base64 data URLs, or http(s) URLs.',
},
{
name: 'mediaType',
type: 'string',
description: 'The IANA media type of the file.',
},
],
},
],
},
],
},
{
type: 'AssistantModelMessage',
parameters: [
{
name: 'role',
type: "'assistant'",
description: 'The role for the assistant message.',
},
{
name: 'content',
type: 'string | Array<TextPart | FilePart | ReasoningPart | ToolCallPart>',
description: 'The content of the message.',
properties: [
{
type: 'TextPart',
parameters: [
{
name: 'type',
type: "'text'",
description: 'The type of the message part.',
},
{
name: 'text',
type: 'string',
description: 'The text content of the message part.',
},
],
},
{
type: 'ReasoningPart',
parameters: [
{
name: 'type',
type: "'reasoning'",
description: 'The type of the message part.',
},
{
name: 'text',
type: 'string',
description: 'The reasoning text.',
},
],
},
{
type: 'FilePart',
parameters: [
{
name: 'type',
type: "'file'",
description: 'The type of the message part.',
},
{
name: 'data',
type: 'string | Uint8Array | Buffer | ArrayBuffer | URL',
description:
'The file content of the message part. String are either base64 encoded content, base64 data URLs, or http(s) URLs.',
},
{
name: 'mediaType',
type: 'string',
description: 'The IANA media type of the file.',
},
{
name: 'filename',
type: 'string',
description: 'The name of the file.',
isOptional: true,
},
],
},
{
type: 'ToolCallPart',
parameters: [
{
name: 'type',
type: "'tool-call'",
description: 'The type of the message part.',
},
{
name: 'toolCallId',
type: 'string',
description: 'The id of the tool call.',
},
{
name: 'toolName',
type: 'string',
description:
'The name of the tool, which typically would be the name of the function.',
},
{
name: 'args',
type: 'object based on zod schema',
description:
'Parameters generated by the model to be used by the tool.',
},
],
},
],
},
],
},
{
type: 'ToolModelMessage',
parameters: [
{
name: 'role',
type: "'tool'",
description: 'The role for the assistant message.',
},
{
name: 'content',
type: 'Arraytemperature or topP, but not both.',
},
{
name: 'topP',
type: 'number',
isOptional: true,
description:
'Nucleus sampling. The value is passed through to the provider. The range depends on the provider and model. It is recommended to set either temperature or topP, but not both.',
},
{
name: 'topK',
type: 'number',
isOptional: true,
description:
'Only sample from the top K options for each subsequent token. Used to remove "long tail" low probability responses. Recommended for advanced use cases only. You usually only need to use temperature.',
},
{
name: 'presencePenalty',
type: 'number',
isOptional: true,
description:
'Presence penalty setting. It affects the likelihood of the model to repeat information that is already in the prompt. The value is passed through to the provider. The range depends on the provider and model.',
},
{
name: 'frequencyPenalty',
type: 'number',
isOptional: true,
description:
'Frequency penalty setting. It affects the likelihood of the model to repeatedly use the same words or phrases. The value is passed through to the provider. The range depends on the provider and model.',
},
{
name: 'seed',
type: 'number',
isOptional: true,
description:
'The seed (integer) to use for random sampling. If set and supported by the model, calls will generate deterministic results.',
},
{
name: 'maxRetries',
type: 'number',
isOptional: true,
description:
'Maximum number of retries. Set to 0 to disable retries. Default: 2.',
},
{
name: 'abortSignal',
type: 'AbortSignal',
isOptional: true,
description:
'An optional abort signal that can be used to cancel the call.',
},
{
name: 'headers',
type: 'Record<string, string>',
isOptional: true,
description:
'Additional HTTP headers to be sent with the request. Only applicable for HTTP-based providers.',
},
{
name: 'experimental_repairText',
type: '(options: RepairTextOptions) => Promise
Returns
<PropertiesTable
content={[
{
name: 'usage',
type: 'PromiseContent-Type header to text/plain; charset=utf-8 and writes each text delta as a separate chunk.',
properties: [
{
type: 'ResponseInit',
parameters: [
{
name: 'status',
type: 'number',
isOptional: true,
description: 'The response status code.',
},
{
name: 'statusText',
type: 'string',
isOptional: true,
description: 'The response status text.',
},
{
name: 'headers',
type: 'Record<string, string>',
isOptional: true,
description: 'The response headers.',
},
],
},
],
},
{
name: 'toTextStreamResponse',
type: '(init?: ResponseInit) => Response',
description:
'Creates a simple text stream response. Each text delta is encoded as UTF-8 and sent as a separate chunk. Non-text-delta events are ignored.',
properties: [
{
type: 'ResponseInit',
parameters: [
{
name: 'status',
type: 'number',
isOptional: true,
description: 'The response status code.',
},
{
name: 'statusText',
type: 'string',
isOptional: true,
description: 'The response status text.',
},
{
name: 'headers',
type: 'Record<string, string>',
isOptional: true,
description: 'The response headers.',
},
],
},
],
},
]}
/>
More Examples
<ExampleLinks examples={[ { title: 'Streaming Object Generation with RSC', link: '/examples/next-app/basics/streaming-object-generation', }, { title: 'Streaming Object Generation with useObject', link: '/examples/next-pages/basics/streaming-object-generation', }, { title: 'Streaming Partial Objects', link: '/examples/node/streaming-structured-data/stream-object', }, { title: 'Recording Token Usage', link: '/examples/node/streaming-structured-data/token-usage', }, { title: 'Recording Final Object', link: '/examples/node/streaming-structured-data/object', }, ]} />