FlowParse
Feature August 2026 14 min read

Line-Item Level Invoice JSON

A header field and a total are easy. Rebuilding a multi-page line-item table correctly — quantities, unit prices, tax rates, every row — is the part that actually determines whether an AP platform's PO matching works. This is the feature that returns it as clean, typed JSON.

FlowParse
flowparse.io

The total is easy. The table is the hard part.

Almost any OCR service can find a total on an invoice — it's usually the largest number near a word like "Total" or "Amount Due," and pattern matching gets you most of the way there. Rebuilding the line-item table underneath that total correctly — every quantity, every unit price, every tax rate, in the right order, without merging or splitting rows — is a fundamentally harder problem, and it's the one that actually matters for an AP platform.

This page describes that specific capability: reading a full line-item table, however many rows and however many pages it spans, and returning it as a clean array your matching logic can use directly.

FlowParse
flowparse.io

Why line-item accuracy determines whether PO matching works

Three-way PO matching — comparing what was ordered, what was received and what was billed — depends entirely on the invoice's quantities and unit prices being correct, line by line. A total that happens to match the PO total tells you nothing about whether the individual quantities are right; two compensating errors on two different lines can produce a correct-looking total while the underlying match is genuinely wrong.

An AP platform whose extraction only reliably captures header fields and a total is, in practice, still asking a human to open every invoice and re-key the line items before real matching can happen — which defeats much of the point of automating AP in the first place. Line-item accuracy is where extraction quality is actually tested.

This matters even more once straight-through processing enters the picture. A platform that wants to post a high-confidence invoice directly, with no human touching it at all, needs to trust every individual quantity and unit price on that invoice, not just its total — a single wrong quantity on one of forty lines is exactly the kind of error a header-only or total-only check will never catch, since the total can still come out correct by coincidence.

What this doesn't decide

Doesn't perform the PO match itself

It returns clean, typed line-item data. Comparing it against your platform's own purchase order records is your matching logic.

Doesn't decide what counts as a matching tolerance

A small quantity or price variance between the invoice and the PO is a judgment call your product makes — extraction just gives you accurate numbers to compare.

Doesn't categorize line items into a chart of accounts

It returns the description as printed on the invoice. Mapping that description to a GL code is typically your platform's own categorization logic, informed by your customers' chart of accounts.

Each of these three boundaries follows the same principle: extraction stops at the point where a decision requires context only your platform has — your own PO records, your own tolerance policy, your own customers' chart of accounts. Everything up to that point is reading the document accurately; everything past it is your product's logic.

The line-item JSON shape

line_items array, from POST /extract
{
  "line_items": [
    {
      "description": "Widget, 10mm, zinc-plated",
      "quantity": 40,
      "unit_price": 46.00,
      "tax_rate": 8,
      "amount": 1840.00,
      "confidence": 0.99
    },
    {
      "description": "Freight surcharge",
      "quantity": 1,
      "unit_price": 65.00,
      "tax_rate": 8,
      "amount": 65.00,
      "confidence": 0.94
    }
  ]
}

Every line carries the same five fields plus its own confidence score, whether it's a normal product row or a miscellaneous charge like freight or a discount line — nothing about the shape changes based on what kind of line it is.

Keeping the shape uniform across every kind of line matters for your own downstream code — a matching function that has to branch on whether a row is a "normal" item or a "special" charge is more code to write and more code to get wrong. A consistent shape means one code path handles every row in the array, regardless of what it represents on the printed invoice.

What gets read per line

FieldType
descriptionString, full text including wrapped lines
quantityDecimal number
unit_priceDecimal number
tax_rateDecimal number (percentage)
amountDecimal number, the line total

Numbers come back as actual JSON numbers, not localized strings like "1.840,00" — your platform's matching and calculation logic can use them directly, regardless of which country or number format the original invoice used.

Multi-page tables, specifically

A line-item table that continues onto a second or third page is one of the most common places a hand-built extraction pipeline breaks — the header row doesn't repeat, the page break falls mid-row, or the parser treats each page as a separate table and returns two disconnected arrays instead of one continuous one.

Extraction here treats the full document as one logical table regardless of page breaks — a row that's visually split across a page boundary is still read and returned as a single line item, and the resulting array preserves the original row order across the whole document.

A repeating header row on pages two and three is recognized as a header, not miscounted as an additional line item — a mistake that would otherwise inflate the line count and throw off any downstream check that compares the number of rows against a purchase order's expected line count.

FlowParse
flowparse.io

How to actually benchmark this before you commit

An overall accuracy percentage on a vendor's marketing page rarely tells you what you need to know. The number worth asking for — and the number worth testing yourself before committing to an integration — is line-item accuracy specifically, measured against a real sample of your own suppliers' invoices, not a curated demo set chosen to look good.

A practical benchmark takes twenty to thirty representative invoices from your actual supplier mix, including a few multi-page ones and a few scanned or lower-quality ones, and checks two things: whether the line count matches the invoice exactly, and whether the sum of the returned line amounts reconciles to the printed subtotal. Both checks are mechanical enough to script, and together they catch the two failure modes — dropped or duplicated rows, and misread individual amounts — that matter most for downstream matching.

Because /validate is free and a trial plan lets real invoices run through /extract, this benchmark can be run before any commercial commitment — a concrete answer on your own documents, rather than a general accuracy claim taken on faith.

How it works

1

Send the invoice to /extract

One call, the full document, any number of pages.

2

The table is located and reconstructed

Column boundaries and row breaks identified from the document's own layout, not a fixed template.

3

Each row is typed and cross-checked

Quantity × unit price compared against the line amount; the sum of lines compared against the subtotal.

4

The array comes back with the rest of the invoice

line_items sits alongside the header fields and totals in the same response.

A forty-line invoice, extracted

A distributor's invoice with 43 line items spans three pages, with the table header repeating on pages two and three and one line item split visually across the page-one/page-two boundary.

CheckResult
Line items returned43 of 43, in original order
Page-boundary rowRead as a single row, not split into two
Sum of line amounts vs. subtotalMatched, confirming no line was dropped or duplicated
Lines flagged for review1, a smudged unit price on line 29

The one flagged line didn't require reviewing the other 42 — the platform's review queue surfaced only that specific row, with its low-confidence field highlighted, while the remaining 42 lines flowed straight into the PO match.

For comparison, the same invoice run through a header-only extraction approach would have returned a single total and left all 43 lines to be re-keyed by hand before any real matching could happen — the difference between a two-minute review and an hour of manual data entry, on one invoice alone.

Table layouts this is built to handle

A supplier that omits the tax-rate column

Returns the columns actually present; tax_rate is omitted or null rather than the whole extraction failing.

Nested sub-totals within the table

A category sub-total row within the line-item table is recognized as a sub-total, not miscounted as an additional line item.

Discount or credit lines with negative amounts

Read with their negative sign preserved, so the line-item sum still reconciles correctly against the subtotal.

A table with merged description-and-SKU columns

The combined text is returned in description; splitting a SKU code out of it, if needed, is a parsing step your platform can apply on the returned string.

Header-only extraction vs. line-item extraction

Header-onlyWith line items
Confirms an invoice exists and its totalConfirms exactly what was billed, quantity and price per item
Two-way match against a PO total onlyGenuine three-way match: ordered vs. received vs. billed, line by line
A human re-keys every line for GL codingGL coding logic runs directly against structured line data
A compensating error on two lines goes unnoticedIndividual line variances are visible, not hidden inside a matching total

The gap between the two columns widens with invoice complexity, not narrows — a simple one-line invoice is nearly as easy to match on a total alone as on its full line-item detail. A forty-line invoice with mixed quantities and tax rates is exactly where header-only matching quietly loses its reliability, which is also exactly the kind of invoice a growing AP platform sees more of as its customer base matures.

Who uses this

AP2P platform engineering teams

Line-item data structured well enough to drive real three-way matching, not just header-level checks.

Procurement software vendors

Ordered-vs-billed quantity comparisons built on typed, reliable invoice line data.

Spend-management platforms

Line-level categorization and budget tracking fed directly from extracted invoice data.

ERP integration teams

A consistent line-item schema to map into a GL, regardless of which supplier or invoice layout produced it.

Each of these roles ultimately depends on the same underlying capability, just applied to a different downstream decision — a procurement platform comparing ordered versus billed quantities and a spend-management tool categorizing budget line by line are both, at their core, consuming the same typed line_items array, just for different purposes.

Why line items are where extraction quality actually gets tested

Any extraction tool can be made to look accurate on a header field — there are only a handful of candidate values on the page, and pattern matching against labels like "Invoice #" gets you most of the way. A line-item table has no such shortcut: forty rows means forty independent opportunities to merge two rows, drop one, or misalign a column, and a table spanning multiple pages multiplies that risk further.

This is why line-item accuracy, more than header accuracy, is the number worth asking about when evaluating an invoice extraction API for an AP platform — a vendor quoting overall field accuracy without breaking out line-item performance specifically is quoting the easier half of the problem.

A useful gut check when comparing vendors: ask specifically what happens to a multi-page invoice with a repeating table header, and whether the answer is confident and specific or vague and general. A vendor that has genuinely solved multi-page line-item reconstruction can describe exactly how it handles the case; one that hasn't tends to answer in generalities about "advanced OCR" without addressing the specific failure mode being asked about.

FlowParse
flowparse.io

Get your API key

Run a real multi-page invoice through /extract and see the line_items array yourself. See the full invoice OCR API overview for how this fits into the rest of the extraction workflow, or the build vs. buy frameworkif you're still deciding whether to integrate at all.

A single test call is usually enough to answer the specific question this page is about — send one of your own real multi-line invoices and check whether the returned array matches every row, in order, with the right quantities and prices.

Security and privacy

Uploads are encrypted with TLS from end to end.

Processing runs on infrastructure with SOC 2-aligned controls.

Original documents are deleted shortly after processing.

Nothing you upload is ever used to train AI models.

Full details are on the security page. The same controls apply regardless of how many lines a given invoice carries.

Frequently asked questions

See your own line items extracted

Get a free API key and run a real multi-line invoice through the API.

Keep reading