This workflow corresponds to n8n.io template #9772 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "fB4si9amQw4D2TK2",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Google Spreadsheet -> Invoice Generation -> Email",
"tags": [],
"nodes": [
{
"id": "c2e9a234-394c-4c5e-ab59-a5311fa61ed8",
"name": "When clicking \u2018Execute workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-144,
16
],
"parameters": {},
"typeVersion": 1
},
{
"id": "1f9f59c4-9927-4a0f-8aaf-64488bdc5a13",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
-576
],
"parameters": {
"width": 864,
"height": 448,
"content": "# Invoice Management With Airtable \nHere you will find an example of how you can create \nand manage your invoices for free, easily, and beautifully:\n[Public Airtable Example](https://airtable.com/apphyDa3uYAq0VOMW/shrSe39NZYrqm4gtE)\n\n"
},
"typeVersion": 1
},
{
"id": "895fe916-1db2-4055-a87e-804a6be14383",
"name": "Get Ready Invoices",
"type": "n8n-nodes-base.airtable",
"position": [
144,
16
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "apphyDa3uYAq0VOMW",
"cachedResultUrl": "https://airtable.com/apphyDa3uYAq0VOMW",
"cachedResultName": "Custom JS - Invoicing Template"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tblW46vfkwOFQJLMs",
"cachedResultUrl": "https://airtable.com/apphyDa3uYAq0VOMW/tblW46vfkwOFQJLMs",
"cachedResultName": "Invoices"
},
"options": {},
"operation": "search",
"filterByFormula": "{Status} = 'Ready'"
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "5c20d60e-72b3-45db-8df0-223676a7880e",
"name": "Get Clients",
"type": "n8n-nodes-base.airtable",
"position": [
1024,
0
],
"parameters": {
"id": "={{ $('Get Ready Invoices').item.json['Client ID'][0] }}",
"base": {
"__rl": true,
"mode": "list",
"value": "apphyDa3uYAq0VOMW",
"cachedResultUrl": "https://airtable.com/apphyDa3uYAq0VOMW",
"cachedResultName": "Custom JS - Invoicing Template"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tblQdiFVsZ9w3sahJ",
"cachedResultUrl": "https://airtable.com/apphyDa3uYAq0VOMW/tblQdiFVsZ9w3sahJ",
"cachedResultName": "Clients"
},
"options": {}
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "1da85e53-eaf2-4928-b1bb-0d2d7eb56056",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
-96
],
"parameters": {
"color": 2,
"width": 416,
"height": 560,
"content": "## Define Your Company Details\nHere you can customize your own company details."
},
"typeVersion": 1
},
{
"id": "047f3d97-760b-4307-a17f-a92d4c8f268d",
"name": "Get Invoice Items",
"type": "n8n-nodes-base.airtable",
"position": [
528,
128
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "apphyDa3uYAq0VOMW",
"cachedResultUrl": "https://airtable.com/apphyDa3uYAq0VOMW",
"cachedResultName": "Custom JS - Invoicing Template"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tblASYLVpsnrUoKt5",
"cachedResultUrl": "https://airtable.com/apphyDa3uYAq0VOMW/tblASYLVpsnrUoKt5",
"cachedResultName": "Invoice-Items"
},
"options": {},
"operation": "search",
"filterByFormula": "=FIND(\"{{ $json.ID }}\", ARRAYJOIN({Invoice}))"
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "3e86f778-d65a-47c6-8fd4-83b8063174e1",
"name": "Aggregate",
"type": "n8n-nodes-base.aggregate",
"position": [
848,
128
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData",
"destinationFieldName": "items"
},
"typeVersion": 1
},
{
"id": "32205005-9879-4abe-be18-d77126675ccb",
"name": "Loop Over Items",
"type": "n8n-nodes-base.splitInBatches",
"position": [
352,
16
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "9e68a44d-f0d2-407b-88fb-bf97032504b0",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2144,
-96
],
"parameters": {
"color": 5,
"width": 416,
"height": 560,
"content": "## Mark Invoices as \"Sent\"\nFinally, the invoices are set to \u201cSent\u201d so that they will never be reloaded again next time."
},
"typeVersion": 1
},
{
"id": "6d4c0372-e2b4-45fb-8840-82378e557f4c",
"name": "Update record",
"type": "n8n-nodes-base.airtable",
"position": [
2288,
0
],
"parameters": {
"base": {
"__rl": true,
"mode": "list",
"value": "apphyDa3uYAq0VOMW",
"cachedResultUrl": "https://airtable.com/apphyDa3uYAq0VOMW",
"cachedResultName": "Custom JS - Invoicing Template"
},
"table": {
"__rl": true,
"mode": "list",
"value": "tblW46vfkwOFQJLMs",
"cachedResultUrl": "https://airtable.com/apphyDa3uYAq0VOMW/tblW46vfkwOFQJLMs",
"cachedResultName": "Invoices"
},
"columns": {
"value": {
"id": "={{ $('Get Ready Invoices').item.json.id }}",
"Status": "Sent"
},
"schema": [
{
"id": "id",
"type": "string",
"display": true,
"removed": false,
"readOnly": true,
"required": false,
"displayName": "id",
"defaultMatch": true
},
{
"id": "ID",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client ID",
"type": "array",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Client ID",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Client Name",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Client Name",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Description (from Invoice-Items)",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Description (from Invoice-Items)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Total",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Total",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Invoicedate",
"type": "dateTime",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Invoicedate",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Status",
"type": "options",
"display": true,
"options": [
{
"name": "Delayed",
"value": "Delayed"
},
{
"name": "Sent",
"value": "Sent"
},
{
"name": "Paid",
"value": "Paid"
},
{
"name": "Ready",
"value": "Ready"
}
],
"removed": false,
"readOnly": false,
"required": false,
"displayName": "Status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Create Invoice (Airtable API)",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Create Invoice (Airtable API)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Create Invoice (Get Parameters)",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Create Invoice (Get Parameters)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Invoice-Items",
"type": "array",
"display": true,
"removed": true,
"readOnly": false,
"required": false,
"displayName": "Invoice-Items",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Prices (from Invoice-Items)",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Prices (from Invoice-Items)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Default Hourly Rate (from Client ID)",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Default Hourly Rate (from Client ID)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Total (from Invoice-Items)",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "Total (from Invoice-Items)",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ClientAddressField1",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "ClientAddressField1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ClientAddressField2",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "ClientAddressField2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "ClientTax",
"type": "string",
"display": true,
"removed": true,
"readOnly": true,
"required": false,
"displayName": "ClientTax",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [
"id"
],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "update"
},
"credentials": {
"airtableTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "6792cf9c-9aa6-444e-9c1c-66cf5784341d",
"name": "Generate Invoice",
"type": "@custom-js/n8n-nodes-pdf-toolkit.invoiceGenerator",
"position": [
1728,
0
],
"parameters": {
"issuer": {
"issuerValues": {
"email": "={{ $json.Email }}",
"phone": "={{ $json.Phone }}",
"taxId": "={{ $json.TaxId }}",
"address": "={{ $json.Address }}",
"logoUrl": "={{ $json.Logo }}",
"companyName": "={{ $json.CompanyName }}"
}
},
"billing": {
"billingValues": {
"notes": "Please transfer the amount within 14 days.",
"taxRate": 19,
"currency": "EUR",
"invoiceDate": "={{ $('Get Ready Invoices').item.json['Client ID'][0] }}",
"invoiceNumber": "={{ $('Get Ready Invoices').item.json.ID }}"
}
},
"payment": {
"paymentValues": {
"BIC": "={{ $json['Bic/Swift'] }}",
"bankName": "={{ $json['Bank Name'] }}",
"accountNumber": "={{ $json['Account Number'] }}"
}
},
"itemsJson": "={{ $('Loop Over Items').item.json.items }}",
"itemsMode": "json",
"recipient": {
"recipientValues": {
"name": "={{ $('Get Clients').item.json['Comany Name'] }}",
"taxId": "={{ $('Get Clients').item.json.Tax }}",
"address": "={{ $('Get Clients').item.json.Street }} {{ $('Get Clients').item.json['Street No.'] }}\n{{ $('Get Clients').item.json['Postal Code'] }} {{ $('Get Clients').item.json.City }}"
}
}
},
"credentials": {
"customJsApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "b3263d7d-e8ca-4776-8d27-08773ab65549",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
96,
-96
],
"parameters": {
"color": 5,
"width": 1040,
"height": 560,
"content": "## Collect Invoice Data From Airtable \nHere, all invoices with the status \u201cReady\u201d are retrieved and enriched with the respective invoice items and client information."
},
"typeVersion": 1
},
{
"id": "7904b830-14ce-4ff5-8ca4-e4ab2cd4a644",
"name": "Set Company Details",
"type": "n8n-nodes-base.set",
"position": [
1344,
0
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "860bad3a-81d5-4591-9d8d-3f399e88227d",
"name": "CompanyName",
"type": "string",
"value": "MyCompany"
},
{
"id": "4f473e5c-1f8a-4fce-971b-7bcf3a585953",
"name": "Address",
"type": "string",
"value": "My Street 45\n12322 New York"
},
{
"id": "a4de3c7f-2470-48a2-81ee-22d43dbbded5",
"name": "TaxId",
"type": "string",
"value": "US12124234"
},
{
"id": "f6b26bc0-dbe7-433b-96ff-843a137afa99",
"name": "Email",
"type": "string",
"value": "user@example.com"
},
{
"id": "9ee8496d-93c8-4828-aa43-a4168ffd7c39",
"name": "Phone",
"type": "string",
"value": "+1234567890"
},
{
"id": "a66fb0d6-a2c2-4d9d-86aa-fe3f7dc97e6e",
"name": "Logo",
"type": "string",
"value": "https://equalengineers.com/wp-content/uploads/2024/04/dummy-logo-5b.png"
},
{
"id": "717ca346-29d6-4d0a-9942-af8db75c23ce",
"name": "Account Number",
"type": "string",
"value": "12345677"
},
{
"id": "db4d6b35-9ddb-4f38-a6a1-2f66a36d58d6",
"name": "Bic/Swift",
"type": "string",
"value": "1234"
},
{
"id": "d08fdf69-c730-4bda-b621-dd8a429ed3ac",
"name": "Bank Name",
"type": "string",
"value": "Bank of XYZ"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "a0d0705b-5d60-4845-bace-2e0cc9a9a8bd",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1648,
-96
],
"parameters": {
"color": 4,
"width": 448,
"height": 560,
"content": "## Generate Invoice & send email with invoice\n"
},
"typeVersion": 1
},
{
"id": "bbdd0964-c9ea-4c4b-b402-7a2e34e79c70",
"name": "Map Fields",
"type": "n8n-nodes-base.set",
"position": [
688,
128
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "a95b61df-c10d-43f1-b005-d6d84c6fec47",
"name": "description",
"type": "string",
"value": "={{ $json.Description }}"
},
{
"id": "f290e440-dd5b-46f9-a23b-be419443685b",
"name": "quantity",
"type": "string",
"value": "={{ $json.Hours }}"
},
{
"id": "09688f5f-0461-4c04-988a-2b92da3e595e",
"name": "unitPrice",
"type": "string",
"value": "={{ $json['Custom Hourly Rate'] || $json['Default Hourly Rate'][0]}}"
},
{
"id": "bcdadef7-0f5b-48a3-851b-f7fe5f401fa7",
"name": "invoiceId",
"type": "string",
"value": "={{ $json.ID }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "0a5e9db0-410f-4b5c-99cf-a616107942a5",
"name": "Send Email With Attachment",
"type": "n8n-nodes-base.emailSend",
"position": [
1904,
0
],
"parameters": {
"text": "Hello,\n\nPlease find attached your invoice for the last month. Thank you very much for your cooperation.\n\nBest regards,\nHenrik",
"options": {
"attachments": "data"
},
"subject": "Your Invoice for Last Month",
"toEmail": "user@example.com",
"fromEmail": "={{ $json.InvoiceEmail }}",
"emailFormat": "text"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "cc9d1907-9d69-4f72-b3a0-76ce416e75e8",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
-96
],
"parameters": {
"color": 3,
"width": 288,
"height": 560,
"content": "## Run this workflow manually\n"
},
"typeVersion": 1
},
{
"id": "ec0d2733-966b-49ff-ab2f-5a944882e916",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
288,
0
],
"parameters": {
"width": 720,
"height": 448,
"content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n## Loop Over Items\nSince the number of invoice items does not match the number of invoices, we have to retrieve them in a loop and aggregate them so that they match the number of invoices."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "4c90ec99-f624-4f7f-a4be-ccd8653cdb04",
"connections": {
"Aggregate": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Map Fields": {
"main": [
[
{
"node": "Aggregate",
"type": "main",
"index": 0
}
]
]
},
"Get Clients": {
"main": [
[
{
"node": "Set Company Details",
"type": "main",
"index": 0
}
]
]
},
"Loop Over Items": {
"main": [
[
{
"node": "Get Clients",
"type": "main",
"index": 0
}
],
[
{
"node": "Get Invoice Items",
"type": "main",
"index": 0
}
]
]
},
"Generate Invoice": {
"main": [
[
{
"node": "Send Email With Attachment",
"type": "main",
"index": 0
}
]
]
},
"Get Invoice Items": {
"main": [
[
{
"node": "Map Fields",
"type": "main",
"index": 0
}
]
]
},
"Get Ready Invoices": {
"main": [
[
{
"node": "Loop Over Items",
"type": "main",
"index": 0
}
]
]
},
"Set Company Details": {
"main": [
[
{
"node": "Generate Invoice",
"type": "main",
"index": 0
}
]
]
},
"Send Email With Attachment": {
"main": [
[
{
"node": "Update record",
"type": "main",
"index": 0
}
]
]
},
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "Get Ready Invoices",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
airtableTokenApicustomJsApismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
> ⚠️ Notice: > This workflow uses the CustomJS Invoice Generator node from customjs.space, which requires a self-hosted n8n instance and a CustomJS API key.
Source: https://n8n.io/workflows/9772/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This template is perfect for Gumroad creators, solopreneurs, digital product sellers, and freelancers who want to track and thank customers automatically — without spending time on manual work.
This template is ideal for solo store owners, eCommerce marketers, automation beginners, or anyone using Shopify and Gmail who wants to recover lost revenue without coding.
Supercharge your insurance agency's efficiency with this powerful automation template for n8n. Designed specifically for commercial insurance brokers and agents, this workflow transforms the tedious p
This guide will walk you through setting up your n8n workflow. By the end, you'll have a fully automated system for managing your recruitment pipeline.
This n8n workflow lets you control access to your internal Telegram bots and automation systems based on user roles and departments. It ensures that only authorized team members — defined in your empl