CertSafari
    CLAUDE-CERTIFIED-DEVELOPER-FOUNDATIONS-CCDV-F · Lessons

    Domain 6 · Lesson 18/25

    Claude Structured Outputs: JSON Schemas and Strict Tool Use

    Output Handling

    7 min read
    3.67% of exam
    3 sources
    Published 29 Sep 2026
    Docs as of 24 Sep 2026

    What you will be able to do

    • Explain what constrained decoding guarantees and what it leaves to your own validation code
    • Request schema-conforming JSON with output_config.format and read it from the right content block
    • Use SDK helpers such as client.messages.parse() and understand how they transform and re-validate schemas
    • Enable strict: true on tool definitions and know where it is rejected or needs data-handling care

    Key concept

    Constrained decoding — Claude's token sampling is limited to outputs that fit your JSON Schema, so the response always matches the schema's structure. It replaces the older approach of hoping the model follows format instructions and retrying when it does not.

    1.Why prompting alone is not enough

    Any code that consumes Claude's output has to parse it. If you only ask for JSON in the prompt, you are relying on the model to follow that instruction every time. The structured outputs documentation lists what goes wrong "even with careful prompting": parsing errors from invalid JSON syntax, missing required fields, inconsistent data types, and schema violations that you then have to catch and retry.

    Structured outputs deal with this at generation time. The feature has two parts, and you can use them separately or in the same request. JSON outputs (output_config.format) control the format of Claude's own response. Strict tool use (strict: true) makes tool names and tool inputs match your schema. The documentation sums up the result as "always valid", "type safe" and "no retries needed for schema violations."

    Sources1

    2.JSON outputs with output_config.format

    Setting it up takes three steps. Define a JSON Schema, add output_config.format with type: "json_schema" and that schema, then parse the response. The JSON comes back in the response's text content block, not in a separate field. The schema uses standard JSON Schema, but only a subset of it is supported.

    You usually don't write the raw schema yourself. The SDKs build it from native types: Pydantic in Python, Zod or typed JSON Schema literals in TypeScript, plain classes in Java and C#, and so on. In Python, the recommended entry point is client.messages.parse(), which returns a typed parsed_output.

    client.messages.parse() with a Pydantic model: the SDK sends the schema, validates the reply, and exposes parsed_outputpython
    response = client.messages.parse(
        model="claude-opus-5-5",
        max_tokens=1024,
        messages=[
            {
                "role": "user",
                "content": "Extract contact info: John Smith, john@example.com, interested in the Pro plan",
            }
        ],
        output_format=ContactInfo,
    )
    
    # Access the parsed output directly
    contact = response.parsed_output
    print(contact.name, contact.email)

    The helpers also rewrite your schema before sending it. They remove constraints that constrained decoding does not support, such as minimum, maximum, minLength and maxLength. They move each removed constraint into the field description (for example, "Must be at least 100"), add additionalProperties: false to every object, and keep only supported string formats. Then they validate the response against your original schema, constraints included. Claude sees a simplified schema, and your code still enforces the rest. If you need to edit the transformed schema by hand, transform_schema() gives it to you so you can pass it through output_config yourself.

    The Agent SDK has the same pattern. You pass outputFormat / output_format with a JSON schema, and the final result message carries a structured_output field. The error handling shown in its examples is worth copying: a single-shot query() raises after it yields an error result such as error_max_structured_output_retries, so wrap it in try and don't assume a validated object always comes back.

    Sources12

    3.Strict tool use for agent tool calls

    In an agent, tool inputs are output too, and your functions run on them directly. Without strict mode, the model can pass the wrong type or leave out a required field. The documentation's booking example: a function that expects passengers: int might get "two" or "2". With strict: true it always gets passengers: 2.

    You enable it with a top-level "strict": true next to name, description and input_schema. That gives two guarantees: the tool input follows input_schema, and the tool name is always valid (one of the tools you provided or a server tool). The input arrives in response.content[x].input of a tool_use block:

    A strict-mode tool_use block: input follows input_schema and the name is guaranteed validjson
    {
      "type": "tool_use",
      "name": "get_weather",
      "input": {
        "location": "San Francisco, CA"
      }
    }

    Three constraints to know. First, the computer use and browser use toolset entries do not accept strict: true, and a request that sets it on them is rejected. Second, strict schemas are compiled into grammars and cached for up to 24 hours after last use, apart from message content. Strict tool use is HIPAA eligible, but because of that separate cache, PHI must stay out of property names, enum values, const values and patterns, and appear only in messages. Third, strict mode uses the same schema subset as JSON outputs.

    Sources3

    4.Choosing between the two

    JSON outputs and strict tool use: what each one constrains
    AspectJSON outputsStrict tool use
    How you enable itoutput_config.format with type: "json_schema""strict": true on the tool definition
    What it constrainsClaude's response formatTool names and tool inputs
    Where you read the resultThe response's text content blockresponse.content[x].input on a tool_use block
    Typical useExtracting data, structured reports, formatting API responsesAgentic workflows, type-safe function calls, nested tool parameters

    A team builds a pipeline that extracts contact fields (name, email, plan) from support tickets and feeds them directly into a database insert without any try/except around the JSON parsing step. The pipeline occasionally crashes because Claude's response includes explanatory text before the JSON or omits a required field. What is the most effective fix to guarantee schema conformance without relying on prompt wording alone?

    Sources1

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.Constrained decoding enforces every constraint in your Pydantic model, including minimum, maximum and length limits.Why is that wrong?

      The SDK removes unsupported constraints before sending the schema and enforces them afterwards by validating the response against the original schema. That check happens in your code, not during decoding.

      Covered in JSON outputs with output_config.format

    2. 2.strict: true can be added to any tool in the tools array, including the computer use and browser use toolsets.Why is that wrong?

      Those toolset entries do not accept strict mode, and a request that sets it on them is rejected.

      Covered in Strict tool use for agent tool calls

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “Without structured outputs, Claude can generate malformed JSON responses or invalid tool inputs that break your applications.”
      ↩︎ Why prompting alone is not enough
      “You can use these features independently or together in the same request.”
      ↩︎ Why prompting alone is not enough
      “The parse() method automatically transforms your Pydantic model, validates the response, and returns a parsed_output attribute.”
      ↩︎ JSON outputs with output_config.format
      “Remove unsupported constraints (for example, minimum, maximum, minLength, maxLength)”
      ↩︎ JSON outputs with output_config.format
      “Strict tool use (strict: true): Guarantee schema validation on tool names and inputs”
      ↩︎ Choosing between the two
      “Structured outputs guarantee schema-compliant responses through constrained decoding:”
      ↩︎ Key concept
      “This means Claude receives a simplified schema, but your code still enforces all constraints through validation.”
      ↩︎ Exam trap 1
    2. 2.
      “The result message contains structured_output with validated data”
      ↩︎ JSON outputs with output_config.format
    3. 3.
      “Without strict mode, Claude might return incompatible types ("2" instead of 2) or omit required fields, breaking your functions and causing runtime errors.”
      ↩︎ Strict tool use for agent tool calls
      “Do not include PHI in input_schema property names, enum values, const values, or pattern regular expressions.”
      ↩︎ Strict tool use for agent tool calls
      “The computer use and browser use toolset entries (computer_toolset_20260801 and browser_toolset_20260801) don't accept strict: true”
      ↩︎ Exam trap 2

    Continue to page 2 of 2

    Defensive Parsing and Skepticism Toward Claude Output