Automatic reminders for overdue invoices
Every morning, clients with unpaid overdue invoices get a polite reminder email.
How it works
- Read your invoices sheet.
- Keep invoices that are unpaid and past their due date.
- Send each client a friendly reminder with the amount and days late.
Diagram
Code
JavaScript used in the Code step — already included in the template below.
// Invoices sheet columns: invoice | client | email | amount | due_date | status
// Keeps unpaid invoices that are past their due date.
const DAY = 24 * 60 * 60 * 1000;
const today = new Date();
today.setHours(0, 0, 0, 0);
return $input.all()
.map((item) => item.json)
.filter((r) => r.email && String(r.status).toLowerCase() !== "paid" && new Date(r.due_date) < today)
.map((r) => ({
json: { ...r, days_late: Math.floor((today - new Date(r.due_date)) / DAY) },
}));Build it
Pick your tool — same automation, step by step.
Copy and paste straight into an n8n canvas (Ctrl+V), or download and use Import from File. Then connect your own credentials and replace every YOUR_… placeholder.
Show code (139 lines)
{
"name": "Automatic reminders for overdue invoices (Flowngn)",
"nodes": [
{
"parameters": {
"content": "## Automatic reminders for overdue invoices\nEvery morning, clients with unpaid overdue invoices get a polite reminder email.\n\n**Setup**\n1. Open each node and connect your own credentials.\n2. Replace every YOUR_… placeholder.\n3. Test once, then activate.\n\nFree template from Flowngn",
"height": 260,
"width": 340
},
"id": "329e24cb-bac4-44a3-ab91-22f1786e75ae",
"name": "Setup notes",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
-420,
-60
]
},
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * 1-5"
}
]
}
},
"id": "329e24cb-bac4-44a3-ab91-22f1786e75ae",
"name": "Weekdays 9:00",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
0,
0
]
},
{
"parameters": {
"operation": "read",
"documentId": {
"__rl": true,
"value": "YOUR_SPREADSHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "Invoices",
"mode": "name"
},
"options": {}
},
"id": "329e24cb-bac4-44a3-ab91-22f1786e75ae",
"name": "Read invoices",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
300,
0
]
},
{
"parameters": {
"jsCode": "// Invoices sheet columns: invoice | client | email | amount | due_date | status\n// Keeps unpaid invoices that are past their due date.\nconst DAY = 24 * 60 * 60 * 1000;\nconst today = new Date();\ntoday.setHours(0, 0, 0, 0);\n\nreturn $input.all()\n .map((item) => item.json)\n .filter((r) => r.email && String(r.status).toLowerCase() !== \"paid\" && new Date(r.due_date) < today)\n .map((r) => ({\n json: { ...r, days_late: Math.floor((today - new Date(r.due_date)) / DAY) },\n }));"
},
"id": "329e24cb-bac4-44a3-ab91-22f1786e75ae",
"name": "Find overdue",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
600,
0
]
},
{
"parameters": {
"sendTo": "={{ $json.email }}",
"subject": "=Friendly reminder: invoice {{ $json.invoice }}",
"emailType": "text",
"message": "=Hi {{ $json.client }},\n\nJust a friendly reminder that invoice {{ $json.invoice }} for {{ $json.amount }} was due {{ $json.days_late }} day(s) ago. If you've already paid, please ignore this email.\n\nThank you!\nYOUR_NAME",
"options": {
"appendAttribution": false
}
},
"id": "329e24cb-bac4-44a3-ab91-22f1786e75ae",
"name": "Send reminder",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2.1,
"position": [
900,
0
]
}
],
"connections": {
"Weekdays 9:00": {
"main": [
[
{
"node": "Read invoices",
"type": "main",
"index": 0
}
]
]
},
"Read invoices": {
"main": [
[
{
"node": "Find overdue",
"type": "main",
"index": 0
}
]
]
},
"Find overdue": {
"main": [
[
{
"node": "Send reminder",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {},
"settings": {
"executionOrder": "v1"
},
"meta": {
"templateCredsSetupCompleted": false
},
"tags": []
}In Make, create a new scenario and add these modules in order:
- Schedule the scenario: Weekdays 9:00
- Google Sheets › Search Rows
- Tools › Set variable / Iterator + Array aggregator (same logic as the Code step)
- Gmail › Send an Email
- Every module run uses Make operations — the free plan includes a monthly quota.
- Make's built-in functions (map, sum, formatDate…) can replace most Code steps; for complex logic use a code module.
- Module and step names can differ slightly as Make and Zapier update their apps.
In Zapier, create a new Zap and add these steps in order:
- Schedule by Zapier — Weekdays 9:00
- Google Sheets — Lookup Spreadsheet Rows (or Code by Zapier)
- Code by Zapier — Run JavaScript (paste the code from the Code section)
- Gmail — Send Email
- Zaps with more than two steps need a paid Zapier plan.
- Webhooks, Filters/Paths and Code by Zapier are premium features on some Zapier plans.
- Code by Zapier runs JavaScript: reuse the code shown above, reading inputs from inputData instead of $json.
- Module and step names can differ slightly as Make and Zapier update their apps.
Tips
- Mark an invoice "paid" in the sheet and reminders stop automatically.
- Add a step so reminders go at most once a week per invoice.
Related flows
Weekly KPI report by email
Every Monday, get a short summary of last week's key numbers from your sheet.
AI reads receipt emails into your expense sheet
AI pulls the vendor, amount, currency and date out of receipt emails and logs them.
Monthly expenses by category, emailed to your accountant
On the 1st of every month, total last month's expenses by category and email the summary to your accountant.