Vector Store Node

The canvas node that reads and writes a Vector Store. One node does one of three things — Insert content, Query for it, or Delete it — against a store you created in Settings. Every field takes a template, so the same node can index a scraped page, a Drive file, or a webhook body.

ℹThe store itself — model, API key, backend, default chunking — is set up once under Settings → Vector Stores. Start with the Vector Stores Quick Start if you have not created one yet. Integrating by API instead? See the Vector Stores API reference.

First: pick a store

Nothing else on the node appears until a store is chosen, on purpose: without a store there is nothing to search or write to, so a Top K or a filter set beforehand would be a promise about nothing. The picker can also create a store right there, with the same form as the settings page. If the store this node used was deleted, the node says so and hides everything else until you pick or create another one.


The three modes

ModeDoesWhat the next node receives
InsertSplits the incoming text and files into passages and stores themHow many passages went in, how many were already there, and any warnings
QuerySearches by meaning and returns the best matchesA list of matches, one per passage, which a Loop can go through one by one
DeleteRemoves the passages of a document, or the ones matching a filterHow many passages were removed

A new node has no mode picked, and until you pick one it does not run — an event that reaches it stops there with a note saying so. Nothing is searched, loaded or deleted on a choice nobody made.

Every field is a template over the incoming payload — the Data Picker next to each one lists what you can use — so {{payload.text}} works everywhere, as does a value from another node in the same flow.


Insert mode

Content type — the shortcut

Under Mode there is a Content type dropdown with eight options: PDF, Markdown, Plain text, JSON, CSV, Code, Short pieces and Custom. Pick one and the node fills in the Configuration tab (Text to ingest, Source doc name, Source doc id, the replace toggle) and the Advanced tab (the chunking for that type, with the numbers from the chunking table). Nothing is chosen when the node opens. Edit any of those fields by hand and the dropdown switches to Custom, which means exactly that: every field is yours.

For PDFs sent to a webhook this is the whole setup: pick PDF, and send the file as multipart/form-data with a docId field next to it. The webhook's example payloads include PDF upload, so you can see the shape before sending one.

Configuration tab

  • Text to ingest — what gets stored. It is split using the store's chunking, and the type of content (JSON, CSV, Markdown, code, plain text) is recognised so the split respects its structure.
  • Source doc name — the label that shows in the store's Content tab and next to every match.
  • Source doc id — what identifies the document for you: a URL, a page id, a file id. A later Delete, and the replace toggle below, key on it.
  • Metadata — a small set of labels stored with every passage of this ingest, which a Query can later filter by. Written as key: value lines (tenant: {{payload.tenant}}, lang: en); Use JSON expression switches to the raw JSON if you prefer it.
textA typical insert node
Text to ingest      {{payload.article.body}}
Source doc name     {{payload.article.title}}
Source doc id       {{payload.article.url}}
Metadata            { "tenant": "{{payload.tenant}}", "lang": "en" }

Replace existing chunks for this doc

The toggle appears once Source doc id has a value. When it is on and a document with that id is already in the store, its old passages are removed before the new ones go in — so the store never holds two versions of the same page. Off (the default), passages accumulate: identical text is skipped, but outdated passages of a document that changed stay where they are.

Files in the payload

With auto-extract on (the default), the node looks for files in the incoming payload and reads the text out of PDFs, CSVs, JSON and text files. Images and other binaries are skipped and listed in the output. Each file becomes its own document, split by its own type, and every passage remembers which file it came from. Turn auto-extract off to store only the text field.

Advanced tab

Insert mode only. Leave a field empty and the store's chunking applies; fill it in and it wins for that type of content. Which numbers to put there, by type of content, is in Chunking.

ContentSettings
PDF, Markdown, Code, ProseSize and Overlap, in characters
CSVRows per chunk; the header is repeated on every chunk
JSONMax chars per chunk (4000 if empty). JSON is split by its own structure, so the store's Size is not used here — this is the only place that limit can be changed.
Max chars per fileCuts each extracted file at that length before splitting (-1 for no limit). The cheap way to cap what a 400-page PDF costs in embeddings.

What comes out

  • chunksInserted — passages stored.
  • skipped — passages that were already there, word for word.
  • upsertedOver — old passages removed by the replace toggle, when it acted.
  • warnings — only when the splitter had to force something. Worth routing to a Filter node if this store feeds an agent.
  • skippedFiles — files that produced no text, with the reason.

When nothing arrives to store, the node does not fail: it returns chunksInserted: 0 and a skippedReason that says why. The exact shape of the output is in the API reference.


Query mode

  • Query — the question, usually {{payload.question}}.
  • Top K — how many matches to return, at most 50.
  • Min score — matches below this score are dropped. Scores go from 0 to 1; for anything that feeds an AI Node, set it — 0.6 to 0.7 is a sensible floor.
  • Metadata filter — only passages whose labels match, for example { "tenant": "{{payload.tenant}}" }.

The output is a list of matches; each one carries the passage text (content), its score, the document it came from (sourceDocName, sourceDocId) and its metadata. A Loop or an Aggregator after the node goes through the matches one by one; to hand the whole list to an AI Node, write {{payload.matches}} in its prompt.


Delete mode

Takes a source doc id, a metadata filter, or both. If neither has a value after the templates are filled in, the node removes nothing and says so in its output — that guard is the difference between removing one document and emptying the store.


Metadata filters: simple values only

A filter is a flat set of labels with plain values — { "tenant": "acme", "lang": "en" }. Lists, nested objects and keys that start with $ are refused, and a filter that cannot be filled in stops the node instead of running without it. That is deliberate: the value comes from the incoming payload, and a filter that quietly widened to “everyone” would leak other customers' passages in Query mode and empty the store in Delete mode.

So you write the keys and take only the values from the payload — tenant: {{payload.tenant}}. A whole filter coming in the payload ({{payload.filter}}) is refused, because then the payload would choose which labels to check. The same goes for the Metadata of an Insert: if it does not come out as a set of labels, the step stops instead of storing passages without them.

ℹOn the managed backend, filtering by your own metadata keys is not available yet — narrow by document instead, or use a store on your own PostgreSQL, where any key works with no setup.

The Content tab

The node embeds the same passage browser as the store page, so you can check what an insert actually produced without leaving the canvas — filter by document name, read a passage whole, delete a bad one. It is the fastest way to answer “did my template fill in what I think it did”.


Patterns worth copying

Keep a store in sync with a folder

textScheduled → Drive Action → Vector Store (insert)
Scheduled Workflow (hourly)
  → Drive Action: list files in folder
  → Vector Store (insert)
       Text to ingest    (empty — the files come through)
       Source doc id     {{payload.fileId}}
       Source doc name   {{payload.name}}
       Replace existing chunks for this doc: ON

Edited files replace themselves, untouched files cost nothing, and the store never holds two versions of a document.

Answer a question with what the store knows

textWebhook → Vector Store (query) → AI Node
Webhook
  → Vector Store (query)
       Query        {{payload.question}}
       Top K        5
       Min score    0.65
       Filter       { "tenant": "{{payload.tenant}}" }
  → AI Node
       Prompt       Answer using only this context: {{payload.matches}}

If the agent should decide when to search rather than always searching, skip the Query node and give the store to the AI Node as a tool — see As a tool on an AI Node.

Forget a document when the source deletes it

textWebhook (document.deleted) → Vector Store (delete)
Vector Store (delete)
  Source doc id   {{payload.documentId}}

Good to know

  • Every query is billed to your API key — the question has to be processed before it can be compared. A Query node inside a loop over 500 items is 500 billed calls.
  • A paused store refuses both reads and writes. If a node started failing for no visible reason, check whether someone paused the store in Settings.
  • Chunk size is in characters, and for plain text it is the store's setting that applies, not the node's. See Chunking.
  • A list coming in runs the node once per item. Feed it the output of a node that produces a list and it runs for each — usually what you want for Insert, rarely for Query.
  • The Advanced tab only applies in Insert mode. In Query and Delete it shows a note instead of settings that would do nothing.