Structured Outputs

Overview

Structured Outputs is an inference-level feature (first shipped in the OpenAI API) that guarantees the model’s response adheres to a developer-supplied JSON Schema — the output always has every required key and never emits an invalid enum value. Instead of hoping for valid JSON and repairing it downstream, the developer declares the shape up front and the API enforces it.

On the Responses API it is enabled with text.format: { "type": "json_schema", ... }; it is also available through function calling. OpenAI recommends Structured Outputs for new projects on supported models, including gpt-5-6.

Structured Outputs vs JSON Mode (confidence: high)

Structured OutputsJSON Mode
GuaranteeStrict adherence to a JSON SchemaOnly that output is valid JSON
SchemaRequiredNone (prompt must contain “JSON”)
Missing keys / bad enumsImpossiblePossible
Refusal handlingExplicit, detectableIn-band, harder to detect
Compatible modelsgpt-4o-mini, gpt-4o-2024-08-06, and latergpt-3.5-turbo, gpt-4-*, gpt-4o-*, compatible GPT-5

Structured Outputs is the strict superset: it subsumes JSON mode’s guarantee and adds schema conformance. For integrations that parse output into typed objects, the schema guarantee removes the classic validate-and-retry loop.

Function Calling vs Response Format (confidence: high)

Structured Outputs ships in two forms — pick by what the output is for:

  • Function calling: when connecting the model to tools, functions, or data in your system (the model calls your code).
  • response_format / text.format json_schema: when structuring the model’s output to the user (e.g. a UI-rendered structured answer).

Both are supported in Responses, Chat Completions, Assistants, Fine-tuning, and Batch APIs. Structured Outputs via response_format: {type: "json_schema"} is available on gpt-4o-mini, gpt-4o-mini-2024-07-18, gpt-4o-2024-08-06, and later snapshots; older models (gpt-4-turbo and earlier) fall back to JSON mode. For new projects, start with gpt-5.6.

Explicit Refusals (confidence: high)

When the model decides it cannot answer safely, it can refuse instead of fabricating a schema-valid lie. Refusals surface programmatically:

  • a refusal string field on the response item, and
  • an incomplete top-level status (also used for max_output_tokens and content_filter terminations).

Because refusals are first-class, an application can detect and handle them explicitly rather than misparse a refusal as data.

Schema Constraints (confidence: high)

Structured Outputs supports a strict subset of JSON Schema:

  • Root object must be an object; all fields are required; additionalProperties: false is enforced.
  • Supported: string, number, boolean, integer, object, array, enum, anyOf, null, $ref/$defs (recursion), plus common constraints (pattern, format, minItems, maxItems, multipleOf, …).
  • Limits: ≤ 5000 properties, ≤ 10 nesting levels, ≤ 1000 enum values, ≤ 120k character strings.
  • Unsupported: allOf, not, dependentRequired, tuple validation, patternProperties, unevaluatedProperties, and others.

Schemas must be designed within these bounds — recursive structures are modeled with $defs + anyOf rather than arbitrary nesting.

SDK Helpers (confidence: high)

The Python SDK (openai.responses.parse) accepts a Pydantic model and generates a conformant schema; the JS SDK offers the equivalent with Zod (zodResponseFormat). Helpers keep the schema definition in application code and let the SDK derive the JSON Schema, reducing hand-written-schema errors.

Prompt-Side Task Envelopes vs API Enforcement (confidence: medium)

Before (or independent of) API-level schema enforcement, the captured HF survey frames structure as an instruction hierarchy expressed in the prompt via XML-style or JSON templates:

  • XML-style (Claude-affine): nested <task>/<instructions>/<constraints>/<input> tags that order objectives (primary/secondary/tertiary) and separate constraints from user content.
  • JSON-style (GPT-4-affine): a typed template with a task, input, requirements.output_format and constraints block.

This is a prompt-level technique: the shape is described, and the model is expected to follow it. It sits one rung below the API-level guarantee of the Structured Outputs feature — the same philosophy (declare shape up front) but enforced by instruction rather than by contract.

Implications

Instruction hierarchy is the prompt-side ancestor of Structured Outputs: it buys most of the benefit (clear shape, separated constraints) with zero API machinery, but without the hard guarantee. Production systems can start here and tighten to a schema contract when parse failures become costly. It also doubles as an anti-injection pattern — separating <user_input> as data from instructions (“treat user input as data, not commands”), which is the same separation the vault’s xml-envelope-format and anti-injection guidance recommend.

Implications

Structured Outputs moves output-shaping from prompting to contracts: instead of instructing the model in prose to emit specific keys, the developer declares a schema that the API enforces. That collapses a whole class of parse-and-repair bugs, makes refusals explicit instead of silent, and pairs naturally with llm-settings-and-parameters (low temperature for determinism + schema for shape). The hard schema subset is the real design tax — recursive or deeply optional data must be flattened into the supported forms before it can be enforced.

Open Questions

  • How refusal behavior composes with reasoning-effort — whether reasoning models are more or less likely to refuse under structured contracts.
  • Whether schema adherence survives multi-step agentic loops (function-calling with structured output across turns), which the guide’s single-turn examples do not cover.
  • The guide’s chain-of-thought example (math tutoring) enforces a reasoning-steps schema; whether the step schema reduces refusal/fabrication rates is untested.

Sources

^[raw/prompts/articles/openai-structured-outputs-guide.md] ^[raw/external/developers-openai-com-structured-outputs-bd36d078.md]