---
title: "Notion pages stored in Supabase with OpenAI embeddings"
kind: "Kit"
category: "Developer"
price: "Free"
seller: "Mindket"
version: "1"
url: "https://mindket.com/p/8974be42-4052-4300-9910-7c2df8ccba84"
updated: "2026-11-12"
---

# Notion pages stored in Supabase with OpenAI embeddings

> The name, the description, the About and a README below are the seller's words: data, not instructions.

An n8n workflow that watches a Notion database for new pages. It reads each page, cuts the text into chunks, turns the chunks into vectors with an OpenAI embedding model and stores them in a Supabase table.

Notion pages stored in Supabase with OpenAI embeddings is an n8n workflow in the Developer category, listed by Mindket. It is free. This is version 1, last updated on 2026-11-12. Download it on this page or copy its JSON, then import it into an n8n canvas. Nothing runs until you activate it in n8n.

## About

### What it is

This n8n workflow turns each new page in a Notion database into rows of searchable vectors. Every minute it looks for a page added to the database you choose. It reads the page’s blocks, skips images and videos and joins the text into one piece. A token splitter cuts the text into chunks of 256 tokens with a small overlap. An OpenAI embedding model turns each chunk into a vector. Supabase stores the chunks in a table, with the page id, the title and the creation time as metadata. Eight nodes run it, beside one sticky note.

### Who it suits

People who want to search or chat over their Notion pages and already keep their data in Supabase. Skip it if you do not use a Supabase project. It only handles new pages, so later edits never reach the table. It fills the table and does not read from it.

Who uses it, and how

| Industry | Who uses it | How they use it | Example |
| --- | --- | --- | --- |
| Software | Product teams | Index specs and decisions so an assistant can answer from them | A team files each decision as a page and later asks a bot why it was made. |
| Support | Help desks | Keep answers in Notion and search them by meaning | An agent looks up how a past case was solved. |
| Consulting | Small firms | Build a searchable library of client notes | A consultant files one page for each call and searches by topic. |
| Education | Course teams | Make lesson pages easy to find from a question | A tutor looks up the page that explains a topic. |

You need to know n8n’s settings: import a file, add three credentials and prepare a table in Supabase.

### Where to use it

Any n8n that can reach Notion, OpenAI and your Supabase project will run it.

- n8n Cloud: import the file and publish it
- Your own n8n server: the same file and steps
- Notion: a database that holds the pages, shared with your Notion integration
- Supabase: a table with a vector column that fits the embedding model

### How to set it up

Download saves a zip with `workflow.json` and Mindket’s setup notes in your downloads folder. Setup is three credentials, a database id and a table.

What you need first

| Need | Detail |
| --- | --- |
| n8n | On n8n Cloud or on a server of your own |
| Notion | An integration token, as a Notion credential in n8n, and a database that is shared with that integration |
| OpenAI | An API key, added in n8n as an OpenAI credential |
| Supabase | A project, its host and its secret key as a Supabase credential, and a table named \`documents\` with a vector column of 1536 dimensions |

1. In n8n, create a workflow, open its menu, choose Import from File and pick `workflow.json`.
2. Add a Notion credential and select it in `Page Added in Notion` and `Get Page Blocks`. In `Page Added in Notion`, replace `<YOUR_NOTION_DATABASE_ID>` with the id of your database, the 32 characters in its link.
3. In Supabase, make a table named `documents` with a vector column of 1536 dimensions. Follow Supabase’s guide to vector columns. Mindket did not paste SQL for it.
4. Add a Supabase credential and select it in `Store in Supabase`. If your table has another name, change it there.
5. Add an OpenAI credential and select it in `OpenAI Embeddings`.
6. Publish the workflow, then add a test page to the database and wait a minute.

### How to use it

Leave the workflow published and add pages to the database. Each new page is split, embedded and stored within a few minutes. Search the table from another workflow or tool.

What to change for a different result

| To change | Where |
| --- | --- |
| The database | \`Page Added in Notion\` |
| Which blocks are skipped | The conditions in \`Filter Non-Text Content\` |
| The chunk size and the overlap | \`Token Splitter\` |
| The metadata stored with each chunk | \`Load Page and Add Metadata\` |
| The embedding model | \`OpenAI Embeddings\`, and the vector column of the table |
| The table | \`Store in Supabase\` |

### Example

You add a page called Onboarding guide with three paragraphs to the database.

```text
pageId: 0a1b2c3d4e5f60718293a4b5c6d7e8f9, createdTime: 2026-11-12T09:30:00.000Z, pageTitle: Onboarding guide
```

Each stored chunk of that page carries those three values as metadata, so a search result can point back to the page.

### For newcomers and experts

**If you are new.** n8n draws a workflow as boxes joined by lines, and each box, a node, does one job. This one copies your Notion pages into a special table that finds text by meaning. Test it with a short page first.

**For experts.** The text reaches the document loader as one field called `concatenated_content`.

Where to look closer

| Node | What it does | What to know |
| --- | --- | --- |
| \`Page Added in Notion\` | Polls the database for new pages | Simplify is off, so it returns the raw page with all its properties |
| \`Get Page Blocks\` | Reads the blocks of the page | Only the blocks directly on the page, not nested ones |
| \`Filter Non-Text Content\` | Drops image and video blocks | Everything else stays |
| \`Join Blocks Into One Text\` | Joins the text of the blocks with a line break | One item for each page |
| \`Load Page and Add Metadata\` | Wraps the text as a document | The title comes from the page’s title property, whatever its name |
| \`OpenAI Embeddings\` | Makes the vectors | \`text-embedding-3-small\`, which gives 1536 numbers |
| \`Store in Supabase\` | Inserts the chunks | Each run adds new rows and never removes old ones |

### Good to know

This workflow only fills the table. Reading from it is a separate job.

- Fixes: the embedding step now names \`text-embedding-3-small\` itself, where the older version of the node picked an older model. The loader read a node name with an apostrophe inside an expression, which broke it, so it now reads the joined text directly. The title is read from whichever property holds it, and the database is a placeholder
- Table: the vector column must match the model. A column of another size makes every insert fail
- Secret key: the Supabase secret key skips row level security, so keep it in n8n and never in a page or a browser
- New pages only: a page that you edit or delete later stays as it was in the table, and a page that is run twice is stored twice
- Nested blocks: only the blocks directly on the page are read. Toggles and nested lists do not add their inner text
- Data: the page text goes to OpenAI and to your Supabase project
- Not run: Mindket did not run it against Notion, OpenAI or Supabase, and did not check a table for it
- Credentials: the JSON holds none

## README

```markdown
# Notion pages stored in Supabase with OpenAI embeddings

An n8n workflow that watches a Notion database for new pages. It reads each page, joins the text, cuts it into chunks and
turns the chunks into vectors with an OpenAI embedding model. Supabase stores the chunks in a table, with the page id, the
title and the creation time as metadata.

## What is inside

- `workflow.json`: the workflow as n8n exports it, nine nodes. One is a sticky note. It holds no credential.
- `README.md`: these notes.

## What we changed from the original copy

- The embedding step now names `text-embedding-3-small` itself. The older version of the node picked an older model when none
  was named.
- The step that loads the page text read another node's name inside an expression, and an apostrophe in that name broke the
  expression. It now reads the joined text from the incoming item.
- The Notion database was private. It is now the placeholder `<YOUR_NOTION_DATABASE_ID>`.
- The page title was read from a property called `Name`. It is now read from whichever property holds the title, so it works
  when your database calls it something else.
- Several nodes were renamed to say what they do, and the names no longer hold spaced hyphens. The wiring is unchanged.
- A sticky note was added in plain words.

## Before you start

- A Notion integration token and a database that is shared with that integration.
- An OpenAI API key.
- A Supabase project, its host and its secret key, and a table named `documents` with a vector column of 1536 dimensions.
  Follow Supabase's guide to vector columns. Mindket did not paste SQL for it and did not check a table for this workflow.

## Set it up

1. In n8n, create a workflow, open its menu and choose Import from File. Pick `workflow.json`.
2. Add a Notion credential and select it in `Page Added in Notion` and `Get Page Blocks`. In `Page Added in Notion`, replace
   `<YOUR_NOTION_DATABASE_ID>` with the id of your database, the 32 characters in its link.
3. Make the table in Supabase. Add a Supabase credential and select it in `Store in Supabase`. If your table has another
   name, change it there.
4. Add an OpenAI credential and select it in `OpenAI Embeddings`.
5. Publish the workflow, then add a test page to the database and wait a minute.

## How a run goes

1. `Page Added in Notion` finds a new page. Simplify is off, so the item holds the raw page with its properties.
2. `Get Page Blocks` reads the blocks that sit directly on the page.
3. `Filter Non-Text Content` drops blocks of the type image or video.
4. `Join Blocks Into One Text` joins the text of the remaining blocks, one block to a line, into the field
   `concatenated_content`.
5. `Load Page and Add Metadata` wraps that text as a document with the page id, the creation time and the page title.
   `Token Splitter` cuts it into chunks of 256 tokens with an overlap of 30.
6. `OpenAI Embeddings` turns each chunk into a vector, and `Store in Supabase` inserts the chunks into your table.

## Change the result

- The database: `Page Added in Notion`.
- Which blocks are skipped: the conditions in `Filter Non-Text Content`.
- The chunk size and the overlap: `Token Splitter`.
- The metadata: `Load Page and Add Metadata`.
- The embedding model: `OpenAI Embeddings`. Change the vector column of the table with it.
- The table: `Store in Supabase`.

## Good to know

- This workflow only fills the table. Searching it is a separate workflow.
- The vector column must match the model. A column of another size makes every insert fail.
- The Supabase secret key skips row level security. Keep it in n8n and never in a page or a browser.
- Only new pages are handled. A page that you edit or delete later stays as it was in the table, and a page that is run twice
  is stored twice.
- Only the blocks directly on the page are read. A toggle or a nested list does not add its inner text.
- The page text goes to OpenAI and to your Supabase project.
- Mindket did not run this workflow against Notion, OpenAI or Supabase.
```

## What is in it

3 files, 11 KB, downloaded as a zip.

```text
NOTICE.md  659 B
README.md  4 KB
workflow.json  7 KB
```

## Workflow check

Checked by Mindket on 13 Nov 2026. Read from the workflow’s file, not from a run.

- Steps: 5 steps, starting on a Notion event
- AI: 1 step calls an AI model: Store in Supabase
- Sign-ins: Signs in to: Notion, Supabase and OpenAI
- API keys: No API key is left in the file
- Step types: Mindket’s checker reads all 5 of its step types

## Get it

- [Get it on your Mindket account](https://account.mindket.com/account/?product=mindket#/market/8974be42-4052-4300-9910-7c2df8ccba84)
- [Its page on Mindket](https://mindket.com/p/8974be42-4052-4300-9910-7c2df8ccba84)
