§Use caseOne operator

Check the sum before you trust it

Any model can read a table off a PDF. The part that goes wrong is trusting the same model to add it up. Below is how I actually build this: the AI transcribes, a Code node does the arithmetic, and the two never get to disagree without somebody finding out.

The step that isn't a model call
The step that isn't a model call
The n8n canvas showing the Reconcile Totals code node and the IF that routes a report to Line Items or Needs Review.
All 15 nodes, and the setup written on the canvas beside them
All 15 nodes, and the setup written on the canvas beside them
The whole PDF report reconciliation workflow on the n8n canvas, fifteen nodes with the setup written on it as sticky notes.

The questionHow do I get a table out of a PDF report without trusting the AI's own maths?

How the working version is put together

  1. Watch one label, not the inbox

    A Gmail trigger watches a single label for report attachments, the same security boundary I use on every mailbox-triggered build. Only PDFs move past the filter; anything else in that label is ignored.

  2. Transcribe, don't calculate

    I tell the extraction prompt to copy the total exactly as printed on the document, not compute one. That instruction is the whole point of the build. If the model calculated its own total, the reconciliation step downstream would just be checking the model against itself.

  3. Add it up in code, not in the model

    I built a plain Code node that sums the line items in JavaScript and compares that sum to the stated total within a tolerance you set. Nothing here calls a model. A demo that reconciles five clean reports proves nothing; this is what survives a report where the model misread one row.

  4. Write only what checked out

    I split a reconciled report into one row per line item in your Line Items sheet. A mismatch never gets written there. It goes to a Needs Review tab with the delta shown, plus a Slack ping, so a person looks at it before it reaches your books.

The kit

Extract PDF report tables into Google Sheets and flag totals that don't reconcile

This one is built and gated, staging for Etsy now: 15 working nodes, the setup written on the canvas, and a setup guide for every node. If you want it sooner, or set up around your own reports, start a brief instead.

Why the model shouldn't grade its own homework

I have watched an extractor misread one figure on an otherwise clean table and hand back a total that looked entirely plausible. Nothing about that error is visible from the output alone, because a wrong number reads exactly like a right one until somebody checks it against the page.

So I put the check outside the model. A Code node reads the same rows and adds them up itself, in ordinary arithmetic nobody has to trust. If that sum doesn't match what's printed on the document, the report is flagged rather than booked.

What actually breaks

I've found some report types never carry a printed total at all, certain inventory sheets among them. Left as-is, those get flagged as a mismatch every time, which is the honest outcome: there's nothing to check the sum against, so it should not be booked unread.

I fill in a row missing its own line total from quantity times unit price for that row alone; the document's stated total is never touched by that shortcut, because the whole design rests on that number staying untouched by anything but the page itself.

Why take this from me

I built this after re-keying one too many expense reports by hand because I didn't trust the AI to add them up right. The proof below is what's actually running, not a description of it.

Read this before you spend anything

Who should not buy this

If your reports already arrive as CSV or a spreadsheet, there is no PDF for me to read and this buys you nothing. And if you're genuinely fine trusting a model's own arithmetic on financial totals, the reconciliation step is overhead you don't want.

If every report you receive looks nothing like the last one, in a way where even the columns change shape, I need to tailor the extraction prompt to your own report family before this is worth running unattended.

What lands on your desk

  • I set it up inside your own n8n, reading your own report mailbox, under your own credentials
  • Your tolerance and sheet tabs written into the settings with you
  • The Needs Review path wired in, so a mismatch costs you a flag and never a silent wrong number in your books
  • A Google Sheets log of every line item on a match, and every mismatch with its delta
  • A walkthrough I write down, so the next person to touch this is not dependent on me

Questions this page answers

Does the AI decide whether the report is correct?
No, the AI only transcribes what's printed on the page. A plain Code node does the arithmetic and the comparison, and that step never calls a model.
What happens when the sums don't match?
Nothing gets written to your Line Items sheet. It goes to a Needs Review tab with the computed total, the stated total and the difference, plus a Slack alert.
What if a report has no printed total at all?
It's flagged as a mismatch by design, since there's nothing to check the extracted sum against. You read it before it reaches your books, same as any other flagged report.

Want this built and handed over working?

One line is enough to start. You get an honest answer on fit, and a number rather than a discovery call.

Start a brief