Adonis Consulting logoADONISCONSULTING

By Bradley Roth, Adonis Consulting ·

PDF Invoices to Raw Data: What It Actually Takes (We Lost Money Learning This)

Four hundred hours of typing, every year

An HVAC company out of Kansas City. Busy shop, real fleet, and vendor invoices arriving constantly: some as email attachments, some as actual paper from suppliers who bill the way they’ve billed since the nineties. Every one of those invoices had to become clean rows in the accounting system. Who billed us, how much, for what, against which job, which lines.

An accounting person keyed them. By hand. Every one.

The work organized itself one of two ways depending on the week: two hours of keying every day, or let the stack build and burn a whole eight-hour day on it each week. Both versions, priced at $28 an hour (my assumption for a loaded bookkeeping wage; swap in your own number):

  • Daily: 2 hours × 260 workdays = 520 hours ≈ $14,560 a year
  • Weekly: 8 hours × 52 weeks = 416 hours ≈ $11,648 a year

Call it 400 to 500 hours a year of typing. The calculator has the daily version pre-filled if you want to run your own stack through it. And that’s wages only, before a single mistyped invoice does what mistyped invoices do; I priced that part separately.

They wanted it automated. I took the job. Here’s the honest version of what happened, including the part where I lost money on it.

Version one: OCR and a parsing script

We started where a sensible person starts: off-the-shelf OCR, plus a Python script that parsed the recovered text into fields and staged it for the accounting system. The first demos looked nearly done. That feeling lasted about two weeks.

Then the client’s team started finding garbage in real fields. OCR doesn’t read an invoice; it reads a page. It pulled the phone number out of the vendor’s logo. It found the tiny side-notes next to the totals, the “questions about this order? call your rep” text, and crammed those words into whichever field sat nearest. A quantity field holding “THANK YOU FOR YOUR BUSINESS” is not a data problem you patch with find-and-replace rules; it’s a sign the approach itself is wrong. Cleaning up after OCR by hand was slower than keying the invoice the old way, which is the exact opposite of the assignment.

If someone tells you plain OCR solves PDF invoice entry, they’ve never watched it read a logo.

There’s a business lesson in here and it’s mine, not the client’s: I underquoted this project. Version one failed on my watch and it cost Adonis roughly triple the time I’d planned. We finished it anyway, at the quoted price, because a fixed quote is a promise about my risk, not the client’s. That one’s on me.

Version two: a model that reads documents

What actually worked was a document-extraction LLM. Think of it as next-generation OCR: instead of scraping characters off the page and guessing what they mean, it reads the whole document and returns structured fields, logo text and side-notes sorted away from the real data.

We self-host it on our own GPUs in our own data center. Vendor invoices never leave infrastructure we control. If your CFO has ever asked a vendor “where exactly does our data go,” you know why that sentence is in here.

The harness, and the hook that made it trustworthy

A model alone isn’t a system. Around it sits a lightweight custom harness, a stripped-down automation runner, that fires tool hooks at each step of the pipeline. The hook that matters most runs after parsing and before anything touches the accounting system: our own Python validation script, which confirms every required field. Client name. Address. Phone. Contact. The invoice lines. Quantities. Price. Total. All present, all plausible, the lines summing to the total.

If validation fails, the document goes to a human instead of the ledger. Nothing imports on a guess. Version one’s failure mode, invented data sitting in real fields, is structurally impossible now: the logo text never reaches a field, and the fields that do arrive have been checked against the document itself.

Trust, earned in batches

Nobody at that shop trusted version three on day one, and they shouldn’t have. Neither did I. So we ran it the slow way: the model parsed, the hook validated, and a human compared the result against what they would have keyed themselves. Thousands of documents went through that loop before the client let the pipeline import directly into their ERP with limited-to-no human oversight. Trust was earned one clean batch at a time. I don’t know a faster honest way to earn it.

What it looks like now, and what it saved

They use it day in, day out. Invoices arrive by email, get parsed, validated, and posted; the paper ones get scanned and take the same road. Nobody at that company has a two-hour daily keying block or an eight-hour Friday block anymore. That’s the wage bill, $11,648 to $14,560 a year, returned before you count the errors that stopped happening.

And it cost us money to build the first time. That’s the deal I’d make again: I’d rather lose money on version one and ship version three right than bill hours forever on version two.

Killing re-keying is one of the five things I automate most, and this build is the version where the source is paper and PDFs instead of another database. The ServiceTitan-to-QuickBooks version of the same argument, moving data between systems instead of retyping it, is here. If PDFs stack up in your office the way they stacked in theirs, email me the run: what arrives, from whom, and where it needs to land. A human (me) reads it and answers within the hour, usually minutes.

Reading is the easy part

If something in this article described your week, email me the process. A human (me) reads every one and answers within the hour, usually minutes.

Email me Call