This workflow corresponds to n8n.io template #14269 — we link there as the canonical source.
This workflow follows the Agent → Datatable recipe pattern — see all workflows that pair these two integrations.
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 →
{
"nodes": [
{
"id": "2befd473-43b7-42bb-9fcd-925e35c58044",
"name": "Invoice Upload Form",
"type": "n8n-nodes-base.formTrigger",
"position": [
-1824,
96
],
"parameters": {
"options": {
"appendAttribution": false,
"respondWithOptions": {
"values": {
"formSubmittedText": "Thank you! Your invoice is being processed. You will receive an email confirmation shortly."
}
}
},
"formTitle": "Invoice Upload - AI Processing System",
"formFields": {
"values": [
{
"fieldType": "email",
"fieldLabel": "Your Email Address",
"requiredField": true
},
{
"fieldType": "file",
"fieldLabel": "Invoice File (PDF or Image)",
"multipleFiles": false,
"requiredField": true,
"acceptFileTypes": ".pdf, .jpg, .jpeg, .png"
}
]
},
"formDescription": "Upload your invoice (PDF or image) for automated processing and validation"
},
"typeVersion": 2.3
},
{
"id": "82dca76f-328a-40c2-8139-ec6affe6e513",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
-1552,
96
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "reportRecipientEmail",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Email address for weekly reports__>"
},
{
"id": "id-2",
"name": "validCurrencies",
"type": "string",
"value": "USD,EUR,GBP,CAD,AUD,JPY,CHF"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "8c6c66cc-ffa8-4184-bfad-ec96682e18e7",
"name": "Store Raw Form Submission",
"type": "n8n-nodes-base.dataTable",
"position": [
-1328,
96
],
"parameters": {
"columns": {
"value": {},
"mappingMode": "autoMapInputData"
},
"options": {},
"dataTableId": {
"__rl": true,
"mode": "id",
"value": "invoice_form_submissions"
}
},
"typeVersion": 1
},
{
"id": "4dec86d9-c3bd-4384-b8a2-0785d7bb8f91",
"name": "Extract Invoice Content",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-1024,
96
],
"parameters": {
"options": {},
"operation": "pdf",
"binaryPropertyName": "invoiceFile"
},
"typeVersion": 1.1
},
{
"id": "3fc45009-48db-4fce-9de3-c125f3222621",
"name": "Extract Invoice Data with AI",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-800,
96
],
"parameters": {
"text": "={{ $json.text }}",
"options": {
"systemMessage": "You are an expert invoice data extraction assistant. Extract all relevant information from the provided invoice text and return it in the structured format.\n\nExtract the following fields:\n- Invoice number\n- Invoice date (format as YYYY-MM-DD)\n- Vendor/supplier name\n- Currency (3-letter ISO code like USD, EUR, GBP)\n- Total amount (numeric value only)\n- Subtotal (numeric value only)\n- Tax amount (numeric value only)\n- Line items with description, quantity, unit price, and amount\n\nBe precise with numbers and dates. If a field is not found, use null."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "03f1a3b9-fedc-4c5f-9812-97129e98269f",
"name": "Invoice Data Schema Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-592,
320
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n \"type\": \"object\",\n \"properties\": {\n \"invoiceNumber\": {\n \"type\": \"string\",\n \"description\": \"The invoice number\"\n },\n \"invoiceDate\": {\n \"type\": \"string\",\n \"description\": \"The invoice date in YYYY-MM-DD format\"\n },\n \"vendorName\": {\n \"type\": \"string\",\n \"description\": \"The name of the vendor\"\n },\n \"currency\": {\n \"type\": \"string\",\n \"description\": \"3-letter currency code (e.g., USD, EUR, GBP)\"\n },\n \"totalAmount\": {\n \"type\": \"number\",\n \"description\": \"The total amount of the invoice\"\n },\n \"lineItems\": {\n \"type\": \"array\",\n \"description\": \"Array of line items in the invoice\",\n \"items\": {\n \"type\": \"object\",\n \"properties\": {\n \"description\": {\n \"type\": \"string\",\n \"description\": \"Description of the line item\"\n },\n \"quantity\": {\n \"type\": \"number\",\n \"description\": \"Quantity of the item\"\n },\n \"unitPrice\": {\n \"type\": \"number\",\n \"description\": \"Unit price of the item\"\n },\n \"amount\": {\n \"type\": \"number\",\n \"description\": \"Total amount for the line item\"\n }\n }\n }\n },\n \"taxAmount\": {\n \"type\": \"number\",\n \"description\": \"The tax amount\"\n },\n \"subtotal\": {\n \"type\": \"number\",\n \"description\": \"The subtotal before tax\"\n }\n }\n}"
},
"typeVersion": 1.3
},
{
"id": "1c5937a1-63a7-4d9f-8dd0-8b1796d9cf4e",
"name": "Validate Invoice Data",
"type": "n8n-nodes-base.code",
"position": [
-416,
96
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Validate invoice data\nconst invoiceData = $input.item.json;\n\n// Initialize validation result\nconst validationResult = {\n isValid: true,\n errors: []\n};\n\n// Get valid currencies from Workflow Configuration node\nconst validCurrencies = $('Workflow Configuration').item.json.validCurrencies || ['USD', 'EUR', 'GBP'];\n\n// Validate date format (YYYY-MM-DD)\nconst dateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\nif (!invoiceData.date || !dateRegex.test(invoiceData.date)) {\n validationResult.isValid = false;\n validationResult.errors.push('Invalid date format. Expected YYYY-MM-DD');\n}\n\n// Validate currency is in valid list\nif (!invoiceData.currency || !validCurrencies.includes(invoiceData.currency)) {\n validationResult.isValid = false;\n validationResult.errors.push(`Invalid currency. Must be one of: ${validCurrencies.join(', ')}`);\n}\n\n// Validate total amount is greater than zero\nconst totalAmount = parseFloat(invoiceData.totalAmount);\nif (isNaN(totalAmount) || totalAmount <= 0) {\n validationResult.isValid = false;\n validationResult.errors.push('Total amount must be greater than zero');\n}\n\n// Return the validation result along with original invoice data\nreturn {\n ...invoiceData,\n validation: validationResult\n};"
},
"typeVersion": 2
},
{
"id": "d4ace010-b345-493d-b3db-ecfbb3a115a4",
"name": "Check Validation Result",
"type": "n8n-nodes-base.if",
"position": [
-240,
96
],
"parameters": {
"options": {},
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "id-1",
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $('Validate Invoice Data').item.json.isValid }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.3
},
{
"id": "ae5a40be-3e93-4dc8-b969-965d134278c8",
"name": "Prepare Success Email Data",
"type": "n8n-nodes-base.set",
"position": [
16,
-48
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "emailSubject",
"type": "string",
"value": "Invoice Processed Successfully"
},
{
"id": "id-2",
"name": "emailBody",
"type": "string",
"value": "=<html>\n<body>\n<h2>Invoice Processed Successfully</h2>\n<p>Your invoice has been successfully processed and validated.</p>\n<h3>Invoice Details:</h3>\n<ul>\n<li><strong>Invoice Number:</strong> {{ $json.invoiceNumber }}</li>\n<li><strong>Vendor:</strong> {{ $json.vendorName }}</li>\n<li><strong>Date:</strong> {{ $json.invoiceDate }}</li>\n<li><strong>Total Amount:</strong> ${{ $json.totalAmount }}</li>\n</ul>\n<p>The invoice has been stored in the system and is ready for further processing.</p>\n</body>\n</html>"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "f5cd3484-3d2a-4034-aef6-085ab713559f",
"name": "Store Validated Invoice",
"type": "n8n-nodes-base.dataTable",
"position": [
224,
-48
],
"parameters": {
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"dataTableId": {
"__rl": true,
"mode": "name",
"value": "validated_invoices"
}
},
"typeVersion": 1
},
{
"id": "f67acac8-a840-4148-8b5b-6bd9c8e36e0d",
"name": "Send Success Email",
"type": "n8n-nodes-base.gmail",
"position": [
400,
-48
],
"parameters": {
"sendTo": "={{ $('Workflow Configuration').first().json.userEmail }}",
"message": "={{ $json.emailBody }}",
"options": {},
"subject": "={{ $json.emailSubject }}"
},
"typeVersion": 2.2
},
{
"id": "21d45666-aa82-4d19-9833-2c1751b8d6ec",
"name": "Prepare Error Email Data",
"type": "n8n-nodes-base.set",
"position": [
32,
448
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "emailSubject",
"type": "string",
"value": "Invoice Validation Failed"
},
{
"id": "id-2",
"name": "emailBody",
"type": "string",
"value": "=<html>\n<body>\n<h2>Invoice Validation Failed</h2>\n<p>The uploaded invoice could not be processed due to the following validation errors:</p>\n<div style=\"background-color: #f8d7da; border: 1px solid #f5c6cb; padding: 15px; border-radius: 5px; margin: 10px 0;\">\n<strong>Validation Errors:</strong>\n<ul>\n{{ $json.validationErrors ? $json.validationErrors.map(error => '<li>' + error + '</li>').join('') : '<li>Unknown validation error</li>' }}\n</ul>\n</div>\n<p><strong>Invoice Details:</strong></p>\n<ul>\n<li>Submission Time: {{ $json.submissionTime || 'N/A' }}</li>\n<li>File Name: {{ $json.fileName || 'N/A' }}</li>\n</ul>\n<p>Please review the invoice and resubmit with the correct information.</p>\n</body>\n</html>"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "825ad618-79fe-4941-8666-b266935c0f18",
"name": "Send Error Email",
"type": "n8n-nodes-base.gmail",
"position": [
304,
448
],
"parameters": {
"sendTo": "={{ $('Workflow Configuration').first().json.userEmail }}",
"message": "={{ $json.emailBody }}",
"options": {},
"subject": "={{ $json.emailSubject }}"
},
"typeVersion": 2.2
},
{
"id": "062eb808-d9ff-4e9f-b507-aa58246c8ce7",
"name": "Weekly Report Schedule",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-1856,
848
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
},
"typeVersion": 1.3
},
{
"id": "d2197dc0-6ffd-45f7-83b5-1a15c68f80fe",
"name": "Fetch Weekly Invoices",
"type": "n8n-nodes-base.dataTable",
"position": [
-1648,
848
],
"parameters": {
"operation": "get",
"returnAll": true,
"dataTableId": {
"__rl": true,
"mode": "id",
"value": "validated_invoices"
}
},
"typeVersion": 1
},
{
"id": "d3cc2957-8e93-459e-ae15-a537a72fcb65",
"name": "Generate Weekly Report",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-1312,
848
],
"parameters": {
"text": "={{ JSON.stringify($input.all()) }}",
"options": {
"systemMessage": "You are a financial reporting assistant. Generate a comprehensive weekly spending report based on the provided invoice data.\n\nYour report should include:\n1. Executive Summary: Total spending for the week, number of invoices processed\n2. Spending by Vendor: Break down spending by vendor name\n3. Spending by Currency: Show totals in each currency\n4. Top 5 Largest Invoices: List the highest value invoices with details\n5. Trends and Insights: Any notable patterns or observations\n\nFormat the report in clean HTML with proper headings, tables, and styling. Make it professional and easy to read."
},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "5a124c06-ecb7-44b1-ad1b-47b65913fb52",
"name": "Send Weekly Report Email",
"type": "n8n-nodes-base.gmail",
"position": [
-880,
848
],
"parameters": {
"sendTo": "={{ $('Weekly Report Schedule').first().json.reportRecipientEmail || \"<__PLACEHOLDER_VALUE__Weekly report recipient email__>\" }}",
"message": "={{ $json.output }}",
"options": {},
"subject": "=Weekly Invoice Processing Report - {{ $now.format(\"MMMM DD, YYYY\") }}"
},
"typeVersion": 2.2
},
{
"id": "84897497-8775-4bbd-9472-ab7803562fb2",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2736,
64
],
"parameters": {
"width": 544,
"height": 560,
"content": "## How it works\nThis workflow helps you automatically process invoices using AI.\n\nA user uploads an invoice file (PDF or image) through a form. The file is read and the text is extracted. Then AI pulls out important details like invoice number, vendor name, date, currency, and total amount.\n\nAfter that, the data is checked to make sure it looks correct. For example, it verifies the date format, allowed currencies, and that the total amount is valid.\n\nIf everything is correct, the invoice is saved and a confirmation email is sent to the user. If something is wrong, the user receives an email with the issues so they can fix and resend the invoice.\n\nThe workflow also runs weekly. It collects all processed invoices and creates a simple summary report using AI, which is sent by email.\n\n## Setup steps\n1. Add your OpenAI credentials\n2. Connect Gmail for sending emails\n3. Set up Data Tables for storing invoices\n4. Add your report email in the config node\n5. Test with a sample invoice\n6. Turn on the workflow"
},
"typeVersion": 1
},
{
"id": "ceda8874-d6f4-43c6-9a38-e502b493ff86",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1920,
0
],
"parameters": {
"color": 7,
"width": 272,
"height": 304,
"content": "## Form Input\nCollects user email and invoice file via form trigger."
},
"typeVersion": 1
},
{
"id": "9c41db39-f23f-464e-a515-bbeb1165b2ca",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1616,
-64
],
"parameters": {
"color": 7,
"width": 448,
"height": 352,
"content": "## Configuration and Submission Storage\nDefines report email and valid currencies used in validation. and \nStores raw form data for tracking and auditing purposes."
},
"typeVersion": 1
},
{
"id": "30b7e206-f747-46a4-a457-e1caa6d45d09",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1120,
-64
],
"parameters": {
"color": 7,
"width": 256,
"height": 352,
"content": "## File Extraction\nExtracts text content from uploaded invoice files."
},
"typeVersion": 1
},
{
"id": "6ec8389d-16e9-47e2-a970-b0d31b1649c4",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-816,
-64
],
"parameters": {
"color": 7,
"width": 352,
"height": 352,
"content": "## AI Processing\nAI converts extracted text into structured invoice data."
},
"typeVersion": 1
},
{
"id": "92d876b3-73b7-4444-a5e6-ccb6f66a76cf",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-448,
-48
],
"parameters": {
"color": 7,
"width": 336,
"height": 320,
"content": "## Validation\nChecks date format, currency, and total amount accuracy."
},
"typeVersion": 1
},
{
"id": "f0fd8081-f55c-499e-b20e-d425cf108499",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-48,
-144
],
"parameters": {
"color": 7,
"width": 592,
"height": 288,
"content": "## Success Path\nStores valid invoices and sends confirmation email."
},
"typeVersion": 1
},
{
"id": "ee0715f0-74ee-4d2d-87ec-53f5c1650662",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-32,
336
],
"parameters": {
"color": 7,
"width": 544,
"height": 320,
"content": "## Error Path\nSends email with validation errors for correction."
},
"typeVersion": 1
},
{
"id": "a7d71fc5-cb30-4a94-b8c4-d658b006f750",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1952,
704
],
"parameters": {
"color": 7,
"width": 480,
"height": 320,
"content": "## Weekly Trigger\nRuns weekly to process stored invoices for reporting."
},
"typeVersion": 1
},
{
"id": "9c113796-c4a5-4844-85a2-1bc58c6cb015",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1344,
704
],
"parameters": {
"color": 7,
"width": 320,
"height": 320,
"content": "## Report Generation\nAI generates a formatted weekly invoice summary report."
},
"typeVersion": 1
},
{
"id": "5395f5e9-3ad2-4fff-a989-93e6593dea29",
"name": "Sticky Note10",
"type": "n8n-nodes-base.stickyNote",
"position": [
-992,
704
],
"parameters": {
"color": 7,
"width": 320,
"height": 320,
"content": "## Report Email\nSends weekly report to configured recipient."
},
"typeVersion": 1
},
{
"id": "e9f97f4b-4f7d-4e0c-9f84-b2c091f5705b",
"name": "OpenAI GPT-5-mini Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-784,
320
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "gpt-5-mini"
},
"options": {},
"builtInTools": {}
},
"typeVersion": 1.3
},
{
"id": "88e5d798-a530-46ae-ac1c-2bbc331421f1",
"name": "OpenAI GPT-5-mini Model for Reports",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
-1232,
1072
],
"parameters": {
"model": {
"__rl": true,
"mode": "id",
"value": "gpt-5-mini"
},
"options": {},
"builtInTools": {}
},
"typeVersion": 1.3
}
],
"connections": {
"Invoice Upload Form": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"Fetch Weekly Invoices": {
"main": [
[
{
"node": "Generate Weekly Report",
"type": "main",
"index": 0
}
]
]
},
"Validate Invoice Data": {
"main": [
[
{
"node": "Check Validation Result",
"type": "main",
"index": 0
}
]
]
},
"Generate Weekly Report": {
"main": [
[
{
"node": "Send Weekly Report Email",
"type": "main",
"index": 0
}
]
]
},
"Weekly Report Schedule": {
"main": [
[
{
"node": "Fetch Weekly Invoices",
"type": "main",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "Store Raw Form Submission",
"type": "main",
"index": 0
}
]
]
},
"Check Validation Result": {
"main": [
[
{
"node": "Prepare Success Email Data",
"type": "main",
"index": 0
}
],
[
{
"node": "Prepare Error Email Data",
"type": "main",
"index": 0
}
]
]
},
"Extract Invoice Content": {
"main": [
[
{
"node": "Extract Invoice Data with AI",
"type": "main",
"index": 0
}
]
]
},
"OpenAI GPT-5-mini Model": {
"ai_languageModel": [
[
{
"node": "Extract Invoice Data with AI",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Store Validated Invoice": {
"main": [
[
{
"node": "Send Success Email",
"type": "main",
"index": 0
}
]
]
},
"Prepare Error Email Data": {
"main": [
[
{
"node": "Send Error Email",
"type": "main",
"index": 0
}
]
]
},
"Store Raw Form Submission": {
"main": [
[
{
"node": "Extract Invoice Content",
"type": "main",
"index": 0
}
]
]
},
"Invoice Data Schema Parser": {
"ai_outputParser": [
[
{
"node": "Extract Invoice Data with AI",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Prepare Success Email Data": {
"main": [
[
{
"node": "Store Validated Invoice",
"type": "main",
"index": 0
}
]
]
},
"Extract Invoice Data with AI": {
"main": [
[
{
"node": "Validate Invoice Data",
"type": "main",
"index": 0
}
]
]
},
"OpenAI GPT-5-mini Model for Reports": {
"ai_languageModel": [
[
{
"node": "Generate Weekly Report",
"type": "ai_languageModel",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates invoice handling from upload to reporting using AI.
Source: https://n8n.io/workflows/14269/ — 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 workflow automates end-to-end contract and invoice management using AI intelligence. It processes proposals through intelligent contract generation, approval workflows, and automated invoicing. O
Automates SaaS operations by consolidating user management, AI-driven support triage, analytics, and billing into one unified system. User signups flow through registration, support requests route via
This workflow automates legal policy governance for legal teams, policy managers, and compliance officers, eliminating manual document review, approval classification, and multi-channel stakeholder di
Submit a LinkedIn profile URL through a form. The workflow finds their email and company info using Wiza, then researches the prospect and their company with Perplexity AI to uncover recent news, grow
This workflow serves as a comprehensive "Workflow Nodes SEO & Documentation Generator". It uses AI to analyze, rename, and document n8n workflows, offering a streamlined way to optimize workflow reada