Reminders & follow-up
What chases an unpaid invoice, when it fires, and what you have to do yourself.
An invoice that was opened for payment and then forgotten is the normal case, not the exception. Wajub can chase it for you on a schedule fixed in code, with no per-invoice policy and nothing to configure. What matters most is knowing when that machinery is armed, because for a lot of integrations it never is.
An invoice sent through the API is never chased
Reminders are scheduled by the Dashboard's Send button, in the same code path that renders the PDF
and mails the invoice. POST /invoices/{id}/send does none of that: there is no reminder code in
the API at all. If your invoices are issued by your own software, the follow-up is yours too, and
the last section of this page is the one to read.
When the schedule is armed
At the first send from the Dashboard, and only then. Three conditions all have to hold, and missing any one of them means that invoice has no reminders, permanently.
| Condition | If it fails |
|---|---|
| The send happens in the Dashboard | Nothing is scheduled |
The invoice is leaving draft | A resend schedules nothing, the original run stands |
The invoice carries a due_date | Nothing is scheduled, there is no date to count from |
The reminders are written out in one go at that moment, each with its own slot, its recipient and its wording. The customer's email is copied in at the same time, so a later correction on the customer record does not reach reminders already queued.
The schedule
Four reminders, all by email, all at 09:00, all counted from the due date.
| Reminder | Slot | Type |
|---|---|---|
| Due today | due_date at 09:00 | upcoming |
| Three days late | due_date + 3 | overdue |
| A week late | due_date + 7 | overdue |
| Two weeks late | due_date + 14 | final |
A queue runs every hour and sends whatever slot has come due, so a reminder leaves within the hour of its slot rather than at 09:00 exactly. After the fourth, nothing more is sent: there is no escalation beyond two weeks.
The reminder before the due date does not fire
A fifth reminder is meant to go out three days ahead, and its guard measures the gap between the due date and today in a direction that makes the comparison always false on the date library in use. The reminder is never created. In practice the first thing your customer hears is on the due date itself, not before it.
Sending an invoice that is already late
The three overdue slots are computed from due_date without checking whether it has passed. Send
an invoice a month after its due date and all three slots are already behind you, so the next
hourly run sends all three at once. Give a late invoice a due date you can still count forward
from, or expect the customer to receive three emails in a minute.
What stops the chase
Two things, and no others.
A paid invoice stops it. The sender re-reads the invoice before each send and cancels the reminder if the total has been settled, so the queue drains itself as soon as the money lands.
Cancelling the invoice stops it. Cancelling clears every pending reminder along with the document.
A partially paid invoice keeps being chased, which is the intent, since something is still owed. And a reminder that fails to send is not retried: a retry routine exists with a budget of three attempts, but nothing runs it, so a bounced address is the end of that reminder.
The reminder settings do nothing
Settings → Invoice carries a Reminders block with an on and off toggle, the days before and the days after. All three are stored against your team and read back only by that same screen. The scheduler never consults them: turning reminders off does not turn them off, and adding a day does not add a slot. The schedule above is the one that runs, for every account.
Following up from your own code
If you issue invoices through the API you have two signals to build on, and they behave differently.
The first is the list, filtered on what is outstanding.
curl "https://api.wajub.com/invoices?status=overdue&payment_status=unpaid" \
-H "Authorization: sk.kZ3qP8mWvL2xR7tB5nY4hC6dF9jS1aG0eU3i…"payment_status takes unpaid, partially_paid or fully_paid, and narrows on what has actually
been received rather than on the status label. due_date_from and due_date_to bracket the window
when you want this week's late invoices rather than all of them.
The overdue label lags by up to a day
Nothing flips an invoice to overdue at midnight. A job does it once a night at 01:00, so an
invoice that fell due this morning still reads sent until tomorrow. If you need the distinction
on the day, compare due_date against today yourself rather than filtering on the status.
The second signal is the webhook, with one gap worth planning around.
invoice.updatedeventThe gap is overdue itself. The nightly job writes that status in bulk, which skips the event
machinery, so no webhook is emitted when an invoice goes late. Overdue is something you notice by
asking, not something you are told.
So the pattern that works: hold your own list of open invoices, check it on your own schedule, and send your own reminder over the channel that customer actually reads. The message needs the payment URL, which you rebuild from the invoice id.
https://invoice.wajub.com/inv_LRQqYvlhrgUOE225KMKURelated pages
- InvoiceThe document, its payment page, and the full lifecycle.
- QuickstartIssue an invoice and get it paid, start to finish.
- Recurring invoicesWhat the recurring flag configures, and what it does not.
- WebhooksWhere invoice.updated fits with payment.succeeded.
- Invoices API referenceEvery filter on the list endpoint.