JSON Mode & Structured Outputs: Reliable JSON from LLMs
Why plain JSON mode only guarantees valid syntax, how schema-constrained structured outputs enforce an exact shape, and how OpenAI, Claude and Gemini each implement it.
By default, an LLM is a free-text generator: nothing stops it from wrapping a JSON response in a markdown code fence, adding a sentence of commentary before it, or drifting from the shape you asked for. JSON mode and structured outputs are API-level features that remove that uncertainty, with two different strength levels behind those names.
Two tiers, not one feature
| JSON mode | Structured outputs | |
|---|---|---|
| Guarantees | Syntactically valid JSON | Valid JSON matching your exact schema |
| How it's enforced | Model is instructed to emit JSON | Constrained at the token-sampling layer: the decoder cannot emit a token that would violate the schema |
| Shape control | None — any valid JSON passes | Full — required fields, types, enums, nesting all enforced |
| Status (2026) | Legacy on most providers | The production default for extraction and agent workflows |
The practical difference is large. In OpenAI's own evaluations, schema-constrained structured outputs reach 100% schema compliance, function calling reaches roughly 86%, and plain JSON mode with no schema trails both. If you are parsing the result in code rather than just displaying it to a person, the constrained option is worth the extra setup.
How each major provider implements it
| Provider | Field / mechanism | Schema dialect |
|---|---|---|
| OpenAI | response_format: type=json_schema, strict=true | Standard JSON Schema |
| Anthropic Claude | Native output_format with json_schema, or a forced tool call (tool_choice naming a specific tool) | Standard JSON Schema |
| Google Gemini | responseMimeType: "application/json" plus responseSchema | OpenAPI-subset schema historically; a separate responseJsonSchema field accepts standard JSON Schema |
Gemini also has a provider-specific option, propertyOrdering, that fixes the order fields are emitted in. Field order does not usually matter for parsing JSON, but it can measurably affect answer quality, since the model reasons about earlier fields before generating later ones.
Field and parameter names shift as providers ship new API versions. Treat the table above as a starting point, and confirm the exact field name against the provider's own current documentation before shipping.
Building and checking the schema
Write the schema by hand for anything simple, or generate a starting point from a real example response using this site's JSON Schema Generator: paste a JSON object shaped the way you want the model's output to look, and it infers the types, required fields, and structure for you to refine.
Once a model actually returns something, validate and inspect it with the JSON Formatter rather than assuming the schema constraint alone caught every problem: it still helps to see the real output, especially while iterating on a schema or debugging a refusal case.
What structured outputs do not solve
A schema constraint guarantees shape, not correctness. The model can still put a wrong but correctly-typed value into a field, since nothing about JSON Schema validation touches factual accuracy. Keep validating and spot-checking values the same way you would for any other model output.
Refusals are the other case worth handling explicitly: a model can decline to produce the content at all (a safety refusal, or a request outside what it will do), and that response usually arrives in a different field than the structured result would. Code that only checks "did this parse as JSON" will treat a refusal as a mysterious failure instead of the distinct, expected case it actually is.
Try it now
Frequently asked questions
It usually gets close, but "usually" is the problem: a plain-text instruction has no hard guarantee behind it. The model can still wrap the response in markdown code fences, add an explanatory sentence before the JSON, or produce a shape that is valid JSON but not the one you needed.
JSON mode and structured outputs exist specifically to remove that uncertainty at the API level instead of relying on prompt wording alone.