Guide Topics NotionAI agents & MCP

How to Get a Notion API Key and Find the IDs Your Requests Need

On this page
TL;DRFor your own scripts, create a personal access token: turn on Developer Mode in Notion’s settings, open Personal access tokens in the sidebar’s developer section and click New token. For a team automation, a workspace owner creates an internal connection, copies its API token and shares pages with it. Send the token as Authorization: Bearer … together with Notion-Version: 2026-03-11. A page or database ID is the 32 characters at the end of its link, before any ?v=; the free Notion ID finder pulls it out for you.

A Notion API key is the token your code sends with every request to Notion’s API. In 2026 there are three kinds: a personal access token that acts as you, an internal connection token for team automations, and OAuth for apps that other people install. Below: how to create each one, give it access to your pages, find the page, database and data source IDs your requests need, and fix the errors almost everyone hits on the first try.

Checked October 27, 2026. Notion now calls integrations “connections”, keeps its developer portal inside the app behind Developer Mode, and added personal access tokens on May 12, 2026. Tutorials that send you to “My integrations” describe the earlier setup. Old developer portal links redirect to the new tools, and tokens that start with secret_ still work.

Which Notion API key do you need?

Notion’s developer docs list three ways to authenticate. They differ in whose permissions the token carries, what it can see and who is allowed to create it.

Personal access tokenInternal connectionPublic (OAuth)
Acts asYouIts own bot userEach user who connects it
Can reachEverything you can open in one workspaceOnly pages and databases shared with itThe pages each user picks when signing in
Who creates itFull members, if the plan’s policy allows; owners alwaysWorkspace ownersIts developer; each user approves access
Use it forYour scripts, CLI work, testing, tools you trustTeam automations, syncs, internal dashboardsApps other people install

A quick way to choose:

  • A script, notebook or tool only you use: a personal access token. Nothing to share, working in two minutes.
  • An automation the team relies on: an internal connection. It keeps working when the person who set it up leaves, and it sees only the pages you share with it.
  • An app other people install: a public connection with OAuth. Never ask your users to paste a token.
  • Claude, ChatGPT, Cursor or another AI app: usually no key at all. Notion’s hosted MCP server signs you in with OAuth; our Notion MCP guide covers the setup.

Option 1: create a personal access token

A personal access token (PAT) acts as you, with your workspace membership and page permissions. Notion’s own API quickstart starts with one, because there is nothing to set up besides the token.

  1. Turn on Developer Mode. In Notion, open Settings, search for Developer Mode and switch it on. It’s a local setting: the browser and the desktop app each need it turned on, and it isn’t available on mobile.
  2. Open the token list. A developer section appears in the sidebar. Open Personal access tokens and click New token. The direct link is notion.so/developers/tokens.
  3. Name it and set its scope. Pick the Notion API capability (add Workers only if you deploy Notion Workers) and an expiration: 7, 30, 90 or 180 days, or 1 year, the default. If a workspace picker appears, choose the workspace: a token belongs to one workspace.
  4. Click Create token and copy the value right away. Notion shows it once and never again, not even to admins. Put it in a password manager or your project’s secret store.

New tokens start with ntn_. Notion switched from secret_ on September 25, 2024, and older tokens keep working. Don’t check the prefix in your code, though: Notion says the format may change and asks developers to treat tokens as opaque strings.

Can’t create a token?

Guests and restricted members can’t create PATs at all. For everyone else, the plan sets who may create one with Notion API access:

PlanWho can create PATs by defaultCan admins change it?
FreeWorkspace owners onlyNo
PlusAll workspace membersNo
BusinessWorkspace owners onlyYes: owners only, or all members
EnterpriseWorkspace owners and selected groupsYes: owners only, owners and selected groups, or all members

On Business and Enterprise, ask a workspace owner to allow it under Settings → Connections. If an admin later narrows the policy, tokens you already have stop working and return unauthorized.

What a PAT can reach

Everything you can open in that workspace: pages, databases, comments and files. Pages don’t need to be shared with it. That is what makes PATs quick, and also what makes a leaked PAT expensive. Notion’s docs describe no read-only PAT: the Notion API capability reads, creates and updates. If a job only needs to read a few pages, an internal connection with only Read content is the safer key. When you lose access to a page or leave the workspace, the token loses it too.

Option 2: create an internal connection token

An internal connection is a bot user that belongs to one workspace. Use it for automations the team depends on, or for any tool that should see a few pages rather than everything you can open. Older guides call it an “internal integration”, and its token the “internal integration secret” or “integration token”.

  1. Check that you’re a workspace owner. Only owners can create connections. If you aren’t one, ask an owner, or create a free personal workspace to experiment in, as Notion’s FAQ suggests.
  2. Create the connection. In the developer section of the sidebar, or at notion.so/developers, open Internal connections, click Create a new connection, enter a name and choose the workspace. A connection can’t move to another workspace later; you’d create a new one there.
  3. Copy the API token. Open the connection’s Configuration tab and copy the API token. Owners can also reach it from Settings → Connections: the ••• menu next to the connection has an option to retrieve the token.
  4. Set capabilities on the same tab (the list is below).
  5. Give it pages. A new connection sees nothing, and every request fails until you share something. In the Content access tab, click Edit access and select pages and databases. Or open a page in Notion, click ••• in the top-right corner, find Connections, choose Add connection and search for yours. Sharing a page also shares its child pages.

Capabilities limit what the token can do, even on pages it can see. Notion’s docs recommend asking for the minimum:

  • Read content, Update content, Insert content, in any combination. An export needs only Read content. A form that adds rows needs only Insert content. A script that sets a status needs only Update content.
  • Read comments, Insert comments.
  • User information: none, without email addresses, or with email addresses.

Because the connection is its own user, its access doesn’t depend on people. If the teammate who shared a page leaves the workspace, the connection keeps that page. Every workspace owner can see all internal connections, including ones that others created.

Option 3: OAuth for apps other people use

If you’re building a product, don’t ask users to paste tokens. Create a public connection instead: each user signs in through Notion’s OAuth window and picks the pages your app may see. Exchange the OAuth code for a token on a server you control. The client secret must never reach a browser, and Notion’s OAuth token endpoints are deliberately closed to browser code. IVGraph connects this way: you choose pages in Notion’s window and never handle a key.

Test the key with one request

Keep the token in an environment variable rather than in your code. On macOS or Linux:

export NOTION_API_KEY="ntn_…"

In Windows PowerShell it’s $env:NOTION_API_KEY = "ntn_…". Then ask Notion who the token belongs to:

curl https://api.notion.com/v1/users/me \
  -H "Authorization: Bearer $NOTION_API_KEY" \
  -H "Notion-Version: 2026-03-11"

A working key returns a user of type bot; for a personal access token, its owner is you. Next, see what the key can reach. Search without a query returns every page or data source the token can access. This filter keeps only the data sources of your databases, each with its own ID and its parent database’s ID:

curl -X POST https://api.notion.com/v1/search \
  -H "Authorization: Bearer $NOTION_API_KEY" \
  -H "Notion-Version: 2026-03-11" \
  -H "Content-Type: application/json" \
  -d '{"filter": {"property": "object", "value": "data_source"}}'

Every request needs the Notion-Version header; 2026-03-11 is the latest version. In JavaScript, the official SDK takes the token once and retries rate-limited requests for you. Its current release sends 2025-09-03 by default, so set the version explicitly:

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

const notion = new Client({
  auth: process.env.NOTION_API_KEY,
  notionVersion: "2026-03-11",
});

const me = await notion.users.me({});
console.log(me.type, me.name);

Where to find a page, database or block ID

Every page, database and block in Notion has an ID: a UUID of 32 hexadecimal characters. Links show it without dashes, and the API accepts it with or without them. With dashes it’s grouped 8-4-4-4-12, so 1429989fe8ac4effbc8f57f56486db54 becomes 1429989f-e8ac-4eff-bc8f-57f56486db54.

The quickest way: Developer Mode

With Developer Mode on, a developer bar at the bottom of Notion shows the ID of the page, block, database or data source you’re looking at. Right-click a block or a database and open the Developer section to copy an ID directly. Like the setting itself, this works in the browser and the desktop app, not on mobile.

From a link

Copy a page’s link with Share → Copy link, or a block’s link from its ⋮⋮ menu with Copy link to block. Each kind of link keeps the ID in a fixed place:

Page
https://www.notion.so/acme/Launch-plan-1429989fe8ac4effbc8f57f56486db54

Database (full-page view)
https://www.notion.so/acme/248104cd477e80fdb757e945d38000bd?v=8f1c2a7e3b5d4c6e9a0b1c2d3e4f5a6b

Block
https://www.notion.so/acme/Launch-plan-1429989fe8ac4effbc8f57f56486db54#5c7d2e9a1b3f4c8d9e0f1a2b3c4d5e6f
In the linkWhat it isWhere you use it
The last 32 characters, after the page titlePage ID/v1/pages/{page_id}; also the block ID of the page’s content
The 32 characters before ?v=Database ID/v1/databases/{database_id}
The value after ?v=View IDView endpoints only; never a database ID
The value after p=, when a row is open in a side peekThat row’s page ID/v1/pages/{page_id}
The 32 characters after #Block ID/v1/blocks/{block_id}

Since June 2026, page links in API responses use another form, https://app.notion.com/p/…. The ID is still the last 32 characters, and older notion.so links keep working.

Two cases trip people up:

  • Inline databases. An inline database lives inside a page, so the address bar shows the page’s ID. Open the database as a full page first, then copy the link.
  • Linked views. If a database’s view menu offers Open source database, you’re looking at a linked view. The API can’t read linked databases: open the source, use its ID and share the source with your connection.

Inside a database, a formula property with id() shows each row’s page ID without dashes, and id(prop("Project").first()) gives the ID of a related page. That helps when an automation tool asks you for row IDs.

Have a link, need the ID? Paste it into our free Notion ID finder. It pulls out the page, database, view and block IDs with or without dashes and writes a test request for you. It runs in your browser and never asks for your key.

Open the Notion ID finder

The data source ID, the one that isn’t in the link

Since API version 2025-09-03, a database is a container for one or more data sources. The data source holds the properties and the rows, so querying rows and creating pages in a database go through endpoints under /v1/data_sources/. Those take a data source ID, not the database ID from the link. Three ways to get it:

  • In Notion: open the database’s settings menu, go to Manage data sources and click Copy data source ID. With Developer Mode on, right-clicking the database works too.
  • From the API: retrieve the database and read its data_sources list.
  • From search: the data_source filter shown above.
curl https://api.notion.com/v1/databases/248104cd477e80fdb757e945d38000bd \
  -H "Authorization: Bearer $NOTION_API_KEY" \
  -H "Notion-Version: 2026-03-11"

# the part of the response you need
{
  "object": "database",
  "id": "248104cd-477e-80fd-b757-e945d38000bd",
  "data_sources": [
    { "id": "248104cd-477e-80af-bc30-000bd28de8f9", "name": "Grocery list" }
  ]
}

Then query the rows with POST /v1/data_sources/248104cd-477e-80af-bc30-000bd28de8f9/query. Most databases have a single data source today, but don’t build on that. Notion’s upgrade guide warns that once someone adds a second source to a database, connections still on an older API version stop finding it in search, and their reads, writes and queries on it fail.

In code

The official JavaScript SDK does this parsing for you: extractPageId, extractDatabaseId and extractBlockId arrived in September 2025. They return the ID with dashes and prefer the ID in the path over query parameters, so a database link doesn’t hand you the view ID by mistake.

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

extractDatabaseId("https://www.notion.so/acme/248104cd477e80fdb757e945d38000bd?v=8f1c2a7e3b5d4c6e9a0b1c2d3e4f5a6b");
// "248104cd-477e-80fd-b757-e945d38000bd"

Fix the errors you’ll hit first

Error responses carry an HTTP status, a code and a readable message. These six cover nearly every first-day problem:

Error and messageUsual causeFix
401 unauthorized
API token is invalid.
A typo or a missing Bearer; an expired, revoked or refreshed token; a workspace that stopped allowing your PATsCopy the token again and send it in the Authorization header as Bearer <token>. Create a new PAT if the old one expired
404 object_not_found
Could not find database…
The page isn’t shared with the connection; a view ID instead of the database ID; a linked database; a page in another workspaceShare the page or its parent with the connection; take the ID before ?v=; use the source database
403 restricted_resource
API token does not have…
A missing capability, such as editing with only Read content, or a Free workspace over its block limitAdd the capability on the Configuration tab; the message names the cause
400 validation_error
body failed validation…
A malformed ID, a wrong property name or type, or a value over a size limitRead the message: it names the field
400 missing_version
Notion-Version header…
No Notion-Version headerAdd Notion-Version: 2026-03-11
429 rate_limited
You have been rate limited…
Too many requestsWait for Retry-After; the limits are below

Three more problems that don’t look like errors:

  • Relation properties come back empty. Share the related database with the connection too. Otherwise the properties based on that relation are left out of the response. How relations work is explained in our Notion relations guide.
  • Search returns nothing. A token only finds what it can access. For a connection, that’s the pages shared with it and their children.
  • A request that worked yesterday fails today. A PAT may have expired, an admin may have revoked it, or someone refreshed the connection’s token. For internal and public connections, the Health tab in the developer tools lists the last 24 hours of requests with their error codes and rate-limit hits.

Notion API rate limits in 2026

Notion changed its limits on September 9, 2026. Older answers describe one flat average of three requests per second with waits of up to 15 minutes. Now the limit depends on the plan and is counted per minute. Here is what Notion’s request limits page says:

LimitValue
Per connection, Business and Enterprise600 requests per minute, an average of 10 per second
Per connection, all other plans, Free and Plus included180 requests per minute, an average of 3 per second
Per workspaceOne budget shared by all of the workspace’s connections, scaled to the plan
Query a data sourceAbout 3 requests per second per connection
One requestUp to 1,000 blocks and 500 KB
Text, links, lists2,000 characters per text item or URL; up to 100 items per array, relation or multi-select in one request
One page of resultsUp to 100 items (page_size); continue with start_cursor

The per-connection budget resets every 60 seconds and can be spent in a single burst. Over a limit, Notion answers with HTTP 429, the code rate_limited and a Retry-After header in seconds. For the per-connection limit that wait never exceeds 60 seconds; the shared workspace limit can ask for longer. The field additional_data.rate_limit_reason says which limit you hit. A 529 service_overload means Notion itself is busy: treat it like a 429. Notion MCP tool calls draw from the same limits.

How to stay inside them:

  1. Send requests through one queue, not through parallel workers that each retry on their own.
  2. On 429 or 529, wait for Retry-After and retry. If it happens again, back off exponentially with a little jitter, and cap the number of attempts.
  3. Don’t retry most 400 errors: fix the request. A 429 with the reason public_api_request_blocked won’t clear by waiting either; contact Notion support.
  4. Before repeating a write that returned 503, read additional_data.retry_guidance. The change may already be saved, and repeating it would apply it twice.

Keep the key safe

Anyone who has the token can do whatever it allows. For a PAT that’s everything you can open; for a connection, every page shared with it.

  • Store it outside your code: an environment variable for local work, with .env listed in .gitignore, and a secret manager in production.
  • Never put it in a web page. The Notion API accepts requests from browser code, so a token embedded in a page that others can open is usable by anyone who views its source.
  • Don’t paste it into chats, support tickets or issue trackers, and that includes conversations with AI assistants.
  • Use one token per tool and per environment, so revoking one doesn’t break the rest.
  • Grant the minimum. For a third-party tool, an internal connection that sees only the pages you share is safer than a PAT that sees everything you can. Give experimental PATs a short expiration.
  • Turn on secret scanning in your repository and CI. The ntn_ prefix exists so that scanners can recognize Notion tokens.

If a token leaks, act in this order. In Notion, open Settings → Connections → Develop or manage connections, find the connection or token, and click Refresh for an internal connection or revoke the PAT. Replace the old value everywhere it was used. Then check recent changes to your pages and databases, and look for connections you don’t recognize. Workspace admins can revoke any member’s PAT from Settings → Connections as well, although they can never see or copy the token itself.

When you don’t need an API key

  • AI apps. Claude, ChatGPT, Cursor, Codex and VS Code connect to Notion’s hosted MCP server through OAuth, so there is no key to create. Our Notion MCP setup helper gives you the exact config for each app. Two exceptions: on Business and Enterprise, a workspace owner can create an MCP token for clients that can’t open a sign-in window, and the open-source, self-hosted MCP server takes an API token, although Notion no longer actively maintains it.
  • Apps that use Notion sign-in. A tool that opens Notion’s window and asks you to pick pages uses a public connection, and you never see a token.
  • Seeing how your workspace connects. People often collect page and database IDs to map relations by hand. IVGraph connects through Notion’s OAuth window and draws every page, mention and database relation as an interactive 3D graph. It’s free up to 500 nodes.

If an agent should read that graph, IVGraph has a read-only API for agents with its own service token on the Pro and Max plans: search, page content, neighbors and paths between pages. There’s no IVGraph MCP server yet.

A page selected in IVGraph’s 3D graph: its properties, a link back to Notion and 47 connections grouped by database
In IVGraph each page keeps its link back to Notion, and its relations are grouped by database. No IDs to copy and no key to paste.

FAQ

Is the Notion API free?

Notion doesn’t list a separate price for API access. Personal access tokens and connections work on every plan, Free included. The plan changes the rate limit, 180 requests per minute per connection or 600 on Business and Enterprise, and who may create personal access tokens. One catch: a Free workspace with more than one member has a lifetime limit of 1,000 blocks. Once it’s reached and a three-day grace period ends, internal connections can’t create pages or blocks; reading and editing still work.

What is the Notion API rate limit?

Since September 9, 2026, each connection gets 180 requests per minute on Free, Plus and other plans and 600 per minute on Business and Enterprise, counted in a fixed 60-second window. A separate limit is shared by all connections in a workspace, and querying a data source is limited to about 3 requests per second. Over a limit, Notion returns HTTP 429 with a Retry-After header.

Does a Notion API key expire?

Personal access tokens do: you choose 7, 30, 90 or 180 days, or 1 year, which is the default. Notion’s docs give internal connection tokens no expiry date, but you can refresh one at any time, which replaces it. An expired, revoked or replaced token returns 401 unauthorized.

What is the difference between a database ID and a data source ID?

The database ID is in the database’s link, before ?v=. Since API version 2025-09-03 a database can hold several data sources, and querying rows or creating pages needs the data source ID. Copy it in Notion with Manage data sources → Copy data source ID, or read the data_sources list that GET /v1/databases/{id} returns.

See how your pages connect, no key required

IVGraph signs in through Notion’s own OAuth window and shows every page, mention and database relation as an interactive 3D graph. Free up to 500 nodes.

Map my Notion
Andrii Danylchenko

About the Author

Andrii Danylchenko is the Founder and CTO of IVGraph. A visionary technologist passionate about transforming how people interact with knowledge, he leads IVGraph's technical development, architecting the 3D graph visualization engine and Notion sync.

Keep reading

More from the Journal

Guide

What Is a Second Brain? How It Works and What AI Changes

A plain-English guide to the second brain: Tiago Forte's CODE and PARA, how it differs from PKM, Zettelkasten and an LLM wiki, how to choose an app, and what AI and a graph of your notes add.

Guide

The Zettelkasten Method: How Linked Notes Help You Think and Write

What a Zettelkasten is, how Luhmann’s slip box worked, and how to build one in Obsidian or Notion, with example notes, common mistakes and a way to see your links as a graph.

Guide

Claude and Obsidian: Four Ways to Connect an Agent to Your Vault

Connect Claude Code or Claude Desktop to an Obsidian vault: direct folder access, the Obsidian CLI, Obsidian skills, MCP servers and agent plugins—plus Cursor, Codex, permissions and an LLM wiki layout.

Guide

Obsidian Graph View: A Practical Guide to Reading Your Notes as a Network

A practical guide to Obsidian’s global and local graphs: ways to open them, filters, color groups and CSS colors, display and forces settings, Maps of Content—and how graph views work in Logseq and Anytype.

Guide

What Is a Knowledge Graph? A Plain-English Guide with Examples

A plain-English explanation of knowledge graphs with a graph you can click, examples from Google and Wikidata to biomedicine and your own notes, how they compare with databases, mind maps and vector search, and how to build one.

Guide

GraphRAG, Explained: When a Knowledge Graph Beats Vector Search

How GraphRAG works, where it helps beyond vector search, and what extra indexing and maintenance to budget for. Plus a practical starting point for linked Notion workspaces.

Guide

Notion vs Obsidian: Which One Fits the Way You Think?

An honest Notion vs Obsidian comparison updated for 2026: storage, offline mode, Bases vs databases, graph view in both apps, AI agents and pricing—plus how to move from Notion to Obsidian with the official Importer.