Documentation Index Fetch the complete documentation index at: https://mintlify.com/vercel/ai/llms.txt
Use this file to discover all available pages before exploring further.
Generating Structured Data
While text generation is useful, many applications need structured, typed data. The AI SDK Core provides built-in support for generating schema-validated structured data through the output property on generateText and streamText.
Why Structured Data?
Structured data generation is essential for:
Data extraction : Extract information from unstructured text
Classification : Categorize content into predefined types
Synthetic data : Generate test data or examples
Form filling : Generate structured responses for forms
API responses : Create typed data for downstream systems
Basic Usage
Use Output.object() with a schema to generate structured data:
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
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.' ,
});
// output is fully typed and validated
console . log ( output . recipe . name );
console . log ( output . recipe . ingredients );
Output Types
The AI SDK supports multiple output formats through the Output object:
Output.object()
Generate a structured object matching a schema:
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
schema: z . object ({
name: z . string (),
age: z . number (),
email: z . string (). email (),
interests: z . array ( z . string ()),
}),
}),
prompt: 'Generate a user profile for a software engineer.' ,
});
// Fully typed
console . log ( output . name ); // string
console . log ( output . age ); // number
console . log ( output . interests ); // string[]
Output.array()
Generate an array of structured elements:
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . array ({
element: z . object ({
city: z . string (),
temperature: z . number (),
condition: z . string (),
}),
}),
prompt: 'List weather for San Francisco, London, and Tokyo.' ,
});
// output is an array of weather objects
for ( const weather of output ) {
console . log ( ` ${ weather . city } : ${ weather . temperature } °F, ${ weather . condition } ` );
}
Streaming Arrays
When streaming arrays, use elementStream to receive complete elements as they’re generated:
import { streamText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { elementStream } = streamText ({
model: openai ( 'gpt-5' ),
output: Output . array ({
element: z . object ({
name: z . string (),
class: z . string (),
description: z . string (),
}),
}),
prompt: 'Generate 3 fantasy RPG characters.' ,
});
for await ( const character of elementStream ) {
console . log ( 'Character:' , character . name );
console . log ( 'Class:' , character . class );
console . log ( 'Description:' , character . description );
console . log ( '---' );
}
Output.choice()
Choose from a fixed set of options:
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . choice ({
options: [ 'positive' , 'negative' , 'neutral' ],
}),
prompt: 'Classify the sentiment: "This product exceeded my expectations!"' ,
});
console . log ( output ); // 'positive' | 'negative' | 'neutral'
Output.json()
Generate arbitrary JSON without schema validation:
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . json (),
prompt: 'Generate a JSON object with city weather data for multiple cities.' ,
});
// output is any valid JSON
console . log ( output );
// {
// "San Francisco": { "temperature": 65, "condition": "Foggy" },
// "New York": { "temperature": 72, "condition": "Sunny" }
// }
Output.json() only validates that the response is valid JSON. For type safety, use Output.object() or Output.array().
Output.text()
Generate plain text (this is the default when no output is specified):
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . text (),
prompt: 'Write a haiku about programming.' ,
});
console . log ( output ); // string
Schema Definitions
The AI SDK supports multiple schema libraries:
Zod Schemas
import { z } from 'zod' ;
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
schema: z . object ({
title: z . string (),
tags: z . array ( z . string ()),
published: z . boolean (),
}),
}),
prompt: 'Generate blog post metadata' ,
});
JSON Schema
import { generateText , Output , jsonSchema } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
schema: jsonSchema ({
type: 'object' ,
properties: {
name: { type: 'string' },
age: { type: 'number' },
},
required: [ 'name' , 'age' ],
}),
}),
prompt: 'Generate a person profile' ,
});
Property Descriptions
Add descriptions to schema properties to guide the model:
import { z } from 'zod' ;
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
schema: z . object ({
name: z . string (). describe ( 'The name of the recipe' ),
servings: z . number (). describe ( 'Number of servings (1-12)' ),
ingredients: z . array (
z . object ({
name: z . string (),
amount: z . string (). describe ( 'Amount in grams or ml' ),
})
). describe ( 'List of ingredients with amounts' ),
steps: z . array ( z . string ()). describe ( 'Step-by-step cooking instructions' ),
}),
}),
prompt: 'Generate a pasta recipe for 4 people.' ,
});
Descriptions help:
Clarify ambiguous property names
Specify expected formats
Provide context for nested structures
Output Name and Description
Provide a name and description for the output to improve generation quality:
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
name: 'Recipe' ,
description: 'A complete recipe with ingredients and steps' ,
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 recipe for chocolate cake.' ,
});
Streaming Structured Data
Stream structured data as it’s generated using streamText:
import { streamText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { partialOutputStream } = streamText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
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.' ,
});
// Stream partial objects as they're built
for await ( const partialObject of partialOutputStream ) {
console . log ( partialObject );
// { recipe: { name: "Lasagna" } }
// { recipe: { name: "Lasagna", ingredients: [{ name: "pasta" }] } }
// ...
}
Partial outputs cannot be validated against the schema since they’re incomplete. Validation happens on the final output.
Structured output can be combined with tool calling:
import { generateText , Output , tool , stepCountIs } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
tools: {
weather: tool ({
description: 'Get weather for a location' ,
inputSchema: z . object ({ location: z . string () }),
execute : async ({ location }) => {
return { temperature: 72 , condition: 'sunny' };
},
}),
},
output: Output . object ({
schema: z . object ({
summary: z . string (),
recommendation: z . string (),
}),
}),
stopWhen: stepCountIs ( 5 ),
prompt: 'What should I wear in San Francisco today?' ,
});
console . log ( output . summary );
console . log ( output . recommendation );
Generating structured output counts as a step. Configure stopWhen to allow enough steps for both tool execution and output generation.
Error Handling
When generateText cannot generate valid structured data, it throws NoObjectGeneratedError:
import { generateText , Output , NoObjectGeneratedError } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
try {
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
schema: z . object ({
name: z . string (),
age: z . number (),
}),
}),
prompt: 'Generate a person' ,
});
} catch ( error ) {
if ( NoObjectGeneratedError . isInstance ( error )) {
console . log ( 'Failed to generate object' );
console . log ( 'Cause:' , error . cause );
console . log ( 'Text:' , error . text );
console . log ( 'Usage:' , error . usage );
}
}
For streaming, use the onError callback:
import { streamText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const result = streamText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
schema: z . object ({ name: z . string () }),
}),
prompt: 'Generate data' ,
onError ({ error }) {
console . error ( 'Stream error:' , error );
},
});
Examples
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
schema: z . object ({
company: z . string (),
position: z . string (),
location: z . string (),
salary: z . string (). optional (),
requirements: z . array ( z . string ()),
}),
}),
prompt: `Extract job posting details from:
"We're hiring a Senior Software Engineer in San Francisco.
Requirements: 5+ years experience, TypeScript, React.
Competitive salary."` ,
});
console . log ( output );
Content Classification
import { generateText , Output } from 'ai' ;
import { openai } from '@ai-sdk/openai' ;
import { z } from 'zod' ;
const { output } = await generateText ({
model: openai ( 'gpt-5' ),
output: Output . object ({
schema: z . object ({
category: z . enum ([ 'technology' , 'business' , 'health' , 'entertainment' ]),
confidence: z . number (). min ( 0 ). max ( 1 ),
keywords: z . array ( z . string ()),
}),
}),
prompt: 'Classify this article: "New AI model achieves breakthrough in natural language understanding"' ,
});
console . log ( `Category: ${ output . category } ` );
console . log ( `Confidence: ${ output . confidence } ` );
Next Steps
Tool Calling Combine structured output with tools
Prompt Engineering Tips for better structured data generation
Settings Configure generation parameters