# Structured Output Guide **Last Updated**: 2025-10-25 Best practices for using JSON schemas with OpenAI's structured outputs feature. --- ## When to Use Structured Outputs Use structured outputs when you need: - ✅ **Guaranteed JSON format**: Response will always be valid JSON - ✅ **Schema validation**: Enforce specific structure - ✅ **Type safety**: Parse directly into TypeScript types - ✅ **Data extraction**: Pull specific fields from text - ✅ **Classification**: Map to predefined categories --- ## Schema Best Practices ### 1. Keep Schemas Simple ```typescript // ✅ Good: Simple, focused schema { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' }, }, required: ['name', 'age'], additionalProperties: false, } // ❌ Avoid: Overly complex nested structures // (they work but are harder to debug) ``` ### 2. Use Enums for Fixed Options ```typescript { type: 'object', properties: { category: { type: 'string', enum: ['bug', 'feature', 'question'], }, priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], }, }, required: ['category', 'priority'], } ``` ### 3. Always Use `strict: true` ```typescript response_format: { type: 'json_schema', json_schema: { name: 'response_schema', strict: true, // ✅ Enforces exact compliance schema: { /* ... */ }, }, } ``` ### 4. Set `additionalProperties: false` ```typescript { type: 'object', properties: { /* ... */ }, required: [ /* ... */ ], additionalProperties: false, // ✅ Prevents unexpected fields } ``` --- ## Common Use Cases ### Data Extraction ```typescript const schema = { type: 'object', properties: { person: { type: 'string' }, company: { type: 'string' }, email: { type: 'string' }, phone: { type: 'string' }, }, required: ['person'], additionalProperties: false, }; // Extract from unstructured text const completion = await openai.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'system', content: 'Extract contact information' }, { role: 'user', content: 'John works at TechCorp, email: john@tech.com' }, ], response_format: { type: 'json_schema', json_schema: { name: 'contact', strict: true, schema } }, }); const contact = JSON.parse(completion.choices[0].message.content); // { person: "John", company: "TechCorp", email: "john@tech.com", phone: null } ``` ### Classification ```typescript const schema = { type: 'object', properties: { sentiment: { type: 'string', enum: ['positive', 'negative', 'neutral'] }, confidence: { type: 'number' }, topics: { type: 'array', items: { type: 'string' } }, }, required: ['sentiment', 'confidence', 'topics'], additionalProperties: false, }; // Classify text const completion = await openai.chat.completions.create({ model: 'gpt-4o', messages: [ { role: 'system', content: 'Classify the text' }, { role: 'user', content: 'This product is amazing!' }, ], response_format: { type: 'json_schema', json_schema: { name: 'classification', strict: true, schema } }, }); const result = JSON.parse(completion.choices[0].message.content); // { sentiment: "positive", confidence: 0.95, topics: ["product", "satisfaction"] } ``` --- ## TypeScript Integration ### Type-Safe Parsing ```typescript interface PersonProfile { name: string; age: number; skills: string[]; } const schema = { type: 'object', properties: { name: { type: 'string' }, age: { type: 'number' }, skills: { type: 'array', items: { type: 'string' } }, }, required: ['name', 'age', 'skills'], additionalProperties: false, }; const completion = await openai.chat.completions.create({ model: 'gpt-4o', messages: [{ role: 'user', content: 'Generate a person profile' }], response_format: { type: 'json_schema', json_schema: { name: 'person', strict: true, schema } }, }); const person: PersonProfile = JSON.parse(completion.choices[0].message.content); // TypeScript knows the shape! ``` --- ## Error Handling ```typescript try { const completion = await openai.chat.completions.create({ model: 'gpt-4o', messages, response_format: { type: 'json_schema', json_schema: { name: 'data', strict: true, schema } }, }); const data = JSON.parse(completion.choices[0].message.content); return data; } catch (error) { if (error.message.includes('JSON')) { console.error('Failed to parse JSON (should not happen with strict mode)'); } throw error; } ``` --- ## Validation While `strict: true` ensures the response matches the schema, you may want additional validation: ```typescript import { z } from 'zod'; const zodSchema = z.object({ email: z.string().email(), age: z.number().min(0).max(120), }); const data = JSON.parse(completion.choices[0].message.content); const validated = zodSchema.parse(data); // Throws if invalid ``` --- **See Also**: Official Structured Outputs Guide (https://platform.openai.com/docs/guides/structured-outputs)