Structured Output

Prompting

Definition

Guaranteed formatted output (typically JSON) from Claude. The most reliable method is to define a schema as a tool and set tool_choice to force its use — Claude's tool_use blocks are always valid JSON. Alternatively, use --output-format json with --json-schema in Claude Code CLI.

Example Usage

Define a JSON schema as a tool definition and set tool_choice: {type: 'tool', name: 'output_schema'} to guarantee parseable output.

In Depth

Structured output refers to guaranteed machine-parseable responses from Claude — typically JSON — rather than free-form prose. The reliability gap between "ask Claude to output JSON" and "guarantee parseable JSON every time" is what structured output closes.

The recommended approach: tool-forcing. The most reliable path is to define your desired schema as a tool-choice configuration and set it to force use of a named tool:

{
  "tool_choice": {"type": "tool", "name": "extract_result"},
  "tools": [{
    "name": "extract_result",
    "description": "Return the structured result.",
    "input_schema": {
      "type": "object",
      "properties": {
        "sentiment": {"type": "string", "enum": ["positive","negative","neutral"]},
        "confidence": {"type": "number"}
      },
      "required": ["sentiment","confidence"]
    }
  }]
}

When Claude returns a tool_use content block, the input field is always valid JSON. Setting strict: true on the tool definition additionally enforces that every required property is present and no extra properties appear.

The API-level alternative: output_config. For use cases where you want JSON output without the tool-use ceremony, the current API supports output_config: {format: {type: "json_schema", schema: {...}}}. Note: the *deprecated* top-level output_format field is not the same thing — use output_config with the nested format key.

CLI path. In Claude Code CLI, pass --output-format json together with --json-schema <path-to-schema.json> to constrain non-interactive output.

Validation loop as a fallback. Even with tool-forcing, complex schemas occasionally produce outputs that pass JSON parsing but fail application-level validation (e.g., an enum value outside the declared set on an older model). A validation loop that checks the output and retries with the error message provides a reliable second line of defense. See Structured Output via Tool Use & JSON Schemas for a full walkthrough.

What structured output does not fix. Hallucinated *values* inside a valid schema — a confident but wrong sentiment score — are a separate problem that structured output cannot solve. Schema correctness is not semantic correctness.

How It Compares

ApproachReliabilityRequiresNotes
Tool-forcing (tool_choice: tool)HighestTool definition + tool_choicetool_use block input is always valid JSON
output_config JSON schemaHighAPI output_config.format fieldNo tool overhead; current API
Prose instruction ("output JSON")Low–MediumNothing extraModel may add prose, markdown fences, or comments
Response prefill (legacy)N/ALast assistant turnRemoved (400) on current models — do not use
CLI --output-format json --json-schemaHigh (CLI only)Claude Code CLIFor non-interactive / CI use cases

How It's Tested & Common Confusions

  • Scenario: "You need Claude to always return a parseable JSON object. Which approach is most reliable?" — correct answer: define a tool with the target schema and set tool_choice: {type: "tool", name: "..."}, not a prose instruction like "respond only in JSON".
  • API fact: "Which field enables JSON schema output at the API level?" — output_config: {format: {type: "json_schema", ...}}, NOT output_format.
  • True/false: "strict: true in a tool definition guarantees valid JSON tool parameters" — TRUE.
  • Trap: Confusing output_config (current) with output_format (deprecated) or with response prefill (removed).

Frequently Asked Questions

What is the difference between output_config and output_format?

`output_config: {format: {type: "json_schema", schema: {...}}}` is the current API field for schema-constrained output. The top-level `output_format` field is deprecated and should not be used in new code. Always use `output_config` with the nested `format` key.

Does strict: true on a tool guarantee semantically correct values?

`strict: true` guarantees that the tool parameters conform to the declared JSON schema — all required fields are present and values match declared types and enums. It does not guarantee that the values are *correct* (e.g., the sentiment label matches the actual text). Use a validation loop or an evaluator step for semantic correctness.