JSON Mode Prompt — With and Without Native Support
Native JSON modes guarantee syntax, not your schema. The prompt contract that covers field names, types, and null discipline — whether or not the API has JSON mode.
Overview
OpenAI, Claude, and Gemini all offer some form of native structured output — and teams keep getting burned by assuming that solves the problem. Native modes guarantee the response parses; they don't guarantee it contains your field names, your types, or null instead of invented values. The prompt contract still does that work. This resource loads a support-ticket contract that works identically with JSON mode on (where it constrains content) and off (where it also forces syntax) — one prompt, both worlds.
Workflow
-
Generate the loaded contract
Note what native JSON mode can't do here: the severity value space, the null rule, the no-extra-fields rule.
-
Pair with your API settings
JSON mode on: keep the schema and validation sections, the syntax rules become redundant insurance. JSON mode off: everything earns its place.
-
Constrain values in descriptions
The severity field shows the pattern — enumerate legal values in the description and the model treats it as validation.
Why This Works
- Separating syntax (the API's job) from schema discipline (the prompt's job) keeps both reliable
- Value-space constraints in field descriptions are the cheapest enum enforcement available
- One contract across providers means switching models is a config change, not a rewrite
Best for
- API developers using response_format or structured output features
- Teams running the same prompt on multiple model providers
- Anyone who shipped JSON mode and still got wrong field names
Not for
- Pure chat use where a human reads the output — the contract is overhead there
- Validating responses after the fact — that's the AI Output Validator
Use cases
- Writing one prompt that behaves across APIs with and without JSON mode
- Constraining value spaces (severity: critical/high/medium/low) that native modes don't enforce
- Migrating between model providers without rewriting the output handling