{
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "name": "AI Invoice & Receipt Extractor: email PDF \u2192 structured data \u2192 bookkeeping sheet + approval",
  "tags": [],
  "nodes": [
    {
      "id": "c3d4e5f6-0001-4a10-9a01-cc3333330001",
      "name": "Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1280,
        40
      ],
      "parameters": {
        "width": 540,
        "height": 760,
        "content": "## \ud83d\udcc4 AI Invoice & Receipt Extractor\n\n**Who it's for:** Small businesses, bookkeepers, finance & ops teams that get invoices and receipts by email and re-type them into a spreadsheet by hand.\n\n**What it does:** When an email with a PDF attachment arrives, it reads the document, an AI extracts the key fields (vendor, invoice number, dates, totals, tax, category), appends a clean row to your bookkeeping sheet, and sends high-value invoices to an approver in Slack.\n\n### How it works\n1. **New Invoice Email** triggers on inbound mail with attachments.\n2. **Extract Text from PDF** reads the attached document.\n3. **Extract Invoice Fields** returns `{ vendor_name, invoice_number, invoice_date, due_date, currency, subtotal, tax_amount, total_amount, category, summary }`.\n4. **Log to Bookkeeping Sheet** appends the row.\n5. **High-Value?** routes invoices over your threshold to **Send for Approval** in Slack.\n\n### Setup (~10 min)\n- Connect **Gmail**, **OpenAI**, **Google Sheets** & **Slack** credentials.\n- In **New Invoice Email**, adjust the search filter (e.g. a label or sender).\n- Set the approval threshold in **High-Value?** and pick your Slack channel.\n- Activate."
      },
      "typeVersion": 1
    },
    {
      "id": "c3d4e5f6-0002-4a10-9a01-cc3333330002",
      "name": "Warning",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1280,
        820
      ],
      "parameters": {
        "color": 3,
        "width": 540,
        "height": 220,
        "content": "## \u26a0\ufe0f Before you run\n- This template reads the **first PDF attachment** (`attachment_0`). For multi-file emails, add a loop / adjust the binary property.\n- Scanned image-only PDFs need OCR \u2014 swap **Extract Text from PDF** for an OCR / OpenAI vision step.\n- Always keep a human approval step for payments \u2014 the AI extracts, it does **not** pay.\n- Use a cheap model (e.g. `gpt-4o-mini`). This template ships **without credentials** \u2014 connect your own Gmail, OpenAI, Google Sheets & Slack accounts."
      },
      "typeVersion": 1
    },
    {
      "id": "c3d4e5f6-0003-4a10-9a01-cc3333330003",
      "name": "Section: Capture",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -680,
        -20
      ],
      "parameters": {
        "color": 4,
        "width": 620,
        "height": 600,
        "content": "## 1 \u00b7 Capture the document\nTrigger on incoming email with an attachment and pull the text out of the PDF.\n**Tune the email filter in \"New Invoice Email\".**"
      },
      "typeVersion": 1
    },
    {
      "id": "c3d4e5f6-0004-4a10-9a01-cc3333330004",
      "name": "Section: Extract",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -40,
        -20
      ],
      "parameters": {
        "color": 5,
        "width": 360,
        "height": 600,
        "content": "## 2 \u00b7 Extract fields with AI\nTurn the raw invoice text into clean, structured data: vendor, invoice number, dates, currency, subtotal, tax, total and a spend category."
      },
      "typeVersion": 1
    },
    {
      "id": "c3d4e5f6-0005-4a10-9a01-cc3333330005",
      "name": "Section: Record",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        340,
        -20
      ],
      "parameters": {
        "color": 6,
        "width": 540,
        "height": 600,
        "content": "## 3 \u00b7 Record & approve\nAppend a row to your bookkeeping sheet, and send invoices above your threshold to an approver in Slack before they get paid."
      },
      "typeVersion": 1
    },
    {
      "id": "c3d4e5f6-0010-4a10-9a01-cc3333330010",
      "name": "New Invoice Email",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        -620,
        240
      ],
      "parameters": {
        "simple": false,
        "filters": {
          "q": "has:attachment"
        },
        "options": {
          "downloadAttachments": true
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c3d4e5f6-0011-4a10-9a01-cc3333330011",
      "name": "Extract Text from PDF",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -340,
        240
      ],
      "parameters": {
        "options": {},
        "operation": "pdf",
        "binaryPropertyName": "attachment_0"
      },
      "typeVersion": 1
    },
    {
      "id": "c3d4e5f6-0012-4a10-9a01-cc3333330012",
      "name": "Extract Invoice Fields",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        0,
        240
      ],
      "parameters": {
        "text": "=Extract the invoice/receipt data from the document text below. If a field is missing, use an empty string (or 0 for numbers). Use ISO dates (YYYY-MM-DD).\n\nDocument text:\n{{ $json.text }}\n\nReturn:\n- vendor_name\n- invoice_number\n- invoice_date\n- due_date\n- currency (ISO code, e.g. USD)\n- subtotal (number)\n- tax_amount (number)\n- total_amount (number)\n- category: best-guess spend category (e.g. Software, Travel, Office, Marketing, Utilities, Other)\n- summary: one short line describing the purchase.",
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.5
    },
    {
      "id": "c3d4e5f6-0013-4a10-9a01-cc3333330013",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        -40,
        480
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "gpt-4o-mini"
        },
        "options": {}
      },
      "typeVersion": 1.2
    },
    {
      "id": "c3d4e5f6-0014-4a10-9a01-cc3333330014",
      "name": "Parse Invoice (JSON)",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        140,
        480
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"vendor_name\": \"Acme SaaS Inc.\",\n  \"invoice_number\": \"INV-2026-0042\",\n  \"invoice_date\": \"2026-06-01\",\n  \"due_date\": \"2026-06-15\",\n  \"currency\": \"USD\",\n  \"subtotal\": 200.00,\n  \"tax_amount\": 18.00,\n  \"total_amount\": 218.00,\n  \"category\": \"Software\",\n  \"summary\": \"Monthly subscription \u2013 Pro plan\"\n}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "c3d4e5f6-0015-4a10-9a01-cc3333330015",
      "name": "Log to Bookkeeping Sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        560,
        120
      ],
      "parameters": {
        "columns": {
          "value": {
            "Tax": "={{ $json.output.tax_amount }}",
            "Total": "={{ $json.output.total_amount }}",
            "Status": "Unpaid",
            "Vendor": "={{ $json.output.vendor_name }}",
            "Category": "={{ $json.output.category }}",
            "Currency": "={{ $json.output.currency }}",
            "Due Date": "={{ $json.output.due_date }}",
            "Received": "={{ $now.toISO() }}",
            "Invoice #": "={{ $json.output.invoice_number }}",
            "Invoice Date": "={{ $json.output.invoice_date }}"
          },
          "schema": [],
          "mappingMode": "defineBelow",
          "matchingColumns": []
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "id",
          "value": "gid=0",
          "cachedResultName": "Invoices"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "YOUR_GOOGLE_SHEET_ID"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "c3d4e5f6-0016-4a10-9a01-cc3333330016",
      "name": "High-Value?",
      "type": "n8n-nodes-base.if",
      "position": [
        560,
        360
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-highvalue",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.output.total_amount }}",
              "rightValue": 1000
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c3d4e5f6-0017-4a10-9a01-cc3333330017",
      "name": "Send for Approval",
      "type": "n8n-nodes-base.slack",
      "position": [
        840,
        360
      ],
      "parameters": {
        "text": "=:heavy_dollar_sign: *Invoice needs approval*\n*{{ $json.output.vendor_name }}* \u2014 {{ $json.output.currency }} {{ $json.output.total_amount }}\nInvoice {{ $json.output.invoice_number }} \u00b7 due {{ $json.output.due_date }} \u00b7 {{ $json.output.category }}\n{{ $json.output.summary }}",
        "select": "channel",
        "resource": "message",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": ""
        },
        "operation": "post",
        "otherOptions": {}
      },
      "typeVersion": 2.3
    }
  ],
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "High-Value?": {
      "main": [
        [
          {
            "node": "Send for Approval",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    },
    "New Invoice Email": {
      "main": [
        [
          {
            "node": "Extract Text from PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Extract Invoice Fields",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse Invoice (JSON)": {
      "ai_outputParser": [
        [
          {
            "node": "Extract Invoice Fields",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Extract Text from PDF": {
      "main": [
        [
          {
            "node": "Extract Invoice Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Invoice Fields": {
      "main": [
        [
          {
            "node": "Log to Bookkeeping Sheet",
            "type": "main",
            "index": 0
          },
          {
            "node": "High-Value?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}