Logo
Apdf tutorials October 2026 3 min read

How to Turn Scanned Invoices into Structured Data with an Agent

Everyone who's tried to automate invoice intake knows the wall: OCR reads the scan fine, but tabular layouts come back scrambled — descriptions divorced from their amounts, dates split across lines. The regex parser that worked on Monday's invoice breaks on Tuesday's.

That wall is exactly where a language model shines. With Apdf connected over MCP, the OCR tools deliver the characters and the agent does what regexes can't: reassemble meaning from messy text, then hand you clean JSON.

What you'll build
Two scanned supplier invoices → verified, structured records — this conversation, working end to end: “Extract July's invoices” → vendors, numbers, line items, totals — sums cross-checked
MCP access needs Pro (14-day trial, no card)
1

Connect the agent to Apdf

claude mcp add --transport http apdf https://apdf.io/mcp/main
2

Ask for records, not text

You
These are July's scanned supplier invoices — extract vendor, invoice number, date, line items and totals as JSON:
https://files.northlight.example/inbox/invoice-scan-1.pdf
https://files.northlight.example/inbox/invoice-scan-2.pdf
Claude
apdf · read-pdf-content-with-ocr ×2
Both OCR'd — the scans read in column-scrambled order, which is normal for tabular layouts, but every field is present. Structured records below, with the line items summed against each stated total.

Look at what the agent actually had to work with — the raw OCR return for the first invoice:

{
    "pages_total": 1,
    "characters_total": 215,
    "pages": [
        {
            "page": 1,
            "characters": 215,
            "content": "Brenner\nINVOICE\n\nBuerotechnik\n\n2026-0714\n\n—\n\nissued\n\nJuly\n\nDescription\nToner\n\ncartridges\n\nPrinter\n\nTOTAL\n\nPayment\n\n2026\n\nAmount\nHP\n\n207X\n\nmaintenance\n\nJuly\n\nDUE\n\n2,\n\nGmbH\n\n(4x)\n\n312.00\n\nEUR\n\n145.00\n\nEUR\n\n457.00\n\nEUR"
        }
    ]
}

A regex parser dies here. The agent reassembles it:

[
    {
        "vendor": "Brenner Buerotechnik GmbH",
        "invoice_no": "2026-0714",
        "date": "2026-07-02",
        "lines": [
            { "description": "Toner cartridges HP 207X (4x)", "amount": 312.00 },
            { "description": "Printer maintenance July", "amount": 145.00 }
        ],
        "total": 457.00,
        "currency": "EUR",
        "sum_check": "312.00 + 145.00 = 457.00 ✓"
    },
    {
        "vendor": "Skyline Catering UG",
        "invoice_no": "R-88231",
        "date": "2026-07-09",
        "lines": [
            { "description": "Team lunch July 8 (14 pax)", "amount": 406.00 },
            { "description": "Delivery fee", "amount": 18.50 }
        ],
        "total": 424.50,
        "currency": "EUR",
        "sum_check": "406.00 + 18.50 = 424.50 ✓"
    }
]
3

Make the sum check non-negotiable

The sum_check field isn't decoration — it's the guard that makes agentic extraction accountable. OCR's classic failure mode is a mangled digit, and a line-items-versus-total cross-check catches it cold: if the sum doesn't match the stated total, the agent flags the invoice for human eyes instead of feeding a wrong number into your books.

Heads up: Extraction feeds accounting — keep a review step for flagged invoices and spot-check a sample of clean ones. The agent turns hours of typing into minutes of checking; it shouldn't turn into zero checking.

From here, scale is a sentence — “do the same for everything in the inbox folder and give me a CSV” — and the agent loops the same two tools over the batch.

Where to go from here

The same connection carries every PDF operation — and the engagement layer behind them.

After the API call

Your code made the PDF.
Then it went dark.

Opened, read, re-read, dropped on page 4 — you never see any of it. Share the PDFs you generate through Apdf recipient links, and every signal becomes something you can act on: ping Slack, update the CRM, let an agent follow up. Same account, same API token, one more call.

Your PDF, after sending Live
document:loaded CFO
page:read p4 · 38s
link:clicked pricing

API · Webhook · MCP