Structured Outputs & JSON Mode (2026): Reliable JSON From LLMs

How to get reliable, schema-valid JSON from LLMs — JSON mode, schema prompting, validation and retries — with copy-paste examples so parsing never breaks again.

Structured Outputs & JSON Mode (2026): Reliable JSON From LLMs

Why Structured Outputs

If your app parses LLM output, free-form text is a liability — a stray sentence or markdown fence breaks JSON.parse. Structured outputs make the model return valid, schema-shaped JSON every time, so extraction, classification and pipelines are reliable.

Three Levels of Reliability

  1. Prompt for JSON — ask for JSON and give an example. Easy, but not guaranteed.
  2. JSON mode — the model is constrained to emit syntactically valid JSON.
  3. Schema-constrained — the output must match a JSON schema you supply (strongest guarantee).

Use the strongest level your chosen model supports — confirm options in the docs.

Example

payload = {
  "model": "gemini-3.5-flash",
  "messages": [
    {"role": "system", "content": "Extract fields as JSON only. No prose, no markdown."},
    {"role": "user", "content": "Invoice #A-190 from Acme, total $4,200, due 2026-08-01."}
  ],
  "response_format": {"type": "json_object"}   # enable JSON mode (name varies by model)
}
# expected: {"invoice_no":"A-190","vendor":"Acme","total":4200,"due":"2026-08-01"}

Then validate before trusting it:

import json, jsonschema
schema = {
  "type": "object",
  "properties": {
    "invoice_no": {"type": "string"},
    "vendor": {"type": "string"},
    "total": {"type": "number"},
    "due": {"type": "string"},
  },
  "required": ["invoice_no", "total"],
}
data = json.loads(resp_text)
jsonschema.validate(data, schema)   # raises if the shape is wrong

Make It Bulletproof

  • Always validate against a schema; don't assume.
  • Retry on invalid — reissue with "Your previous output was invalid JSON; return only valid JSON matching the schema." One retry fixes most cases.
  • Say "JSON only, no markdown" in the system prompt to avoid ```json fences.
  • Keep schemas flat where you can; deeply nested schemas are harder for models.
  • Lower temperature for extraction tasks.

Great For

Data extraction, classification/tagging, function arguments (pairs with function calling), and any step feeding downstream code. For cheap high-volume extraction, DeepSeek V4 Flash or Gemini Flash are strong; see cheapest LLM API.

Bottom Line

Enable JSON/schema mode, tell the model "JSON only," validate against a schema, and retry once on failure. Do that and LLM output becomes a dependable data source. Start from the Python quickstart.

Start free with a $1 credit and lock down your JSON.

About the author

Claire Lowe

Claire Lowe

AI and API researcher at LinkModel

Claire Lowe is an AI and API researcher at LinkModel, specializing in generative AI models, API pricing, provider comparisons, and multimodal infrastructure. Her work is grounded in official documentation, primary-source pricing data, and hands-on research, with a focus on helping developers and businesses make informed decisions about AI models and API providers.

Related Posts