The policy is visible
The reminder ladder is a table finance can read and change, not a set of thresholds spread across a cron job and a mail-merge.
Invoice reminders
A job reads the overdue rows every morning, decides which reminder each one is due, sends it, and writes the stage back — so the ledger and the outbox never disagree.
The problem
The rules are not complicated — a nudge at seven days, a firmer one at fourteen, a call list at thirty, and never chase a customer who is already in a payment plan. What is hard is doing it every morning, to every row, without chasing someone twice or missing a week.
The usual answer is a spreadsheet and a person, or a scheduled script that nobody wants to touch. Both fail the same way: when a customer says "I never got a reminder", nobody can produce what was sent, when, or which rule decided it.
What the flow looks like
Numbered because the order is the execution order, not because it is a list. However many steps it has, the whole thing is one run.
Query your own database directly — Postgres, MySQL, Snowflake, BigQuery, Redshift or MongoDB — on the schedule you set. No export, no copy of your ledger living somewhere else.
The Loop node runs a child flow once for each row, so the dunning policy is written once for one invoice and applied to every one of them.
A payment plan, a raised dispute, an account in collections. The exclusions are conditions on the canvas rather than a WHERE clause nobody remembers.
Days overdue, amount, customer tier and last contact meet in one grid. Finance owns the grid; nobody has to open a script to move a threshold.
A first notice by email, a final notice by SMS, and anything over your ceiling to a person instead of a template.
Email through SendGrid, SMS through Twilio, or an internal alert into Slack — each with your own credentials and your own templates.
Record the stage the invoice reached and when it was sent, so tomorrow’s run starts from what actually happened rather than from the calendar.
Past the last reminder, the invoice becomes a case in a queue with the history attached — a person’s job, handed over cleanly, without stopping the run.
What the flow can reach
A Connection node calls one of 52 packaged providers, or any HTTPS or JSON API you have credentials for. Six databases connect directly. Every call happens inside the run, with your credentials, and lands on the same trace as the rest of it.
What changes
The reminder ladder is a table finance can read and change, not a set of thresholds spread across a cron job and a mail-merge.
Exclusions and last-contact state are part of the flow, and the stage is written back on every run, so the next morning’s pass sees what yesterday actually did.
Open the run for that invoice on that date: the rule that fired, the template that went out, the provider’s response, and the retry if the first attempt failed.
Questions
A job reads rows from a source — a database query, an S3 bucket or an uploaded file — and runs the flow over each one on the schedule you set. Each row is one run, so a morning pass over 400 overdue invoices is 400 runs against your allowance.
No. A PostgreSQL node queries your database with your credentials during the run and uses the result in that run. What is kept is the trace of the decision — the rule that fired and the value each step produced — not a mirror of your finance data.
Yes, two ways. A Create Case node opens a case in a queue and the run carries on, which suits a review of yesterday’s batch. A Manual Review node pauses the run at that node and resumes it from the same place once someone answers, which suits a single high-value invoice.
Ready when you are
Build the flow in Sandbox, run your own cases through it, and read the trace before anything reaches a customer.