Skip to content

Getting Started

This guide shows the first steps for @visus-io/notion-sdk-ts. You install the SDK and send your first API call in a few minutes.

Terminal window
npm install @visus-io/notion-sdk-ts

Requirements:

  • Node.js 18 or later. This version has the built-in fetch function.
  • A Notion integration token. Create one at My Integrations.
import { Notion } from '@visus-io/notion-sdk-ts';
const notion = new Notion({
auth: process.env.NOTION_TOKEN, // Your integration token
});
const page = await notion.pages.retrieve('page-id');
console.log(page.getTitle());
console.log(page.url);

API version 2026-03-11 requires a data source ID. Get the data source ID before you create the page:

import { prop, parent } from '@visus-io/notion-sdk-ts';
// Get the database and its data source
const database = await notion.databases.retrieve('database-id');
const dataSourceId = database.dataSources[0].id;
// Create a page
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'),
'Due Date': prop.date('2025-03-01'),
},
});
import { block, richText } from '@visus-io/notion-sdk-ts';
await notion.blocks.children.append('page-id', {
children: [
block.heading2('Meeting Notes'),
block.paragraph('Discussed the roadmap for Q2.'),
block.paragraph(richText('Action item: ').build().concat(richText('ship v2').bold().build())),
block.toDo('Follow up with design', { checked: false }),
block.divider(),
block.code('console.log("hello")', 'typescript'),
],
});
import { filter, sort } from '@visus-io/notion-sdk-ts';
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()],
});
for (const page of results.results) {
console.log(page.getTitle(), page.url);
}
const search = await notion.search.query({
query: 'project planning',
filter: { property: 'object', value: 'page' },
});
for (const result of search.results) {
console.log(result.getTitle(), result.url);
}

Set your Notion integration token:

const notion = new Notion({
auth: process.env.NOTION_TOKEN,
});

The SDK uses Notion API version 2026-03-11. You cannot change this version. To find the version in code, use the exported constant:

import { NOTION_VERSION } from '@visus-io/notion-sdk-ts';
console.log(NOTION_VERSION); // '2026-03-11'

See the Migration Guide to upgrade from an earlier SDK version.

const notion = new Notion({
auth: process.env.NOTION_TOKEN,
timeoutMs: 30_000, // 30 seconds (default: 60 seconds)
});

The SDK handles rate limiting automatically. To turn this off, set retryOnRateLimit to false:

const notion = new Notion({
auth: process.env.NOTION_TOKEN,
retryOnRateLimit: false, // Disable automatic retries
maxRetries: 5, // Or adjust max retries (default: 3)
});
import { richText } from '@visus-io/notion-sdk-ts';
// Simple text
richText('Hello world').build();
// Formatted text
richText('Important').bold().italic().color('red').build();
// With link
richText('Notion').link('https://notion.so').build();
// Combine multiple segments
richText.join(
richText('Normal '),
richText('bold').bold(),
richText(' and '),
richText('italic').italic(),
);
import { block } from '@visus-io/notion-sdk-ts';
const content = [
block.heading1('Title'),
block.paragraph('Some text'),
block.bulletedListItem('First item'),
block.bulletedListItem('Second item'),
block.divider(),
block.callout('Important note!', { icon: { type: 'emoji', emoji: '⚠️' } }),
];
await notion.blocks.children.append('page-id', { children: content });
import { paginate } from '@visus-io/notion-sdk-ts';
// Get all blocks from a page
const allBlocks = await paginate((cursor) =>
notion.blocks.children.list('page-id', { start_cursor: cursor }),
);
console.log(`Total blocks: ${allBlocks.length}`);
import { NotionAPIError, NotionValidationError } from '@visus-io/notion-sdk-ts';
try {
await notion.pages.retrieve('page-id');
} catch (error) {
if (error instanceof NotionValidationError) {
console.error('Invalid input:', error.message);
} else if (error instanceof NotionAPIError) {
console.error(`API error ${error.status}:`, error.message);
if (error.isNotFound()) {
console.error('Page not found');
} else if (error.isUnauthorized()) {
console.error('Invalid token or missing permissions');
}
}
}