thinkhard.SI

Prompt patterns Extract to JSON

Extract to JSON

When a program will read the answer, ask for JSON: one object per record, exact key names, set formats for dates and numbers, and null wherever a value is missing. The output then means the same thing on every run, and an import or automation can take it without cleanup.

DataPublished October 29, 2026, a 6-minute readAll patterns

What it is

Ask a model to pull the due date out of twenty invoices and you get twenty sentences: “Due March 1”, “Payment is due on 1/3”, “Net 30 from the invoice date”. A person can read those. An accounts system cannot. JSON fixes the shape: every invoice becomes one object, every field has a name that never changes, and every value has a type, such as a date written as 2026-03-01 or a total written as a plain number.

A good extraction prompt states six things: the exact key names, the type or format of each value, the allowed values where there is a fixed list, one object per record inside an array, null when a value is missing or unreadable, and nothing before or after the JSON. One example object helps more than a paragraph of description, as in show one example.

The null rule matters most. Without it, a model that cannot find a due date will often supply a likely one, and an invented date looks exactly like a real one once it is in your system.

When it helps

Use it when you pull the same fields from many documents: invoices, order forms, contracts, applications, emails. Use it to classify messages so a ticket system or automation can route them. Use it whenever the next reader is a tool, such as a no-code automation, a script or a database import. And use it for any extraction you will run again, because a fixed schema keeps this month’s output comparable with last month’s.

When it does not

If a person will read the result, JSON is the wrong format. For figures you will paste into a spreadsheet, ask for a table or CSV instead, as in the table from a PDF or email template.

In a chat app, nothing enforces the format. The model writes JSON as text, and it can drop a comma, add a key or put a sentence before the opening bracket. Run the output through a JSON validator or your import tool’s test before you rely on it, and use structured outputs on the API for anything in production.

Valid is not correct. Even a schema that is enforced guarantees the shape, not the facts. Spot-check a sample of records against the documents, especially totals and dates.

Fields flatten judgment. A yes or no for “contract auto-renews” hides the clause that makes it conditional. Add a short field that quotes the source text for any value you may need to defend. On Claude’s newest models, do not add a field for the model’s reasoning; Anthropic’s documentation says requests like that can be declined.

JSON repeats every key in every record, so a long array costs more output than the same data as CSV.

Before and after

Two extractions from different kinds of work. The scores are the Prompt Grader’s free estimate with Written for set to Any chat model. A score counts what the prompt states; it does not grade the answer.

Before 1 out of 10
Get the details out of these invoices.

"""
[invoices]
"""
After 9 out of 10
Invoices, separated by lines of dashes:
"""
[invoices]
"""

Extract the fields below from each invoice above. The output goes straight to our accounts payable system, which rejects any record that does not match this structure.

Output: a JSON array, one object per invoice, with exactly these keys:
{"supplier": string, "invoice_number": string, "invoice_date": "YYYY-MM-DD", "due_date": "YYYY-MM-DD", "currency": "USD" | "EUR" | "GBP", "total": number}

Write numbers without currency symbols or thousands separators. If a field is missing or unreadable, use null; do not guess. Make sure every invoice appears exactly once. Return only the JSON, with no comments before or after it.

“Get the details” returns a readable list with different details for each invoice. The second returns one array with the same six keys every time, dates in one format, and null where an invoice has no due date, so the import either accepts it or fails loudly.

Before 2 out of 10
Summarize these support emails into a spreadsheet.

"""
[support emails]
"""
After 10 out of 10
Support emails from this morning:
"""
[support emails]
"""

Classify each email above so our ticket system can route it. Return one JSON object per email, in a JSON array, with these keys:
- "from": the sender's email address
- "product": one of "app", "billing", "hardware", "unknown"
- "urgency": "high" if the customer says they cannot work, otherwise "normal"
- "summary": one sentence, under 20 words, that should let an agent act without opening the email

Example: {"from": "ops@example.com", "product": "billing", "urgency": "normal", "summary": "Asks why the March invoice shows two seat charges."}

Do not include customer names or phone numbers in the summary. If the product is not clear from the email, use "unknown" instead of guessing.

The first prompt gets a table whose columns the model chose, which may change on the next run. The second gets four fixed keys with a closed list of products, a rule for urgency the routing can trust, and “unknown” instead of a guessed product.

The line to add

Return only a JSON array, one object per {{record}}, with exactly these keys:
{"{{key}}": string, "{{key}}": number, "{{key}}": "YYYY-MM-DD", "{{key}}": "{{allowed value}}" | "{{allowed value}}"}

Example object: {{one filled-in example}}

Write numbers without symbols or separators. If a value is missing or unclear, use null; do not guess. No text before or after the JSON.

Paste the documents above this block, fenced off so the model can tell them from your instructions, as in fence off pasted text. Before an import, test the prompt on a handful of awkward documents, such as a scan, a credit note or an invoice in another currency, in Prompt Tester.

In ChatGPT, Claude, Gemini and Copilot

In all four chat apps, JSON is text the model writes, usually in a code block you can copy. The prompt above is all you can do there, so validate the result before it goes anywhere.

Through the APIs, all three model vendors can enforce a schema. OpenAI says that while both its JSON mode and Structured Outputs produce valid JSON, “only Structured Outputs ensure schema adherence” (Structured model outputs). Anthropic says Claude’s structured outputs constrain responses to a schema through constrained decoding, with exceptions such as refusals and responses cut off by the token limit (Structured outputs). Google says Gemini can be configured to adhere to a JSON Schema, that not every schema feature is supported, and that you should always validate the values in your application (Structured outputs).

Anthropic’s refusals page lists a reasoning or thinking field in JSON output among the requests its newest models may decline (Keep reasoning in thinking blocks). A field that quotes the source text is a different thing, and it is the one worth having.

Key takeaways

  • Use JSON when a program reads the output; use a table or CSV when a person does.
  • Name the keys, the formats and the allowed values, and give one example object.
  • Ask for null when a value is missing, and say not to guess.
  • In a chat app, validate the JSON; on the API, use structured outputs.
  • A valid shape is not a correct value. Spot-check against the documents.

Questions

How do I get ChatGPT to output JSON?

Ask for it exactly: “Return only a JSON array, one object per invoice, with exactly these keys”, then list the keys with their types and allowed values, add one example object, and say to use null for anything missing. In the chat app nothing enforces the format, so check the output with a JSON validator. Through the API, use Structured Outputs.

Can I trust JSON that AI extracts from documents?

Trust the shape only if a schema enforces it, and never trust the values without a check. A model can misread a scan or supply a likely value for a missing field. Ask for null instead of guesses, add a field that quotes the source text, and spot-check a sample of records against the documents before an import.

Should I ask AI for JSON or CSV for a spreadsheet?

For a spreadsheet you paste into by hand, CSV or a table is simpler and costs less output, because JSON repeats every key in every record. Use JSON when an automation, script or import tool expects it, or when a record has nested parts, such as an invoice with several line items.

Prompts to use with this

Browse all 519 prompts