Turn the AP inbox into a ledger you can reconcile
Vendor invoices, statements and credit notes become rows: vendor, invoice number, PO, due date, total. Query for the exceptions, check them against the document, hand the clean file to whatever pays them.
Northwind Supply Co.
Acme Logistics LLC
Meridian Print
SELECT vendor_name, count(*) AS invoices, sum(total) AS due
FROM "invoice_line_item"
WHERE purchase_order IS NULL
GROUP BY 1;| # | vendor_name | invoice_number | purchase_order | total | status |
|---|---|---|---|---|---|
| 1 | Northwind Supply Co. | INV-2041 | PO-88214 | 1240.00 | ok |
| 2 | Acme Logistics LLC | INV-2042 | — | 3980.50 | no PO |
| 3 | Meridian Print | INV-2044 | PO-88231 | 1015.00 | duplicate |
| 4 | Cascade Facilities | INV-7781 | PO-88190 | 402.75 | ok |
Whatever the vendor sent, one ledger
Invoices, month-end statements and credit notes are three different documents describing the same thing you owe. They land in the same table.
Acme Logistics LLC
| vendor_name | invoice_number | purchase_order | total | due_date |
|---|---|---|---|---|
| Acme Logistics LLC | INV-2042 | — | 3980.50 | 2026-07-08 |
Invoices, statements, credit notes. One ledger.
A vendor invoice
A month-end statement
A credit note
A payables month, in three jobs
Clear the month’s invoices
One dataset for everything that arrived, so approving a batch is reading a table rather than opening forty PDFs.
Find what needs chasing
Invoices with no PO, the same invoice number twice, a vendor you have never paid before. All of it one WHERE clause away.
Prepare the file your ERP imports
Export exactly the columns the import template wants, named the way it wants them.
The starter schema, plus what payables adds
The first group is the app’s invoice schema, verbatim. The second is what payables teams define on top, 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
fields AP teams usually add
- purchase_order string
- due_date string
- payment_terms string
- remit_to string
the same rows, asked a different question
Once the ledger is a table, the exception list is a WHERE clause — and it runs over the whole folder rather than the batch that arrived this morning.
| vendor_name | invoice_number | purchase_order | total | reason |
|---|---|---|---|---|
| Harbor Freight Co. | INV-6620 | — | 2210.00 | no PO on the invoice |
| Tellus Cleaning | INV-4417 | PO-87740 | 860.00 | invoice number seen twice |
| Ridgeline Paper | INV-9903 | PO-88015 | 1174.25 | due in 4 days |
The rows a person still has to see
Extraction is not approval. What it changes is that review means reading a row next to its document, instead of typing the document into a spreadsheet first.
| document | review |
|---|---|
| northwind-2041.pdf Northwind Supply Co. | checked |
| acme-logistics-jul.pdf Acme Logistics LLC | needs a look |
| meridian-print.png Meridian Print | on hold |
| cascade-7781.pdf Cascade Facilities | checked |
the row, beside the page
Every value points back to the page it was read from, so a check is reading a row beside a document rather than re-keying it.
↓ export CSV → your ERP
What AP teams ask us
Starting with what this doesn’t do.
- Does this pay the invoices?
- No. sheetscope stops at clean, checked data. It never touches your bank, your ledger or your approval chain. It removes the keying, not the control.
- How do I catch what it got wrong?
- Every row is traceable to its document, and extraction is per field, so review means reading a row beside a page rather than re-keying it.
- Half our invoices arrive with no PO.
WHERE purchase_order IS NULLis the exception queue: a query you edit, not a workflow rule somebody configures for you.- Vendors send the same invoice twice.
GROUP BY vendor_name, invoice_number HAVING count(*) > 1, across every document you have ever uploaded rather than just this batch.- It has to land in NetSuite, Xero or Sage.
- CSV and Excel out, with the columns you defined. The import template becomes a
SELECTlist rather than a mapping screen.