The quantity is the point
Most invoice extraction is built around the total, because the total is what gets paid. For anything involving stock that is the wrong field to care about. A total tells you what you owe; it tells you nothing about how many of what arrived at what price, which is the only thing stock is made of.
This page is about the row rather than the document: what comes out of each line, what is deliberately not guessed, and the one check that tells you whether a particular invoice was read correctly. If you want the reconciliation this feeds, that is on the stock purchase reconciliation page.
What comes out of each row
| Field | Example | Why it is separate |
|---|---|---|
| Description | Widget blue 500ml | Matching to your catalogue |
| Product code | WB-500 | Far more reliable than description |
| Quantity | 24 | Meaningless without the next field |
| Unit of measure | case | The most damaging assumption if guessed |
| Unit price | 18.40 | Where price changes become visible |
| Line discount | 5% | Keeps list price and paid price apart |
| Line total | 419.52 | Feeds the sum check |
| Source file / page | inv-8841.pdf p2 | Traces a figure back to a document |
Alongside the rows, the document-level fields come through as usual: supplier, invoice number and date, currency, net, tax and gross totals. Those belong to the invoice; the rows belong to the stock.
Read by meaning, not by position
The old way of reading invoices is a template per supplier: quantity lives at these coordinates, price at those. It works beautifully on the supplier it was built for and breaks the first time that supplier changes their invoicing software — silently, because the template still finds numbers, just the wrong ones.
Reading by meaning asks a different question of the page: which column contains counts, which contains money, which text is a description. That holds when the layout moves, when a new supplier appears, and when someone sends a document that has never existed before. For a business with forty suppliers rather than four, it is the difference between a system that works and a maintenance job.
It also removes the worst failure mode of templates, which is not breaking loudly but breaking quietly. A template that has slipped one column produces perfectly formed data that is entirely wrong, and nothing about the output announces it.
The unit of measure deserves its own field
A quantity without a unit is not data, it is a number. Twelve can be twelve bottles, twelve cases of six, or twelve kilograms, and the same supplier will use more than one convention across their range — often on the same invoice.
So the stated unit is captured as its own field rather than being absorbed into the description or assumed away. That does not solve the problem by itself; it makes the problem visible, which is the most a document can honestly do. The supplier says cases. Whether a case is six or twelve is not on the invoice.
What follows is a decision recorded once per product: a conversion column of your own, applied deliberately. Ten minutes per supplier, and it removes an error class that otherwise appears only in a stock count, where it is indistinguishable from loss.
Packs, cases and multipliers inside descriptions
Many suppliers put the pack size in the product description rather than in a field: Widget 6x500ml. It is readable by a person and it is prose, not data, which means anything automatic reading it is interpreting rather than extracting.
The description comes through whole, so the information is not lost. What is deliberately avoided is parsing that text into a multiplier automatically, because the notations are not consistent — 6x500ml, 500ml x6, CS/6 and 6pk all appear, and so does 2x4 meaning something else entirely.
The practical approach is the same as for units: derive the multiplier once per product code, keep it in your own lookup, and apply it. Since descriptions repeat almost exactly across invoices from the same supplier, that work compounds rather than recurring.
Discounts, surcharges and delivery lines
A discount stated on a row is extracted as its own value rather than being netted into the unit price. It matters because the two questions behind those numbers are different: what does this supplier list at, and what do we actually pay. Netting them merges the answers and loses the negotiation history.
Delivery, handling and fuel surcharges come through as their own lines, in the position the invoice puts them. That is what allows a consistent treatment across suppliers who present carriage completely differently — one inside the unit price, one on a separate row, one on a separate document a week later.
The reason to keep these visible is not tidiness. Freight applied inconsistently makes product cost incomparable between suppliers, which undermines exactly the comparison a buyer most wants to make.
The line-sum check
One check is worth more than an accuracy percentage, because it applies to the document in front of you rather than to a population: the sum of the extracted lines, plus the stated charges and tax, should equal the invoice total.
When it agrees, the rows are almost certainly complete and correctly read — a misread line would have to be offset by another error of exactly the opposite size to survive. When it disagrees, one of two things is true: a line was read wrong, or the invoice contains something the lines do not explain, such as a settlement discount or a rounding adjustment. Both are worth seeing.
This is the same principle as the balance check on a bank statement, and it is the reason both are trustworthy: the document is asked to confirm itself, using arithmetic its own author put there.
Awkward layouts that break naive extraction
Real supplier invoices are messier than the examples in software demos, and a few patterns account for most extraction failures elsewhere.
Tables spanning pages. A header repeated at the top of page two is read as data by anything that treats each page separately, adding a row that looks like a product called «Description».
Multi-line descriptions. A product name that wraps onto a second line splits the row, so a quantity ends up attached to half a description.
Sub-totals inside the table. A category sub-total sitting among the rows gets counted as a line, which is the fastest way to double an invoice.
Two columns of prices. List price and net price side by side, where reading the wrong one is undetectable without the sum check.
| Layout problem | What naive extraction does | Symptom in the data |
|---|---|---|
| Table spans two pages | Reads the repeated header as data | A product called “Description” |
| Description wraps to a second line | Splits the row | Quantity attached to half a name |
| Sub-total inside the table | Counts it as a line | Invoice value roughly doubles |
| List and net price columns | Picks one at random | Undetectable without the sum check |
| Rotated or skewed scan | Misaligns columns | Prices in the quantity column |
Each of these is handled structurally rather than by pattern-matching a particular supplier, which is why the same handling survives a layout change. The line item extraction page goes further into the table logic.
Scans, photographs and paper that has been folded
A large share of supplier invoices in stock-heavy businesses never exist digitally. They arrive with the delivery, get signed, get folded into a pocket, and reach the office as a photograph. OCR handles the first step; the structuring and the checks are then identical to a digital PDF.
What changes is the confidence profile. On a clean PDF, everything reads with high certainty and review is a formality. On a creased photograph taken in a badly lit warehouse, a handful of fields will be uncertain — and those are flagged, so the review is a short list rather than a full re-read of two hundred rows.
Scan quality repays effort more than anything else here. A flat page at 300 DPI reads almost perfectly; a skewed photo does not. A minute spent rescanning is consistently cheaper than the corrections that follow a bad capture, though it never feels that way at the time.
Product codes beat descriptions
Where an invoice carries a product code or SKU, it is extracted alongside the description — and it is the field to match on wherever it exists. Descriptions drift: the same physical item is «Widget blue 500ml» on one invoice and «WIDGET BLU 500» on the next, and matching on text produces two products where there is one.
Codes are stable within a supplier and meaningless across them, which is the shape of the mapping problem: one lookup per supplier, from their code to your SKU, built once and extended when new products appear. It is unglamorous and it is what makes year-on-year cost comparison possible at all.
Where no code exists, the description plus supplier is usually enough to group reliably, because the same supplier tends to describe the same item the same way. It is the cross-supplier case that needs your own mapping — and no extraction can supply it, because the connection exists only in your business.
Review before it becomes data
Extraction does not mean trusting blindly. Before export, the rows are shown in an editable preview with uncertain fields and any sum mismatch already highlighted. Correcting a smudged digit takes seconds while it is on screen and considerably longer once it has become a stock valuation.
The reason to keep a human step here is specific to stock. A wrong bank transaction is wrong once. A wrong unit price becomes the cost of every unit of that product until it is corrected, and it propagates into margin, into pricing decisions, and into the closing valuation.
Only what you confirm reaches the file. The editable preview page covers how the review works in practice.
A month of invoices in one pass
One invoice at a time is useful for a spot check and useless as a process. Batch processing takes up to 100 files into a single export, with every row recording the document and page it came from — so a month of purchases from thirty suppliers becomes one table.
That is the shape the analysis needs. Filter by product to see every purchase of it across suppliers and dates. Filter by supplier to check what a price list actually cost you. Pivot by month to see when things moved. None of those questions can be answered one document at a time, which is why per-invoice review alone never produces the insight people expect from it.
It also makes the exceptions manageable: rather than reviewing thirty documents, you review the handful of rows that were flagged, wherever they happen to sit.
Export and mapping into your system
Excel and CSV, both carrying the same fields. Choose .xlsx when a person opens the file — the data types travel inside it, so a decimal comma cannot be reinterpreted by someone else's regional setting. Choose CSV when a system imports.
Most inventory and accounting systems accept a purchase import with a defined column set, and the export is arranged to map cleanly onto it. Where your system expects its own SKU rather than the supplier's code, the lookup sits between the two — built once, reused every month, and worth keeping in the same file so it does not get lost.
Keep the source-file column through the import if the system allows a reference field. It is the thing that lets someone six months from now walk a cost back to the document it came from, and it costs nothing to carry.
Through the API
For a business receiving invoices continuously, the useful version of this is not a person uploading files. The API returns the same line-level structure as JSON, so documents arriving by email or landing in a watched folder can be extracted and pushed onward automatically.
Automate the mechanical half first — extraction, the sum check, filing by supplier. Leave the judgement calls manual for longer than feels necessary: unit conversions, product mapping for new items, and anything where a wrong answer would be applied silently to every future purchase of that product.
One design note worth stating: have a failed sum check stop the pipeline rather than warn it. In an automated run nobody is watching, and an invoice whose lines do not add up should never flow onward into a valuation on the assumption that someone will notice later.
What it will not guess
It will not convert units for you. It will not decide that «6x500ml» means six units rather than one. It will not map a supplier's code to your SKU. Every one of those is a decision where a wrong answer is applied consistently and silently, which makes it exactly the kind of thing that should be recorded by a person once rather than inferred every time.
It also does not value stock or decide accounting policy. FIFO, weighted average and the treatment of landed cost are yours; this produces the inputs they operate on.
And nothing is kept: the original file is deleted immediately after extraction, processing runs on EU-hosted infrastructure over TLS, and documents are never used to train AI models — the security page has the detail.
See the lines from your own supplier
Extract one real invoice free — no registration — and check the quantities and unit prices against the paper.
