Subscribe
Prompt Engineering
8 min read

How to Get JSON From ChatGPT, Claude and Gemini

How to get clean JSON from ChatGPT, Claude and Gemini: prompt steps for chat apps, the structured output setting in each API, and 6 copy-paste templates.

Olivetti-style cover reading JSON Output, ChatGPT, Claude, Gemini, Prompts and schemas, with a sample JSON object on a teal block and curly braces on red
Olivetti-style cover reading JSON Output, ChatGPT, Claude, Gemini, Prompts and schemas, with a sample JSON object on a teal block and curly braces on red

You ask a chatbot for JSON and get a friendly sentence, a code fence, and a short essay after the data. That is fine for reading. It breaks a spreadsheet import, a Zapier step, or the app you built last weekend.

There are two ways to get clean JSON. In a chat app, you write a tighter prompt. In the API, you turn on structured outputs, a setting that makes the model follow a schema. This guide covers both for ChatGPT, Claude and Gemini, with copy-paste templates and a small local test.

What JSON is, in one minute

JSON is a plain-text format for data. It uses keys and values inside curly braces:

{"name": "Dana Ruiz", "email": "dana@ruizbakery.com", "topic": "demo"}

A program can read it only if it is exact: double quotes, no trailing commas, no extra words around it. A schema is a description of the shape you want. It lists the keys, the type of each value (text, number, true/false, list), and the allowed values.

Why the plain "give me JSON" prompt fails

A vague request leaves the model to invent the shape. It picks its own key names, nests some fields, and adds notes. Anthropic lists the usual problems without structured outputs: invalid JSON syntax, missing required fields, inconsistent data types, and schema violations (Claude docs).

We saw all of this in our own test below. The fix in a chat window is to spell out the shape. The fix in code is to give the API the schema.

How to get JSON in a chat app: 6 steps

These steps work in ChatGPT, Claude and Gemini chats. In a normal chat, the prompt does all the work.

  1. Name every key. Write the exact key names you want, in the order you want. Do not let the model choose.
  2. Say the type of each value. Text, number, true/false, or a list. Google's advice for schemas is the same idea: use specific types such as integer, string and enum (Gemini docs).
  3. List allowed values. If a field can only be "demo", "pricing", "support" or "other", say so. This stops new labels.
  4. Say what to do when data is missing. Ask for null and add "Do not guess." OpenAI warns that a model that always tries to fit a schema can make up values when the input does not fit. Its fix is to say in the prompt what to return in that case, such as empty values or a set sentence (OpenAI docs).
  5. Ask for JSON only. Write "Reply with one JSON object and nothing else." Expect code fences anyway from some models (see the test).
  6. Check the result. Paste it into a JSON validator, or let your script strip the fences before it parses. Google's guide says to validate values in your app even when the syntax is correct.

For hard cases, add one or two filled-in examples. Our guide to few-shot prompting shows how. If you send the same format rules every time, put them in a system prompt or custom instructions.

How to get guaranteed JSON in the API

All three APIs can make the reply follow a JSON Schema. OpenAI says this means you do not need to worry about the model leaving out a required key or inventing an invalid enum value (a value outside your list). The details differ.

OpenAI (ChatGPT models)

  • Set text.format to {"type": "json_schema", "strict": true, "schema": ...} in the Responses API (OpenAI docs).
  • OpenAI says Structured Outputs works on its latest models, starting with GPT-4o. It suggests gpt-6-astra for new projects.
  • Every field must be listed as required. To make a field optional, allow null in its type, for example ["string", "null"].
  • Every object must set additionalProperties: false.
  • A schema can have up to 5,000 object properties and 10 levels of nesting.
  • If the model refuses for safety reasons, the response has a refusal field instead of your data. Check for it.
  • The older JSON mode ({"type": "json_object"}) only promises valid JSON, not your schema. It also needs the word "JSON" somewhere in your prompt, or the API returns an error. OpenAI recommends Structured Outputs over JSON mode when you can use it.

Anthropic (Claude)

  • Put the schema in output_config.format with "type": "json_schema" (Claude docs). Anthropic's SDK helpers set this for you.
  • Objects must set additionalProperties to false. Claude does not support number limits such as minimum and maximum, or string length limits. Anthropic says SDK helpers can move those limits into the field description, and a helper that validates responses still checks them.
  • The first request with a new schema is slower while the grammar compiles. Anthropic caches it for 24 hours from last use.
  • Claude adds a short system prompt about the format, so input tokens go up a little.
  • Three edge cases still return output that may not match: a safety refusal (stop_reason: "refusal"), a cut-off reply (stop_reason: "max_tokens"), and enum values in a different capital letter. Anthropic says to compare enum values without case.
  • Required properties come first in the output, then optional ones. If order matters, mark every property required.

Google (Gemini)

  • Set response_format with mime_type set to application/json and your schema in schema (Gemini docs). Google's examples call the Interactions API and also set "type": "text" in that object. The Python and JavaScript SDKs accept Pydantic and Zod schemas.
  • Gemini does not enforce some limits, such as minLength, maxLength and uniqueItems. The API drops them without an error. minItems and maxItems are enforced.
  • Very large or deeply nested schemas can fail with a 400 INVALID_ARGUMENT error. Google's fixes: lower nested array limits, shorten names, and mix required fields in with optional ones.
  • Google lists clear description fields, strong types and a clear prompt as best practices.

Structured outputs or function calling?

Both OpenAI and Google draw the same line. Use structured outputs to shape the model's final answer. Use function calling (tools) when the model needs your app to do something, such as look up an order. Anthropic offers strict tool use for the second case and says the two work together.

We tested it: Gemma 3 1B, run locally

We ran three prompt styles on Gemma 3 1B, a small open model, through llama.cpp on our own machine, at temperature 0. The task: pull a name, email, date and topic out of four short customer messages. We scored each reply on three things: does it parse as JSON with no cleanup, does it have exactly our four keys, and are all values right.

Bar chart of our Gemma 3 1B test, 4 messages per prompt style: vague prompt 0 of 4 on parsing, keys and values; spelled-out prompt 0 of 4 parse as-is, 4 of 4 exact keys and values; prompt plus JSON schema 4 of 4 on all three
  • Vague prompt ("Turn this message into JSON."): 0 of 4 parsed as-is. Every reply came in a code fence. After we stripped the fences, 3 of 4 parsed; the fourth had an explanation after the JSON. 0 of 4 used our keys. The model chose its own: "sender", "request", "contact", "recipient".
  • Spelled-out prompt (keys, allowed values, null rule, "No code fences, no extra text"): still 0 of 4 parsed as-is, because the model kept the code fences. After stripping them, 4 of 4 parsed, with the right keys and all values right.
  • Same prompt plus a JSON schema (llama.cpp's response_format with json_schema, which constrains the output like the hosted APIs): 4 of 4 parsed as-is, with the right keys and all values right.

We also sent an off-topic message ("What's a good name for a golden retriever puppy?") with the schema on. The model returned every key as null and topic "other". It did this with and without an extra fallback line, so one test does not show that the line is needed. On bigger hosted models your results will differ. The pattern is the useful part: the prompt fixes the keys, and the schema fixes the format.

The shape of a good JSON prompt

Diagram of the 5 parts of a JSON prompt (task, output rule, keys, null rule, input) and the API schema setting for each vendor: OpenAI text.format, Claude output_config.format, Gemini response_format

A good JSON prompt has five parts, in this order:

  1. The task in one line ("Extract the details from the message below.")
  2. The output rule ("Reply with one JSON object and nothing else.")
  3. The keys, each with a type or allowed values
  4. The null rule ("If a detail is missing, use null. Do not guess.")
  5. The input, clearly marked

6 copy-paste templates

Replace the parts in square brackets. They work in ChatGPT, Claude and Gemini chats.

1. Extract contact details

Extract the details from the message below. Reply with one JSON object and nothing else. No code fences, no extra text.
Use exactly these keys:
- name: the sender's name as written, or null
- email: the sender's email, or null
- date: the date they ask for, as written, or null
- topic: one of "demo", "pricing", "support", "other"
If a detail is missing, use null. Do not guess.

Message: [paste message]

This is the exact prompt we tested above.

2. Turn a list into rows

Turn the text below into a JSON array. Each item is an object with these keys:
- item: text
- quantity: number, or null if not given
- unit: text, or null
Reply with the JSON array only.

Text: [paste shopping list or notes]

3. Classify many short texts

Label each review below. Reply with a JSON array only. Each object has:
- id: the number in front of the review
- sentiment: one of "positive", "negative", "mixed"
- reason: one short sentence
Use only those three sentiment values.

Reviews:
1. [review]
2. [review]

4. Pull data from an invoice or receipt

Read the receipt below. Reply with one JSON object and nothing else:
- vendor: text
- date: in YYYY-MM-DD format, or null
- total: number with no currency sign
- currency: three-letter code such as "USD", or null
- line_items: array of objects with "description" and "amount"
If you cannot read a value, use null. Do not guess.

Receipt: [paste text or attach image]

5. Make test data for an app

Create 5 sample users as a JSON array. Each object has:
- id: integer starting at 1
- full_name: text
- signup_date: YYYY-MM-DD in 2026
- plan: one of "free", "pro", "team"
Reply with the JSON array only. Use made-up names.

6. Fix broken JSON

The text below should be one valid JSON object but has errors. Fix only the syntax. Do not add, remove or rename keys. Reply with the fixed JSON only.

[paste broken JSON]

Common problems and fixes

  • Code fences around the JSON. Small models add them even when told not to (our test). Strip the leading ```jsonline and the closing fence in your code, or use the API schema setting.
  • New key names. List the keys and say "Use exactly these keys."
  • Made-up values. Add a null rule and "Do not guess." OpenAI also suggests examples and splitting a hard task into smaller steps when outputs have mistakes.
  • Long lists cut off. A reply that hits the token limit is incomplete JSON. Claude marks this with stop_reason: "max_tokens". Raise the limit or ask for fewer items per call.
  • Right format, wrong facts. A schema checks shape, not truth. Google tells developers to validate values in their app and handle outputs that match the schema but are wrong.

Bottom line

In a chat app, name the keys, the types, the allowed values and the null rule, then check the result. In code, use the schema setting in the OpenAI, Claude or Gemini API, and still check for refusals, cut-off replies and wrong values. If you are building a small app this way, our guide to building an app with AI and no code shows where a JSON step fits.

Sources

Prompt EngineeringStructured OutputChatGPTClaudeGemini