The Client class is the main entry point for interacting with the Notion API. It handles authentication, request management, and provides access to all API endpoints.
Basic Initialization
Create a client instance with your Notion API token:
import { Client } from '@notionhq/client'
const notion = new Client({
auth: process.env.NOTION_API_KEY,
})
Client Options
The client accepts several configuration options:
Authentication
Your Notion integration token or OAuth access token. Can also be provided per-request.
const notion = new Client({
auth: 'secret_1234567890abcdefghijklmnopqrstuv',
})
Base URL
baseUrl
string
default:"https://api.notion.com"
The base URL for Notion API requests. Useful for testing or proxying.
const notion = new Client({
auth: process.env.NOTION_API_KEY,
baseUrl: 'https://api.notion.com', // default
})
Notion Version
notionVersion
string
default:"2025-09-03"
The Notion API version to use. Defaults to Client.defaultNotionVersion.
const notion = new Client({
auth: process.env.NOTION_API_KEY,
notionVersion: '2025-09-03',
})
Request Timeout
Request timeout in milliseconds. Requests exceeding this limit will throw a RequestTimeoutError.
const notion = new Client({
auth: process.env.NOTION_API_KEY,
timeoutMs: 30000, // 30 seconds
})
Custom Fetch
Custom fetch implementation. Useful for testing or using alternative HTTP clients.
import fetch from 'node-fetch'
const notion = new Client({
auth: process.env.NOTION_API_KEY,
fetch: fetch,
})
HTTP Agent
Node.js HTTP agent for connection pooling and proxy support. Silently ignored in browsers.
import { Agent } from 'node:http'
const agent = new Agent({
keepAlive: true,
maxSockets: 50,
})
const notion = new Client({
auth: process.env.NOTION_API_KEY,
agent: agent,
})
Retry Configuration
See Retries for detailed retry configuration.
Logging
See Logging for logging configuration options.
Making Requests
The client provides namespaced methods for each API resource:
// Blocks
await notion.blocks.retrieve({ block_id: 'block-id' })
await notion.blocks.update({ block_id: 'block-id', ... })
await notion.blocks.delete({ block_id: 'block-id' })
await notion.blocks.children.list({ block_id: 'block-id' })
await notion.blocks.children.append({ block_id: 'block-id', children: [...] })
// Pages
await notion.pages.create({ parent: { database_id: 'db-id' }, properties: {...} })
await notion.pages.retrieve({ page_id: 'page-id' })
await notion.pages.update({ page_id: 'page-id', properties: {...} })
await notion.pages.move({ page_id: 'page-id', parent: {...} })
// Databases
await notion.databases.create({ parent: { page_id: 'page-id' }, ... })
await notion.databases.retrieve({ database_id: 'db-id' })
await notion.databases.update({ database_id: 'db-id', ... })
// Data Sources
await notion.dataSources.create({ ... })
await notion.dataSources.retrieve({ data_source_id: 'ds-id' })
await notion.dataSources.update({ data_source_id: 'ds-id', ... })
await notion.dataSources.query({ data_source_id: 'ds-id', ... })
// Users
await notion.users.retrieve({ user_id: 'user-id' })
await notion.users.list({})
await notion.users.me({})
// Comments
await notion.comments.create({ parent: { page_id: 'page-id' }, rich_text: [...] })
await notion.comments.retrieve({ comment_id: 'comment-id' })
await notion.comments.list({ block_id: 'block-id' })
// Search
await notion.search({ query: 'meeting notes' })
Custom Requests
For advanced use cases, you can make custom requests using the request method:
const response = await notion.request({
path: 'blocks/block-id',
method: 'get',
query: { filter_properties: 'title' },
})
Request Parameters
The API endpoint path (without the /v1/ prefix).
method
'get' | 'post' | 'patch' | 'delete'
required
The HTTP method.
query
Record<string, string | number | boolean | string[]>
URL query parameters.
Request body for POST and PATCH requests.
auth
string | { client_id: string; client_secret: string }
Override the client-level auth for this request.
Per-Request Authentication
You can override the client-level authentication for individual requests:
const notion = new Client() // No default auth
// Use different tokens for different requests
await notion.pages.retrieve({
page_id: 'page-id',
auth: 'secret_workspace_a_token',
})
await notion.blocks.retrieve({
block_id: 'block-id',
auth: 'secret_workspace_b_token',
})
OAuth Authentication
For OAuth flows, provide client_id and client_secret:
const notion = new Client()
// Exchange authorization code for access token
const tokenResponse = await notion.oauth.token({
client_id: process.env.OAUTH_CLIENT_ID,
client_secret: process.env.OAUTH_CLIENT_SECRET,
grant_type: 'authorization_code',
code: authorizationCode,
redirect_uri: 'https://example.com/callback',
})
// Use the access token for subsequent requests
const authedClient = new Client({
auth: tokenResponse.access_token,
})
See the OAuth guide for more details.
Type Safety
All methods return fully typed responses:
import { PageObjectResponse } from '@notionhq/client'
const page = await notion.pages.retrieve({ page_id: 'page-id' })
// TypeScript knows the shape of the response
if (page.object === 'page' && 'url' in page) {
const url: string = page.url
const createdTime: string = page.created_time
}
See TypeScript for more on working with types.