← All case studies
Composite example

Invoice extraction, with a human approval gate

Ardent Partners puts the average cost to process one invoice by hand at $9.40. This pipeline drafts every field automatically, checks its own math, and refuses to post a single entry to accounting until a person signs off on it.

The problem: AI extraction is where compliance says no

What actually blocks this project.

Someone on the back-office team re-types every invoice by hand: vendor, invoice number, line items, tax, total. It's slow, and every manual entry is a chance to fat-finger a number.

The obvious fix runs into a wall the moment it reaches finance or compliance. An AI extraction tool means two separate problems stacked on top of each other: sending vendor and payment data to a third-party API, and letting a model write directly to the ledger with no one checking its work. Most teams that hear "AI" and "accounting system" in the same sentence say no before the demo finishes.

What I built: a pipeline that drafts, never posts

The system that replaced manual entry.

A self-hosted OCR and LLM pipeline reads each invoice, extracts the same fields a person would, checks its own math against six validation rules, and scores its confidence per field. Every result lands in a review queue, never in the accounting system directly. A person looks at the source page next to the extracted values, corrects anything wrong, and only then does an entry go through. Nothing else in the system can make that call, by design.

How it works: four stages before anything is posted

The pipeline every invoice moves through.

Every invoice moves through the same four stages. Only a human decision moves it past the fourth.

Read

Text-layer PDFs are read directly. Scanned pages go through Tesseract, which returns a real confidence score instead of assuming perfect accuracy.

Extract

A local LLM, running on Ollama, nothing leaves the network, returns strict JSON: vendor, invoice number, line items, subtotal, tax, total.

Validate & score

Six rules check the math, the date, and duplicates. Each field gets a confidence score blending OCR quality, source grounding, and which rules it passed.

Approve

High-confidence, validated items queue for a one-click approval. Everything else waits in an exception queue until a person clears it.

The full n8n workflow canvas: webhook intake, OCR, local LLM extraction with a repair-prompt retry, duplicate check, six validation rules, confidence scoring, routing to a pending-approval or exception queue, and a second, separate flow triggered only by an explicit human approval that posts to the accounting API.
The real workflow canvas. Two separate flows: intake and scoring on top, and a posting flow on the bottom that only a human approval can trigger.
The review UI showing an extracted invoice with per-field confidence badges. Every field reads 100% except invoice number, which reads 50%, flagged because the system detected the same vendor and invoice number already on file.
A real extraction: every field is clean except invoice number, dropped to 50% the moment the duplicate check caught it.

How failures are handled: caught, scored, never guessed past

What happens when something is wrong.

The model is allowed to be wrong. It is never allowed to be wrong silently.

Broken or hallucinated JSON
If the model returns malformed JSON, or a field that doesn't match anything in the source text, the workflow retries once with a repair prompt, then routes to the exception queue instead of guessing.
Math that doesn't add up
Line items are checked against the subtotal, and subtotal plus tax against the total, to the cent. A mismatch routes straight to the exception queue.
Duplicate invoices
Same vendor, same invoice number, already on file: blocked automatically, regardless of how confident the model was about everything else.
Technically valid, still uncertain
A document that passes every rule but scores below the confidence threshold still goes to the exception queue instead of the fast lane.
The review queue showing four invoices pending approval at 100% confidence, and two flagged in the exception queue: one tagged validation_failed for an arithmetic mismatch, one tagged duplicate for a repeated invoice number.
A real queue: four clean invoices waiting on a one-click approval, two others held back with the exact reason attached.
A validation results panel showing five rules passed (line items sum to subtotal, subtotal plus tax equals total, date plausible, currency valid, required fields present) and one failed (invoice number not duplicate).
Every rule that ran on that invoice, not just the one that failed. The reviewer sees the full picture, not a single red flag.

The result

Why the gate is the whole pitch.

Ardent Partners puts the average cost to process an invoice by hand at $9.40; best-in-class AP teams, almost entirely through automation, do it for $2.78. The extraction part of that gap isn't hard, most tools can read a PDF. The part that actually stops teams from automating is trust: a system finance will turn on has to prove it can't post something wrong without a person seeing it first.

That's what this pipeline is built to prove. The extraction logic, the six validation rules, and the approval gate all sit in code you can read end to end, including the one place in the entire system where a write to accounting is even possible, and the fact that a human decision is the only thing that reaches it.