Claude API JSON Mode: Output Formatting Guide
If you're looking for a response_format: json_object flag like some other APIs offer, Claude doesn't have one. There is no single "JSON mode" switch you can flip in the request body. What Claude does have is a set of reliable techniques — tool use with a schema, system prompt constraints, and assistant message prefilling — that together give you output as structured and predictable as a dedicated JSON mode, often more so.
This matters because unstructured text responses are hard to parse in production. If you're building anything that feeds Claude's output into a database, a UI component, or another API call, you need valid JSON every time, not "mostly valid JSON with occasional explanatory sentences before the braces." Below are the three approaches that actually work, in order of reliability.
Why Claude doesn't need a literal "JSON mode"
Other providers added a JSON mode flag because, without it, models frequently wrapped JSON in markdown fences, added commentary, or produced malformed objects. Claude's models are generally better at following explicit formatting instructions, but the underlying problem is the same: a model generating free text can always decide to add a sentence you didn't ask for.
Anthropic's recommended fix isn't a formatting flag — it's tool use. When you define a tool with a JSON schema and force Claude to call it, the model's output is structurally constrained by the schema itself, not just by instructions it might ignore.
Method 1: Tool use with a forced tool call (most reliable)
This is the closest thing to a true JSON mode. Define a tool that represents the exact shape of data you want, then force Claude to use it with tool_choice.
curl https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"tools": [{
"name": "extract_order",
"description": "Extract structured order data",
"input_schema": {
"type": "object",
"properties": {
"order_id": {"type": "string"},
"total": {"type": "number"},
"items": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["order_id", "total", "items"]
}
}],
"tool_choice": {"type": "tool", "name": "extract_order"},
"messages": [
{"role": "user", "content": "Order #4521: 2x widget, 1x gadget, total $45.00"}
]
}'
The response comes back as a tool_use content block with input already matching your schema — no parsing a text blob, no stripping markdown fences. This is the approach Anthropic itself recommends for structured output, and it's the one you should default to for anything that feeds into downstream code.
If you're calling Claude through SubToAPI, the request shape is identical — just point it at https://api.subtoapi.app/v1/messages with your sub_live_... key instead of a raw Anthropic key. See /docs/tools for the full tool-use reference and /docs/messages for the base request format.
Method 2: System prompt + strict instructions
When you don't want the overhead of defining a tool — for example, a simple one-off extraction — a tightly worded system prompt gets you most of the way there:
You are a JSON-only API. Respond with valid JSON and nothing else.
Do not include markdown code fences, explanations, or any text
outside the JSON object. If you cannot answer, return {"error": "reason"}.
Pair this with a clear description of the schema in the same system prompt (field names, types, whether fields are optional). This works well for simpler tasks but is less bulletproof than tool use — Claude can still occasionally add a stray newline or a fenced code block, especially on longer or more creative outputs.
Method 3: Prefill the assistant turn
A less obvious but effective trick: start the assistant's response for it. If you prefill the assistant message with {, Claude is far less likely to prepend any explanatory text, because it's continuing a message that's already begun as JSON.
{
"messages": [
{"role": "user", "content": "Summarize this review as JSON with fields: sentiment, score, summary."},
{"role": "assistant", "content": "{"}
]
}
Combine this with the strict system prompt from Method 2 and you get a meaningful reliability boost with almost no added complexity. Just remember to prepend the { back onto the response text before parsing, since it won't be echoed in the output.
Validating and handling the edge cases
No matter which method you use, treat JSON parsing as a step that can fail:
- Always wrap parsing in a try/catch. Even with tool use, malformed input can occur if your schema is ambiguous.
- Use
stop_sequenceslike"\n\n"or"`"if you're using the plain-text approach and want to cut off trailing commentary. - Validate against your schema, not just
JSON.parsesuccess. A valid JSON object with the wrong shape will break your code just as badly as invalid JSON. - Log failures separately from successful parses so you can see if a particular prompt or input type is causing drift over time.
try {
const block = response.content.find(c => c.type === "tool_use");
const data = block.input; // already a parsed object, no JSON.parse needed
validateSchema(data);
} catch (err) {
console.error("Structured output validation failed:", err);
}
Note the tool-use path skips JSON.parse entirely — Anthropic parses the model's structured output into input for you, which removes one whole class of parsing bugs.
If you're standardizing this across a team, running everything through one API key management layer helps — see /docs/quickstart for setup and /pricing for plan details if you need to add seats for teammates building against the same Claude access.
questions
Does Claude have a dedicated JSON mode like GPT-4? No. There's no response_format toggle. The equivalent is forcing a tool call with tool_choice, which constrains output to a JSON schema more reliably than a text-based flag would.
Why does Claude sometimes wrap JSON in markdown code fences? This happens most often with plain-text prompting rather than tool use. A strict system prompt telling Claude to omit fences, combined with prefilling the assistant turn with {, largely eliminates it.
Is tool use overkill for simple JSON extraction tasks? Not really — even for a single field, tool use guarantees schema-shaped output and removes manual parsing. For truly trivial one-off cases, a strict system prompt plus prefill is a reasonable lighter-weight alternative.