{
  "id": "7PVU0dnK3csdntrn",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "PageIndex RAG - Vectorless PDF Q&A",
  "tags": [],
  "nodes": [
    {
      "id": "cb4bce05-a6d3-40a6-8611-d1b5f9ecde1b",
      "name": "Sticky Note - Summary",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4224,
        2016
      ],
      "parameters": {
        "color": 7,
        "width": 608,
        "height": 576,
        "content": "##  \ud83e\udde0 Workflow Summary\n\n**PageIndex Vectorless RAG Bot**\n\n\nThis workflow builds a vectorless RAG system using [PageIndex](https://pageindex.ai) \u2014 no embeddings, no vector database. PageIndex builds a hierarchical tree index (like a Table of Contents) from your PDF, and the LLM reasons over that tree to find precise answers.\n\n\n---\n\n\n**\ud83d\udcc4 Flow 1 \u2014 PDF Upload (Run Once)**\nSend a PDF file to the Telegram bot. It downloads and indexes it on PageIndex cloud.\n\n**\ud83d\udcac Flow 2 \u2014 Q&A (Runs Every Time)**\nSend any question to the Telegram bot. It fetches all your indexed docs, passes them to PageIndex LLM reasoning, and returns a cited answer.\n\n\n---\n\n**\ud83d\udd11 Required Credentials**\n- Telegram Bot Token (via @BotFather)\n- PageIndex API Key (via dash.pageindex.ai)\n\n**\ud83d\udca1 How PageIndex Works**\nInstead of vector similarity search, PageIndex builds a tree of section summaries. The LLM reads the tree, decides which sections are relevant, retrieves only those, and generates the answer \u2014 with page citations included."
      },
      "typeVersion": 1
    },
    {
      "id": "669aff95-ffe9-499d-97d0-5f9d3a02054f",
      "name": "Sticky Note - Flow 1 Header",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4848,
        2016
      ],
      "parameters": {
        "color": 5,
        "width": 856,
        "height": 96,
        "content": "## \ud83d\udcc4 Flow 1 -> PDF Knowledge Upload\nRun this flow by sending a PDF file to the Telegram bot. The PDF is downloaded and indexed on PageIndex cloud. Run once per document."
      },
      "typeVersion": 1
    },
    {
      "id": "e5526cd9-4df7-48a8-8098-77fb89f4188f",
      "name": "Sticky Note - Receive PDF",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4848,
        2128
      ],
      "parameters": {
        "width": 258,
        "height": 472,
        "content": "### \ud83d\udcce Receive PDF Document\n**Purpose:** Entry point for PDF upload flow. Listens for incoming Telegram messages that contain a file/document.\n\n**Input:** Telegram message with a PDF attachment\n**Output:** `message.document.file_id` used to download the file\n\n**Note:** Only send PDF files here. Other file types will cause errors downstream."
      },
      "typeVersion": 1
    },
    {
      "id": "ebbd31aa-c73c-4489-ac06-563ed1107fd4",
      "name": "Sticky Note - Download PDF",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5120,
        2128
      ],
      "parameters": {
        "width": 274,
        "height": 472,
        "content": "### \u2b07\ufe0f Download PDF File\n**Purpose:** Downloads the PDF binary from Telegram's file storage using the `file_id`.\n\n**Input:** `message.document.file_id` from Telegram Trigger\n**Output:** Binary PDF file data\n\n**Note:** Telegram stores files temporarily. This node fetches the actual file content before it expires."
      },
      "typeVersion": 1
    },
    {
      "id": "2a06e5cd-e74d-4ab1-a82a-a21b2ac9b1b0",
      "name": "Sticky Note - Index PDF",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5408,
        2128
      ],
      "parameters": {
        "width": 290,
        "height": 472,
        "content": "### \u2601\ufe0f Index PDF on PageIndex\n**Purpose:** Uploads the PDF to PageIndex cloud. PageIndex builds a hierarchical tree index (TOC) using LLM - no vectors.\n\n**Input:** Binary PDF data\n**Output:** `doc_id` (e.g. `pi-abc123`) assigned to this document\n\n**Note:** Processing takes 10\u201360s depending on PDF size. The doc is stored permanently."
      },
      "typeVersion": 1
    },
    {
      "id": "57988369-c99a-4be1-b8c6-a8e80749f56d",
      "name": "Receive PDF Document",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        4928,
        2432
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "35a146e0-cba2-4e9a-a766-821f5becea38",
      "name": "Download PDF File",
      "type": "n8n-nodes-base.telegram",
      "position": [
        5216,
        2432
      ],
      "parameters": {
        "fileId": "={{ $json.message.document.file_id }}",
        "resource": "file",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "140249e8-c6f3-4e70-a6b7-e32dd3023320",
      "name": "Index PDF on PageIndex",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5504,
        2432
      ],
      "parameters": {
        "url": "https://api.pageindex.ai/doc/",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "contentType": "multipart-form-data",
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "file",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "api_key",
              "value": "YOUR_PAGEINDEX_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "04057de2-5fec-45fb-8824-68a204192fd4",
      "name": "Sticky Note - Flow 2 Header",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4224,
        2624
      ],
      "parameters": {
        "color": 4,
        "width": 1466,
        "height": 80,
        "content": "## \ud83d\udcac Flow 2 -> Q&A Chat\nRun this flow by sending any text message to the Telegram bot. It fetches all indexed docs, sends the question to PageIndex LLM reasoning, and returns a cited answer to the same user."
      },
      "typeVersion": 1
    },
    {
      "id": "64697575-d379-4f4d-8d3e-2666019ebd6d",
      "name": "Sticky Note - Receive Question",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4224,
        2720
      ],
      "parameters": {
        "color": 6,
        "width": 290,
        "height": 519,
        "content": "### \ud83d\udcac Receive User Question\n**Purpose:** Entry point for Q&A flow. Listens for text messages sent to the Telegram bot.\n\n**Input:** Telegram text message from user\n**Output:** `message.text` (the question) and `message.from.id` (for reply routing)\n\n**Note:** Any text message triggers this flow. The answer is always sent back to the same user."
      },
      "typeVersion": 1
    },
    {
      "id": "622fbf87-1349-4de5-82ba-27fdf02e49d8",
      "name": "Sticky Note - Fetch Docs",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4528,
        2720
      ],
      "parameters": {
        "color": 6,
        "width": 258,
        "height": 519,
        "content": "### \ud83d\udcda Fetch All Indexed Documents\n**Purpose:** Retrieves the list of all documents already indexed in your PageIndex account.\n\n**Input:** PageIndex API key (header)\n**Output:** Array of document objects including `id`, `name`, `status`, `pageNum`\n\n**Note:** Only documents with `status: completed` are ready for querying."
      },
      "typeVersion": 1
    },
    {
      "id": "6fb9f267-cb04-4155-82f8-9eae020cefdb",
      "name": "Sticky Note - Extract IDs",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4800,
        2720
      ],
      "parameters": {
        "color": 6,
        "width": 258,
        "height": 519,
        "content": "### \ud83d\udd11 Extract Document IDs\n**Purpose:** Maps the documents array into a clean array of `doc_id` strings for use in the chat API.\n\n**Input:** `documents` array from PageIndex\n**Output:** `doc_ids` array (e.g. `[\"pi-abc123\", \"pi-def456\"]`)\n\n**Note:** Passing multiple doc_ids allows PageIndex to reason across all your indexed documents at once."
      },
      "typeVersion": 1
    },
    {
      "id": "534a8b8e-f17c-4042-a2ac-d2ed8706bb4d",
      "name": "Sticky Note - LLM Reasoning",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5072,
        2720
      ],
      "parameters": {
        "color": 6,
        "width": 338,
        "height": 519,
        "content": "### \ud83e\udde0 LLM Reasoning over Document Tree\n**Purpose:** Core RAG step. Sends the user question + all doc_ids to PageIndex. The LLM reasons over the hierarchical tree index to find and retrieve the most relevant sections.\n\n**Input:** User question + `doc_ids` array\n**Output:** LLM-generated answer with page citations\n\n**Note:** No vector search involved. PageIndex uses tree traversal + LLM reasoning."
      },
      "typeVersion": 1
    },
    {
      "id": "f4cc58b5-26fd-4096-bef2-785a5f294d90",
      "name": "Sticky Note - Send Answer",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5424,
        2720
      ],
      "parameters": {
        "color": 6,
        "width": 274,
        "height": 519,
        "content": "### \ud83d\udce4 Send Answer to User\n**Purpose:** Delivers the LLM-generated answer back to the user on Telegram.\n\n**Input:** `choices[0].message.content` from PageIndex response\n**Output:** Text message sent to the user's Telegram chat\n\n**Note:** Reply is routed using `message.from.id` so each user gets their own response."
      },
      "typeVersion": 1
    },
    {
      "id": "369a3577-6c59-4d02-a551-a6cab6308a20",
      "name": "Receive User Question",
      "type": "n8n-nodes-base.telegramTrigger",
      "position": [
        4320,
        3040
      ],
      "parameters": {
        "updates": [
          "message"
        ],
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "22cab621-7b73-465f-81e1-8531cb3fcfcc",
      "name": "Fetch All Indexed Documents",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4608,
        3040
      ],
      "parameters": {
        "url": "https://api.pageindex.ai/docs",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "api_key",
              "value": "YOUR_PAGEINDEX_API_KEY"
            }
          ]
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "e320a50f-32a7-4bcc-a9c6-d9e09192652d",
      "name": "Extract Document IDs",
      "type": "n8n-nodes-base.set",
      "position": [
        4880,
        3040
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "59845b9c-a89b-41a0-a038-ec0f8d06bf91",
              "name": "doc_ids",
              "type": "array",
              "value": "={{ $json.documents.map(d => d.id) }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b697c98a-4b45-446b-8a72-0765b411e305",
      "name": "LLM Reasoning over Document Tree",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5200,
        3040
      ],
      "parameters": {
        "url": "https://api.pageindex.ai/chat/completions",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"messages\": [\n    {\n      \"role\": \"user\",\n      \"content\": \"{{ $('Receive User Question').item.json.message.text }}\"\n    }\n  ],\n  \"stream\": false,\n  \"doc_id\": {{ JSON.stringify($json.doc_ids) }},\n  \"temperature\": 0.5,\n  \"enable_citations\": false\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "api_key",
              "value": "YOUR_PAGEINDEX_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "9632028b-74b7-46f2-897b-7b22ed91de11",
      "name": "Send Answer to User",
      "type": "n8n-nodes-base.telegram",
      "position": [
        5504,
        3040
      ],
      "parameters": {
        "text": "={{ $json.choices[0].message.content }}",
        "chatId": "={{ $('Receive User Question').item.json.message.from.id }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "d98e663c-e64f-4450-af7f-af70ecd02ef0",
  "connections": {
    "Download PDF File": {
      "main": [
        [
          {
            "node": "Index PDF on PageIndex",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Document IDs": {
      "main": [
        [
          {
            "node": "LLM Reasoning over Document Tree",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive PDF Document": {
      "main": [
        [
          {
            "node": "Download PDF File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive User Question": {
      "main": [
        [
          {
            "node": "Fetch All Indexed Documents",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Index PDF on PageIndex": {
      "main": [
        []
      ]
    },
    "Fetch All Indexed Documents": {
      "main": [
        [
          {
            "node": "Extract Document IDs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "LLM Reasoning over Document Tree": {
      "main": [
        [
          {
            "node": "Send Answer to User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}