The credit controller at a 35-person UK distributor showed us her process in March. £180,000 in invoices over 60 days. She wrote the first reminder from a mental template she had built over four years. The formal demand she always started fresh, worried she had missed something legally important. Three hours every week, the same five letter types — none saved in a consistent format. Two pre-legal notices had gone to the wrong contacts because a debtor company had changed their accounts payable contact and nobody had updated the record.
That's not a discipline problem — it's a process design problem. Here's what we built, what broke, and how the pipeline recovered 40% of that aged debt in 90 days.
What UK credit control actually involves: the five letter types, their legal weight, and the escalation timeline
UK credit control runs through five distinct letter types, each with a different tone and legal purpose:
- First reminder (7–14 days overdue): Friendly, assumes an oversight. No legal language. Goal: payment within the week.
- Second reminder / statement of account (14–30 days): Firmer. References the first reminder and may include a full statement of account showing all outstanding balances.
- Formal demand (30–45 days): States the amount, the original due date, and the statutory interest accruing under the Late Payment of Commercial Debts (Interest) Act 1998. The statutory interest line is not optional — if you omit it, you lose the right to claim it later.
- Pre-legal notice (45–60 days): States that legal proceedings will begin within 14 days if the debt is not settled. This is the last automated letter before a County Court Money Claim.
- Letter before action (LBA) (60+ days): Formal pre-action protocol letter with specific wording. This is what a court expects to have been sent before a small claim is filed.
The escalation timeline matters because courts look at creditor conduct. The Practice Direction on Pre-Action Conduct expects creditors to have given debtors a reasonable opportunity to pay before filing. Jumping from second reminder to county court in two weeks will not reflect well.
Aged debtor data extraction: pulling overdue invoice data from Xero, QuickBooks, and Sage automatically
The pipeline starts with a nightly sync from the accounting system. For this client, that was Xero. The Xero Accounting API exposes invoice status (AUTHORISED, PAID, VOIDED) along with DueDate and AmountDue, which is enough to build the aged debtor extract without touching the UI.
For QuickBooks Online, the equivalent is the Invoices query endpoint via the REST API. For Sage 50, you're usually looking at an ODBC connection or a CSV export via Sage's own scheduler — the API surface is thinner and less reliable.
The extraction runs nightly at 23:00. The output is a structured JSON file per debtor:
{
"debtor_id": "C-00482",
"company_name": "Albright Industrial Supplies Ltd",
"contact_email": "[email protected]",
"registered_office": "14 Parkway Industrial Estate, Coventry, CV6 4AQ",
"invoices": [
{
"invoice_ref": "INV-2026-0341",
"amount_due": 4800.00,
"due_date": "2026-07-01",
"days_overdue": 79,
"currency": "GBP"
}
],
"dispute_flag": false,
"relationship_tier": "standard",
"payment_history": "slow_payer"
}
This structured extract is what the letter generation step consumes. Without it, the LLM has nothing clean to work from — hallucinating invoice amounts in a legal letter is an obvious failure mode. Our invoice data extraction pipeline and the Invoice OCR case study cover the validation layers we add when documents arrive as PDFs rather than structured API data.
LLM-generated dunning letters: how to write credit control correspondence that reads human and holds legal weight
We use Claude (Anthropic's API) for letter generation. The prompt includes: the debtor's name, invoice references, amounts, days overdue, a pre-computed statutory interest figure, and the letter type. The system prompt defines the firm's tone for each tier and includes the mandatory wording for formal demands — the model doesn't improvise legal language, it fills a defined template.
The critical constraint: the model generates prose, not numbers. The statutory interest calculation runs in Python before the prompt call:
def statutory_interest(amount: float, days_overdue: int, base_rate: float = 0.0425) -> float:
"""Calculate statutory interest under Late Payment of Commercial Debts Act 1998."""
annual_rate = base_rate + 0.08 # 8 percentage points above Bank of England base rate
daily_rate = annual_rate / 365
return round(amount * daily_rate * days_overdue, 2)
def debt_recovery_compensation(amount: float) -> float:
"""Fixed statutory compensation per debt — not per invoice."""
if amount < 1000:
return 40.00
elif amount < 10000:
return 70.00
else:
return 100.00
The computed values feed into the prompt as formatted strings: "Statutory interest accrued: £47.23 (12.25% p.a. under the Late Payment of Commercial Debts (Interest) Act 1998)". The model copies this into the letter — it does not compute it. That separation matters.
One finding: LLM-generated letters for high-value accounts need human review. A formal demand to a £200k customer is a relationship decision. We surface those for sign-off rather than sending automatically.
Debtor segmentation: payment history, relationship status, and dispute flag — the three signals that determine which letter sends
Not every debtor 45 days overdue should receive the same letter. The pipeline applies three signals before selecting a letter type:
Payment history — pulled from the accounting system's historical invoice records. A debtor who has consistently paid within 45 days previously gets a softer second reminder. A debtor who has required formal demands on two prior occasions gets escalated faster.
Relationship tier — a manually maintained field in HubSpot. Key accounts and long-term clients follow a softer path: their second reminder triggers a phone call suggestion to the credit controller rather than an automated letter.
Dispute flag — checked against both the CRM and the monitored credit control inbox. Any email from the debtor containing words like "query", "dispute", "incorrect invoice", or "not received" in the last 14 days pauses the sequence and routes to a human.
def select_letter_type(invoice: dict, debtor: dict) -> str:
days_overdue = invoice["days_overdue"]
if debtor.get("dispute_flag"):
return "dispute_acknowledgement"
if days_overdue <= 14:
return "first_reminder"
elif days_overdue <= 30:
if debtor["relationship_tier"] == "key_account":
return "soft_second_suggest_call"
return "second_reminder"
elif days_overdue <= 45:
return "formal_demand"
elif days_overdue <= 60:
return "pre_legal_notice"
else:
return "escalate_to_human"
This logic is auditable in a spreadsheet. Predictive payment models exist, but the added complexity isn't worth it at these debt volumes. For the parallel voice-based chase track, see our accounts receivable voice agent post.
UK legal requirements for pre-legal demand letters: the specific wording and notice periods before county court proceedings
The pre-legal notice is where automation needs the most care. The Late Payment of Commercial Debts (Interest) Act 1998 gives you the right to claim 8% above the Bank of England base rate — but only if the letter explicitly claims it. Send a vague "pay or we'll take legal action" letter without the statutory interest line and you forfeit that interest.
Mandatory elements of a valid pre-legal demand:
- The exact amount owed (principal + statutory interest + statutory compensation)
- The original invoice reference(s) and due date(s)
- The statutory interest rate stated explicitly
- A payment deadline — standard practice is 14 days from the letter date
- A clear statement that county court proceedings will follow if payment is not received
The letter must go to the registered office address if the debtor is a limited company — not just the trading address. The pipeline cross-references the extracted company name against the Companies House Public Data API to validate the registered address before generating the letter.
One detail that caught us out: a 14-day deadline in a letter dated 1 September means the earliest you can file is 15 September. Day zero is the letter date under the Civil Procedure Rules.
PDF delivery and delivery confirmation: sending letters in a format that creates the paper trail a court claim needs
The letters go out as PDFs, not HTML emails. Courts expect documentary evidence, and a PDF with a visible issue date and delivery confirmation is harder to challenge than a reformatted email thread.
We use SendGrid for delivery with delivery event tracking. The pipeline stores both the PDF and the SendGrid webhook payload (delivered, opened, bounced) in an S3 bucket keyed by {debtor_id}/{invoice_ref}/{letter_type}/{date}.pdf. That path structure makes it straightforward to pull the full correspondence history for any debtor when preparing a court bundle.
If a letter bounces — wrong address, full mailbox — the pipeline flags it within the hour. Two of the distributor's original pre-legal notices had reached the wrong contact for exactly this reason: the email bounced, nobody checked the sent items, and she assumed delivery.
Response tracking and human escalation: flagging disputes, part-payments, and silence for the credit controller
The pipeline monitors four response types after each letter sends:
Payment received — the nightly Xero sync closes the invoice. The debtor automatically drops out of the chase sequence.
Part-payment — the invoice balance drops but doesn't clear. The pipeline sends a "part-payment acknowledged" letter and holds further escalation for five business days, waiting for the remainder before resuming the sequence.
Dispute or query — detected via email monitoring on the credit control inbox. Dispute keywords trigger an immediate flag; all automation pauses until the credit controller clears it.
Silence — the most common outcome. Handled by the escalation timer: if no response within the configured window, the next letter type generates automatically.
The credit controller receives a daily summary email — plain text, not a dashboard — showing who paid, who disputed, which letters sent, and which accounts need her review before a pre-legal notice goes out. That queue review was the highest-value step in the build. She caught two accounts mid-negotiation with the sales team that would have received a formal demand uninvited. Human judgement on high-stakes accounts cannot be automated away. The same design principle runs through our purchase order automation work, where exception queues handle high-value mismatches.
What changed in 2025–2026: UK Late Payment of Commercial Debts Act enforcement and small claims court filing tools
Two developments in the past 12 months changed the practical landscape for SME debt recovery.
First, the UK government's payment practices reporting requirements for large companies got more enforceable. From April 2026, large companies must disclose the exact percentage of invoices paid beyond contractual terms — and the data is public. SMEs now have a credible way to check a prospect's payment behaviour before extending credit terms, not just after the invoice goes overdue.
Second, HMCTS expanded the Online Civil Money Claims service in 2025 to handle claims up to £25,000 (previously capped at £10,000). A distributor can now file a small claim for a genuinely significant invoice without instructing solicitors. The pipeline produces a claim-ready summary document — debtor details, invoice history, letter timeline, statutory interest calculation — formatted for the OCMC portal. Filing takes under 30 minutes.
One counterpoint: the Federation of Small Businesses' Late Payment Report found 37% of small businesses said automated chasing had damaged at least one customer relationship. Automated letters at the wrong tone, or to the wrong contact, can cost more than the invoice is worth. Build the human escalation path before you switch automated sends on.
Good / Bad / Ugly: three credit control automation approaches and their 90-day debt recovery rates
| Approach | Setup time | 90-day recovery rate | Primary failure mode |
|---|---|---|---|
| Manual (status quo — Word + memory) | None | 38% | Wrong contacts, inconsistent wording, statutory interest never claimed |
| Template mail-merge (Outlook + Word templates) | 1 day | 44% | No escalation logic, no dispute detection, no delivery confirmation |
| Automated pipeline (this build) | 2–3 weeks | 61% | Phone-in disputes invisible; BACS settlement race condition on pre-legal sends |
Good: The pipeline sent the right letter to the right contact every time. In 90 days, 61% of invoices over 60 days were either paid in full or on a formal payment plan — up from 38% manually. That's roughly £43,000 recovered from the same aged debt pool in the same period.
Bad: Two invoices were in genuine commercial dispute — goods had arrived damaged. Email keyword detection caught one. The other debtor had telephoned the distributor rather than emailing. That account received an automated second reminder before the credit controller spotted the flag. Avoidable with a tighter CRM dispute-status sync, but only if the credit controller actually logs the call.
Ugly: The pipeline generated a pre-legal notice to a debtor who had made a part-payment via BACS the same morning. The Xero sync runs at 23:00 and BACS clears in the afternoon — there's a window of several hours where the payment is in the bank but not reflected in the accounting system. We added a manual pre-send check for any account within 24 hours of a pre-legal letter going out, but the race condition is structurally present for any business that does not use real-time bank feeds.
The difference between 44% (mail-merge) and 61% (automated pipeline) is dispute detection that pauses the sequence, and delivery confirmation that catches bounces. Those two features alone justify the build cost if you carry more than £50k in aged debt.