Notion to Snowflake: How to Move Your Data

Move Notion into Snowflake with Airbyte. Why opt-in page sharing decides your dataset, the Data Sources rename in v4.0.0, and handling a 30-level block tree.

Summarize with AI:

Moving Notion into Snowflake lets you join the content your teams actually work in to the numbers your warehouse already holds. Notion is a capable place to run a project tracker or a lightweight CRM, but it cannot tell you how those records relate to revenue, tickets or headcount, and its own search will not answer a question that spans two databases and a year of history.

This guide covers the managed path with Airbyte. Two things shape the build more than anything else: the integration sees only what somebody has explicitly shared with it, and a Notion page is a tree of nested blocks rather than a row of text.

Notion to Snowflake at a glance:

CapabilitySupportedWhat it means for this pipeline
Page accessOpt-in onlyThe integration sees pages explicitly shared with it, nothing else
Databases streamRenamedCalled Data Sources from connector version 4.0.0 onwards
Block nestingUp to 30 levelsRebuilding a page means walking a tree, not reading a column
Excluded blocksSeveralchild_page, child_database and AI blocks do not come through
Rate limitAround 3 per secondLarge workspaces sync slowly rather than failing outright

Why move data from Notion to Snowflake?

Two situations account for most of these pipelines.

The first is that Notion has quietly become a system of record. Somebody built a client tracker, a hiring pipeline or a roadmap as a Notion database, other teams started relying on it, and now it holds facts that exist nowhere else. Those records only become useful analytically once they sit beside the warehouse tables they describe, and Notion offers no way to join across that boundary.

The second is governance and history. Warehousing the workspace gives you a queryable record of what exists, who owns it and how it changed, which is the sort of question that comes up during an audit or a migration and that in-product search cannot answer. The pairing makes less sense if your workspace is small and the real aim is to power an application rather than to analyse anything. A warehouse is an expensive place to serve single-record lookups from, and Notion to PostgreSQL covers that shape better.

What do you need before you start?

Four things, and the second one determines your entire dataset:

An integration and its token. Create an internal integration in your Notion settings and keep its secret, or use OAuth if you prefer. The Notion source documentation walks through both routes.

A decision about what the integration can see. Access is opt-in per page. A freshly created integration sees nothing at all until somebody connects it to specific pages, and sharing a parent page passes that access down to its children. Work out which top-level pages cover the ground you want before you sync anything.

Snowflake objects and a role. A warehouse, database, schema and a role that can create tables. Most workspaces are modest in volume, so the smallest warehouse is usually ample; the constraint here is the source's pace rather than Snowflake's.

A start date, or a clear view of the default. Leave it blank and the connector reaches back two years, which is a reasonable default but not the same as everything. If your workspace predates that and the older pages matter, set the date deliberately.

If your Snowflake account restricts inbound traffic by IP, add the Airbyte Cloud IP addresses to the network policy before you begin.

How do you build a Notion to Snowflake pipeline in Airbyte?

Step 1: Share pages with the integration from the top down

This is the step that decides what your dataset contains, and it happens in Notion rather than in Airbyte. Because sharing a parent cascades to its children, connecting the integration to a handful of well-chosen top-level pages is far more maintainable than sharing hundreds of individual ones. Write down which pages you shared, because six months later nobody will remember why a particular team's content is absent.

Step 2: Configure the Notion source

Click Sources in the left navigation, then New Source, and select Notion, following adding a source. Supply the token and your start date. If you are looking for a stream called Databases and cannot find one, it was renamed to Data Sources in version 4.0.0, which catches out anyone following older notes.

Step 3: Configure the Snowflake destination

Click Destinations, then New Destination, and select Snowflake, following adding a destination. Supply the account identifier, warehouse, database, schema and role. Notion content is arbitrary text written by people, so give this its own schema rather than dropping it beside your modelled tables, and assume it will eventually contain something sensitive.

Step 4: Create the connection and decide how pages get rebuilt

Click Connections, then New connection, select your streams and a sync mode. The decision worth making now is whether anything downstream needs whole pages as readable text. If it does, that reassembly is a recursive query you will write in Snowflake, and it is easier to plan for than to retrofit once somebody asks why the page content column looks like fragments.

Daily is plenty for most workspaces. The connector works at roughly three requests per second, so a large workspace takes a while on its first pass, and retried requests do not eat into the retry budget, which means transient failures tend to resolve themselves rather than end the sync.

Why does your sync miss pages that clearly exist?

Because Notion access is opt-in rather than inherited from whoever created the integration. An integration begins with access to nothing, and gains a page only when somebody connects it to that page. This is a sensible privacy model and a confusing one to debug, because a workspace administrator looking at the same content in the browser sees everything the pipeline cannot.

The cascade is the lever. Sharing a parent page grants access to everything beneath it, so the sensible approach is a small number of deliberate grants at the top of each area rather than page-by-page sharing that nobody maintains. New pages created under a shared parent arrive automatically; new top-level pages do not, which is the gap that opens up over time.

Sharing is not the only reason content goes missing. The connector excludes child_page and child_database blocks along with AI blocks, so a page that is mostly links to sub-pages arrives looking thin even when access is correct. Nothing errors in either case. The dataset simply looks complete, which is why it is worth spot-checking a page you know well against what landed before anyone builds on top of it.

How should Snowflake hold a 30-level block tree?

As nested structure, not as flattened columns. A Notion page is not a document with a body field; it is blocks containing blocks, nesting as deep as thirty levels, where a toggle holds a list that holds a paragraph that holds more toggles. Snowflake handles semi-structured data natively, so the tree can land as it arrives rather than being forced into a shape it does not have.

Reassembling a readable page is then a recursive query. You walk from a page's top-level blocks down through their children, accumulating text in order, which a recursive common table expression does comfortably. Build it once as a view and let everything downstream read that rather than having each analyst work out the traversal again and quietly get a different answer.

Two Snowflake habits pay off here. Use TRY_CAST rather than a plain cast when pulling typed values out of Notion properties, since it returns null on failure instead of raising and stopping the query, and people put unexpected things in property fields. And because page content is free text that may contain personal data, salary discussions or customer names, masking policies and row access policies are worth applying to the content columns from the start rather than after somebody notices.

Frequently asked questions

Where did the databases stream go?

It was renamed to Data Sources in connector version 4.0.0. The content is the same, so guides and internal notes written before that version will point you at a name that no longer appears.

Will this pull pages nobody shared with the integration?

No. Access is opt-in per page and cascades only downwards from a shared parent, so unshared areas of the workspace stay invisible to the pipeline regardless of who created the integration.

How far back does the first sync reach?

Two years, if you leave the start date blank. Set it explicitly when your workspace is older than that and the earlier history is part of what you are trying to capture.

Why is the first sync slow on a large workspace?

The connector works at around three requests per second, and a deeply nested workspace needs a request per level of block. It is a question of patience on the first pass rather than a configuration problem; later incremental syncs are much lighter.

Can I do this without writing code?

The pipeline itself, yes, since the setup above is entirely UI-driven. Turning the block tree back into readable pages needs a recursive query in Snowflake, so plan for one view even if nothing else requires SQL.

Get your Notion data into Snowflake

Share a small number of top-level pages deliberately and record which ones, because that list is your dataset definition whether or not anybody writes it down. Set the start date rather than accepting two years by accident. Land the blocks as nested structure, build the recursive view once, and apply masking to content columns before somebody puts something sensitive in a page nobody expected you to be reading.

Airbyte's connector catalog includes 600+ pre-built connectors, so the tools your teams write in can sit beside the systems they report on. For the same source into a different warehouse, see Notion to BigQuery, and for a comparable knowledge base into the same destination, Confluence to Snowflake.

Start syncing now →

Integrate with 700+ apps using Airbyte

Move data from 700+ sources into warehouses, lakes, and beyond. Set up pipelines in minutes with pre-built connectors and the Connector Builder.