← Blog

AI Use Cases

Extract invoice data to JSON with AI, without made-up values

November 10, 2026 · 6 min

Extract invoice data to JSON with AI, without made-up values

To extract invoice data to JSON with AI, list the fields, require null for missing values, and check the answer against the source. In our November 9, 2026 test, all three models left the absent due date and tax ID as null. The only recorded difference was whether the total came back as a number or a string.

What prompt should you use to extract invoice data to JSON with AI?

Name the fields and tell the model what to do when one is missing. We sent this exact prompt in EVA Multi Chat, using a fictional invoice rather than a customer's document.

Extract this fictional invoice into JSON only. Keys: invoice_id, vendor, total_usd, due_date, tax_id. Copy stated values; missing fields must be null. No guesses. Invoice: INV-2048; Vendor: Cedar Studio; Total: USD 480.00.

The source gives an invoice ID, vendor, and total. It has no payment terms and no tax ID, so a correct answer has nothing to put in those two fields.

Ask for extraction from the supplied text, not for a finished invoice. Looking up missing details is a different job, and it needs its own evidence checks.

A plausible payment date is not a stated payment date.

We left one requirement out of the prompt: the amount's type. Watch the quotation marks below.

What did three models return for the same invoice?

All three models kept both absent fields null. We scored the run by counting made-up values, and found none.

Results recorded November 9, 2026:

Modelinvoice_idvendortotal_usddue_datetax_idInvented values
GPT-6.1 SolINV-2048Cedar Studio480.00 (number)nullnull0
Claude Opus 5.5INV-2048Cedar Studio480.00 (number)nullnull0
Gemini 4 ArgonINV-2048Cedar Studio"480.00" (string)nullnull0

The complete recorded answers follow unchanged.

GPT-6.1 Sol

{"invoice_id":"INV-2048","vendor":"Cedar Studio","total_usd":480.00,"due_date":null,"tax_id":null}

Claude Opus 5.5

{
  "invoice_id": "INV-2048",
  "vendor": "Cedar Studio",
  "total_usd": 480.00,
  "due_date": null,
  "tax_id": null
}

Gemini 4 Argon

{ "invoice_id": "INV-2048", "vendor": "Cedar Studio", "total_usd": "480.00", "due_date": null, "tax_id": null }

The quoted amount is easy to miss when you read for accuracy. Gemini returned the stated amount, and we never asked for a numeric type, so we don't count it as an error.

If your importer needs a number, say so in the prompt and rerun it across the models you want to compare. Our guide to AI output acceptance criteria explains how to set those rules before collecting answers.

Why does a string versus number difference matter?

In JSON, "480.00" is text and 480.00 is a number. The JSON Schema numeric reference is explicit: a numeric string does not satisfy type: number. (We checked the JSON Schema pages linked here on November 9, 2026.)

A spreadsheet may accept either. A database column or an automation step that expects a number may reject the text, or store it in a way that breaks a later sum. Decide what the receiving field expects, then write that into the prompt or add a conversion rule.

Here's a version with types added. We haven't tested this revision.

Extract only the supplied invoice text into one JSON object.
Use exactly these keys and types:
- invoice_id: string or null
- vendor: string or null
- total_usd: number or null
- due_date: YYYY-MM-DD string or null
- tax_id: string or null

Copy stated values. Missing fields must be null.
Do not infer payment terms, calculate a due date, or look up a tax ID.
Use total_usd only when the source explicitly states a USD total.
Do not convert currencies. If a date is ambiguous, return null.
Return JSON only.

Invoice text:
[paste approved, sanitized text here]

If you're building the importer, check these rules in code too. Naming fields under properties doesn't require them to appear, as the JSON Schema object reference explains. required specifies which keys must be present; additionalProperties: false rejects extra keys.

Keep due_date in the object even when it is null. A reviewer can see an empty field; a missing key is easy to overlook.

How do you check the output before you trust it?

Compare each returned value with the invoice text before importing it. Start with the absent fields, because a believable date or identifier is easy to skim past.

  • Find the source text for each non-null value. For amounts, compare the numeric value and currency, rather than demanding identical display formatting.
  • Check that absent values are real null, not the string "null" or an empty string. The JSON Schema null reference treats these as different values.
  • Confirm the required keys and types match your importer. Reject an unexpected field instead of silently giving it a destination.
  • Read ambiguous amounts and dates manually. Don't assume a currency from the vendor's address or resolve an ambiguous date by habit.

Also decide what your system does with a null amount. It means "not on the document", so it should never turn into a zero balance on import.

Before connecting this to an importer, try documents with different layouts and deliberate gaps, and keep a hand-checked answer for each. Include documents where every field is present, too. A model that returns null everywhere would otherwise pass.

Save the prompt alongside those reference answers. A portable AI task brief is useful when you switch models: the new model should receive the same source text and acceptance rules, without relying on an earlier conversation.

When is a chat prompt not enough?

A chat-only test isn't enough to approve an unattended invoice import. Our recorded run started with short, readable text; it didn't test extracting text from an image or locating totals across pages.

If your starting point is a scan, evaluate the text-reading step separately before judging field extraction. For a document with line items, check which total you want the workflow to return. A subtotal, tax amount, and balance due shouldn't compete for an undefined field called total.

Send unreadable text and conflicting values to a person for review. Require the importer to stop on those cases rather than choosing the most plausible answer. Test that stop condition, too: what happens to a rejected document, and who will notice it waiting?

We recorded one run on one short invoice. It says nothing about line items, files with several invoices, or whether the same model answers the same way twice. There is no winner here; a folder of real invoices needs its own test.

FAQ

Can I use this as a ChatGPT invoice-extraction benchmark?

No. The recorded GPT-6.1 Sol answer came from EVA Multi Chat, not a test of the ChatGPT app. Use the fictional prompt as a starting exercise in your chosen tool and inspect its actual response before drawing conclusions.

What should I do with an ambiguous due date?

Send it to a person. The revised prompt returns null for ambiguous dates, so flag those documents for review instead of treating them like ones with no date at all.

Does valid JSON prove that the invoice data is correct?

No. A made-up due date can sit inside perfectly valid JSON. Format checks catch structure; only comparing values with the source catches invented ones.

Is it safe to paste real invoices into AI?

Use fictional or sanitized documents while testing. For real invoices, check your organization's authorization and the specific tool's data-handling terms first. Don't paste bank details, personal information, or confidential client material just to try a prompt.

Try EVA with the fictional invoice above to compare answers side by side in Multi Chat. Keep the original prompt for your first run so you can inspect the amount's type before asking for a revision.

Try EVA free

We count visits anonymously, without cookies. Accept to also allow analytics cookies, session recordings, and limited sharing with Google to measure our ads. Our analytics never collect the content of your chats. Privacy Policy · Your Privacy Choices