{
  "name": "Track Expenses from Gmail & Drive Receipts in Google Sheets with AI (template)",
  "nodes": [
    {
      "id": "b7b9effe-b501-4a94-bdd5-6cfcb6573e35",
      "name": "Email Receipt In",
      "type": "n8n-nodes-base.gmailTrigger",
      "position": [
        0,
        160
      ],
      "parameters": {
        "simple": false,
        "filters": {
          "q": "label:receipts",
          "readStatus": "both"
        },
        "options": {
          "downloadAttachments": true,
          "dataPropertyAttachmentsPrefixName": "attachment_"
        },
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        }
      },
      "typeVersion": 1.4
    },
    {
      "id": "f4dce20d-b343-4a7e-b32e-1ba7e0b37bf6",
      "name": "Normalize Email",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        160
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const j = $input.item.json;\nconst bin = $input.item.binary || {};\nconst attKey = Object.keys(bin).find(k => k.startsWith('attachment_'));\nlet kind = 'text';\nif (attKey) {\n  const mt = (bin[attKey].mimeType || '').toLowerCase();\n  const fn = (bin[attKey].fileName || '').toLowerCase();\n  if (mt.includes('pdf') || fn.endsWith('.pdf')) kind = 'pdf';\n  else if (mt.startsWith('image/')) kind = 'image';\n}\nconst stripHtml = h => (h || '').replace(/<style[\\s\\S]*?<\\/style>/gi, ' ').replace(/<script[\\s\\S]*?<\\/script>/gi, ' ').replace(/<[^>]+>/g, ' ').replace(/&nbsp;/g, ' ').replace(/\\s+/g, ' ').trim();\nconst bodyText = (j.text && j.text.trim()) ? j.text.trim() : (stripHtml(j.html) || j.snippet || '');\nconst from = (j.from && j.from.value && j.from.value[0] && j.from.value[0].address) ? j.from.value[0].address : (typeof j.from === 'string' ? j.from : '');\nconst out = {\n  source: 'email',\n  kind,\n  subject: j.subject || '',\n  from_address: from,\n  body_text: String(bodyText).slice(0, 8000),\n  receipt_link: 'https://mail.google.com/mail/u/0/#all/' + (j.id || j.threadId || '')\n};\nif (kind === 'text') {\n  return { json: out };\n}\nreturn { json: out, binary: { data: bin[attKey] } };"
      },
      "typeVersion": 2
    },
    {
      "id": "a7ccdee1-d6d7-4f76-aa4d-d7c6afd561d3",
      "name": "Has Attachment?",
      "type": "n8n-nodes-base.if",
      "position": [
        448,
        160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.kind }}",
              "rightValue": "text"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "57e2d9ed-8ffd-4d5b-85a2-1577aa57de88",
      "name": "Archive Receipt File",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        672,
        144
      ],
      "parameters": {
        "name": "={{ $now.toFormat('yyyy-MM-dd') + ' ' + ($binary.data.fileName || 'receipt') }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 3
    },
    {
      "id": "10218c31-2ded-4eaa-9c84-cfa5301c4228",
      "name": "Use File Link",
      "type": "n8n-nodes-base.set",
      "position": [
        896,
        144
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a-source",
              "name": "source",
              "type": "string",
              "value": "email"
            },
            {
              "id": "a-kind",
              "name": "kind",
              "type": "string",
              "value": "={{ $('Normalize Email').item.json.kind }}"
            },
            {
              "id": "a-subject",
              "name": "subject",
              "type": "string",
              "value": "={{ $('Normalize Email').item.json.subject }}"
            },
            {
              "id": "a-from",
              "name": "from_address",
              "type": "string",
              "value": "={{ $('Normalize Email').item.json.from_address }}"
            },
            {
              "id": "a-body",
              "name": "body_text",
              "type": "string",
              "value": "={{ $('Normalize Email').item.json.body_text }}"
            },
            {
              "id": "a-link",
              "name": "receipt_link",
              "type": "string",
              "value": "={{ $json.webViewLink }}"
            },
            {
              "id": "a-bin",
              "name": "data",
              "type": "binary",
              "value": "={{ $('Normalize Email').item.binary.data }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "e210bc7f-5ae9-4652-a797-11bfe28b2406",
      "name": "Route by Type",
      "type": "n8n-nodes-base.switch",
      "position": [
        1104,
        272
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "PDF",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.kind }}",
                    "rightValue": "pdf"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Image",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.kind }}",
                    "rightValue": "image"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Email body",
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.kind }}",
                    "rightValue": "text"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.4
    },
    {
      "id": "565f0242-1eba-4948-816b-98646c737612",
      "name": "Paper Receipt In",
      "type": "n8n-nodes-base.googleDriveTrigger",
      "position": [
        416,
        544
      ],
      "parameters": {
        "event": "fileCreated",
        "options": {},
        "pollTimes": {
          "item": [
            {
              "mode": "everyMinute"
            }
          ]
        },
        "triggerOn": "specificFolder",
        "folderToWatch": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6d2d9022-13ba-46c2-ad82-0f716d4af6ca",
      "name": "Download Receipt File",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        640,
        544
      ],
      "parameters": {
        "fileId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.id }}"
        },
        "options": {
          "binaryPropertyName": "data"
        },
        "operation": "download"
      },
      "typeVersion": 3
    },
    {
      "id": "f17af80b-0218-4cfb-9a8d-955206276907",
      "name": "Normalize Upload",
      "type": "n8n-nodes-base.code",
      "position": [
        864,
        544
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const trig = $('Paper Receipt In').item.json;\nconst bin = $input.item.binary || {};\nconst b = bin.data || {};\nconst mt = (b.mimeType || trig.mimeType || '').toLowerCase();\nconst fn = (b.fileName || trig.name || '').toLowerCase();\nlet kind = 'unsupported';\nif (mt.includes('pdf') || fn.endsWith('.pdf')) kind = 'pdf';\nelse if (mt.startsWith('image/') || /\\.(png|jpe?g|webp|gif)$/.test(fn)) kind = 'image';\nreturn { json: {\n  source: 'upload',\n  kind,\n  subject: '',\n  from_address: '',\n  body_text: '',\n  file_name: b.fileName || trig.name || '',\n  receipt_link: trig.webViewLink || ('https://drive.google.com/file/d/' + (trig.id || '') + '/view')\n}, binary: bin };"
      },
      "typeVersion": 2
    },
    {
      "id": "38cb704a-81a0-4be0-8f97-cdcd2fd4793c",
      "name": "Extract PDF Text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        1296,
        128
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1.1
    },
    {
      "id": "2febce55-d00f-4099-a782-09bb47e680d5",
      "name": "Extract Receipt Data",
      "type": "@n8n/n8n-nodes-langchain.informationExtractor",
      "position": [
        1568,
        176
      ],
      "parameters": {
        "text": "={{ ($('Route by Type').item.json.subject ? 'Email subject: ' + $('Route by Type').item.json.subject + '\\nEmail from: ' + $('Route by Type').item.json.from_address + '\\n\\n' : '') + ($json.text ? 'Document text:\\n' + $json.text : 'Email body:\\n' + ($('Route by Type').item.json.body_text || '')) }}",
        "options": {
          "systemPromptTemplate": "You extract structured data from receipts, invoices, and order or payment confirmation emails. Extract every value that IS present in the content. Set a field to null only when the value is genuinely not stated. Never invent or guess values that are not present. Dates must be formatted YYYY-MM-DD. The total is the final amount paid including tax. Choose category only from the allowed list; use Other when unsure. Set is_receipt to false for marketing emails, newsletters, shipping-only notifications, or anything that is not evidence of a purchase or payment."
        },
        "schemaType": "manual",
        "inputSchema": "{\"type\":\"object\",\"properties\":{\"is_receipt\":{\"type\":\"boolean\",\"description\":\"true only if this is an actual receipt, invoice, or payment/order confirmation; false for newsletters, marketing, shipping-only notifications, or anything else\"},\"vendor\":{\"type\":[\"string\",\"null\"],\"description\":\"Merchant or company name exactly as shown; null if not stated\"},\"date\":{\"type\":[\"string\",\"null\"],\"description\":\"Purchase or invoice date as YYYY-MM-DD; null if not stated\"},\"total\":{\"type\":[\"number\",\"null\"],\"description\":\"Final total amount paid including tax, number only; null if not stated\"},\"currency\":{\"type\":[\"string\",\"null\"],\"description\":\"ISO 4217 code such as USD or EUR; infer from an unambiguous currency symbol; null if unclear\"},\"category\":{\"type\":[\"string\",\"null\"],\"description\":\"Best fit from: Meals & Dining, Groceries, Travel, Transport, Software & Subscriptions, Office & Supplies, Utilities & Phone, Shopping, Health, Entertainment, Other\"},\"payment_method\":{\"type\":[\"string\",\"null\"],\"description\":\"Payment method as shown, e.g. Visa ending 1234, PayPal, Cash; null if not stated\"}},\"required\":[\"is_receipt\"]}"
      },
      "typeVersion": 1.2
    },
    {
      "id": "08286db5-0344-4bf8-9bf1-3c4776b25d34",
      "name": "Claude (Text)",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        1568,
        368
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-6",
          "cachedResultName": "Claude Sonnet 4.6"
        },
        "options": {}
      },
      "typeVersion": 1.5
    },
    {
      "id": "18c4d32d-403d-4388-8036-2135915d1018",
      "name": "Extract Receipt (Vision)",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        1568,
        512
      ],
      "parameters": {
        "text": "This is a photo or scan of a receipt or invoice. Extract every value that IS visible in the image. Set a field to null only when the value is genuinely not shown. Never invent or guess values. Fields: is_receipt (true only if this is an actual receipt, invoice, or payment confirmation), vendor, date (YYYY-MM-DD), total (final amount paid including tax, number only), currency (ISO 4217, infer from an unambiguous symbol), category (best fit from: Meals & Dining, Groceries, Travel, Transport, Software & Subscriptions, Office & Supplies, Utilities & Phone, Shopping, Health, Entertainment, Other), payment_method (as shown, else null).",
        "batching": {},
        "messages": {
          "messageValues": [
            {
              "type": "HumanMessagePromptTemplate",
              "messageType": "imageBinary"
            }
          ]
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.9
    },
    {
      "id": "c40cc5ba-ce57-4083-9717-4819489d7612",
      "name": "Claude (Vision)",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        1568,
        736
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-sonnet-4-6",
          "cachedResultName": "Claude Sonnet 4.6"
        },
        "options": {}
      },
      "typeVersion": 1.5
    },
    {
      "id": "c2872723-b726-4215-9336-3cc1a32fff96",
      "name": "Receipt Fields Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1744,
        736
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\"type\":\"object\",\"properties\":{\"is_receipt\":{\"type\":\"boolean\",\"description\":\"true only if this is an actual receipt, invoice, or payment/order confirmation; false for newsletters, marketing, shipping-only notifications, or anything else\"},\"vendor\":{\"type\":[\"string\",\"null\"],\"description\":\"Merchant or company name exactly as shown; null if not stated\"},\"date\":{\"type\":[\"string\",\"null\"],\"description\":\"Purchase or invoice date as YYYY-MM-DD; null if not stated\"},\"total\":{\"type\":[\"number\",\"null\"],\"description\":\"Final total amount paid including tax, number only; null if not stated\"},\"currency\":{\"type\":[\"string\",\"null\"],\"description\":\"ISO 4217 code such as USD or EUR; infer from an unambiguous currency symbol; null if unclear\"},\"category\":{\"type\":[\"string\",\"null\"],\"description\":\"Best fit from: Meals & Dining, Groceries, Travel, Transport, Software & Subscriptions, Office & Supplies, Utilities & Phone, Shopping, Health, Entertainment, Other\"},\"payment_method\":{\"type\":[\"string\",\"null\"],\"description\":\"Payment method as shown, e.g. Visa ending 1234, PayPal, Cash; null if not stated\"}},\"required\":[\"is_receipt\"]}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "909ef27e-25c1-43a0-95ce-70ec3c5ab52b",
      "name": "Is Receipt?",
      "type": "n8n-nodes-base.if",
      "position": [
        1984,
        304
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "leftValue": "={{ $json.output.is_receipt }}"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "b5a4d37c-f939-4f0f-bc87-1d69472931b4",
      "name": "Log Expense",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2208,
        304
      ],
      "parameters": {
        "columns": {
          "value": {
            "Date": "={{ $json.output.date || '' }}",
            "Total": "={{ $json.output.total ?? '' }}",
            "Source": "={{ $('Route by Type').item.json.source }}",
            "Vendor": "={{ $json.output.vendor || '' }}",
            "Category": "={{ $json.output.category || 'Other' }}",
            "Currency": "={{ $json.output.currency || '' }}",
            "Logged At": "={{ $now.toISO() }}",
            "Receipt Link": "={{ $('Route by Type').item.json.receipt_link }}",
            "Payment Method": "={{ $json.output.payment_method || '' }}"
          },
          "schema": [
            {
              "id": "Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Vendor",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Vendor",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Currency",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Currency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Category",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Category",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Payment Method",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Payment Method",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Source",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Receipt Link",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Receipt Link",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Logged At",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Logged At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow"
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "f0484270-a93c-4d77-832f-0d2365b86255",
      "name": "Sticky Note 7d600171",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -608,
        -128
      ],
      "parameters": {
        "width": 520,
        "height": 900,
        "content": "# Receipt & Expense Tracker\n\nLogs every receipt (emailed, attached, or photographed) to one Google Sheet, with AI extraction by Claude. Every row links back to the original receipt. No OCR service needed.\n\n## How it works\n1. Emails labeled **Receipts** are picked up every minute. Attachments get archived to Drive; body-only receipts keep a Gmail link.\n2. Photos or PDFs dropped into a Drive folder are picked up too. Snap paper receipts with the Drive mobile app.\n3. Claude reads the PDF text, image, or email body and extracts vendor, date, total, currency, category, and payment method.\n4. Anything that is not a real receipt is filtered out; the rest append to your Expense Log sheet.\n\n## Setup\n1. Connect Gmail, Google Drive, and Google Sheets (Sign in with Google).\n2. Add your Anthropic API key in the two Claude model nodes.\n3. In Gmail, create a label named **Receipts** plus a filter that applies it to receipt emails.\n4. Create a Google Sheet with headers: Date, Vendor, Total, Currency, Category, Payment Method, Source, Receipt Link, Logged At, then select it in \"Log Expense\".\n5. Create two Drive folders, **Receipt Drop** and **Receipt Archive**, and select them in \"Paper Receipt In\" and \"Archive Receipt File\".\n\n## Customize\n- Edit the category list in both extraction prompts.\n- Using a different label name? Edit the search query in \"Email Receipt In\".\n- Email-only? Delete the bottom branch.\n- Add a monthly pivot tab, dedup, or currency conversion."
      },
      "typeVersion": 1
    },
    {
      "id": "2a8bcde1-eee6-48fc-9bb1-9acd8ca51e6a",
      "name": "Sticky Note 11509a44",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 1120,
        "height": 300,
        "content": "## Email receipts in\nWatches the Receipts label. Attachments are archived to Drive for a permanent link; body-only receipts keep their Gmail link."
      },
      "typeVersion": 1
    },
    {
      "id": "4f0ed011-c3d1-41c2-9231-7284a2423ddb",
      "name": "Sticky Note 71e1a8a0",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        336,
        368
      ],
      "parameters": {
        "color": 7,
        "width": 720,
        "height": 330,
        "content": "## Paper receipts in (optional)\nDrop a photo or PDF into the Receipt Drop folder. The Drive mobile app works great. Delete this branch if you only track email."
      },
      "typeVersion": 1
    },
    {
      "id": "c6cac7e4-4e35-491b-bf5c-09cb444a768f",
      "name": "Sticky Note 9905f5e0",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1264,
        -48
      ],
      "parameters": {
        "color": 7,
        "width": 620,
        "height": 920,
        "content": "## AI extraction\nClaude reads PDF text, images, and email bodies directly. Both extractors use the same fields; edit the category list in both prompts."
      },
      "typeVersion": 1
    },
    {
      "id": "6ce68faf-8e01-4bb4-9ffa-648c0a4775fa",
      "name": "Sticky Note 3941ea75",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1904,
        144
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 332,
        "content": "## Check & log\nNon-receipts are dropped. Real ones append to the Expense Log with a link to the original receipt."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "connections": {
    "Is Receipt?": {
      "main": [
        [
          {
            "node": "Log Expense",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude (Text)": {
      "ai_languageModel": [
        [
          {
            "node": "Extract Receipt Data",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Route by Type": {
      "main": [
        [
          {
            "node": "Extract PDF Text",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract Receipt (Vision)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Extract Receipt Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Use File Link": {
      "main": [
        [
          {
            "node": "Route by Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude (Vision)": {
      "ai_languageModel": [
        [
          {
            "node": "Extract Receipt (Vision)",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Has Attachment?": {
      "main": [
        [
          {
            "node": "Archive Receipt File",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Route by Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Email": {
      "main": [
        [
          {
            "node": "Has Attachment?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Email Receipt In": {
      "main": [
        [
          {
            "node": "Normalize Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract PDF Text": {
      "main": [
        [
          {
            "node": "Extract Receipt Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Upload": {
      "main": [
        [
          {
            "node": "Route by Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Paper Receipt In": {
      "main": [
        [
          {
            "node": "Download Receipt File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Archive Receipt File": {
      "main": [
        [
          {
            "node": "Use File Link",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Receipt Data": {
      "main": [
        [
          {
            "node": "Is Receipt?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Receipt File": {
      "main": [
        [
          {
            "node": "Normalize Upload",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receipt Fields Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Extract Receipt (Vision)",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Extract Receipt (Vision)": {
      "main": [
        [
          {
            "node": "Is Receipt?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}