notion-sdk-js is a free, open source api development & testing project written in TypeScript and released under MIT. It has 5,664 GitHub stars, 712 forks and 80 open issues, and was last pushed 27 hours ago. On this registry it ranks #42 of 103 tracked projects in API Development & Testing, with 5 head-to-head comparisons available. It gained 1 stars over the last 3 tracked days.

What is notion-sdk-js?

Notion SDK for JavaScript is the official JavaScript and TypeScript client for the Notion API, and it is aimed at developers building Node.js applications and integrations that read from or write to Notion workspaces.

What it is

The project is a client library published as @notionhq/client, written in TypeScript and licensed under MIT. It wraps the Notion REST API so that callers work with JavaScript objects and promises instead of constructing HTTP requests by hand. Client accepts either an integration token or an OAuth access token through the auth option, and every request method returns a Promise carrying the parsed response.

The concrete problem it solves is request construction and error surface for the Notion API. Endpoint parameters are grouped into a single object, so a caller does not need to remember whether a given parameter belongs in the path, the query string, or the request body. It also normalises failures: API errors reject with an APIResponseError whose code property identifies the condition, and APIErrorCode enumerates the known server error codes. The ecosystem is the JavaScript and TypeScript toolchain, and what it replaces is hand-written HTTP plumbing around the Notion API.

Key capabilities

  • Client constructor from @notionhq/client takes one options object, with auth accepting an integration token or an OAuth access token.
  • Request methods such as notion.users.list({}) and notion.dataSources.query({ data_source_id, filter }) return promises with parsed responses.
  • Endpoint parameters are grouped into a single object, removing the need to track path, query, and body placement separately.
  • Error handling exposes APIResponseError, its code property, the APIErrorCode enumeration, and the isNotionClientError type guard.
  • Logging defaults to writing warnings and errors to the console, with LogLevel.DEBUG also logging response bodies, and a custom logger receiving logLevel, message, and extraInfo.
  • Client options include timeoutMs for emitting a RequestTimeoutError, baseUrl for pointing at a mock server, agent for controlling TCP socket creation, and retry.
  • TypeScript types ship with the package, so request and response shapes are available to typed consumers.

Who uses it and how

  • Node.js applications that treat Notion as a data source, using an integration token for single-workspace access.
  • OAuth-based integrations, where the access token is passed through the same auth option as an integration token.
  • Teams running behind corporate proxies, using the agent option with https-proxy-agent to route requests.
  • Developers testing against a mock server, swapping the root URL through the baseUrl option.
  • People evaluating the API quickly through the linked Val Town template, and those debugging a failing query by enabling LogLevel.DEBUG to see response bodies.

Getting started

Install with npm install @notionhq/client, then construct new Client({ auth: process.env.NOTION_TOKEN }) and call any endpoint method. Notion's getting started guide covers the surrounding setup steps.

How it compares

No comparable client libraries are named in the facts provided for this entry, so it stands alone in this registry.

When to use it — and when not to

A self-hoster needs a Node.js runtime and a Notion integration token or OAuth access token; nothing else is required to operate, since the library carries no database, storage, or mail dependencies. Teams not working in JavaScript or TypeScript should look elsewhere, because the package targets that toolchain only. The evident weakness is maintenance surface: the repository carries 80 open issues, and the README is written as an API reference, deferring setup and higher-level guidance to external Notion documentation rather than covering them in place.

project readme (upstream, from github) — read inline

Notion SDK for JavaScript

Notion logo

A JavaScript and TypeScript client for the Notion API. This reference covers the SDK's methods, options, and helpers.

Build status npm version

Installation

npm install @notionhq/client

Open Val Town Template

Usage

[!NOTE] For setup steps, see Notion's getting started guide.

Client accepts an integration token or an OAuth access token.

const { Client } = require("@notionhq/client")

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

Make a request to any Notion API endpoint.

;(async () => {
  const listUsersResponse = await notion.users.list({})
  console.log(listUsersResponse)
})()

[!NOTE] See the complete list of endpoints in the API reference.

Request methods return a Promise with the response. For example:

{
  results: [
    {
      object: "user",
      id: "d40e767c-d7af-4b18-a86d-55c61f1e39a4",
      type: "person",
      person: {
        email: "[email protected]",
      },
      name: "Avocado Lovelace",
      avatar_url:
        "https://secure.notion-static.com/e6a352a8-8381-44d0-a1dc-9ed80e62b53d.jpg",
    },
    // ...
  ]
}

Endpoint parameters are grouped into a single object. You don't need to remember which parameters go in the path, query, or body.

const myPage = await notion.dataSources.query({
  data_source_id: "897e5a76-ae52-4b48-9fdf-e71f5945d1af",
  filter: {
    property: "Landmark",
    rich_text: {
      contains: "Bridge",
    },
  },
})

Handling errors

Notion API errors reject the request with an APIResponseError. The code property identifies the error. APIErrorCode contains the known server error codes.

const {
  Client,
  APIErrorCode,
  isNotionClientError,
} = require("@notionhq/client")

try {
  const notion = new Client({ auth: process.env.NOTION_TOKEN })
  const myPage = await notion.dataSources.query({
    data_source_id: dataSourceId,
    filter: {
      property: "Landmark",
      rich_text: {
        contains: "Bridge",
      },
    },
  })
} catch (error) {
  if (
    isNotionClientError(error) &&
    error.code === APIErrorCode.ObjectNotFound
  ) {
    // Ask the user to select a different data source.
  } else {
    // Other error handling code
    console.error(error)
  }
}

Logging

The default logger writes warnings and errors to the console. LogLevel.DEBUG also logs response bodies.

const { Client, LogLevel } = require("@notionhq/client")

const notion = new Client({
  auth: process.env.NOTION_TOKEN,
  logLevel: LogLevel.DEBUG,
})

A custom logger receives logLevel, message, and extraInfo. It should return no value.

Client options

The Client constructor accepts one options object.

Option Default value Type Description
auth undefined string Bearer token for authentication. If left undefined, the auth parameter should be set on each request.
logLevel LogLevel.WARN LogLevel Verbosity of logs the instance will produce. By default, logs are written to stdout.
timeoutMs DEFAULT_TIMEOUT_MS number Number of milliseconds to wait before emitting a RequestTimeoutError
baseUrl DEFAULT_BASE_URL string The root URL for sending API requests. This can be changed to test with a mock server.
logger Log to console Logger A custom logging function. This function is only called when the client emits a log that is equal or greater severity than logLevel.
agent Default node agent http.Agent Used to control creation of TCP sockets. A common use is to proxy requests with https-proxy-agent
retry See constants RetryOptions Configuration for automatic retries on rate limits (429), service overloads (529), and server errors (500, 503). See Automatic retries below.

Automatic retries

The client retries failed requests up to 2 times by default. Delays increase with each retry and include a random offset.

Retried errors:

  • rate_limited (HTTP 429) - Too many requests; retried for all HTTP methods
  • service_overload (HTTP 529) - Service overloaded; retried for all HTTP methods
  • internal_server_error (HTTP 500) - Server error; retried only for GET and DELETE
  • service_unavailable (HTTP 503) - Service temporarily unavailable; retried only for GET and DELETE

For server errors, only GET and DELETE are retried to avoid repeating writes. The client uses the Retry-After header when present. It accepts a delay in seconds or an HTTP date.

Retry options:

const notion = new Client({
  auth: process.env.NOTION_TOKEN,
  retry: {
    maxRetries: 5, // Maximum retry attempts (default: 2)
    initialRetryDelayMs: 500, // Initial delay between retries (default: 1000ms)
    maxRetryDelayMs: 60000, // Maximum delay between retries (default: 60000ms)
  },
})

To disable automatic retries:

const notion = new Client({
  auth: process.env.NOTION_TOKEN,
  retry: false,
})

Constants

The SDK exports these defaults and Notion-specific values:

const {
  DEFAULT_BASE_URL, // "https://api.notion.com"
  DEFAULT_TIMEOUT_MS, // 60_000
  DEFAULT_MAX_RETRIES, // 2
  DEFAULT_INITIAL_RETRY_DELAY_MS, // 1_000
  DEFAULT_MAX_RETRY_DELAY_MS, // 60_000
  MIN_VIEW_COLUMN_WIDTH, // 32
} = require("@notionhq/client")

MIN_VIEW_COLUMN_WIDTH is the minimum table column width in pixels. A column at this width appears collapsed. For example:

await notion.views.create({
  database_id: databaseId,
  name: "My view",
  type: "table",
  configuration: {
    table: {
      properties: [
        {
          property_id: checkboxPropId,
          visible: true,
          width: MIN_VIEW_COLUMN_WIDTH,
        },
      ],
    },
  },
})

TypeScript

The package includes types for request parameters, responses, and their fields.

With strict TypeScript, caught errors have type unknown. isNotionClientError narrows the error to a known SDK error type. APIErrorCode identifies server errors; ClientErrorCode identifies errors raised by the client.

import {
  APIErrorCode,
  ClientErrorCode,
  isNotionClientError,
} from "@notionhq/client"

try {
  const response = await notion.dataSources.query({
    data_source_id: dataSourceId,
  })
} catch (error: unknown) {
  if (isNotionClientError(error)) {
    // error is now strongly typed to NotionClientError
    switch (error.code) {
      case ClientErrorCode.RequestTimeout:
        // ...
        break
      case APIErrorCode.ObjectNotFound:
        // ...
        break
      case APIErrorCode.Unauthorized:
        // ...
        break
      default:
        console.error(error)
    }
  }
}
Type guards

These type guards distinguish full API responses from partial responses.

Type guard function Purpose
isFullPage Determine whether an object is a full PageObjectResponse
isFullBlock Determine whether an object is a full BlockObjectResponse
isFullDataSource Determine whether an object is a full DataSourceObjectResponse
isFullPageOrDataSource

readme truncated — read the full docs on github

Frequently asked questions

Is notion-sdk-js free to use?

notion-sdk-js is open source under the MIT licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does notion-sdk-js do?

Official Notion JavaScript Client

What is notion-sdk-js written in?

notion-sdk-js is primarily written in TypeScript. Its source is publicly available at https://github.com/makenotion/notion-sdk-js, and it has 5,664 GitHub stars.