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.