- In short
- Structured outputs enforce a JSON schema at generation time through constrained decoding, which allows only tokens that keep the output valid against the schema - unlike a prompt instruction to return JSON, which the model can still violate on an untested input. JSON outputs constrain the final response (output_config.format with type json_schema) and strict tool use validates the arguments Claude passes to a tool. A guaranteed schema is not a guaranteed success: a refusal or a truncation still returns non-matching output, so code still checks stop_reason, and JSON outputs do not combine with assistant-message prefilling.
A prompt asks; a schema enforces
The everyday way to get JSON out of a model is to ask for it in the prompt: "respond with only a JSON object matching this shape." The Claude Certified Developer - Foundations (CCDV-F) exam wants you to see the gap in that approach. A prompt-level instruction is a request the model can still violate on an input you never tested. It holds on the cases you tried, then on some unusual input the model prepends an explanation, wraps the JSON in prose, or drops a field, and your parser breaks in production. Clear instructions help - this is where instruction clarity and placement earns its keep - but even a perfectly worded instruction is guidance, not a guarantee.
Structured outputs close that gap by enforcing the shape at generation time rather than asking for it. The mechanism is constrained decoding: as the model generates, only tokens that keep the output valid against your JSON schema are allowed to be sampled. A token that would break the schema is never chosen, so a response that violates the schema cannot be produced at all. The difference is categorical. A prompt makes conformance likely; constrained decoding makes it certain, because the invalid output was never reachable.
- Structured outputs and constrained decoding
- A feature that enforces a JSON schema at generation time by allowing only tokens that keep the output valid against the schema (constrained decoding), so a schema-violating response cannot be produced. JSON outputs constrain the final response via output_config.format with type json_schema; strict tool use validates the arguments Claude passes to a tool. It guarantees shape, not success - a refusal or truncation still returns non-matching output.
Two places to constrain: the response and the tool call
Structured outputs apply in two distinct places, and the exam expects you to tell them apart. JSON outputs constrain the model's final response to you: you supply a schema through output_config.format with type json_schema, and the answer Claude returns is guaranteed to match it. Reach for this when your application consumes the model's reply directly and needs it parseable every time - extracting fields from a support ticket, or formatting an API response - because it removes the parse-and-retry code you would otherwise wrap around every call. Strict tool use is the other place: you set strict to true on a tool definition, and the arguments Claude passes to that tool are validated against the input schema before your code runs, so a tool call cannot arrive with a missing or mistyped parameter. This builds on ordinary tool use with JSON schemas, tightening the schema from a description the model should follow into a constraint on the arguments it actually emits - reach for it in agentic loops where a malformed argument would crash the function or trigger the wrong action.
The distinction is about which surface is being guaranteed. JSON outputs guarantee the shape of the final response the application reads; strict tool use guarantees the shape of the arguments a tool receives. Both use the same constrained-decoding idea, but they protect different boundaries - one the reply to your code, the other the call into your tool - and a scenario will sometimes hinge on picking the one that matches where the malformed data was landing. They are not mutually exclusive: you can enable both on the same request when a call both consumes a structured reply and hands structured arguments to a tool.
What constrained decoding costs
The guarantee is not free, and knowing the two costs is part of the knowledge point. First, latency on a new schema. The schema has to be compiled into a grammar the decoder can enforce, and that compilation happens on the first request using it, adding latency to that call. The compiled grammar is then cached - for 24 hours from its last use - so steady traffic on a stable schema pays the compilation cost once, while a workload that keeps swapping schemas pays it repeatedly. The practical implication is that the first call after introducing or changing a schema is slower, and a benchmark that only measures a cold first request will overstate the steady-state cost.
Second, input tokens. Enabling structured outputs injects a format prompt describing the schema into the request, which raises the input token count. It is usually a modest increase, but it is real, and it is worth remembering when you are accounting for the cost of a high-volume endpoint. Neither cost changes the value of the guarantee; they are simply the price of moving conformance from "asked for" to "enforced," and the exam can test whether you know the first-request latency and the added input tokens are expected rather than a bug.
A guaranteed shape is not a guaranteed success
The most important nuance is that a guaranteed schema is not a guaranteed success. Constrained decoding guarantees the shape of the output, but it cannot guarantee the model produced a useful answer inside that shape - and in two cases the output will not match the schema at all despite the constraint. A refusal returns with stop_reason refusal, and a response cut off by the token limit returns with stop_reason max_tokens; in both cases you get output that does not satisfy the schema, because the generation ended before a valid, complete object was produced. So your code still inspects stop_reason before trusting the parse, exactly as it would without structured outputs. The schema constraint narrows the failure modes; it does not remove the need to check for them.
There is also a hard incompatibility to know: JSON outputs do not combine with assistant-message prefilling. Prefilling seeds the start of the assistant's turn to steer its output, but that technique conflicts with the constrained-decoding mechanism, so you cannot use both together. If a design relies on prefilling to force a leading character or shape, JSON outputs are not the tool to stack on top of it. Structured outputs are the enforcement; prefilling is a different lever, and the two are mutually exclusive.
What the CCDV-F exam trips candidates on
Three traps recur. The first is believing a prompt that says "return only JSON" is as reliable as a schema constraint. It is not: it holds on tested inputs and slips on untested ones, whereas constrained decoding makes a schema violation unproducible. When a scenario shows a parser that works in testing and breaks on real traffic, the fix is structured outputs, not a stronger sentence. The second is assuming structured outputs make stop_reason checks unnecessary. A refusal or a max_tokens truncation still breaks the parse, so the check stays - conflating "shape guaranteed" with "success guaranteed" is the exact error being tested.
The third is trying to combine JSON outputs with assistant prefilling, which are incompatible. If a design uses prefilling and then reaches for JSON outputs, that stacking does not work and the scenario is pointing at the conflict. Hold the three ideas together - a schema enforces where a prompt only asks, the shape guarantee is not a success guarantee so you still check stop_reason, and JSON outputs do not combine with prefilling - and the output-handling questions resolve cleanly.
Worked example
A team extracts fields from user messages into JSON. Their prompt instructs Claude to 'reply with only a JSON object.' It passes their test set, but in production the downstream parser occasionally throws, and once a request that was refused for policy reasons was silently stored as a broken record. They ask how to make the output reliable.
Two separate problems are in play, and the fix is not one lever but the right combination. The intermittent parser failures come from relying on a prompt instruction, which is a request the model can violate on inputs the test set never covered - a prepended explanation here, an extra field there. The durable fix is structured outputs: supply the extraction schema through output_config.format with type json_schema so constrained decoding allows only tokens that keep the response valid against the schema. A schema-violating reply then cannot be produced, which is a stronger guarantee than any wording of the prompt.
But structured outputs alone would not have prevented the second incident. The refused request returned with stop_reason refusal, and that output does not match the schema even with the constraint in place, because a refusal ends the generation before a valid object exists. So the code must still inspect stop_reason and treat a refusal or a max_tokens truncation as a failure to route to a fallback, not as data to store. The correct design is both moves together: enforce the shape with a JSON-schema output to kill the parser failures, and keep the stop_reason check to catch the refusals and truncations the schema guarantee does not cover. And if their pipeline had used assistant prefilling to force a leading brace, they would need to drop it, since JSON outputs do not combine with prefilling.
Common misreadings to avoid
Misconception
Telling Claude to 'return only JSON matching this schema' in the prompt is functionally the same as using structured outputs.
What's actually true
Misconception
If the schema is guaranteed, the response is always valid, so I can parse it without checking anything else.
What's actually true
How this shows up on the exam
Domain 6 questions on this knowledge point are applied. A frequent shape describes JSON extraction that passes tests and then breaks a parser in production; the correct diagnosis is that a prompt instruction was doing enforcement it cannot guarantee, and the fix is structured outputs via a JSON schema. Another shape adds a refused or truncated request that slips through as bad data; the correct reading is that a schema guarantee is not a success guarantee, so the stop_reason check must stay. A third simply tests the JSON-outputs-versus-prefilling incompatibility, or the JSON-outputs-versus-strict-tool-use distinction.
This knowledge point builds on tool use with JSON schemas - strict tool use is that same schema idea turned into an enforced constraint - and it works hand in hand with response validation and defensive parsing, since even a schema-valid object still needs its values checked, and with skepticism toward confident output, because a well-shaped answer can still be a wrong one. Enforce the shape, keep the stop_reason check, and validate the contents, and the output is both parseable and trustworthy.
A service uses a prompt that asks Claude to 'output only JSON' and parses the reply directly. It works in testing but throws on some production inputs, and refused requests are being stored as corrupt records. Which change makes the output reliable?
People also ask
What is the difference between structured outputs and a prompt that asks for JSON?
What is constrained decoding?
Can you combine JSON outputs with assistant prefilling?
Watch and learn
Official Anthropic Academy lessons first, then hand-picked walkthroughs. Videos load only when you press play.
No videos curated for this concept yet
We are still curating the best official and community videos for this topic.
Official prep for this domain
Anthropic's own free prep module for this part of the syllabus, on the official prep course. Free with an Anthropic Academy sign-in.
References & primary sources
Master this concept with Archie
Practice it inside an adaptive study session. Archie, your Socratic AI tutor, tracks your mastery with Bayesian Knowledge Tracing and schedules the perfect next review.