Process automation
Invoice-chase agents: the AR audit we run before quoting
An operations lead sends a 412-row chase spreadsheet and asks for an agent. We say yes, but not yet. First we audit the AR data underneath.

An operations lead at a Rotterdam logistics broker sends us a Google Sheet. 412 rows. Column F says "Days late". Column G says "Last reminder". The note in the email body reads: "Can you build an agent that handles this, so my team stops spending Thursdays on it?"
Our answer is always yes. But never yet.
Before we quote a single euro, we audit the data underneath the spreadsheet. Not because we do not trust the operations lead. Because an invoice-chase agent wired to AR data that lies will do damage faster than a tired human ever could. The checklist below is the one we work through before we put a number on the proposal.
Why the audit comes before the quote
A chase agent is a confidence amplifier. It sends polite, well-timed, accurately written messages to your customers, using whatever inputs you give it. If the data says a customer is 47 days late, the agent writes as if the customer is 47 days late. If the customer actually paid two weeks ago through a bank account that nobody reconciled, you have an angry customer and an awkward call with your CFO.
The agent itself is the simple part. We have fourteen running in production at the time of writing. The work that earns the fee happens before the agent exists, in three places where the data quietly disagrees with itself.
Aging buckets that lie
Every accounting package emits aging buckets. Zero to 30 days, 31 to 60, 61 to 90, 90 plus. They look like ground truth. They are not.
The first question we ask: aged from what date? You get a different bucket depending on whether the report anchors to the invoice issue date, the due date, the delivery date, or the date the invoice was opened in the customer's AP portal. We have seen Exact Online accounts where two thirds of the "60+ days" bucket were invoices the customer received nine days ago, because the ERP defaulted to issue-date aging but the agreed terms were net-90. An agent chasing on that data would be wrong on every line.
The second question: is anything in the bucket already paid? Partial payments produce ghost invoices in three ways. A €1,800 invoice with a €1,200 partial payment can still show as €1,800 outstanding if the payment was matched to a credit note instead of the invoice. Bulk settlements that cover ten invoices but land as one bank line leave nine of them open until somebody manually splits them. Credit notes issued against the wrong invoice number sit in the bucket forever.
The third question: who decides when an invoice gets cancelled? In one Belgian client's Magento-plus-Twinfield setup, sales reps could mark an invoice "void" in the CRM, but the void never synced to Twinfield. The aging report kept chasing voided invoices for nine months. Customers got annoyed. Nobody noticed until we ran the audit.
Dispute reasons that never made it into the system
Open any AR system and look at the dispute field. It is almost always either empty or set to a value like "general dispute". Now open the customer service inbox and search for the phrase "we are not paying this". You will find dozens of disputes that never made it into the system of record.
This is the second place a chase agent breaks things. Disputes live in five places we routinely check:
- The accounting package's dispute or hold field, which is usually empty.
- The customer service inbox (Front, Help Scout, Zendesk, or a shared Gmail label).
- Sales rep notes in the CRM, often a free-text "Last contact" field.
- The customer's own AP portal, where they sometimes flag invoices as "in review".
- Slack or Teams DMs between the customer and their account manager.
The first four we can reach with an integration. The fifth we cannot, but we always ask. If account managers handle disputes in DMs and never write them down, no agent will catch them, and you need a process fix before automation, not after.
What we do with the audit output: every invoice in the chase queue gets a dispute-risk flag. The agent never sends a firm reminder to a customer who has an open thread with support or a "do not chase" note from sales. If the flag is set, the invoice routes to a human review queue instead. This single rule has saved more relationships than any clever copy we have ever written.
The bank-feed gap nobody documents
This is the one nobody talks about, and it is where most chase pilots quietly fail in production. The question is simple: how does your accounting system know an invoice has been paid?
For most of our clients the answer is a bank feed. The bank sends a statement file (usually CAMT.053 over ISO 20022 in the EU) which lands in the accounting package overnight or on a schedule. The package tries to auto-match each line to an open invoice. What does not match falls into a suspense account, where a human eventually reconciles it.
The gap is the window between "money arrived" and "invoice marked paid". For some clients that window is twelve hours. For others it is nine days. We measure it before we quote, because the agent's chase schedule has to respect it.
The bank-feed gap has four common failure modes. First, partial payments: the customer paid €4,200 to clear three invoices of €1,400 each, but the bank line shows one €4,200 settlement that the auto-matcher cannot split. Second, payment-processor netting: Stripe payouts, Mollie, and Adyen all settle net of fees and refunds, so a €1,000 invoice produces a €972.40 deposit that the matcher misses. Third, FX conversion: a USD invoice paid in EUR lands at a converted amount that differs from the booked total by the day's spread. Fourth, weekend and holiday batching: a Friday payment may not appear on the feed until Tuesday.
Each of these creates the same risk. The agent chases a customer who has already paid. There is no recovery from this. The customer will not forget. So we always ask for two numbers before we quote: the median bank-feed gap and the 95th percentile. The chase schedule starts after the 95th percentile, not the median.
If your finance team cannot tell you, within five minutes, how long it takes from "money in bank" to "invoice closed in the ledger", you are not yet ready for a chase agent. Fix the gap first. The agent will pay for itself fast once the inputs are clean.
What we send back before we quote
The audit takes us about three working days. The deliverable is a one-page report with three numbers: how many invoices in the current open AR are mislabelled by the aging bucket, how many have a hidden dispute the system of record does not know about, and what the 95th-percentile bank-feed gap looks like. We follow the numbers with the three or four process fixes the client needs to apply before the agent is worth building.
About a quarter of the time, we recommend the client does not build the agent yet. The chase work, in those cases, is hiding a more expensive problem upstream. A spreadsheet of 412 chase lines is not a chase problem, it is a billing-data problem with a chase symptom. Fixing the billing data is the higher-leverage move, and we say so.
The other three quarters, the audit gives us a clean enough picture to quote. When we built the chase agent for the Rotterdam broker we mentioned at the top, the thing that nearly killed the pilot was the bank-feed gap: their suspense account took eleven days to clear on average, and the chase template would have torched a dozen customer relationships in the first week. We ended up wiring the agent into the CAMT.053 file directly, so it saw cleared payments before the accounting package did. That kind of fix is normal in AI agent work, and it is why the audit comes first.
A five-minute version you can run today
Open your aging report and your customer service inbox in two windows. Pick ten invoices at random from the 60+ day bucket. For each one, answer three questions: what date is it aged from, is there a dispute thread in the support inbox, and has any payment been received against it in the last 30 days? If more than two of the ten are wrong on any of those three axes, your AR data is not ready for an agent. That gap is the work to do this quarter.
Key takeaway
A chase agent is a confidence amplifier: if the AR data underneath it is wrong, you scale the wrong messages fast, and customer relationships break in a week.
FAQ
How long does the AR audit take?
About three working days for a mid-sized ledger. We need read-only access to your accounting package and the last 90 days of bank statement files.
Do we need clean data before you start?
No. The point of the audit is to find what is not clean. We use the findings to scope the real work and to decide whether a chase agent is even the right next step.
Will a chase agent replace our finance team?
No. It handles routine first and second reminders on confirmed-clean invoices. Escalations, disputes, and judgement calls stay with people.
What if we do not use CAMT.053 bank statements?
Then we measure your existing feed format, whether MT940, OFX, or a CSV export. The bank-feed gap question and the 95th-percentile rule are the same.