Turn a stack of supplier invoices into one table you can query
Upload your invoice PDFs and scans, define the fields you need, and every vendor’s layout comes back as the same columns, ready to review, query, or hand to accounting.
Northwind Supply Co.
Acme Logistics LLC
Meridian Print
SELECT vendor_name, sum(line_total) AS spend
FROM "invoice_line_item"
GROUP BY 1 ORDER BY 2 DESC;| # | invoice_number | invoice_date | vendor_name | line_description | line_total |
|---|---|---|---|---|---|
| 1 | INV-2041 | 2026-06-03 | Northwind Supply Co. | Corrugated mailers, 12x9 | 640.00 |
| 2 | INV-2041 | 2026-06-03 | Northwind Supply Co. | Pallet freight | 600.00 |
| 3 | INV-2042 | 2026-06-08 | Acme Logistics LLC | LTL haul, Reno → Sparks | 3980.50 |
| 4 | INV-2044 | 2026-06-12 | Meridian Print | Trade show banners (4) | 1015.00 |
One invoice in, the columns you asked for out
Your vendors don’t agree on a layout. A ruled line grid, a paragraph and a phone photo all come back as the same fields, because the schema is yours rather than theirs.
Acme Supply
| invoice_number | vendor_name | invoice_date | purchase_order | total |
|---|---|---|---|---|
| INV-0342 | Acme Supply | 2026-08-04 | PO-9912 | 4182.17 |
Different layouts. Same schema.
One vendor
a ruled line grid
- Invoice #
- INV-0341
- Date
- 2026-06-03
- Total
- 1,240.00
Another vendor
prose, no table at all
Invoice INV-0342 was issued on 8 June 2026. The amount now due is $3,980.50, payable net 30.
A third vendor
a photo of a paper invoice
I N V O I C E
INV-0343
12/06/2026
TOTAL 1,015.00
Three things you stop doing by hand
Process vendor invoices
Turn everything that arrived this month into one consistent dataset, whatever shape it arrived in.
See what you spend, by vendor
Group by vendor, filter by date, sum the line totals. The question you could not ask when it was a folder of PDFs.
Hand a clean file to accounting
Export the columns you defined as CSV or Excel, with no re-keying between the invoice and the system that pays it.
You decide what a row is
The first group is the invoice schema the app starts you with, verbatim. The second is what this page’s examples add on top, and you define those yourself, in the same editor.
invoice_line_item: the starter schema in the app, verbatim
- invoice_number string
- invoice_date string
- vendor_name string
- line_description string
- quantity number
- unit_price number
- line_total number
- currency string
not in the schema: you define these yourself
- purchase_order string
- subtotal number
- tax number
- total number
the same invoices, one row each
The mock at the top of this page is one row per line. Drop the line fields from your schema and the same invoices come back as one row each: who billed you, when, against which PO. The field list is what decides.
| invoice_number | vendor_name | invoice_date | purchase_order |
|---|---|---|---|
| INV-2041 | Northwind Supply Co. | 2026-06-03 | PO-88214 |
| INV-2042 | Acme Logistics LLC | 2026-06-08 | — |
| INV-2044 | Meridian Print | 2026-06-12 | PO-88231 |
Scans, odd layouts, missing POs
The parts of invoice processing that are actually hard.
- My invoices are scans, not text PDFs.
- Scans and phone photos are read before extraction, so a photographed invoice lands in the same columns as a born-digital one.
- Every vendor’s invoice looks different.
- The schema is what you define, not what the vendor prints. A ruled line grid and a paragraph both come back as
invoice_number,vendor_name,line_total. - Invoices run to several pages.
- A document is extracted whole, not page by page. Lines continued on page three land as rows under the same
invoice_number. - Some invoices have no PO number.
- A missing field comes back empty rather than guessed. Leave it out of
required, andWHERE purchase_order IS NULLis your chase list. - Someone has to check these before we pay them.
- Every row is traceable to the document it came from, and the whole result exports to CSV or Excel.