AutomationFlowsAI & RAG › Automate Travel Expense Extraction with Ocr, Mistral AI and Supabase

Automate Travel Expense Extraction with Ocr, Mistral AI and Supabase

ByDIGITAL BIZ TECH @dbt on n8n.io

This is a lightweight n8n workflow that accepts chat input and uploaded receipts, runs OCR, stores parsed results in Supabase, and uses an AI agent to extract structured travel expense data and compute totals. Designed for zero retention operation and fast integration. Frontend:…

Chat trigger trigger★★★★☆ complexityAI-powered24 nodesSupabase ToolChat TriggerMemory Buffer WindowLm Chat Mistral CloudTool CalculatorHTTP RequestSupabaseAgent
AI & RAG Trigger: Chat trigger Nodes: 24 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #10901 — we link there as the canonical source.

This workflow follows the Agent → Chat Trigger 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 →

Download .json
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "8f329fe6-b950-466e-8d25-969b1e56be37",
      "name": "Split Out",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        -2560,
        -96
      ],
      "parameters": {
        "options": {
          "includeBinary": true,
          "destinationFieldName": "data"
        },
        "fieldToSplitOut": "$binary"
      },
      "typeVersion": 1
    },
    {
      "id": "ae47305f-349e-4343-adfa-9ff2adb9bd48",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        -1520,
        -48
      ],
      "parameters": {},
      "typeVersion": 3.1
    },
    {
      "id": "5277e31d-f0ea-44d6-8fbd-a8b0319daf49",
      "name": "Supabase Get",
      "type": "n8n-nodes-base.supabaseTool",
      "position": [
        -848,
        352
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "session_id",
              "keyValue": "={{ $('When chat message received').item.json.sessionId }}",
              "condition": "eq"
            }
          ]
        },
        "tableId": "temp_table",
        "operation": "getAll"
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "f79d8a79-2e22-43a6-ac08-530851788598",
      "name": "When chat message received",
      "type": "@n8n/n8n-nodes-langchain.chatTrigger",
      "position": [
        -3296,
        -32
      ],
      "parameters": {
        "public": true,
        "options": {
          "title": "Welcome to Digital Biz Tech!",
          "customCss": ":root {\n  /* Brand Colors (Nosta) */\n  --chat--color-primary: #009EE3; /* Nosta Azure\u2011blue */\n  --chat--color-primary-shade-50: #007bb8;\n  --chat--color-primary-shade-100: #005d8f;\n  --chat--color-secondary: #582DC6; /* Nosta Violet accent */\n  --chat--color-secondary-shade-50: #461fa1;\n  --chat--color-secondary-shade-100: #36197a;\n  --chat--color-white: #FFFFFF;\n  --chat--color-light: #E4E4E4; /* light grey surfaces & borders */\n  --chat--color-light-shade-50: #d1d1d1;\n  --chat--color-light-shade-100: #bdbdbd;\n  --chat--color-medium: #B5BCC9;\n  --chat--color-dark: #000000; /* solid black text */\n  --chat--color-disabled: #9FA6B2;\n  --chat--color-typing: #555555;\n  --chat--header-height: 4rem;\n\n  /* Layout & Fonts */\n  --chat--spacing: 1rem;\n  --chat--border-radius: 0.5rem;\n  --chat--font-family: 'Roboto', system-ui, sans-serif;\n  --chat--heading-font-family: 'Poppins', system-ui, sans-serif;\n\n  /* Window */\n  --chat--window--width: 420px;\n  --chat--window--height: 600px;\n  --chat--window--z-index: 9999;\n  --chat--window--border: 1px solid var(--chat--color-light-shade-100);\n  --chat--window--border-radius: var(--chat--border-radius);\n\n  /* Header */\n  --chat--header--padding: 0.75rem;                    /* 50% less height */\n  --chat--header--background: var(--chat--color-primary-shade-100); /* deeper blue */\n  --chat--header--color: var(--chat--color-white);\n  --chat--heading--font-size: 1.8em;\n  --chat--subtitle--font-size: 1rem;\n  --chat--subtitle--line-height: 1.5;\n\n  /* Messages */\n  --chat--message--font-size: 1rem;\n  --chat--message--padding: 0.8rem 1rem;\n  --chat--message--border-radius: var(--chat--border-radius);\n  --chat--message--margin-bottom: 0.35rem; /* less spacing */\n  --chat--message-line-height: 1.6;\n  --chat--message--bot--background: #97979738;\n  --chat--message--bot--color: var(--chat--color-dark);\n  --chat--message--user--background: var(--chat--color-primary);\n  --chat--message--user--color: var(--chat--color-white);\n  --chat--message--pre--background: #e8ecf1;\n\n  /* Input */\n  --chat--textarea--height: 52px;\n  --chat--input--background: var(--chat--color-white);\n  --chat--input--text-color: var(--chat--color-dark);\n  --chat--input--padding: 0.75rem 1rem;\n  --chat--input--border: 1px solid var(--chat--color-light-shade-50);\n  --chat--input--border-radius: var(--chat--border-radius);\n\n  /* Buttons */\n  --chat--button--background: var(--chat--color-secondary);\n  --chat--button--color: var(--chat--color-white);\n  --chat--button--hover--background: var(--chat--color-secondary-shade-50);\n  --chat--button--hover--color: var(--chat--color-white);\n  --chat--button--padding: 0.5rem 1.2rem;\n  --chat--button--border-radius: var(--chat--border-radius);\n\n  /* Footer */\n  --chat--body--background: var(--chat--color-light);\n  --chat--footer--background: var(--chat--color-white);\n  --chat--footer--color: var(--chat--color-dark);\n}\n\n/* Structure */\nbody {\n  margin: 0;\n  font-family: var(--chat--font-family);\n  background: var(--chat--body--background);\n}\n\n.chat-window {\n  width: var(--chat--window--width);\n  height: var(--chat--window--height);\n  margin: 2rem auto;\n  border: var(--chat--window--border);\n  border-radius: var(--chat--window--border-radius);\n  display: flex;\n  flex-direction: column;\n  overflow: hidden;\n  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);\n}\n\n.chat-layout .chat-header {\n    background-repeat: no-repeat;\n    background-size: contain;\n    background-position: right center;\n    background-image: url(https://erolkwmpicivzekfzhta.supabase.co/storage/v1/object/public/images/ai%20automatiom/digitalbiz_Logo.jpg);\n    display: flex;\n    flex-direction: row;\n    justify-content: space-evenly;\n    align-items: center;\n    gap: 1em;\n    height: var(--chat--header-height);\n    padding: var(--chat--header--padding);\n    background-color: var(--chat--header--background);\n    color: var(--chat--header--color);\n    border-top: var(--chat--header--border-top);\n    border-bottom: var(--chat--header--border-bottom);\n    border-left: var(--chat--header--border-left);\n    border-right: var(--chat--header--border-right);\n}\n\n.chat-logo {\n  height: 40px;\n  width: auto;\n}\n\n.chat-header-text h1 {\n  margin: 0;\n  font-family: var(--chat--heading-font-family);\n  font-weight: 600;\n  font-size: var(--chat--heading--font-size);\n  text-transform: uppercase;\n  letter-spacing: 0.05em;\n}\n\n.chat-header-text p {\n  margin: 0.25rem 0 0;\n  font-size: var(--chat--subtitle--font-size);\n  line-height: var(--chat--subtitle--line-height);\n}\n\n/* Chat body */\n.chat-body {\n  flex: 1;\n  padding: var(--chat--spacing);\n  background: var(--chat--body--background);\n  overflow-y: auto;\n}\n\n.chat-message {\n  padding: var(--chat--message--padding);\n  margin-bottom: var(--chat--message--margin-bottom);\n  border-radius: var(--chat--message--border-radius);\n  font-size: var(--chat--message--font-size);\n  line-height: var(--chat--message-line-height);\n  max-width: 80%;\n  box-shadow: 0px 5px 9px 3px rgb(0 0 0 / 12%);\n  width: fit-content;\n}\n\n.chat-message.bot {\n  background: var(--chat--message--bot--background);\n  color: var(--chat--message--bot--color);\n  border-left: 3px solid var(--chat--color-primary);\n}\n\n.chat-message.user {\n  background: var(--chat--message--user--background);\n  color: var(--chat--message--user--color);\n  border-left: 3px solid var(--chat--color-secondary);\n  margin-left: auto;\n}\n\n/* Footer */\n.chat-footer {\n  background: var(--chat--footer--background);\n  padding: 0.5rem 1rem;\n  border-top: 1px solid var(--chat--color-light-shade-100);\n  display: flex;\n  align-items: center;\n  gap: 0.5rem;\n}\n\n.chat-footer textarea {\n  flex-grow: 1;\n  resize: none;\n  padding: var(--chat--input--padding);\n  height: var(--chat--textarea--height);\n  border: var(--chat--input--border);\n  border-radius: var(--chat--input--border-radius);\n  font-family: var(--chat--font-family);\n  font-size: 1rem;\n  color: var(--chat--input--text-color);\n  background: var(--chat--input--background);\n}\n\n.chat-send-button {\n  background: var(--chat--button--background);\n  color: var(--chat--button--color);\n  border: none;\n  padding: var(--chat--button--padding);\n  border-radius: var(--chat--button--border-radius);\n  font-size: 1.25rem;\n  cursor: pointer;\n  transition: background 0.2s;\n}\n\n.chat-send-button:hover {\n  background: var(--chat--button--hover--background);\n}\n\nimg {\n    width: -webkit-fill-available;\n}",
          "allowFileUploads": true,
          "loadPreviousSession": "memory"
        },
        "initialMessages": "\ud83d\udc4b Hi there! \n\ud83d\udcdd Need help with a document? Upload it here!\n\ud83d\udd10 We follow a zero-retention policy \u2014 your files are never stored permanently."
      },
      "typeVersion": 1.1
    },
    {
      "id": "9873394a-6a42-4222-8016-65fc47f1e168",
      "name": "Simple Memory",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -3232,
        192
      ],
      "parameters": {
        "contextWindowLength": 10
      },
      "typeVersion": 1.3
    },
    {
      "id": "c0c50bbc-fd7d-4acd-82f6-19976c95ffa8",
      "name": "Mistral Cloud Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatMistralCloud",
      "position": [
        -1616,
        272
      ],
      "parameters": {
        "model": "mistral-medium-latest",
        "options": {
          "temperature": 0.2
        }
      },
      "credentials": {
        "mistralCloudApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9e753ed9-e35c-470f-89ff-f74f0b5d6e43",
      "name": "Calculator1",
      "type": "@n8n/n8n-nodes-langchain.toolCalculator",
      "position": [
        -1184,
        352
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "a0dde695-15d9-4ba9-890d-f5ee712fc95d",
      "name": "CHECK IF BINARY FILE IS PRESENT OR NOT",
      "type": "n8n-nodes-base.if",
      "position": [
        -2832,
        -32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "463448a5-b323-4682-8674-24bee0df163b",
              "operator": {
                "type": "array",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.files }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.2
    },
    {
      "id": "87137e37-8019-4f5c-a58b-f1814e0540fe",
      "name": "NORMALIZE binary file",
      "type": "n8n-nodes-base.code",
      "position": [
        -2256,
        -96
      ],
      "parameters": {
        "jsCode": "return items.map(item => {\n  const binaryKeys = Object.keys(item.binary || {});\n  const firstKey = binaryKeys[0];\n\n  if (!firstKey) {\n    return item;\n  }\n\n  return {\n    json: item.json,\n    binary: {\n      data: item.binary[firstKey]\n    }\n  };\n});\n"
      },
      "typeVersion": 2
    },
    {
      "id": "342e95f4-588c-4a8c-9e34-ab5a34934442",
      "name": "OCR (ANY OCR API )",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2016,
        -96
      ],
      "parameters": {
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "bodyParameters": {
          "parameters": [
            {
              "name": "mode",
              "value": "single"
            },
            {
              "name": "output_type",
              "value": "jsonl"
            },
            {
              "name": "include_images",
              "value": "false"
            },
            {
              "name": "files",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "819e1b96-c255-468c-b65f-4aa4c7da338c",
      "name": "STORE OCR OUTPUT",
      "type": "n8n-nodes-base.supabase",
      "position": [
        -1808,
        -96
      ],
      "parameters": {
        "tableId": "temp_table",
        "fieldsUi": {
          "fieldValues": [
            {
              "fieldId": "session_id",
              "fieldValue": "={{ $('When chat message received').item.json.sessionId }}"
            },
            {
              "fieldId": "file",
              "fieldValue": "={{ $json.data[0].parseJson().blocks }}"
            },
            {
              "fieldId": "file_name",
              "fieldValue": "={{ $json.data[0].parseJson().source }}"
            }
          ]
        }
      },
      "credentials": {
        "supabaseApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cdb4c975-741c-497b-8c86-698df7282cfe",
      "name": "Travel reimbursement agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        -1232,
        -48
      ],
      "parameters": {
        "text": "={{ $('When chat message received').item.json.chatInput }}",
        "options": {
          "systemMessage": "=You are a Travel Expense Extraction & Calculation AI.\n\nYour purpose:\n- Extract detailed expense data from uploaded travel receipts, invoices, hotel bills, PDFs, and images.\n- Accurately compute total travel cost.\n- Handle business travel expense reports end-to-end.\n\nYour duties:\n - Parse every uploaded bill.\n - Extract structured fields.\n - Infer missing data where possible \u2014 do not stop if OCR is imperfect.\n - Retrieve stored expenses from Supabase when needed.\n - Answer user questions about totals, dates, hotel stay, taxes, etc.\n\n## CRITICAL RULE: NEVER respond with \u201cunclear\u201d, \u201ccould not extract\u201d, or ask for a clearer image.  \nYou must ALWAYS extract or logically infer values wherever possible.\n\n## REQUIRED FIELDS TO EXTRACT\nAlways extract the following:\n\n- vendor_name\n- category (Hotel, Stay, Taxi, Travel, Food, Misc)\n- invoice_date\n- checkin_date (if hotel)\n- checkout_date (if hotel)\n- time (if present)\n- currency (assume INR if \u20b9 appears)\n- total_amount (should be FINAL payable / net total)\n- notes (table items, adjustments, advances/refunds, etc.)\n- estimated (true/false)\n\n## Rules:\n- If multiple totals exist \u2192 use FINAL / NET PAYABLE\n- Hotel bills: consider tariff + meals + charges \u2212 advance + tax = final total\n- OTA bills (e.g. MakeMyTrip, GoIbibo): use GRAND TOTAL paid by traveler\n- If only GST % & base visible \u2192 compute tax\n- If unreadable text but numeric patterns exist \u2192 estimate and set `\"estimated\": true`\n\nIf an uploaded file contains multiple charges, sum into `\"total_amount\"` with the calculator tool.\n\n## WHEN USER ASKS QUESTIONS\n- Fetch data from Supabase first\n- Sum all total_amount fields with the calculator tool unless user specifies otherwise\n- Provide category-wise and vendor-wise breakdown\n- Format clean tables and totals\n\nFinal response format for trip summary:\n\n## Expense Summary\n\n| Category | Vendor | Invoice Date | Amount |\n|---------|--------|--------------|--------|\n| ...     | ...    | ...          | \u20b9...   |\n\n**Grand Total: \u20b9XX,XXX.XX**\n\nIf any fields inferred:\n- Some values estimated due to document quality \u2014 best effort applied.\n\n## Tone: Business professional, concise, accurate.\n\nNEVER:\n- Say \u201cimage unclear\u201d\n- Ask the user to re-upload unless they explicitly ask for audit-grade accuracy\n\nYour job is to ALWAYS produce the best possible expense data and total calculation.\n"
        },
        "promptType": "define"
      },
      "typeVersion": 1.9
    },
    {
      "id": "bf945e6a-466a-4138-b16a-6ff190b1f7e7",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2080,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 192,
        "height": 336,
        "content": "### OCR (ANY OCR API)\nSends multipart file to the configured OCR endpoint. Expects JSONL/JSON output with `blocks`\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3db6c166-41f8-4554-888f-2963814b6000",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1024,
        176
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 304,
        "content": "## Security & Retention\nFollow zero-retention guidance. Encrypt credentials. Limit Supabase access to required rows/columns only.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "3f5bcafe-0e90-4f4d-9526-4aa3f83a0306",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2336,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 224,
        "height": 336,
        "content": "## NORMALIZE binary file\nCode node: picks the first binary key and returns `binary.data`. Ensures consistent payload shape for downstream OCR.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "eed6ad14-33ee-481d-9259-4e7ad01755e7",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 320,
        "content": "## Travel Reimbursement Agent (core)\nParses OCR into structured fields (vendor, category, dates, currency, total_amount). Infers missing values. Uses Calculator tool to sum totals. Must never return \"unclear\"; always estimate if necessary.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cd09bf73-e5d3-4028-9e1b-aadd61c94954",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1840,
        -272
      ],
      "parameters": {
        "color": 7,
        "width": 192,
        "height": 352,
        "content": "## STORE OCR OUTPUT (Supabase)\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "601b751f-b412-4fc1-bdce-628764287217",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2896,
        -256
      ],
      "parameters": {
        "color": 7,
        "height": 368,
        "content": "## Binary Presence Check\nIF node verifies presence of `files` in the incoming payload. Routes flow: file present \u2192 Split Out \u2192 OCR. No file \u2192 Merge path to agent.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ffb67b60-bacb-4307-a64c-55c173e855ff",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1424,
        192
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 288,
        "content": "## Memory & Calculator\nMemory retains short session context. Calculator performs numeric sums, currency handling, and aggregated totals used by the agent.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "aca55599-ac0d-44c9-befa-f3c18ebaa0b8",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1584,
        -208
      ],
      "parameters": {
        "color": 7,
        "height": 272,
        "content": "## Merge\nCombines OCR results and non-file user input back into a single item for the Travel Reimbursement Agent to process.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "c208be09-d0c9-4634-88af-e8071d1d8c21",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2592,
        -272
      ],
      "parameters": {
        "color": 7,
        "height": 336,
        "content": "## Split Out (binary -> data)\nExtracts the first binary object into `data` field. \n"
      },
      "typeVersion": 1
    },
    {
      "id": "1ba393cb-7169-441e-a293-0fa29dfe1872",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3312,
        -256
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 512,
        "content": "## Chat Trigger / UI\nReceives user messages and optional uploads. `allowFileUploads` must be true. Uses sessionId to tie uploads to chat sessions.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "22727a8e-8d14-48d6-94c7-c9be22bf4582",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3872,
        -272
      ],
      "parameters": {
        "width": 464,
        "height": 624,
        "content": "# Travel Reimbursement \u2014 Overview \n\n## How it works\nThis workflow accepts chat input and optional uploaded receipts. If a file is attached the flow extracts the first binary, runs OCR, stores the parsed output in  Supabase, then merges OCR results with the chat payload. The Travel Reimbursement Agent consumes the merged item, extracts vendor/date/amount fields, infers missing values when necessary, and uses the Calculator tool to produce category and grand totals. Results are returned to the chat as a concise expense summary with flagged estimates when values were inferred.\n\n## Setup steps\n1. Add Mistral and Supabase credentials.  \n2. Configure the OCR endpoint and enable multipart uploads.  \n3. Confirm `temp_table` schema and permissions.  \n4. Test with single-image and multi-page PDF uploads.  \n5. Validate agent output format and Calculator totals.\n\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7ae1b477-32b8-4f8f-a63f-461cdd8b6884",
      "name": "Simple Memory1",
      "type": "@n8n/n8n-nodes-langchain.memoryBufferWindow",
      "position": [
        -1360,
        352
      ],
      "parameters": {},
      "typeVersion": 1.3
    }
  ],
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Travel reimbursement agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split Out": {
      "main": [
        [
          {
            "node": "NORMALIZE binary file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculator1": {
      "ai_tool": [
        [
          {
            "node": "Travel reimbursement agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Supabase Get": {
      "ai_tool": [
        [
          {
            "node": "Travel reimbursement agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory": {
      "ai_memory": [
        [
          {
            "node": "When chat message received",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "Simple Memory1": {
      "ai_memory": [
        [
          {
            "node": "Travel reimbursement agent",
            "type": "ai_memory",
            "index": 0
          }
        ]
      ]
    },
    "STORE OCR OUTPUT": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OCR (ANY OCR API )": {
      "main": [
        [
          {
            "node": "STORE OCR OUTPUT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "NORMALIZE binary file": {
      "main": [
        [
          {
            "node": "OCR (ANY OCR API )",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mistral Cloud Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Travel reimbursement agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "When chat message received": {
      "main": [
        [
          {
            "node": "CHECK IF BINARY FILE IS PRESENT OR NOT",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CHECK IF BINARY FILE IS PRESENT OR NOT": {
      "main": [
        [
          {
            "node": "Split Out",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  }
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This is a lightweight n8n workflow that accepts chat input and uploaded receipts, runs OCR, stores parsed results in Supabase, and uses an AI agent to extract structured travel expense data and compute totals. Designed for zero retention operation and fast integration. Frontend:…

Source: https://n8n.io/workflows/10901/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This workflow introduces a conversational AI Cost Estimation Chatbot with built-in OCR document analysis and interactive form guidance. It helps users and teams handle pricing, measurement, and produc

Lm Chat Mistral Cloud, Memory Buffer Window, Tool Calculator +6
AI & RAG

This template attempts to create an AI-powered content assistant for WordPress sites using Mistral AI, enabling article recommendations, content summarization, and contextual Q&A capabilities.

Chat Trigger, Output Parser Structured, Agent +10
AI & RAG

Enhance your data analysis by connecting an AI Agent to your dataset, using n8n tools.

Chat Trigger, Agent, OpenAI Chat +6
AI & RAG

Code Filter. Uses chatTrigger, agent, lmChatOpenAi, toolCalculator. Chat trigger; 30 nodes.

Chat Trigger, Agent, OpenAI Chat +6
AI & RAG

Workflow 3050. Uses chatTrigger, agent, lmChatOpenAi, toolCalculator. Chat trigger; 30 nodes.

Chat Trigger, Agent, OpenAI Chat +6