Skip to main content

Overview

A dunning campaign is a timer. Day 3, day 7, day 14, the same ladder for everyone. Three things go wrong on the same day:
  • The customer who has paid on day 8 for two years gets a past due notice on day 3.
  • An invoice a partial payment already covered gets chased for its full face value.
  • A customer whose card expired gets “please pay your invoice” instead of a link to fix the card.
The Dunning Agent reads the account first: twelve months of invoices and payments, the disputes, the provider status. Then it acts at the lowest rung that is justified, or does nothing and tells you why.
Beta. Available on request. Contact us for access.This agent acts. It sends email and re-attempts charges, so start with a dry run.

Campaigns and the agent

Campaigns are the deterministic floor. The agent is the judgment layer for the accounts where a fixed ladder gets it wrong. Running both is fine.

How it decides

One ordered ladder, re-evaluated from live billing data on every run. The first rung that matches wins.

Every overdue invoice enters at the top and stops at the first rung that matches

Net, never face value. A partial payment leaves an invoice fully pending at its face amount in Lago. The agent chases total_amount_cents - total_paid_amount_cents - credit_notes_amount_cents everywhere: the email, the materiality test, the retry cap.

Who gets chased, and how firmly

Two signals. A campaign confuses them. Pattern decides whether to chase. The median pay lag across a customer’s paid invoices, and whether that lag is consistent. Reliably eight days late and six days overdue is not a collections problem, so the agent waits. Scattered lags mean no pattern to respect, so it chases. Score decides the tone. The on-time rate over the last 12 months, nothing more. A customer scored repeat-late who is still inside their usual lag gets wait, not a firm notice. Consistency is not the same as delinquency.

What it can do

  • Send a reminder. One email per customer per run, itemizing every overdue invoice with its net amount and days overdue.
  • Retry a failed charge. Only below the retry cap, and only once. It also emails the customer a portal link to fix the card.
It cannot terminate a subscription, suspend service, issue a credit note or a refund, or apply wallet credit. When one of those is the right call, it says so in Slack and stops.

Guardrails

The agent proposes. A policy engine decides and is the only thing that executes, so every limit below lives in code rather than in a prompt. Freshness re-reads the invoice from Lago in the moment before sending, so an invoice paid between the decision and the send is never chased.

Run it

Three packagings, one decision policy. What changes is where memory lives and how a message goes out. Use the Skill to see the decisions with a person still in the send loop. Use the app when you want it to collect.
Upload the skill folder under Settings → Capabilities → Skills, enable the Gmail and Slack connectors, set your Lago API URL and key, then ask “who owes me money”.It creates Gmail drafts and never sends. Memory lives in one file per customer, holding the score, the payment pattern, the contact history, and any hold. Clear the hold to hand an account back to the agent.

Connect and configure

Adding a new action or a new gate is a small extension: an action is a type, a blast radius, an executor, and a freshness check.
The ladder order, the email templates, and the score thresholds are not settings. Changing them is a code change.

When it hands off

One Slack message per run, ordered by urgency. Each line says what happened, what to do, and how automation resumes. wait and cadence holds are not alerted. They resolve themselves.

Limits

  • Every run sweeps every overdue customer, not only the ones that are due.
  • The scheduled sweep is opt-in and off by default.
  • Emails are plain text. No HTML templates, no branding.
  • The ladder is deterministic, but the wording of a reminder is AI-generated. Read a dry run before trusting it unattended.