Skip to content
Case dossier  /  Client win

Bank reconciliation that runs in the browser, uses no AI, and never guesses

The month-end match between the general ledger and the bank statement runs in a browser tab, auto-matching the clear cases and flagging the rest for review.

22transactions parsed

From a real statement, agreeing with the statement's own count of credits, checks, and debits.

13auto-matched

On the first real test, with zero wrong matches. Everything else went to review instead of a guess.

0uploads

Statements and ledgers are read inside the browser, so account numbers never cross the network.

0AI calls

Deterministic matching rules only, a hard requirement from day one.

01

The problem

Every month, the client's accounting team reconciles each bank account: the general ledger export from their accounting system on one side, the bank's statement PDF on the other. The work is tedious because the two sides rarely describe a payment the same way. The ledger writes a reference one way and the bank prints it another. One check that pays several invoices shows up as several ledger lines but a single cleared item on the statement. Items written last month clear this month.

The client set two rules before any code was written. First, no AI anywhere in the app: every match has to come from a rule a person can follow. Second, real account numbers must never leave the machine. That second rule also meant we could not simply be handed a real statement to build against.

02

What we built

Two tools.

The first is a sanitizer that runs on the client's own computer and turns a real statement and ledger into a safe sample. That let us build and tune the parser against the actual statement layout without ever seeing a real account number.

The second is the reconciliation app itself, a browser app with two tabs: one to make a safe sample, one to reconcile. You drop in the ledger CSV and the statement PDF, and it returns a matched report you can review, adjust, and export.

03

How it works

The sanitizer. Every run of three or more digits is replaced, and the replacement is keyed on the digits alone. The same real number becomes the same fake number whether it appears with a dollar sign, commas, or spaces, so check numbers, amounts, and dates still line up across both files and the sample stays useful for testing. Names found in the ledger columns are scrubbed everywhere, including free-text memos and the PDF. The real-to-fake key stays in a local file that is never shared, and a final pass rescans the output for any real value that slipped through.

Reading the statement. A dedicated parser handles the bank's business statement layout: a credits section, a checks-paid section printed three across, a debits section, and dates without years. It detects that layout on its own and falls back to a general parser for other formats. It also skips the extra report pages that arrive bundled in the same PDF.

Reading the ledger. The tool understands split debit and credit columns and normalizes references, so the ledger's version of a payment and the statement's version line up. Split checks are grouped: when a purely numeric reference appears on two or more ledger rows, those rows are summed and matched to the single cleared check. Journal entries and payment-processor IDs are kept separate so they never group by accident.

Matching. The matcher works in tiers. Exact reference and amount first. Then amount and date within a tolerance, but only when the match is unique. Everything else surfaces as a suggestion or an ambiguity for a person to decide. It never forces a guess. For the rest, a manual linking screen lets the reviewer tie several ledger lines to one bank transaction, with a live check that the ledger lines sum to the bank amount. A second release added a prior-month upload, so items outstanding last month match when they clear this month and are tagged as prior, plus a lean export of status, date, reference, payee, and amount.

Lockdown. The deployed app runs under a strict content security policy that blocks connections to any outside server, and its libraries are bundled in rather than loaded from a third party.

04

The result

On the client's real files, scrubbed, the tool parsed 22 bank transactions, matching the statement's own summary, and auto-matched 13 of them with zero errors. The items it left unmatched were exactly the ones a person should look at: split payments and one item older than the ledger export. We cross-checked the output against the accounting system's own reconciliation report, and the two agreed on what had cleared and what was outstanding.

Split-check matching was then proven on intact sums in a controlled test. The app is deployed, and its second release added prior-month matching and multi-line linking. Reconciliation now happens in a browser tab, on rules anyone on the team can read, with nothing uploaded anywhere.

Your turn

Same problem? Different industry?

We work with one client per vertical at a time. If your shape matches one of our dossiers, we’ll tell you straight.