| name | notion-architecture-variants |
| description | Use when you are choosing or scaffolding how an app talks to Notion via the
API — deciding between a headless CMS (blog/content site), a task tracker
(project management), a knowledge base (wiki), a form-submission handler, or a
data-pipeline source, and wiring the database schema plus integration code.
Trigger with phrases like "notion cms", "notion headless blog",
"notion task tracker", "notion wiki", "notion form handler", "notion data pipeline".
|
| allowed-tools | Read, Write, Edit, Bash(node:*) |
| version | 1.38.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| tags | ["saas","productivity","notion"] |
| compatibility | Designed for Claude Code |
Notion Architecture Variants
Overview
Five validated architecture patterns for using Notion as a backend via the API, each with database schema design, integration code, and deployment tradeoffs. The full copy-ready code for every variant lives in references/implementation.md; this page gives the decision framework, the shared skeleton, and one worked example so you can pick the right pattern and drill into depth on demand.
The five variants:
| Variant | Use case | Core operation |
|---|
| Headless CMS | Blog / content site | Query Status = Published, render blocks to HTML |
| Task Tracker | Project management | Group by status for a board, pages.update on move |
| Knowledge Base | Wiki / internal docs | Workspace search filtered to the wiki database |
| Form Handler | Contact / lead capture | One pages.create per submission |
| Data Pipeline | Analytics / ETL source | Paginate on a last_edited_time watermark |
Prerequisites
@notionhq/client v2.x installed (npm install @notionhq/client)
- Python:
notion-client installed (pip install notion-client)
NOTION_TOKEN environment variable set
- Notion databases created and shared with your integration
Authentication
All variants authenticate the same way: an internal integration token in the
NOTION_TOKEN environment variable, passed as auth when constructing the
client (new Client({ auth: process.env.NOTION_TOKEN }) / Client(auth=...)).
Create the integration at notion.so/my-integrations, then share each database
with the integration from its Notion page — an unshared database returns
object_not_found even with a valid token. Never hard-code the token; read it
from the environment.
Instructions
- Pick the variant that matches your workload using the decision helper in
references/examples.md — content authoring vs.
real-time status vs. high read volume each point to a different pattern.