# Chasing overdue invoices: the tool sequence for AI assistants

> get_attention_digest (invoices_to_chase) or list_invoices → propose_payment_reminders (stages one statement send per overdue client under one batch_id; sends nothing) → read each client's warnings with the person → approve_payment_reminders(batch_id, confirmed: true). A batch where every client was skipped answers code nothing_staged — never report it as sent. One client: propose_send_statement → confirm_pending_operation → approve_pending_operation.

URL: https://biloh.com.au/docs/reference/chasing-overdue-invoices-for-agents
Category: Reference | Audience: agent | Updated: 2026-11-08

**At a glance**

- **Who it's for:** AI assistants working in a Biloh business
- **What it does:** [Chasing overdue invoices, done for you](https://biloh.com.au/capabilities/chasing-overdue)
- **Tools it uses:** [`get_attention_digest`](https://biloh.com.au/connect#get_attention_digest) · [`list_invoices`](https://biloh.com.au/connect#list_invoices) · [`propose_payment_reminders`](https://biloh.com.au/connect#propose_payment_reminders) · [`approve_payment_reminders`](https://biloh.com.au/connect#approve_payment_reminders) · [`propose_send_statement`](https://biloh.com.au/connect#propose_send_statement) · [`confirm_pending_operation`](https://biloh.com.au/connect#confirm_pending_operation) · [`approve_pending_operation`](https://biloh.com.au/connect#approve_pending_operation) · [`propose_resend_statement`](https://biloh.com.au/connect#propose_resend_statement) · [`generate_pay_all_link`](https://biloh.com.au/connect#generate_pay_all_link) · [`list_demo_inbox`](https://biloh.com.au/connect#list_demo_inbox)
- **What a person approves:** Biloh never moves money: its tools record payments that already happened, and a pay-now link opens the business's own Stripe checkout for its client.
- **Checked against the code:** 2026-11-08

This is the sequence an assistant follows when the person it works for says "chase everyone who
owes us". Every reminder is staged first and sent only after the person says yes. Money is integer
cents: `overdue_cents: 196900` is $1,969.00.

## The sequence

| Step | Tool | What it does |
| --- | --- | --- |
| 1 | `get_attention_digest` or `list_invoices` | Who is overdue |
| 2 | `propose_payment_reminders` | Stages one reminder per overdue client; returns `batch_id`. Nothing is sent |
| 3 | (the person) | Reads each client's preview and `warnings`, and says which to send |
| 4 | `approve_payment_reminders` | Sends the chosen ones, with `confirmed: true` |

## Step 1 — who is overdue?

`get_attention_digest` returns an `invoices_to_chase` bucket: one item per client with
`client_id`, `invoice_numbers`, `overdue_cents` and `oldest_days_overdue`, plus `next_tool`. The
bucket is filled only when the business has turned on
`attention.digest.include_money_queues` (default off); `invoices_to_chase.enabled` says which.
`list_invoices` answers who is overdue in every case.

## Step 2 — propose_payment_reminders

Required: `statement_date` (the real send date, `YYYY-MM-DD`, no default) and
`cover_message_template` (plain text; the platform adds the greeting). The only tokens allowed are
`{pay_all_link}`, `{overdue_total}` and `{client_name}`; an unknown token is refused before
anything is staged.

Optional: `client_ids` or `exclude_client_ids`, `min_days_overdue` (default 1), `bundle_scope`
(`outstanding`, the default — only invoices still owing — or `none`), `link_scope` (`all`, the
default — one link paying everything outstanding — or `overdue`, one link per overdue invoice) and
`subject_template`.

It returns `batch_id`, `expires_at` and `clients[]`, each with `recipients`, `greeting`,
`subject`, `cover_message_rendered`, `pay_all_url`, `overdue_cents`, `link_total_cents`,
`attachments`, `operation_id` and `warnings`. Put every warning to the person before approving —
among them: the link also covers invoices not yet due, two part-paid invoices short by the same
amount (an old price), or unanswered email from the client.

A client the server holds back is listed under `skipped` with a `code`:

| `code` | Meaning | What to do |
| --- | --- | --- |
| `nothing_overdue` | Nothing overdue by `min_days_overdue` | Nothing |
| `already_sent` | This statement was already sent | `propose_resend_statement` for that client |
| `unmatched_client_credits` | A bank deposit looks like their payment | Match it, or pass `acknowledge_unmatched_credits: true` |
| `feed_behind_statement_date` | The bank feed stops before `statement_date` | Import the latest statement, or pass `acknowledge_feed_gap: true` |

The same inputs while the sends are still pending return the same `batch_id` with
`idempotent: true` and stage nothing new.

## Step 4 — approve_payment_reminders

Input: `{ batch_id, confirmed: true }`, and `client_ids` to send only some. Without
`confirmed: true` it refuses with `confirmation_required` and sends nothing.

It returns `sent[]` (`client_id`, `operation_id`, `sent_at`, `message_id`, `attachments`) and
`failed[]` (`client_id`, `code`, `error`). A send that has expired comes back with code `expired`;
propose again.

When the batch staged nothing — every client was skipped at step 2 — the answer is
`code: "nothing_staged"`, with `sent: []`, a `message` saying nothing was sent and why, the
`skipped` list and `next_step: "propose_resend_statement"`. Report it as nothing sent.

## One client — the statement send, in three legs

`propose_send_statement` needs `client_id`, `period_start`, `period_end` and `statement_date`. It
runs the same unmatched-deposit and bank-feed gate, and refuses with `already_sent` (with a
`prior_send` block) when that statement has gone. Then `confirm_pending_operation` stages it —
nothing is sent — and `approve_pending_operation` sends it. A resend is different:
`propose_resend_statement` then `confirm_pending_operation`, which sends.

## Where did it go?

On a business whose outbound email is kept rather than delivered — the public demo is one —
`list_demo_inbox` lists every kept email, newest first; pass `since` to see only yours.

**Biloh never moves money: its tools record payments that already happened, and a pay-now link opens the business's own Stripe checkout for its client.**

## Related

- [Chase overdue invoices (how-to)](/docs/how-to/chase-overdue-invoices)
- [The attention digest](/docs/reference/attention-digest)
- [Review Biloh on the demo business](/docs/how-to/review-biloh-on-the-demo-business)
