invoice-pipeline
Email inbox to accounting system: PDF invoices in, validated line items out. Humans review the weird ones.

§ 01 · Overview
An invoice ingestion pipeline that reads PDF invoices from a folder, extracts structured fields via Claude's native PDF handling, validates against rules (VAT number format, subtotal-plus-VAT-equals-total math, duplicate detection), routes every invoice through a human review queue, and appends approved records to a CSV output. Designed for the ambiguous middle of invoice processing: multi-page invoices, credit notes with negative totals, foreign currency, and VAT edge cases.
§ 02 · Estimated impact
§ 03 · Architecture
- 01
Reads every PDF from a configured folder (v0.1) or from a Gmail/Outlook watcher (roadmap v0.2). Each file is passed to Claude's native PDF handling with a strict JSON schema covering supplier, invoice number, VAT number, dates, currency, subtotal, VAT total, total, and per-line description/quantity/unit-price/VAT-rate. Confidence is reported per extraction.
- 02
Validation is rules-based: missing supplier or invoice number, VAT number format, subtotal-plus-VAT-equals-total within a configurable tolerance, line-item versus subtotal drift, and low-confidence extraction. A duplicate store keyed by (supplier, invoice_number) prevents re-processing.
- 03
Every extracted invoice is routed to the review queue provided by hitl-review. A preview markdown file is written to the drafts folder immediately for out-of-band inspection.
- 04
On approval, the invoice is appended to the output CSV with one row per invoice and line items serialised as an embedded JSON column. The duplicate store is updated so a future run recognises the same invoice.
Stack
§ 04 · Positioning
Invoice OCR products either output raw text with no downstream reasoning, or bundle a full accounting UI you're expected to adopt. The gap is the middle layer: rules-based validation, a human-in-the-loop review UX, and pluggable output.
| Alternative | Trade-off |
|---|---|
| Dedicated OCR / AP SaaS platforms | £200-£1,500/mo minimum spend, vendor-owned data, and coupling to the vendor's accounting UI. Sensible for a 500-person AP team; disproportionate for the 5-15 invoice/day SMB where this problem is most common. |
| Zapier or n8n with a generic OCR API | Adequate for well-formed single-page invoices. Degrades on multi-page invoices, credit notes, foreign VAT, and any ambiguity — because human-in-the-loop review is not part of the design. The result is faster processing of unreliable data. |
| Manual data entry by a junior accountant | Slow and error-prone at scale, though essential for genuinely ambiguous invoices. The pipeline is built to route only the ambiguous cases to a human, not to replace judgement altogether. |
§ 05 · Frequently asked
How does invoice-pipeline detect duplicate invoices?
A JSON-file duplicate store keyed on the normalised (supplier, invoice_number) pair. Every approved invoice is recorded on push to CSV, so a subsequent run against the same PDF (or a re-sent one from the supplier) is flagged as duplicate_invoice before extraction spend is incurred. Casing is normalised so 'Acme Ltd · INV-1' matches 'acme ltd · inv-1'.
What happens when Claude's PDF extraction confidence is low?
A low_extraction_confidence warning is added to the invoice's issue list at any confidence below 0.7, and the invoice is queued for human review regardless. Nothing silently drops — every invoice reaches the reviewer with its full extraction and confidence surfaced.
Does invoice-pipeline push directly to Xero or QuickBooks?
Not in v0.1. Approved records are appended to a CSV output that imports cleanly into any accounting system. Direct-push adapters for Xero, QuickBooks, and Sage are on the roadmap for v0.3, all routed through the human review queue.