| name | notion-migration-deep-dive |
| description | Migrate data to/from Notion or between Notion workspaces with data mapping and validation.
Use when migrating data into Notion databases, exporting from Notion, syncing between workspaces, or building ETL pipelines with Notion as source or destination.
Trigger with phrases like "migrate notion", "notion migration", "import to notion", "export from notion", "notion data migration", "notion ETL".
|
| allowed-tools | Read, Bash(npm:*), Bash(node:*) |
| version | 1.38.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","productivity","notion"] |
| compatibility | Designed for Claude Code |
Notion Migration Deep Dive
Overview
Production migration patterns for moving data to, from, and between Notion workspaces — rate-limited bulk import, paginated export, cross-platform conversion, and post-migration validation. Every bulk-write path respects Notion's 3 requests/second average rate limit.
Prerequisites
@notionhq/client v2+ installed (npm install @notionhq/client)
- Python alternative:
notion-client (pip install notion-client)
p-queue for rate-limited concurrency (npm install p-queue)
- Source data access (CSV files, Confluence API, Google Docs API, etc.)
- Target Notion database(s) created with matching property schema
Authentication: create a Notion internal integration at
notion.so/my-integrations, share the
target database(s) with it, and export the secret as NOTION_TOKEN. Every code
sample reads process.env.NOTION_TOKEN — the client never takes an inline
credential.
Instructions
The workflow has three directions. Each step below gives the essential shape;
the full runnable code lives in the reference files so this page stays scannable.
Step 1: Import CSV/JSON into a Notion database
Map each source field to a Notion property value object, strip properties the
target schema does not have, and create pages through a rate-limited queue:
const queue = new PQueue({ concurrency: 3, interval: 1000, intervalCap: 3 });
await notion.pages.create({
parent: { database_id: databaseId },
properties: {
Name: { title: [{ text: { content: record.name || } }] },
: { : { : record. || } },
},
});