A type-safe TypeScript SDK for the Notion API with Zod validation, OOP models, and ergonomic helpers.
- Type-safe Zod v4 runtime validation on every API response; full TypeScript declarations
- Complete API coverage Pages, Blocks, Databases, Data Sources, Comments, Search, Users, File Uploads, Async Tasks, Custom Emojis, Views
- Ergonomic helpers
block,richText,filter,sort,prop,parent,icon,cover, andnotionFilefactories, plus awebhooksignature-verification helper, eliminate verbose JSON and boilerplate - OOP models
Page,Block,Database,User,Comment,DataSource,FileUpload,RichText,AsyncTask,CustomEmoji,Viewwith convenience methods - Automatic pagination
paginate(),paginateIterator(), andpaginateWithMetadata()helpers automatically fetch all pages, plusiterateAllDataSourceRows()/collectAllDataSourceRows()to work around the 10,000-result query cap - Automatic rate limiting Respects
Retry-Afterheader with exponential backoff fallback (configurable) - Client-side size validation Enforces Notion API size limits before sending requests
- Zero bloat Single runtime dependency (
zod); uses built-infetch(Node 18+)
npm install @visus-io/notion-sdk-ts
# or
bun add @visus-io/notion-sdk-tsRequirements: Node.js 18+ or Bun 1.3.10+ (uses native fetch)
import { Notion, block, richText, filter, sort, prop, parent } from '@visus-io/notion-sdk-ts';
const notion = new Notion({ auth: process.env.NOTION_TOKEN });
// Retrieve a page
const page = await notion.pages.retrieve('page-id');
console.log(page.getTitle());
// Create a page in a database
const database = await notion.databases.retrieve('database-id');
const dataSourceId = database.dataSources[0].id;
await notion.pages.create({
parent: parent.dataSource(dataSourceId, database.id),
properties: {
Name: prop.title('New Task'),
Status: prop.status('In Progress'),
Priority: prop.select('High'),
},
});
// Append blocks to a page
await notion.blocks.children.append('page-id', {
children: [
block.heading2('Meeting Notes'),
block.paragraph('Discussed the roadmap for Q2.'),
block.toDo('Follow up with design', { checked: false }),
],
});
// Query a database with filters
const results = await notion.databases.query('database-id', {
filter: filter.and(
filter.status('Status').equals('In Progress'),
filter.select('Priority').equals('High'),
),
sorts: [sort.property('Due Date').ascending()],
});Full documentation is hosted at nts.projects.visus.io. It includes guides and a generated API reference. Source lives in docs/. It has its own dependencies, separate from the root project. Install them once, then run the site locally:
bun run docs:install
bun run docs:devThis SDK now targets Notion API version 2026-03-11 (upgraded from 2025-09-03 in v3.x; originally 2022-06-28 in v1.x). The API version is fixed — it cannot be overridden via client options. See the Migration Guide for complete upgrade details.
This project uses Bun as its package manager for faster dependency installation and script execution.
Install Bun if you haven't already:
curl -fsSL https://bun.sh/install | bashbun install # Install dependencies
bun run build # Compile TypeScript
bun run test # Run tests
bun run test:watch # Watch mode
bun run test:coverage # Coverage report
bun run lint # ESLint
bun run lint:fix # Auto-fix
bun run format # Prettier
bun run docs:install # Install the docs site's dependencies (run once, or after they change)
bun run docs:dev # Run the docs site locally
bun run docs:build # Build the docs siteNote: While this project uses Bun for development, the published package works with both Node.js 18+ and Bun 1.3.10+.
See ARCHITECTURE.md for project structure and architecture.
Contributions are welcome! See CONTRIBUTING.md for how to get started.