Notion SDK for JavaScript

repository·main·Indexed 26 days ago

https://github.com/makenotion/notion-sdk-js

A JavaScript and TypeScript client for the Notion API (version 5.23.2). It provides a type-safe interface for managing pages, users, and data sources, featuring automatic retries for rate limits and server errors, pagination utilities like iteratePaginatedAPI, and support for OAuth token exchange, introspection, and revocation. The SDK supports Notion API versions 2025-09-03 and 2026-03-11, requiring Node.js >= 18.

Tokens
6.9K
Snippets
13
Records
57
Agent score
91%

What's inside @notionhq/client

  1. Migrate to Notion API version 2026-03-11

    main

    When upgrading to the 2026-03-11 API version, be aware of the following breaking changes:

    • Block positioning: The after parameter on appendBlockChildren is replaced by position, which supports after_block, start, and end.
    • Trash status: The archived field is replaced by in_trash on pages, blocks, databases, and data sources.
    • Block type rename: The transcription block type is renamed to meeting_notes.

    Both old and new field names are available in the SDK's TypeScript types for migration, but older fields are marked @deprecated.

  2. Initialize the Notion Client

    main

    Import and initialize the Client using an integration token or an OAuth access token. All API methods return a Promise that resolves to the response object. Endpoint parameters are passed as a single object, so you do not need to distinguish between path, query, or body parameters manually.

    const { Client } = require("@notionhq/client")
    
    // Initializing a client
    const notion = new Client({
      auth: process.env.NOTION_TOKEN,
    })
    
    // Making a request
    ;(async () => {
      const listUsersResponse = await notion.users.list({})
    })()
  3. Handle API errors with APIErrorCode

    main

    If an API request fails, the returned Promise rejects with an APIResponseError. To handle errors safely and avoid typos, compare the error.code property against the APIErrorCode object.

    const { Client, APIErrorCode } = 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 (error.code === APIErrorCode.ObjectNotFound) {
        // Handle specific error case
      } else {
        console.error(error)
      }
    }
  4. Check requirements and compatibility

    main

    Ensure your environment meets the following minimum requirements:

    • Runtime: node >= 18
    • Type definitions (optional): typescript >= 5.9

    Note that SDK versions have minimum recommended Notion API versions due to backwards-incompatible changes:

    • v4.0.0 and above: Minimum recommended API version 2022-06-28
    • v5.0.0 and above: Minimum recommended API version 2025-09-03
  5. Configure Client logging and LogLevel

    main

    The client emits logs to stdout by default, showing only warnings and errors. To debug and see response bodies, set logLevel to LogLevel.DEBUG. You can also provide a custom logger function which accepts three parameters: logLevel, message, and extraInfo.

    const { Client, LogLevel } = require("@notionhq/client")
    
    const notion = new Client({
      auth: process.env.NOTION_TOKEN,
      logLevel: LogLevel.DEBUG,
    })
  6. Configure the Notion API version

    main

    The SDK supports Notion API versions 2025-09-03 and 2026-03-11. The default version is 2025-09-03. To use a specific version, pass the notionVersion option when constructing the Client.

    const notion = new Client({
      auth: process.env.NOTION_TOKEN,
      notionVersion: "2026-03-11",
    })
  7. Configure Automatic retries

    main

    The client automatically retries requests that fail due to rate limiting (429), service overload (529), or transient server errors (500, 503).

    • 429 and 529: Retried for all HTTP methods.
    • 500 and 503: Retried only for idempotent methods (GET, DELETE).

    By default, it retries up to 2 times using exponential back-off with jitter. You can customize this via the retry option.

    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 retries:
    const notionNoRetry = new Client({
      auth: process.env.NOTION_TOKEN,
      retry: false,
    })
  8. Paginate through API results with `iteratePaginatedAPI` and `collectPaginatedAPI`

    main

    Use these utilities to handle paginated endpoints (those accepting start_cursor):

    • iteratePaginatedAPI(listFn, firstPageArgs): Returns an async iterator to process results one by one.
    • collectPaginatedAPI(listFn, firstPageArgs): Returns an array containing all results (ensure data fits in memory).
    // As an async iterator
    for await (const block of iteratePaginatedAPI(notion.blocks.children.list, {
      block_id: parentBlockId,
    })) {
      // Do something
    }
    
    // As an array
    const blocks = await collectPaginatedAPI(notion.blocks.children.list, {
      block_id: parentBlockId,
    })
  9. Make custom requests with `notion.request()`

    main

    If a specific endpoint is not yet available as a dedicated method in the SDK, use notion.request(). This method is generic and allows you to specify the path, method, and body directly.

    // POST /v1/comments
    const response = await notion.request({
      path: "comments",
      method: "post",
      body: {
        parent: { page_id: "5c6a28216bb14a7eb6e1c50111515c3d" },
        rich_text: [{ text: { content: "Hello, world!" } }],
      },
    })
  10. Verify Notion Webhook signatures

    main

    Use verifyWebhookSignature to confirm that incoming webhook requests were sent by Notion. You must provide the raw request body (as text or bytes), the X-Notion-Signature header, and your subscription's verification token.

    Note: Do not use a JSON-parsed body for verification, as re-serialization changes whitespace and will cause verification to fail.

    import { verifyWebhookSignature } from "@notionhq/client"
    
    // In an Express handler
    const ok = await verifyWebhookSignature({
      body: req.body, // Must be raw text/bytes
      signature: req.header("x-notion-signature"),
      verificationToken: process.env.NOTION_WEBHOOK_VERIFICATION_TOKEN!,
    })
    
    if (!ok) {
      return res.status(401).send("invalid signature")
    }