Blog · · 6 min read
How to send unpaid invoice reminders with n8n and AI (no coding)
A step-by-step guide so that every morning n8n checks your invoice sheet, spots overdue invoices and sends polite, escalating AI-written reminders, then tells you when it's time to step in yourself. No code needed.

Chasing invoices is one of the least pleasant parts of running a business. Nobody enjoys writing "hey, you haven't paid me," so it gets put off, and before you know it several invoices are weeks overdue.
In this guide you'll build an n8n workflow that checks your invoice sheet in Google Sheets every morning, finds invoices that are past due and unpaid, sends a polite AI-written reminder (friendly first, firmer later) and alerts you when it's no longer a job for a machine. All you do is mark an invoice "paid" when the money arrives.
If you already extract invoice data with AI, that same sheet is your starting point. And if you follow up on quotes, this workflow is its natural partner: one chases the "yes", the other chases the payment.
What you'll build
A seven-part workflow:
- Schedule Trigger: runs every weekday morning.
- Google Sheets (Get Rows): reads your invoices.
- Filter: keeps only overdue, unpaid ones.
- Edit Fields (Set): works out how late each one is and which reminder is due.
- Switch: first reminder, second reminder, or an alert for you.
- Basic LLM Chain + Gmail: the AI writes the email and Gmail sends it (or saves it as a draft).
- Google Sheets (Update Row): logs how many reminders went out and when.
Step 1: set up the invoice sheet
Create (or adapt) a Google Sheet with one row per invoice and these columns:
number: invoice number.clientandemail: who you're reminding.amount: the total, exactly as it appears on the invoice.due_date: due date inYYYY-MM-DDformat.status:pendingorpaid.reminders: how many reminders have been sent (starts at 0).last_reminder: date of the last one (empty at first).
The golden rule: you change the status column (or your payment provider does, if you connect it later). The workflow never marks anything as paid on its own.
Step 2: run it every morning
Add a Schedule Trigger at a fixed time, for example Monday to Friday at 9:00. Reminders then land during business hours, which tends to come across better than an email at midnight.
Then add a Google Sheets node with the Get Rows operation on your invoice sheet.
Step 3: keep only overdue invoices
Add a Filter with two conditions:
statusis not equal topaid.due_dateis before today:{{ $now.toISODate() }}.
Anything that passes is an overdue, unpaid invoice.
Step 4: work out the delay and what to send
Add an Edit Fields (Set) node with two fields:
days_late:{{ Math.floor($now.diff(DateTime.fromISO($json.due_date), 'days').days) }}days_since_last:{{ $json.last_reminder ? Math.floor($now.diff(DateTime.fromISO($json.last_reminder), 'days').days) : 999 }}
That's all you need to pick the stage. A simple pattern (adjust it to how you work):
- First reminder:
reminders= 0 and at least 1 day late. - Second reminder:
reminders= 1 and at least 7 days since the last one. - Alert for you:
reminders= 2 or more and at least 7 days since the last one. At this point the AI doesn't email the client: it tells you.
Step 5: split the stages with a Switch
Add a Switch with three outputs using the rules above. Anything that matches none of them (say, a reminder sent two days ago) simply doesn't leave through any branch and waits for another day.
This avoids the most common mistake: sending the same reminder to the same client every single morning.
Step 6: let the AI write the reminder
On the first and second reminder branches, add a Basic LLM Chain with an instruction like this:
You are [your name] from [your business]. Write a short email reminding a client about an unpaid invoice. Details: client {{ $json.client }}, invoice {{ $json.number }}, amount {{ $json.amount }}, due on {{ $json.due_date }} ({{ $json.days_late }} days ago). This is reminder number {{ $json.reminders + 1 }}. If it's the first, keep it friendly: assume they simply missed it and offer to resend the invoice. If it's the second, stay courteous but clear: ask for a payment date. Include how to pay: [your bank details or payment link]. Don't threaten, and don't invent late fees, interest or legal deadlines. Maximum 120 words. Return only the body, no subject or signature.
Then a Gmail node:
- To:
{{ $('Edit Fields').item.json.email }} - Subject:
Reminder: invoice {{ $('Edit Fields').item.json.number }} - Body: the AI's text plus your signature.
For the first few weeks, use Create Draft instead of Send. Checking each draft takes a minute, and once you like the tone you switch to sending automatically.
The "alert for you" branch
No AI needed here. A Telegram node (or Slack, or an email to yourself) with something like: "Invoice {{ $json.number }} from {{ $json.client }} ({{ $json.amount }}) is {{ $json.days_late }} days overdue and has had 2 reminders. Time to call." If you don't have a bot yet, the Telegram bot with n8n guide shows how to create one.
A timely phone call from you usually works better than a third automated email.
Step 7: log what went out
After Gmail, add Google Sheets with Update Row, matching the row by number:
reminders:{{ $('Edit Fields').item.json.reminders + 1 }}last_reminder:{{ $now.toISODate() }}
Do the same on the alert branch so it doesn't ping you every morning; it'll alert you again after 7 days if the invoice is still unpaid.
Test it without bothering anyone
- Create two made-up invoices using your own email: one due yesterday, one due 10 days ago with
reminders= 1. - Run the workflow manually.
- Check the drafts in Gmail and that the sheet was updated.
- Run it again: nothing new should go out. If something does, check the Switch conditions.
If a step fails (Sheets permissions, a badly typed date), n8n highlights the exact node. So you don't find out too late, add an error alert like the one in this guide to errors and retries.
Ideas to take it further
- Before the due date: one more branch that, 3 days ahead, sends a "just a heads-up, this is due on Friday." Plenty of people pay on time when reminded early.
- Mark as paid automatically: if you take payments through Stripe or another provider that sends webhooks, a second workflow can set
statustopaidwhen the payment comes in. - Weekly summary: a daily or weekly AI report with the total outstanding and who owes what.
- Client language: add a
languagecolumn and pass it into the instruction so each client gets the email in their own language.
Cost and limits
- Cost: the AI writes a few short emails a day, so the cost is usually small. Sheets and Gmail run on your Google account. Check the current pricing of your AI provider and of n8n.
- Tone: review drafts at first. A cold reminder can cost you a client; a friendly one usually gets paid just the same.
- Legal: this workflow reminds, it doesn't pursue. For late fees, interest or formal collection, talk to your accountant or adviser, and don't ask the AI to make them up.
- Data: the sheet holds client data. Share it only with people who need it.
Start with ready-made templates
If you'd like to skip the basic n8n and AI setup, download the free WhatsApp agent or see the AgentKiosk pack: 8 agents ready to import, with the AI part already set up. You can build these payment reminders on top with the steps above.


