← Blog

Prompt Engineering for Claude Structured Output

2026-09-26 · 5 min read · SubToAPI Team

If you're trying to get Claude to consistently return JSON, XML, or another machine-readable format, the fix is rarely "add more instructions." It's about structuring the prompt itself so the model has no ambiguity about the shape of the output, and validating what comes back. This article covers the specific prompt patterns that make structured output reliable, plus the common mistakes that cause malformed responses.

The short answer: use explicit schema definitions, show a concrete example, constrain the output with prefill or stop sequences where possible, and always parse defensively. The rest of this guide breaks down each piece with real examples you can copy.

Why Claude Sometimes Breaks Structured Output

Claude is a text model — it doesn't "know" JSON is special unless you make the boundaries of the format explicit. Common failure modes:

None of these are model bugs — they're prompt design gaps. Each one has a direct fix.

Pattern 1: Define the Schema Explicitly

Don't describe the output in prose. Show the exact structure, field types, and constraints.

Return a JSON object with exactly these fields:
{
  "title": string,
  "summary": string (max 200 characters),
  "tags": string[] (3 to 5 items),
  "confidence": number (0.0 to 1.0)
}

Do not include any text before or after the JSON object.

This is more reliable than "return the title, summary, tags, and a confidence score in JSON." Explicit types and constraints reduce the model's guessing space significantly.

Pattern 2: Give a Concrete Example

One well-formed example output outperforms three paragraphs of description. Claude pattern-matches strongly on examples.

Example output:
{"title": "Q3 Revenue Report", "summary": "Revenue grew 12% driven by enterprise renewals.", "tags": ["finance", "quarterly", "revenue"], "confidence": 0.92}

Now produce the same structure for this input:
"""
{{document_text}}
"""

If you need multiple output shapes (e.g., different object types depending on input), show one example per shape rather than trying to describe branching logic in prose.

Pattern 3: Use System Prompts to Set the Contract

Put the format contract in the system prompt, not the user message. This keeps formatting rules consistent across turns in a conversation and separates "how to respond" from "what to respond to."

{
  "model": "claude-sonnet-4-5",
  "system": "You are a data extraction engine. Always respond with a single valid JSON object matching the schema provided by the user. Never include markdown formatting, explanations, or text outside the JSON object. If a field cannot be determined, use null.",
  "messages": [
    {"role": "user", "content": "Schema: {\"name\": string, \"email\": string|null}\n\nExtract from: 'Contact John at john@example.com for details.'"}
  ]
}

The explicit "never include markdown formatting" and "use null for unknown fields" instructions eliminate two of the most common failure modes directly.

Pattern 4: Prefill the Assistant Turn

If your API path supports it, prefilling the start of Claude's response with { forces the model to continue directly into JSON rather than starting with a preamble sentence. This is one of the most effective single tricks for structured output because it removes the model's opportunity to add "Sure, here's the JSON:" — that sentence simply can't come after an opening brace.

Pattern 5: Use Tool Definitions for Guaranteed Shape

For anything beyond a quick prompt trick, Claude's tool use (function calling) is the more robust mechanism. Instead of asking Claude to format JSON in free text, you define a tool with a JSON schema, and Claude returns arguments matching that schema in a structured tool_use block — no parsing of prose required.

{
  "name": "extract_contact",
  "description": "Extract contact information from text",
  "input_schema": {
    "type": "object",
    "properties": {
      "name": {"type": "string"},
      "email": {"type": ["string", "null"]}
    },
    "required": ["name", "email"]
  }
}

This shifts structural enforcement from prompt wording to the API layer, which is significantly more reliable for production pipelines. If you're building on top of SubToAPI, the tool use docs cover how to pass schema definitions and handle the resulting tool_use blocks, and the messages guide shows the request/response format end to end.

Pattern 6: Validate and Retry

Even with all the above, treat the model's output as untrusted input. A minimal production loop:

function parseStructured(raw) {
  try {
    return JSON.parse(raw.trim());
  } catch {
    return null;
  }
}

const result = parseStructured(response.content);
if (!result || !result.title) {
  // retry with a stricter system prompt or lower temperature
}

Lowering temperature (0 to 0.2) for extraction and classification tasks reduces formatting drift considerably compared to creative-writing temperatures.

Putting It Together

A reliable structured-output prompt typically combines:

  1. A system prompt that states the format contract and forbids extra text
  2. An explicit schema with types and constraints
  3. One example of correct output
  4. Low temperature
  5. Defensive parsing on your side, or tool use instead of free-text JSON when the stakes are higher

If you're calling Claude through an API layer, this whole flow — schema definition, system prompt, request/response handling — works the same way whether you're testing locally or running production traffic. SubToAPI wraps your existing Claude access into a standard HTTPS API with application keys, so you can build and test these prompt patterns against /v1/messages without managing separate provider credentials. See the quickstart to get a key running in a few minutes.

questions

Does asking Claude to "only return JSON" guarantee valid JSON? No. It reduces the chance of preamble text but doesn't guarantee valid syntax or consistent field names. Combine it with an explicit schema, an example, and server-side validation.

Should I use prompt-based JSON or tool use for structured output? For simple, low-stakes formatting, prompt-based JSON with a schema and example is fine. For anything feeding into a pipeline where malformed output breaks downstream code, use tool use — it enforces structure at the API level rather than relying on the model following instructions in prose.

Does lowering temperature actually help with structured output? Yes, noticeably. Extraction and classification tasks with temperature 0–0.2 produce far more consistent field formatting than default creative-writing temperatures, since the model is less likely to vary phrasing or add extra commentary.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →