Authentication overview

The Notion API provides programmatic access to Notion workspaces, allowing developers to interact with pages, databases, and blocks. To ensure secure and controlled access, all requests to the Notion API must be authenticated. Notion supports two primary authentication mechanisms: internal integrations for private, single-workspace use cases and public integrations using OAuth 2.0 for applications that need to access multiple user workspaces. Choosing the correct method depends on the integration's purpose, audience, and required access level.

Internal integrations are suitable for personal scripts, automation within a single Notion workspace, or integrations where the developer is also the Notion workspace owner or administrator. This method involves creating an API token that grants access to specific pages and databases within that workspace. OAuth 2.0, conversely, is designed for third-party applications or services that need to be authorized by multiple Notion users to access their respective workspaces. This standard protocol enables delegated authorization, where users grant permissions to an application without sharing their Notion login credentials directly with the application.

Proper authentication is critical for maintaining data security and privacy within Notion. Developers must understand the implications of each authentication method, including how credentials are obtained, stored, and used, to prevent unauthorized access and protect sensitive information. The Notion API adheres to standard security practices, including the use of HTTPS for all communications to encrypt data in transit and the recommendation for secure storage of API keys and tokens.

Supported authentication methods

Notion API supports two distinct authentication methods, each designed for different integration scenarios:

Internal Integrations (API Tokens)

Internal integrations function by generating an API token within a specific Notion workspace. This token acts as a bearer token, which is included in the Authorization header of API requests. Access granted by an internal integration is limited to the workspace where it was created and to the specific pages and databases it has been invited to. This method is generally simpler to set up for individual or small-team use cases that do not require external user authorization.

Public Integrations (OAuth 2.0)

OAuth 2.0 is an industry-standard protocol for authorization that allows a user to grant a third-party application limited access to their resources without exposing their credentials. For the Notion API, OAuth 2.0 enables public applications to request and receive authorization from Notion users to access their workspaces. The flow involves obtaining a client ID and client secret, redirecting users to Notion for authorization, and exchanging an authorization code for an access token and refresh token. This method is essential for applications that serve multiple users across different Notion workspaces, as it provides a secure and scalable way to manage delegated permissions. The OAuth 2.0 framework is detailed by the OAuth 2.0 specification.

The following table summarizes the key characteristics of each authentication method:

Method When to Use Security Level / Best Practices
Internal Integrations (API Tokens)
  • Personal scripts and automations
  • Integrations within a single, controlled Notion workspace
  • When the developer has administrative access to the target workspace
  • Token should be treated as sensitive as a password.
  • Store securely (e.g., environment variables, secret management service).
  • Grant minimal necessary permissions to the integration.
  • Revoke tokens promptly if compromised or no longer needed.
Public Integrations (OAuth 2.0)
  • Third-party applications serving multiple Notion users
  • When requiring user consent to access their Notion workspaces
  • Building public-facing integrations or marketplaces
  • Follow OAuth 2.0 best practices (e.g., PKCE for public clients).
  • Securely store client secret (server-side only).
  • Handle access and refresh tokens securely.
  • Implement proper scope management and user consent flows.
  • Ensure redirect URIs are secured.

Getting your credentials

For Internal Integrations:

  1. Create an Integration: Navigate to My integrations in Notion. Click the "New integration" button.
  2. Configure Integration: Provide a name for your integration, select the associated workspace, and specify the capabilities (read, update, insert content, user information).
  3. Retrieve API Token: After creating the integration, an "Internal Integration Token" will be displayed. This is your API token. Copy it immediately as it will only be shown once.
  4. Share with Pages/Databases: For the integration to access specific pages or databases, it must be invited. Open the page or database in Notion, click the "..." (more options) menu, select "Add connections," and choose your integration. This grants the integration permission to interact with that specific resource, based on the capabilities defined during integration creation.

For Public Integrations (OAuth 2.0):

  1. Create an Integration: Similar to internal integrations, start by creating a new integration on My integrations.
  2. Configure as Public: When configuring, select "Public integration." You will need to provide an icon, description, and importantly, configure redirect URIs. These URIs are where Notion will send the authorization code after a user grants permission.
  3. Retrieve Client ID and Client Secret: Upon creating a public integration, you will be provided with a "Client ID" and a "Client Secret." The Client Secret should be treated with the same confidentiality as an API token and never exposed in client-side code.
  4. Implement OAuth Flow: Your application will then need to initiate the OAuth 2.0 authorization code flow. This involves directing users to Notion's authorization URL, handling the redirect back to your application with an authorization code, and exchanging that code for an access token and a refresh token using your Client ID and Client Secret.

Authenticated request example

Once you have obtained your API token (for internal integrations) or an access token (for OAuth 2.0), you can use it to authenticate your requests to the Notion API. The token is typically included in the Authorization header using the Bearer scheme.

Here's an example using curl to retrieve a Notion database. Replace YOUR_NOTION_SECRET with your actual API token and DATABASE_ID with the ID of the database you wish to query.

curl -X GET 'https://api.notion.com/v1/databases/DATABASE_ID'
  -H 'Authorization: Bearer YOUR_NOTION_SECRET'
  -H 'Notion-Version: 2022-06-28'

For Python, using the official Notion SDK:

from notion_client import Client

notion = Client(auth="YOUR_NOTION_SECRET")
database_id = "DATABASE_ID"

# List all pages in the specified database
response = notion.databases.query(
    database_id=database_id
)

for page in response['results']:
    print(page['properties']['Name']['title'][0]['plain_text'])

For JavaScript, using the official Notion SDK:

import { Client } from "@notionhq/client";

const notion = new Client({ auth: "YOUR_NOTION_SECRET" });
const databaseId = "DATABASE_ID";

async function getDatabasePages() {
  const response = await notion.databases.query({
    database_id: databaseId,
  });

  for (const page of response.results) {
    console.log(page.properties.Name.title[0].plain_text);
  }
}

getDatabasePages();

Ensure that the Notion-Version header is always included in your requests, as specified in the Notion API reference documentation. This header helps ensure compatibility with specific API versions.

Security best practices

Adhering to security best practices is essential when integrating with the Notion API to protect your data and your users' data.

  • Least Privilege: Always grant your integration the minimum necessary permissions. When creating an internal integration, carefully select the capabilities (read, update, insert, user information). For OAuth 2.0, request only the scopes required for your application's functionality. This limits the potential impact if a token is compromised.
  • Secure Credential Storage: Never hardcode API tokens or client secrets directly into your application's source code. Store them securely using environment variables, cloud secret management services (e.g., AWS Secrets Manager, Google Secret Manager), or secure configuration files. For client-side applications, ensure that API keys are not directly exposed and use backend proxies where possible.
  • HTTPS Everywhere: The Notion API requires all communication to occur over HTTPS. This encrypts data in transit, protecting sensitive information (like API tokens and data payloads) from eavesdropping and man-in-the-middle attacks. This is a fundamental principle for secure web communication.
  • Token Rotation and Revocation: Regularly rotate your API tokens, especially for internal integrations. If you suspect an API token has been compromised, revoke it immediately through your Notion integration settings. For OAuth 2.0, implement refresh token rotation and revocation mechanisms to manage long-lived access.
  • Error Handling and Logging: Implement robust error handling to gracefully manage authentication failures. Log authentication attempts and failures (without logging the actual credentials) to monitor for suspicious activity.
  • Rate Limiting: Be mindful of Notion API's rate limits. While not strictly an authentication practice, exceeding limits can lead to temporary blocks, which might be perceived as authentication issues. Implement retries with exponential backoff to handle rate limit errors gracefully.
  • Validate Redirect URIs (OAuth 2.0): For public integrations, ensure that your configured redirect URIs are specific, secure, and only under your control. Broad or insecure redirect URIs can be exploited in phishing or token interception attacks.
  • Proof Key for Code Exchange (PKCE) (OAuth 2.0): For public clients (e.g., mobile apps, single-page applications) using OAuth 2.0, implement PKCE to mitigate authorization code interception attacks.