{
  "id": "JdcsYaqlahWsuf6F7LlVU",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Automated invoice data extraction & tracking workflow",
  "tags": [],
  "nodes": [
    {
      "id": "ebb51c1f-8b91-4165-8a14-ff6be7890cb4",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        240,
        1296
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4.1-mini"
        },
        "options": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "2d47510f-724e-462c-94ff-87e86e6daaa4",
      "name": "Structured Output Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        -32,
        1280
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"invoiceNumber\": \"INV-123\",\n  \"from\": \"John Street 23, 12443 Berlin, Germany\",\n  \"to\": \"Smith Street 33, 23222 Berlin, Germany\",\n  \"invoiceDate\": \"2025-08-20\",\n  \"dueDate\": \"2025-08-25\",\n  \"description\": \"Invoice for web development services\",\n  \"amount\": {\n    \"value\": 500,\n    \"currency\": \"USD\"\n  }\n}\n\n"
      },
      "typeVersion": 1.3
    },
    {
      "id": "0a369168-d88e-4097-978e-e25005b0eced",
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -1328,
        1184
      ],
      "parameters": {
        "simple": false,
        "filters": {
          "q": "has:attachment"
        },
        "options": {
          "downloadAttachments": true
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.3
    },
    {
      "id": "717865e0-8312-4fe5-8eb8-6cc1f371e28e",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -1168,
        1184
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3abead72-5035-4211-9852-b591659cf4fd",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $binary ? true : false }}",
              "rightValue": true
            },
            {
              "id": "10738653-34ad-48fe-aa09-cccc3f6f7502",
              "operator": {
                "type": "string",
                "operation": "contains"
              },
              "leftValue": "={{ $json.subject.toLowerCase() }}",
              "rightValue": "invoice"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "60336b22-1df3-4307-a588-a6dc0f7e9682",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -880,
        1328
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "b2d37a06-ae4e-4abc-a403-c479cd06e962",
      "name": "host image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -928,
        1056
      ],
      "parameters": {
        "url": "https://api.imgbb.com/1/upload",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "image",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "attachment_0"
            }
          ]
        },
        "genericAuthType": "httpQueryAuth"
      },
      "credentials": {
        "httpQueryAuth": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 4.2
    },
    {
      "id": "89604f3d-e966-4318-ac4e-29ba608db729",
      "name": "Extract text",
      "type": "n8n-nodes-base.mistralAi",
      "position": [
        -160,
        976
      ],
      "parameters": {
        "options": {},
        "documentType": "image_url"
      },
      "credentials": {
        "mistralCloudApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1
    },
    {
      "id": "797fa0a5-dbd3-4d7e-ab8b-c97932422309",
      "name": "Download Invoice",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -320,
        976
      ],
      "parameters": {
        "url": "={{ $('host image').item.json.data.image.url }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 4.4
    },
    {
      "id": "8c9c6db3-6f30-458e-936c-e6adcacc6ebf",
      "name": "Analyze Invoices",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        16,
        976
      ],
      "parameters": {
        "text": "=You are an expert in analyzing invoices.\n\nHere is an invoice that you should analyze: {{ $json.pages[0].markdown }}",
        "options": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "retryOnFail": true,
      "typeVersion": 2.2
    },
    {
      "id": "355b5cfc-f6cb-4781-8f4c-0f1c47cb5d18",
      "name": "Search Existing Invoices",
      "type": "n8n-nodes-base.airtable",
      "position": [
        -688,
        1056
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appU9XzFqL5Aovj2M",
          "cachedResultUrl": "https://airtable.com/appU9XzFqL5Aovj2M",
          "cachedResultName": "Invoices from Gmail"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblQ9c8ReMH8zfafc",
          "cachedResultUrl": "https://airtable.com/appU9XzFqL5Aovj2M/tblQ9c8ReMH8zfafc",
          "cachedResultName": "Invoice details"
        },
        "options": {},
        "operation": "search",
        "filterByFormula": "={Invoice Number} = \"#{{ $json.data.image.name }}\""
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "1fc26efe-06ae-4cb9-b4ca-153b718c9f12",
      "name": "Check for Duplicates",
      "type": "n8n-nodes-base.switch",
      "position": [
        -512,
        1056
      ],
      "parameters": {
        "mode": "expression",
        "output": "={{ $items(\"Search Existing Invoices\")[0].json.id ? 1 : 0 }}",
        "numberOutputs": 2
      },
      "typeVersion": 3,
      "alwaysOutputData": false
    },
    {
      "id": "c496f51b-943e-41b9-ba27-7a96aa22e695",
      "name": "Validate Data",
      "type": "n8n-nodes-base.if",
      "position": [
        304,
        976
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond1",
              "operator": {
                "type": "string",
                "operation": "notEmpty",
                "singleValue": true
              },
              "leftValue": "={{ $json.output.invoiceNumber }}",
              "rightValue": ""
            },
            {
              "id": "cond2",
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ $json.output.amount.value }}",
              "rightValue": 0
            },
            {
              "id": "cond3",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.output.invoiceDate }}",
              "rightValue": ""
            },
            {
              "id": "cond4",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.output.from }}",
              "rightValue": ""
            },
            {
              "id": "cond5",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.output.to }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "957fca86-bb26-4682-922b-bd4abcc566dd",
      "name": "Invalid Data Handler",
      "type": "n8n-nodes-base.set",
      "position": [
        560,
        1104
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "assign1",
              "name": "error",
              "type": "string",
              "value": "Data validation failed"
            },
            {
              "id": "assign2",
              "name": "step",
              "type": "string",
              "value": "Validate Data"
            },
            {
              "id": "assign3",
              "name": "invoiceSubject",
              "type": "string",
              "value": "={{ $('Gmail Trigger').item.json.subject }}"
            },
            {
              "id": "assign4",
              "name": "timestamp",
              "type": "string",
              "value": "={{ $now }}"
            },
            {
              "id": "assign5",
              "name": "extractedData",
              "type": "string",
              "value": "={{ JSON.stringify($('Analyze Invoices').item.json.output) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "df661869-6506-469b-bb65-4a3adbf379dc",
      "name": "Send Error Email",
      "type": "n8n-nodes-base.gmail",
      "position": [
        784,
        1104
      ],
      "parameters": {
        "sendTo": "user@example.com",
        "message": "=An error occurred while processing an invoice.\n\n\ud83d\udccb Details:\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\ud83d\udd34 Error Type: {{ $json.error }}\n\ud83d\udcdd Failed Step: {{ $json.step }}\n\ud83d\udce7 Invoice Subject: {{ $json.invoiceSubject || 'N/A' }}\n\ud83d\udcca Invoice Number: {{ $json.invoiceNumber || 'N/A' }}\n\u23f0 Timestamp: {{ $json.timestamp }}\n\n\ud83d\udcac Error Message:\n{{ $json.errorMessage }}\n\n\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\n\n\u2699\ufe0f Action Required:\nPlease review the workflow execution in n8n.\n\n\ud83d\udd0d Additional Data:\n{{ $json.extractedData || $json.extractedText || 'No additional data' }}",
        "options": {},
        "subject": "=\u26a0\ufe0f Invoice Processing Error - {{ $json.step }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.1
    },
    {
      "id": "3095cb76-1aca-441a-8157-21a65e785826",
      "name": "No Operation, do nothing1",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -304,
        1280
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "5653a1bb-cec9-4099-8d7d-8aa15a1cb760",
      "name": "upload invoice & details",
      "type": "n8n-nodes-base.airtable",
      "position": [
        560,
        848
      ],
      "parameters": {
        "base": {
          "__rl": true,
          "mode": "list",
          "value": "appU9XzFqL5Aovj2M",
          "cachedResultUrl": "https://airtable.com/appU9XzFqL5Aovj2M",
          "cachedResultName": "Invoices from Gmail"
        },
        "table": {
          "__rl": true,
          "mode": "list",
          "value": "tblQ9c8ReMH8zfafc",
          "cachedResultUrl": "https://airtable.com/appU9XzFqL5Aovj2M/tblQ9c8ReMH8zfafc",
          "cachedResultName": "Invoice details"
        },
        "columns": {
          "value": {
            "To": "={{ $json.output.to }}",
            "From": "={{ $json.output.from }}",
            "Due Date": "={{ $json.output.dueDate }}",
            "Client Name": "={{ $('Gmail Trigger').item.json.to.value[0].name }}",
            "Amount (USD)": "={{ $json.output.amount.value }}{{ $json.output.amount.currency }}",
            "Invoice Date": "={{ $json.output.invoiceDate }}",
            "Invoice Number": "={{ $json.output.invoiceNumber }}",
            "Link to Invoice": "={{ [ { url: $('host image').item.json.data.image.url } ] }}",
            "Short Discription": "={{ $json.output.description }}",
            "Client Email Address": "={{ $('Gmail Trigger').item.json.to.value[0].address }}"
          },
          "schema": [
            {
              "id": "Invoice Number",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Invoice Number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "From",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "From",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "To",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "To",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Invoice Date",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Invoice Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Due Date",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Due Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Name",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Client Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Client Email Address",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Client Email Address",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Amount (USD)",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Amount (USD)",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Short Discription",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Short Discription",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Link to Invoice",
              "type": "array",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "Link to Invoice",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "create"
      },
      "credentials": {
        "airtableTokenApi": {
          "name": "<your credential>"
        }
      },
      "retryOnFail": true,
      "typeVersion": 2.1
    },
    {
      "id": "a4da130a-6c16-47e5-8b66-761720921697",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2336,
        688
      ],
      "parameters": {
        "width": 832,
        "height": 1216,
        "content": "# \ud83d\udee0\ufe0f Setup Guide\n\n**Author:** [Safa Khan]()\n\nFollow the steps below to get this workflow up and running:\n\n### \u2705 Step 1: Choose Your Trigger\n\nDetermine what will kick off this workflow. In this example, we\u2019re using Gmail as the trigger node to watch for incoming emails with invoice attachments.\n\n### \u2705 Step 2: Connect Gmail Credentials\n\nMake sure your Gmail OAuth credentials are connected and attachment downloading is enabled in the trigger node settings.\n\n### \u2705 Step 3: Connect Airtable\n\nConnect your Airtable credentials and confirm your invoice database is ready.\n\nAirtable base link: https://airtable.com/appU9XzFqL5Aovj2M/shrnanmtZpUgbVsEo\n\n### \u2705 Step 4: Add Image Hosting API\n\n#### https://api.imgbb.com/\n\nConnect your imgbb API key in the HTTP Request node.\nThis step uploads invoice attachments and generates a public image URL required for OCR processing.\n\n### \u2705 Step 5: Connect OCR + AI Model\n\n#### https://admin.mistral.ai/organization/api-keys\n\nConnect your AI services to power the extraction and structuring steps:\n\nOCR provider (for text extraction)\n\nAI model (for structured invoice data)\n\nThese nodes convert invoice images into usable invoice records automatically.\n\n### \ud83d\udca1 Final Step: Test It Out\n\nSend a test email with an invoice attachment and verify:\n\nAttachment uploads correctly\n\nOCR extracts text\n\nAI structures invoice data\n\nAirtable record is created\n\nDuplicate invoices are prevented\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7080e6a2-30ca-41de-90db-729b79e08927",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1424,
        1040
      ],
      "parameters": {
        "color": 7,
        "width": 224,
        "height": 304,
        "content": "## Trigger"
      },
      "typeVersion": 1
    },
    {
      "id": "4ef686e8-345e-435a-bff4-5e78dba62bb9",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        1040
      ],
      "parameters": {
        "color": 7,
        "width": 176,
        "height": 304,
        "content": "## Filter Logic"
      },
      "typeVersion": 1
    },
    {
      "id": "27f96b32-fcc6-40a4-997f-e84a0a23864b",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        944
      ],
      "parameters": {
        "color": 7,
        "width": 208,
        "height": 288,
        "content": "## Image hosting"
      },
      "typeVersion": 1
    },
    {
      "id": "4c22a7c8-0d30-4099-9bcf-ca1e43a184f5",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -768,
        944
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 288,
        "content": "## Duplicate Protection"
      },
      "typeVersion": 1
    },
    {
      "id": "a4010d10-4e09-48f0-b22e-852ee668b570",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -368,
        880
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 256,
        "content": "## OCR Extraction"
      },
      "typeVersion": 1
    },
    {
      "id": "d5eab68a-eb4e-408a-b954-98f018749fc4",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        864
      ],
      "parameters": {
        "color": 7,
        "width": 272,
        "height": 272,
        "content": "## AI Data Structuring"
      },
      "typeVersion": 1
    },
    {
      "id": "8ada1b6e-e2a0-4b2c-869a-3194dcdcf955",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        752
      ],
      "parameters": {
        "color": 7,
        "width": 256,
        "height": 256,
        "content": "## Store Invoice"
      },
      "typeVersion": 1
    },
    {
      "id": "b7a2bc04-1fb2-44e9-9ce5-2d8dfead6d33",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        480,
        1024
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 224,
        "content": "## Error Handling"
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "2150715c-4b96-4bcc-a0a4-c6e1757146ac",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "host image",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "host image": {
      "main": [
        [
          {
            "node": "Search Existing Invoices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract text": {
      "main": [
        [
          {
            "node": "Analyze Invoices",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail Trigger": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Data": {
      "main": [
        [
          {
            "node": "upload invoice & details",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Invalid Data Handler",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze Invoices": {
      "main": [
        [
          {
            "node": "Validate Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Invoice": {
      "main": [
        [
          {
            "node": "Extract text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Analyze Invoices",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Check for Duplicates": {
      "main": [
        [
          {
            "node": "Download Invoice",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Invalid Data Handler": {
      "main": [
        [
          {
            "node": "Send Error Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search Existing Invoices": {
      "main": [
        [
          {
            "node": "Check for Duplicates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Structured Output Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Analyze Invoices",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    }
  }
}