@notionhq/client

The official JavaScript and TypeScript client for the Notion API, with typed methods for every endpoint.

SDK
npm
v5.28.0
5,681 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
92 /100 Excellent
Development Activity 92
Maintenance 96
Community 80
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
80 /100 Excellent
Architecture 85
Code Quality 88
Innovation 62
Learning Curve 85

@notionhq/client is Notion’s own SDK for its public REST API, published from the same repository the API team maintains. It wraps every endpoint — pages, databases, data sources, blocks, users, comments, views, file uploads, custom emojis, agents, and webhooks — behind a single Client instance with fully typed request parameters and response shapes, so consumers get compile-time checking instead of hand-rolled fetch calls and loosely-typed JSON.

Beyond thin endpoint wrappers, the package ships pagination helpers (iteratePaginatedAPI, collectPaginatedAPI, iterateAllDataSourceRows) that handle Notion’s cursor-based pagination and its 10,000-row data-source query ceiling, type-guard functions (isFullPage, isFullBlock, isFullDataSource, etc.) for narrowing partial vs. full API objects, and webhook signature verification (verifyWebhookSignature) built on HMAC-SHA256. Retry behavior for rate limits and transient server errors is built into the client and configurable per instance.

Because it’s maintained directly by the Notion API team, the SDK tracks new API surface closely — recent additions like data sources, views, meeting notes, and agent-session endpoints appear here first, ahead of most community wrappers.

What You Get

  • A Client class configured once with an integration token or OAuth access token, exposing every API resource (pages, databases, data sources, blocks, users, comments, views, search, file uploads, custom emojis, agents) as typed methods
  • Full TypeScript types for every request parameter and response shape, generated to match the live API rather than hand-maintained
  • Pagination helpers (iteratePaginatedAPI, collectPaginatedAPI) plus iterateAllDataSourceRows/collectAllDataSourceRows for reading past the 10,000-row data-source query limit
  • Type-guard functions (isFullPage, isFullBlock, isFullDataSource, isFullUser, isFullComment, isFullView) to safely narrow partial vs. full API objects
  • Built-in configurable retries with exponential backoff for rate limits (429), overloads (529), and transient server errors (500/503)
  • Webhook helpers (verifyWebhookSignature, signWebhookPayload) for validating and signing Notion webhook deliveries via HMAC-SHA256
  • Typed error handling via isNotionClientError and APIErrorCode/ClientErrorCode enums instead of parsing raw HTTP error bodies

Common Use Cases

  • Syncing external systems (CRMs, ticketing tools, internal dashboards) with Notion databases and data sources as a source or destination of record
  • Building Notion-based internal tools that create, query, and update pages and database rows programmatically
  • Processing Notion webhook events (page/database/comment created, updated, deleted) in a server endpoint with signature verification
  • Backing up or migrating Notion workspace content — pages, blocks, and their nested children — into another format or store
  • Building integrations distributed via the Notion integrations directory that use OAuth to act on behalf of installing workspaces

Under The Hood

Architecture

The package is a thin, single-layer wrapper: src/Client.ts defines one Client class whose constructor takes auth/timeout/retry/logging options, and whose methods are generated from createEndpointMethods in src/api-endpoint-methods.ts against declarative endpoint definitions in src/api-endpoints/*.ts (one file per resource — pages, databases, data-sources, blocks, comments, views, webhooks, agents, meeting-notes, and more). Each endpoint definition pairs a path/method template with parameter-picking logic (pick, getUnknownParams in src/utils.ts), so adding a new API surface is a data-driven addition rather than a new request-plumbing implementation. Cross-cutting concerns — retries, logging, error normalization — live centrally in Client.ts’s request execution path, so every endpoint gets them uniformly. src/helpers.ts layers pagination and type-guard utilities on top of the raw client rather than baking them into it, keeping the core request path simple.

Tech Stack

Written in TypeScript (99.8% of the codebase) targeting Node 18+, with zero runtime dependencies — it uses the platform fetch (or an injected SupportedFetch implementation) rather than axios or node-fetch, keeping it usable in both Node and browser/edge environments. Builds via tsc to build/src, with package.json’s main/types fields pointing at the compiled output. Tooling includes ESLint with @typescript-eslint, Prettier, cspell for spell-checking docs, husky + lint-staged for pre-commit checks, and markdown-link-check for README link validation.

Code Quality

Tests run under Jest (test/ — Client.test.ts, errors.test.ts, helpers.test.ts, webhooks.test.ts, id-extraction.test.ts, plus a compatibility.test.ts/checkCompatibility.ts pair that appears to guard against accidental breaking changes to the public API surface). Errors are modeled as a closed, typed union (NotionClientError = RequestTimeoutError | UnknownHTTPResponseError | APIResponseError | InvalidPathParameterError) with a compile-time assertion (Assert<NotionErrorCode, NotionClientError["code"]>) that keeps error codes from regressing to a loose string type — an unusually strict internal safeguard. CI runs the build and test suite across four Node major versions (18, 19, 20, 22) on every push and PR. Linting enforces curly: all outside the generated endpoint-definition files, where the rule is deliberately relaxed.

What Makes It Unique

As the SDK published directly by the API’s own maintainers rather than a community wrapper, its type definitions and endpoint coverage track new Notion API surface (data sources, views, meeting notes, agent sessions) as soon as it ships. The iterateAllDataSourceRows/collectAllDataSourceRows helpers specifically work around a Notion API constraint most generic HTTP clients wouldn’t know to handle — the 10,000-row query ceiling — by re-querying from the last row’s timestamp and de-duplicating by ID. Built-in webhook signature verification and zero runtime dependencies (relying on native fetch) are also deliberate choices favoring portability over convenience wrappers.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers