Configuration & Features
Configure the Notion client with various options to customize behavior.
Table of Contents
Section titled “Table of Contents”- Basic Configuration
- Authentication
- API Version
- Request Timeouts
- Rate Limiting & Retries
- Custom Fetch Implementation
- Base URL Configuration
Basic Configuration
Section titled “Basic Configuration”Initialize the Notion client with configuration options:
import { Notion } from '@visus-io/notion-sdk-ts';
const notion = new Notion({ auth: process.env.NOTION_TOKEN, // Required // All other options are optional});Authentication
Section titled “Authentication”The auth parameter is required. It must contain your Notion integration token.
Getting an Integration Token
Section titled “Getting an Integration Token”- Go to https://www.notion.so/my-integrations.
- Click “New integration”.
- Give the integration a name.
- Select the capabilities you need.
- Copy the “Internal Integration Token”.
Using the Token
Section titled “Using the Token”const notion = new Notion({ auth: process.env.NOTION_TOKEN,});Security best practice: Always use environment variables for tokens. Do not hardcode tokens in your code.
# .env fileNOTION_TOKEN=secret_your_token_here// Load from .envimport { config } from 'dotenv';config();
const notion = new Notion({ auth: process.env.NOTION_TOKEN,});API Version
Section titled “API Version”The SDK uses Notion API version 2026-03-11. This version is a fixed constant. You cannot
override it with client options. All schemas, request bodies, and helpers depend on this version.
Finding the Target Version
Section titled “Finding the Target Version”The SDK exports the target version as a read-only constant:
import { NOTION_VERSION } from '@visus-io/notion-sdk-ts';
console.log(NOTION_VERSION); // '2026-03-11'
// Useful for logging or conditional logicconsole.log(`Using Notion API version: ${NOTION_VERSION}`);Every outgoing HTTP request carries the header Notion-Version: 2026-03-11 automatically. You do
not need to configure this header.
See the Migration Guide to upgrade from an earlier SDK version.
Request Timeouts
Section titled “Request Timeouts”Set how long the client waits for a response before the request times out.
Default Timeout
Section titled “Default Timeout”const notion = new Notion({ auth: process.env.NOTION_TOKEN, // Default: 60,000ms (60 seconds)});Custom Timeout
Section titled “Custom Timeout”const notion = new Notion({ auth: process.env.NOTION_TOKEN, timeoutMs: 30_000, // 30 seconds});Very Short Timeout
Section titled “Very Short Timeout”const notion = new Notion({ auth: process.env.NOTION_TOKEN, timeoutMs: 5_000, // 5 seconds (for fast-fail scenarios)});Handling Timeout Errors
Section titled “Handling Timeout Errors”import { NotionRequestTimeoutError } from '@visus-io/notion-sdk-ts';
try { await notion.pages.retrieve('page-id');} catch (error) { if (error instanceof NotionRequestTimeoutError) { console.error('Request timed out after', error.message); }}Rate Limiting & Retries
Section titled “Rate Limiting & Retries”The SDK handles rate limiting automatically with retry logic.
Default Behavior
Section titled “Default Behavior”const notion = new Notion({ auth: process.env.NOTION_TOKEN, retryOnRateLimit: true, // Default: automatically retry 429 responses maxRetries: 3, // Default: retry up to 3 times});How it works:
- The SDK receives a
429 Too Many Requestsresponse. - The SDK checks the
Retry-Afterheader from the Notion API. - The SDK waits for the duration in the header.
- If the header is missing, the SDK uses exponential backoff instead: 1 second, 2 seconds, 4 seconds, 8 seconds, and so on, up to a maximum of 60 seconds.
- The SDK retries the request automatically.
Disable Automatic Retries
Section titled “Disable Automatic Retries”const notion = new Notion({ auth: process.env.NOTION_TOKEN, retryOnRateLimit: false, // Do not retry on 429});Note:
retryOnRateLimitcontrols only 429 retries. The SDK always retries529 Service Overloadresponses, up tomaxRetries, no matter the value ofretryOnRateLimit. SeeisServiceOverloaded().
Custom Max Retries
Section titled “Custom Max Retries”const notion = new Notion({ auth: process.env.NOTION_TOKEN, maxRetries: 5, // Retry up to 5 times});No Retries
Section titled “No Retries”const notion = new Notion({ auth: process.env.NOTION_TOKEN, maxRetries: 0, // Never retry});Rate Limit Error Handling
Section titled “Rate Limit Error Handling”Retries do not prevent all rate limits. You might still get a rate-limited response:
import { NotionAPIError } from '@visus-io/notion-sdk-ts';
try { await notion.pages.retrieve('page-id');} catch (error) { if (error instanceof NotionAPIError && error.isRateLimited()) { console.error('Rate limited after retries'); console.error('Retry after:', error.message); }}Custom Fetch Implementation
Section titled “Custom Fetch Implementation”The SDK uses the native fetch API in Node 18 and later. You can provide your own
implementation instead.
Default Behavior
Section titled “Default Behavior”const notion = new Notion({ auth: process.env.NOTION_TOKEN, // Uses native fetch by default});Custom Fetch
Section titled “Custom Fetch”A custom fetch implementation is useful for these cases:
- Custom logging or telemetry
- A different HTTP client
- Proxy support
- Tests with mock data
const notion = new Notion({ auth: process.env.NOTION_TOKEN, fetch: async (url, init) => { console.log(`Fetching: ${url}`); const response = await fetch(url, init); console.log(`Status: ${response.status}`); return response; },});Proxy Support Example
Section titled “Proxy Support Example”import { HttpsProxyAgent } from 'https-proxy-agent';
const proxyAgent = new HttpsProxyAgent('http://proxy.example.com:8080');
const notion = new Notion({ auth: process.env.NOTION_TOKEN, fetch: (url, init) => fetch(url, { ...init, agent: proxyAgent }),});Mock Fetch for Testing
Section titled “Mock Fetch for Testing”const mockFetch = async (url: string, init?: RequestInit) => { return new Response(JSON.stringify({ id: 'test-id' }), { status: 200, headers: { 'Content-Type': 'application/json' }, });};
const notion = new Notion({ auth: 'test-token', fetch: mockFetch,});Base URL Configuration
Section titled “Base URL Configuration”Change the API base URL. Most projects do not need this option.
Default
Section titled “Default”const notion = new Notion({ auth: process.env.NOTION_TOKEN, baseUrl: 'https://api.notion.com', // Default});Custom Base URL
Section titled “Custom Base URL”A custom base URL is useful for these cases:
- Tests against a mock server
- A proxy
- Development or staging environments
const notion = new Notion({ auth: process.env.NOTION_TOKEN, baseUrl: 'http://localhost:3000', // Local mock server});Complete Configuration Example
Section titled “Complete Configuration Example”This example shows a fully configured client with all options:
import { Notion } from '@visus-io/notion-sdk-ts';import { config } from 'dotenv';
config(); // Load .env
const notion = new Notion({ // Required auth: process.env.NOTION_TOKEN!,
// API Configuration baseUrl: 'https://api.notion.com', // Default
// Timeout Configuration timeoutMs: 60_000, // 60 seconds (default)
// Rate Limiting & Retries retryOnRateLimit: true, // Default maxRetries: 3, // Default
// Custom Fetch (optional) fetch: async (url, init) => { // Add custom logging or a proxy console.log(`API Call: ${url}`); return fetch(url, init); },});Environment-Specific Configuration
Section titled “Environment-Specific Configuration”Configure the client differently for each environment:
const isProduction = process.env.NODE_ENV === 'production';
const notion = new Notion({ auth: process.env.NOTION_TOKEN!, timeoutMs: isProduction ? 60_000 : 10_000, // Use a shorter timeout for development maxRetries: isProduction ? 3 : 0, // Skip retries in development for faster feedback fetch: isProduction ? undefined // Use default fetch : async (url, init) => { // Add debug logging in development console.log(`[DEV] ${init?.method || 'GET'} ${url}`); return fetch(url, init); },});Related Pages
Section titled “Related Pages”- Getting Started: basic setup and initialization.
- Error Handling: how to handle API errors and timeouts.
- Common Use Cases: practical configuration examples.