Case study · TimbraBot

AI-assisted reconciliation, with the evidence in view.

TimbraBot matches an accounting firm's bank transactions to CFDIs, Mexico's electronic tax invoices. It applies well-supported matches and routes the rest to an accountant with the evidence ready to review.

Reply within one business day · No commitment

client companies managed by the firm
15
approved bank-to-invoice links
1,817
links entered by hand
0

Figures from the deployment at BW Asesores, an accounting firm in Mexico City. “0 entered by hand” means no link was typed from scratch; it does not mean zero review or zero errors.

The TimbraBot reconciliation inbox in 3D: a $184,500.00 deposit lifts out of the table, its two invoices of $120,300.00 and $64,200.00 add up to the bank amount with high confidence, and pending movements stay flagged for review.

How the work changes

Without a system, an experienced accountant reads every bank line and searches for the invoice it belongs to among thousands: partial payments, payroll paid in one batch, transfers between the client's own accounts. It is slow, it lands in the month-end window, and a wrong link ends up in a signed tax return.

  1. 1

    Reads the documents

    Extracts every movement from PDF bank statements, each bank with its own layout (10 institutions in this deployment), and checks that balances and movements add up to the cent. A statement that does not add up is flagged and kept out of the metrics.

  2. 2

    Proposes and applies matches

    Deterministic rules resolve most of the work and a model reasons only over what remains. A link is applied without review only with high confidence and hard evidence in the bank description: the counterparty's tax ID (RFC) or legal name.

  3. 3

    Reviews exceptions with evidence

    Everything else reaches the accountant as a proposal, with the movement, invoices, tax folios and amount breakdown. They approve, correct or reject, and each decision feeds the next run. Each expense invoice also gets a deductibility verdict with its reason.

Excerpt from a link's detail: a $184,500.00 SPEI deposit on March 18, with its reference and bank description.
Excerpt from the same detail: a payment-receipt match with high confidence and the engine's note splitting the amount into two invoices of $120,300.00 and $64,200.00, difference $0.00.

Product screenshot with illustrative data.

More product screenshots (6)
Reconciliation inbox: approved movements next to proposals waiting to be approved or rejected, with batch selection.
Product screenshot with illustrative data.
Rules editor: instructions written in plain Spanish, split between those compiled into automatic rules and those kept as context for the model.
Product screenshot with illustrative data.
Uploading a bank statement, with the selected file and its processing status.
Product screenshot with illustrative data.
Deductibility verdicts per invoice, with the reason expanded for an at-risk case.
Product screenshot with illustrative data.
Dashboard with the managed companies and their reconciliation progress.
Product screenshot with illustrative data.
Company indicators: processed movements, tax documents and approved links.
Product screenshot with illustrative data.

The architecture behind it

Almost everything is deterministic code, on purpose. In reconciliation, a model comes in at two points: to read documents with no standard format, and to reason over what the rules could not resolve; what it proposes is validated before it is stored. Separately, a small model compiles the rules the firm writes in plain Spanish into logic.

ORIGINBank statementTax recordOther sourceINGESTIONPrivate storageExtractionmodel read + arithmetic checkNormalized ledgermovements + CFDIENGINEClassificationMirror transfersPayment receiptsAggregate payrollIndividual payrollSingle-paymentCompiled rulesMemoryrule-based proposalsresidueReasoning layerVALIDATIONValidationidentity · directionamount · datecounterparty · no duplicatesvalidrejectedAuto-applyhigh confidence + hard evidenceyes · appliedno · to reviewAccountant's inboxLinkapproveapprove · correct · reject → memoryTAXDeductibility engineVerdictreason + input hash
ORIGININGESTIONENGINEVALIDATIONTAXBank statementTax recordOther sourcePrivate storageExtractionmodel read + arithmetic checkNormalized ledgermovements + CFDICompiled rulesMemoryClassificationMirror transfersPayment receiptsAggregate payrollIndividual payrollSingle-paymentrule-based proposalsresidueReasoning layerValidationidentity · directionamount · datecounterparty · no duplicatesvalidrejectedAuto-applyhigh confidence + hard evidenceyes · appliedno · to reviewLinkAccountant's inboxapproveDeductibility engineVerdictreason + input hashapprove · correct · reject → memory

Rules first

Six auditable, repeatable steps (classification, transfers between the client's own accounts, payment receipts, payroll and single-payment invoices) propose most links without going through a model.

Reasoning where it is needed

The reasoning layer only receives the residue, with the invoices still open, and declares its confidence.

Validation with veto

Server-side code checks every model proposal: invoice, direction, amount, date, counterparty, that an invoice is not assigned twice in the same run, and that each partial payment states its amount. Whatever fails goes back to the inbox.

The firm teaches the engine

Rules are written in plain Spanish and compiled into executable logic; approvals and rejections become memory for the next run.

Technical detail: models, stack, validation, evaluation and cost

Models

Document extraction runs on Claude Sonnet 5, with Claude Opus 5 as fallback on the retry path; the fallback result is adopted only if it is not worse than the primary read. Reconciliation reasoning uses Claude Sonnet 5 and the rules compiler runs on Claude Haiku 4.5.

Stack

Web app on managed hosting, Postgres with row-level security and invite-only access, private object storage for source documents, and a self-hosted orchestration layer running four pipelines. Webhooks authenticate with signed tokens and concurrency is enforced in the database.

Invocation and context

Direct calls to the Anthropic Messages API with no tool use: the contract is structured JSON. Extended thinking is enabled only on the retry path, where a failed arithmetic check gives the model a concrete target. Reasoning runs in chunks of forty movements; entities travel as short positional indices and database identifiers never enter the context. With candidates trimmed to six fields, input dropped 11.5% and output 60% on A/B runs.

Validation

No model output is written straight to the database. Every proposal is re-derived against the candidate set and rejected for an unknown identifier, wrong direction, amount outside tolerance, date out of range, missing applied amount on a partial payment, counterparty contradiction or an invoice already assigned in the same run (legitimate partial payments are recorded with their amount). Rejections are logged by reason and by run.

Evaluation and cost

Every call is logged with model, tokens, cache counters and stop reason, and costed per model. A model change goes through an offline A/B harness that replays real documents with a double baseline and a parity gate on the densest known case. Extraction is content-addressed: re-processing an unchanged document makes no calls.

Build

The app, pipelines, SQL migrations and tests were developed with Claude Code. Workflows and migrations deploy through MCP servers and are verified byte for byte against source.

What the results show

1,702

proposed by the deterministic engine

115

proposed by the reasoning layer

This is where the proposals behind the 1,817 approved links came from. It is not a split between automatic and human approval: it shows which part of the system found each match.

That is the engineering choice. Deterministic logic takes everything it can, because it is auditable, repeatable and cheap; the model is reserved for abbreviated counterparties, amounts that do not match to the cent, or payments split across several invoices, and its proposals also pass a validation step with veto power. On both paths, only high-confidence matches with hard evidence are applied without review.

The pattern of verified reading, rules first, bounded reasoning and validation with veto can be adapted to other document-heavy processes, such as supplier onboarding, invoice approval or case-file review.

Does your team still match documents by hand?

TimbraBot is a WASD Studio product. We design systems like it around each client's process: documents you do not control, rules that do not bend and little room for error.

Talk to us about your process

Tell us which process you want to fix.

Describe the process, the documents involved or the operational problem. We reply within one business day.

16+ Years50+ CompaniesUnity Award Winner

By submitting you accept our Privacy Policy.

Reply within one business day · No commitment

Prefer a direct conversation?

Message us on WhatsApp