Build with Claude API

Structured outputs: get clean JSON from Claude

Structured outputs make Claude return data in a shape you define, a JSON schema, instead of prose you have to parse. You declare the fields and types you need, Claude fills them, and you get back JSON that drops straight into your code. It replaces the fragile please-return-JSON prompt and the regex behind it, which is what makes lead scoring, extraction, and enrichment reliable enough to run unattended.

Overview

My lead-scoring automation ran clean in testing and then broke in production on day two, because Claude, being helpful, prefaced the JSON with Sure, here is the scored list, and my parser choked on the word Sure. I had built the whole pipeline on the hope that the model would return pure JSON every time, and hope is not a parsing strategy.

Structured outputs end that gamble. You tell the API the exact shape you want, and you get that shape back, no preamble, no stray prose, no regex trying to fish JSON out of a sentence. This guide is how to use them, how to design a schema that holds up, and why this is the feature that makes an unattended GTM job trustworthy.

Parsing prose is fragile

Parsing prose is fragile

The naive way to get data from a model is to ask for JSON in the prompt and parse whatever comes back. It works in the demo and fails in production, because a model generating text will sometimes wrap the JSON in a friendly sentence, add a trailing note, or format a number as a word. Every one of those is a crash if your code assumed clean JSON.

So teams pile on defenses: strip the preamble, regex out the braces, retry on failure. That is a lot of brittle scaffolding to compensate for the fact that you asked for structure politely instead of requiring it. The scaffolding is the smell.

Structured output constrains the shape

Structured output constrains the shape

Structured output flips it from a request to a constraint. You provide a JSON schema, the fields, their types, which are required, and the response is held to that shape. Instead of hoping for JSON, you get JSON that matches your schema, which means your code can parse it directly without the defensive scaffolding.

The mental shift is from asking Claude to please format nicely to declaring the contract the output must satisfy. Once the shape is guaranteed, everything downstream, storing it, acting on it, chaining it, gets simpler and more reliable.

Schema in, clean JSON out
01You define the shapea JSON schema
02Claude fills itconstrained to that shape
03You parse with confidenceno regex, no guessing
Declare the fields you need and Claude returns exactly that, so the output drops straight into your code.
Define the schema

Define the schema

You write the schema as JSON schema: an object with named properties, each with a type, and a list of which are required. For a lead scorer that might be a score as an integer, a tier as one of a fixed set of strings, and a reason as text. You attach this to your request, and Claude fills exactly those fields.

The act of writing the schema is also the act of thinking clearly about what you actually need. Vague outputs come from vague asks; a precise schema forces you to decide the fields and types up front, which usually improves the whole design, not just the parsing.

What you get back

What you get back

The response comes back as data matching your schema, ready to use. No sentence to strip, no braces to hunt for. You take the fields and put them where they go, into the CRM, into a dashboard, into the next step of the pipeline. The output is a value your program can trust, not text it has to interpret.

This is what makes the difference between a script you babysit and a job you let run. When the shape is guaranteed, the failure mode where a stray word breaks everything simply does not exist, and that is the whole reason to reach for it.

💡

TipLet the schema, not a fragile prompt, carry the structure. Once the shape is guaranteed you can delete the regex and the retry-on-parse-failure code entirely.

Structured output vs tool use vs asking

Structured output vs tool use vs asking

Three approaches sound similar. Asking for JSON in the prompt is the fragile one you should retire. Tool use is for letting Claude call functions to act, its inputs are structured, but the point is the action, not the final answer. Structured output is for shaping the answer itself into data you consume.

The clean way to choose: if you want Claude to do something, reach for tool use. If you want Claude to return something in a precise shape, reach for structured output. Many GTM jobs use both, tools to gather, structured output to hand you the final scored, shaped result.

A useful combination in practice: tool use to gather and structured output to finish. An agent calls tools to pull CRM history and enrich a contact, then returns its final verdict as a structured object, score, tier, reason. The tools do the acting, the schema shapes the answer, and your pipeline gets a clean record at the end of a messy process.

Designing a good schema

Designing a good schema

A good schema is tight. Include the fields you will actually use and no more, because every extra field is one more thing that can be filled with noise. Use specific types, an integer for a score, an enum for a tier with a fixed set of allowed values, so the output is constrained where it matters. Mark a field required when it must always be present.

Resist deep nesting. A flat, obvious shape is easier for Claude to fill correctly and easier for your code to consume. When you find yourself building a schema three levels deep, ask whether you really need that structure or whether two simpler calls would be cleaner.

  • Only the fields you will use. Extra fields invite noise.
  • Specific types: integers for numbers, enums for fixed choices like a tier.
  • Mark required what must always be present, so a missing value fails loudly.
  • Keep it flat. Deep nesting is harder to fill correctly and harder to consume.
A worked example: extracting contacts

A worked example: extracting contacts

Scoring is one use, extraction is the other big one, and it shows the value sharply. Feed Claude a messy email signature or a scraped about page and ask for a fixed shape, name, title, company, and you get back exactly those fields, ready to drop into your CRM. The input is chaos, the output is a clean record, because the schema refuses to let the mess through.

This is the pattern that turns unstructured GTM data, signatures, transcripts, form free-text, into structured rows you can use. Without a schema you would be writing parsers for every format a human might type; with one, you describe the shape you want and let the model do the normalizing. The schema is the contract that makes messy input safe.

Where it goes wrong

Where it goes wrong

The main failure is a schema that is valid but useless: so loose that a free-text field swallows the real structure, or so over-engineered that the output technically matches but is a pain to work with. Structured output guarantees the shape, not that the shape was a good idea. Garbage schema in, tidy garbage out.

The other is assuming a filled field is a correct field. Structured output guarantees a score is an integer; it does not guarantee the score is right. A tier of high with a nonsense reason is valid JSON and a bad answer. Validate the content, not just the shape, especially before an unattended job acts on it.

  • A schema so loose the structure lives in a free-text field anyway.
  • Over-nested schemas that validate but are miserable to consume.
  • Trusting a well-shaped value as a correct value; validate content, not just shape.
  • Adding fields you do not use, giving the model room to fill them with noise.
The GTM version

The GTM version

Structured output is the quiet workhorse behind most reliable GTM automation. Lead scoring that returns a score, a tier, and a reason. Contact extraction that returns name, title, and company from a messy signature. Enrichment that returns exactly the fields your CRM expects. Each of these has to run unattended and feed another system, which is precisely where guaranteed shape stops being a nicety and becomes the requirement.

The day my scorer returned a clean object every time instead of a hopeful paragraph was the day I stopped watching it run. That is the payoff: shape you can trust turns a script you babysit into a job you forget about. What is the automation you do not fully trust yet because its output is prose instead of data?

How to set it up

How to set it up

Define the schema for exactly what you need

Write a JSON schema with the fields, types, and required list your downstream system expects. For a lead scorer:

python
schema = { "type": "object", "properties": { "score": {"type": "integer"}, "tier": {"type": "string", "enum": ["A", "B", "C"]}, "reason": {"type": "string"}, }, "required": ["score", "tier", "reason"], }
$

Make the call constrained to that shape

Attach the schema to your request so the response is held to it, and give Claude the input to score:

python
$# check the docs for the current structured-output parameter
msg = client.messages.create( model="claude-sonnet-4-6", max_tokens=512, messages=[{"role": "user", "content": f"Score this lead against our ICP: {lead}"}], # ...structured output config per the docs... )
$

Parse straight into your system

The result matches your schema, so parse it directly and use the fields, no preamble stripping, no regex:

python
import json data = json.loads(msg.content[0].text) upsert_to_crm(score=data["score"], tier=data["tier"], reason=data["reason"])
$
💡

TipEven with a guaranteed shape, sanity-check the content before an unattended job acts on it. Valid JSON is not the same as a correct answer.

Delete the defensive scaffolding

Once the shape is guaranteed, remove the regex, the preamble stripping, and the retry-on-parse-failure code. That brittle layer existed only to compensate for asking politely, and it is now dead weight.

FAQ

Frequently asked questions

What are structured outputs?

A way to make Claude return data in a shape you define with a JSON schema, rather than prose you parse. You declare the fields and types, and the response is constrained to match, so you can parse it with confidence.

Why not just ask for JSON in the prompt?

Because a model generating text will occasionally add a friendly sentence, a trailing note, or a word where a number belongs, and each of those crashes a parser. Constraining the shape removes the gamble.

How is this different from tool use?

Tool use lets Claude call functions to act; its inputs are structured but the point is the action. Structured output shapes the final answer into data you consume. Many jobs use both.

How do I define the shape?

As a JSON schema: an object with named properties, each typed, plus a required list. Keep it to the fields you actually use, with specific types like integers and enums where they fit.

Does a guaranteed shape mean a correct answer?

No. It guarantees the structure, not the content. A score can be a valid integer and still be wrong, so validate the content before an unattended job acts on it.

How complex should my schema be?

As flat and tight as possible. Extra fields invite noise and deep nesting is harder for Claude to fill correctly and for your code to consume. If it is getting deep, consider two simpler calls.

What GTM tasks benefit most?

Anything unattended that feeds another system: lead scoring, contact extraction, enrichment shaped to your CRM's fields. Guaranteed shape is what lets those run without you watching.

Can I remove my JSON-cleanup code after switching?

Yes. The regex, preamble stripping, and parse-retry logic existed to compensate for unstructured output. With the shape guaranteed, that scaffolding is dead weight you can delete.

Sources

Sources & further reading

Claude ships fast. This page was last reviewed Aug 23, 2026; verify time-sensitive details against the official docs above before relying on them.

Get the AI-for-GTM playbook in your inbox

New Claude guides, use cases, and prompts every couple of weeks.

Subscribe →