Structured Outputs Explained for Developers β Reliable JSON from LLMs
Structured outputs guarantee that an LLMβs response matches a specific JSON schema. Instead of parsing free-text and hoping for the best, you get valid, typed data every time.
The problem
Without structured outputs:
response = llm("Extract the name and email from this text: ...")
# Returns: "The name is John and the email is john@example.com"
# Or: "Name: John\nEmail: john@example.com"
# Or: '{"name": "John", "email": "john@example.com"}'
# Or something completely different
You have to parse this mess. It breaks constantly. See our guide on why LLM parsing breaks.
The solution
With structured outputs:
response = client.chat.completions.create(
model="gpt-5.4",
messages=[{"role": "user", "content": "Extract name and email from: ..."}],
response_format={
"type": "json_schema",
"json_schema": {
"name": "extraction",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string", "format": "email"}
},
"required": ["name", "email"]
}
}
}
)
# ALWAYS returns valid JSON matching the schema
Provider support
| Provider | Structured outputs | How |
|---|---|---|
| OpenAI | β Native | response_format.json_schema |
| Anthropic | β Via tool use | Define a tool with the schema |
| β Native | response_schema parameter | |
| Mistral | β Native | response_format |
| OpenRouter | β Pass-through | Depends on underlying model |
Structured outputs vs JSON mode
JSON mode: Model outputs valid JSON, but no schema guarantee. Could return any JSON structure.
Structured outputs: Model outputs JSON that matches YOUR specific schema. Fields, types, and required properties are enforced.
Always prefer structured outputs when available. See our detailed comparison.
Use cases
- Data extraction β Pull structured data from unstructured text
- Tool calling β Function parameters are structured outputs
- API responses β LLM generates responses matching your API schema
- Classification β Force output into predefined categories
- MCP tool responses β Structured data from AI tools
With TypeScript (Zod)
import { z } from 'zod';
const schema = z.object({
name: z.string(),
email: z.string().email(),
sentiment: z.enum(["positive", "negative", "neutral"])
});
// Use with OpenAI or any provider that supports structured outputs
See our schema-first AI design guide for building entire apps around structured outputs.
FAQ
What are structured outputs?
Structured outputs are a feature that guarantees an LLMβs response matches a specific JSON schema you define. Instead of parsing free-text responses and hoping the format is correct, you get valid, typed JSON every time β with enforced fields, types, and required properties. This eliminates parsing failures in production applications.
Do all models support them?
Most major providers support structured outputs: OpenAI (native json_schema), Anthropic (via tool use), Google (native response_schema), and Mistral (native response_format). OpenRouter passes through support depending on the underlying model. Smaller or local models may not support schema-enforced outputs, though many support basic JSON mode.
Is JSON mode the same as structured outputs?
No. JSON mode only guarantees the output is valid JSON β it could return any structure. Structured outputs guarantee the JSON matches your specific schema with the exact fields, types, and required properties you defined. Always prefer structured outputs when available, as JSON mode can still return unexpected structures that break your parsing logic.
Related: JSON Mode vs Structured Outputs Β· Why Parsing LLM Output Breaks Β· Schema-First AI App Design Β· What is Tool Calling?