Skip to content

Structured Outputs Explained

Cheatsheet of JSON-mode and strict structured outputs: what each mode guarantees, the schema rules strict mode enforces, and the failure modes to design around.

Asking nicely for JSON gets you JSON most of the time. Structured outputs make it a guarantee — the model is constrained to a grammar. The two flavors differ in how hard the guarantee is.

Reference table · 14 entriesOpen the strict-output-validator tool →
14 of 14 rows
Modes
json modeOutput is valid JSON, but fields are up to the model.response_format: { type: 'json_object' }
json_schemaOutput conforms to your schema — every key, every type.response_format: { type: 'json_schema', strict: true }
tool callingForce shape via a function signature; arguments arrive parsed.tools: [{ function: { parameters: schema } }]
constrained decodingThe mechanism underneath: tokens outside the grammar are masked.logit_bias at decode time
Strict-mode schema rules
additionalProperties: falseEvery object must be closed — no surprise keys."additionalProperties": false
all properties requiredOptional keys are expressed as nullable, not omitted."required": ["name", "tags"]
root is an objectStrict mode cannot return a bare scalar or array.{ "type": "object", … }
unions via anyOfoneOf is unsupported; allOf only as a single-element wrapper."anyOf": [{…}, {…}]
nullable arraysNullability uses the type-array form."type": ["string", "null"]
supported keywordstype/enum/const/items/properties/required + descriptions; minLength, pattern, etc. are ignored."enum": ["yes", "no"]
Failure modes & fixes
truncated outputHit max_tokens mid-JSON — parse fails on a dangling object.raise max_tokens or shrink the schema
refusalsThe model can refuse instead of emitting the schema; check the refusal field.if (resp.refusal) …
hallucinated enumsNon-strict modes can invent values; strict constrains them.use strict: true for enums
first-token latencyLong schemas add prompt overhead before the first token.keep schemas minimal