An invoice extractor can return valid JSON with an internally consistent total and still be wrong. Suppose the source shows a USD 10 discount, but the extracted record sets the discount to zero and increases the total by USD 10. A check that adds only the extracted fields will pass. The application also needs to compare those fields with the invoice.
The following fictional invoice belongs to a proposed purchasing workflow. Its charges and tax convention are illustrative, not accounting or tax advice. The goal is to make a reviewer’s next action clear when the source and the machine record disagree.
Keep the source record beside the candidate
| Printed item | Quantity and unit price | Printed amount |
|---|---|---|
| Packing sleeves | 12 × 8.50 | 102.00 |
| Handling inserts | 5 × 19.60 | 98.00 |
| Subtotal | Sum of the two lines | 200.00 |
| Discount | Subtract from subtotal | 10.00 |
| Tax | Example: 10% of 190.00 | 19.00 |
| Freight | Added after the example tax | 15.00 |
| Total | 200.00 − 10.00 + 19.00 + 15.00 | 224.00 |
I would preserve an immutable source identifier and the original page, then attach evidence to each extracted amount. A person should be able to open the exact discount line from the exception queue. Re-running extraction on a changed attachment creates a new source version rather than overwriting the evidence behind an approved candidate.
Document AI returns detected entities with source anchors, and some fields also receive normalized values. Its response guide distinguishes normalization from enrichment; enrichment can add inferred information that does not appear in the source. Preserve that distinction when selecting fields for a posting record. Google Document AI: source anchors, normalization and enrichment
A source pointer is useful only if the application resolves it against the preserved document. A model-produced page number or copied phrase is still a claim to check. For a scanned page, keep the crop or bounding region when available. If the text layer and visible page disagree, route the discrepancy instead of treating the text layer as conclusive.
Use a schema for the record shape
Claude structured outputs constrain responses using a supported JSON schema. The current documentation also describes unsupported constraints and exceptional outputs, including refusals and token-limit truncation. Inspect the response status and validate the parsed object in the application before starting business checks. Claude: structured outputs and exceptional responses
{
"invoice_id": "INV-204",
"currency": "USD",
"subtotal": "200.00",
"discount": "0.00",
"tax": "19.00",
"freight": "15.00",
"total": "234.00",
"discount_evidence": null
}That candidate can satisfy a schema requiring decimal strings and a currency code. It also satisfies its own total formula: 200 − 0 + 19 + 15 = 234. The original invoice says discount 10 and total 224. This is a semantic extraction error that the record’s shape and internal sum cannot identify by themselves.
Represent an unreadable discount as unknown. Zero means the system has evidence for no discount; unknown means it cannot establish the amount. A default of zero would turn uncertainty into a financial assertion. Use the same distinction for missing quantities, currencies and credit adjustments.
If using Claude’s native citations feature, check feature compatibility: the current structured-output guide says native citation blocks cannot be combined with JSON outputs in the same request. The evidence fields proposed here are application fields, not an assertion that native citations are available in that mode. Claude: JSON output and citation compatibility
Run independent arithmetic and source checks
Use decimal arithmetic with an explicit rounding policy. For the stated example, the first check calculates 12 × 8.50 = 102.00 and 5 × 19.60 = 98.00. It compares their sum with the printed subtotal. A second check compares the extracted discount and total with their source regions. Only after resolving those fields does the application apply the example total equation.
| Check | Observed result | Disposition |
|---|---|---|
| JSON types and required fields | Record has the expected shape | Continue validation |
| Sum of extracted components | 200 − 0 + 19 + 15 = 234 | Internally consistent |
| Discount against original page | Source 10.00; candidate 0.00 | Hold: missing discount evidence |
| Total against original page | Source 224.00; candidate 234.00 | Hold: difference 10.00 |
Do not make the model “fix” the numbers until they balance. Two wrong fields can cancel each other. A changed quantity and a compensating changed unit price could preserve a line total while corrupting inventory or purchase-order matching. Check quantities and units against the order and receipt when those records are available, and keep unavailable records visible as unresolved checks.
Different suppliers use different conventions for tax, freight and line rounding. The production validator needs approved rules for the supported invoice types. The equation above is deliberately narrow. An unsupported convention should create a review item, rather than expanding the accepted tolerance until the invoice passes.
Give the reviewer a bounded correction
The INV-204 exception should show the printed discount beside the extracted zero, the USD 10 difference and a link to the original page. A reviewer can confirm the source amount, select a reason and submit a corrected candidate. Record both values and the reviewer identity, then run the checks again. Preserve the failed candidate as audit history.
Keep duplicate detection separate. In this proposed workflow, the supplier identity, invoice identifier and source fingerprint help locate possible repeats. A duplicate attachment arriving by a second email should lead to the existing candidate, not another posting. An invoice number alone may collide across suppliers or represent a revised document, so a match is a reason to inspect the record, not automatic proof of a duplicate.
Evaluate false acceptance at the invoice level
| Fixture | What the team should demonstrate |
|---|---|
| The omitted USD 10 discount | Hold despite valid JSON and internally matching totals |
| Two changed fields that cancel | Detect field-level disagreement with source or order |
| An unreadable currency or amount | Keep unknown; no guessed zero or currency |
| Credit note and unfamiliar tax convention | Use the supported rule or assign review |
| Repeated attachment and revised invoice | Distinguish a repeat from a new source version |
| Refusal, truncated output or missing source region | No posting candidate from an incomplete extraction |
Measure the share of complete invoices accepted correctly, the wrong records that pass, and the review minutes required for each document type. Field-level accuracy can conceal an invoice with one costly mistake. Use a held-out set with poor scans and multi-page tables, and record the parser and rule versions so a later upgrade can be compared with the same evidence.
After a candidate passes, posting still needs its own approved operation and duplicate protection. Extraction does not authorize payment or a supplier bank-detail change. The companion article explains how to keep instructions inside a document from controlling the action boundary. Read: document data and execution permissions



