A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.
The Notion API is how an app or AI agent works with a Notion workspace: reading and writing pages, querying database rows, editing the content blocks on a page, adding comments, and uploading files. Access is granted through a token and a set of permissions, and a connection only ever sees the pages and databases that have been shared with it. Versions are dated rather than numbered, so an older integration keeps working on its pinned date until it moves up.
An app or AI agent connects to Notion in one of two ways, each with its own token type: direct REST calls, or Notion's hosted MCP server. The connection method does not change an integration's reach, because either way it sees only what's been shared with it and is bound by the same capabilities.
An app or AI agent makes direct HTTPS calls to the endpoints in this reference.
Notion hosts a remote Model Context Protocol server at https://mcp.notion.com/mcp that exposes Notion as standard tools to MCP-aware agents over Streamable HTTP.
A fixed token generated for a single workspace lets the integration act as a bot identity.
A public integration is distributed to other workspaces and gets a token per workspace through an OAuth consent flow, acting on behalf of the authorising user.
A personal access token is tied to one user and acts as that user, with the user's own permissions.
Notion divides its API into functional areas, and each one is a place an agent can act. Each area carries its own permissions, and some reach further into a workspace than others.
Read, create, and update pages and their property values.
Read a database's structure and query the rows inside it. The rows live on its data sources.
Read, add, edit, and remove the content blocks that make up a page.
Find pages and databases across everything shared with the connection.
Read existing comments and add new ones to pages and blocks.
Look up the workspace's members and bots.
Upload files so they can be attached to pages, blocks, or properties.
Create and manage saved views, like tables, boards and calendars, of a data source.
OAuth endpoints used to connect a workspace and manage a connection's token.
Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.
| Method | Endpoint | What it does | Access | Permission | Version | |
|---|---|---|---|---|---|---|
PagesRead, create, and update pages and their property values.4 | ||||||
| POST | /v1/pages | Create a page or a new database row | write | insert_content | Current | |
Creates one page or row under one shared parent. Acts onpage Permission (capability) insert_contentVersionAvailable since the API’s base version Webhook event page.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/pages/{id} | Retrieve a page and its property values | read | read_content | Current | |
Reads one page's properties, not its block content. Acts onpage Permission (capability) read_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/pages/{id}/properties/{property_id} | Retrieve a single property value from a page | read | read_content | Current | |
Reads one property of one page; the correct way to page through large or multi-value properties. Acts onpage property Permission (capability) read_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v1/pages/{id} | Update a page's properties, icon, cover, or trash it | write | update_content | Current | |
Edits one page and can archive it. Cannot move it to a new parent; erase_content is irreversible. Acts onpage Permission (capability) update_contentVersionAvailable since the API’s base version Webhook event page.properties_updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Databases & data sourcesRead a database's structure and query the rows inside it. The rows live on its data sources.8 | ||||||
| POST | /v1/data_sources/{id}/query | Query the rows of a data source, filtered and sorted | read | read_content | New | |
Reads rows from one shared data source. Replaces the legacy database query. Acts ondata source Permission (capability) read_contentVersionIntroduced 2025-09-03 Webhook eventNone Rate limitResults cap at 10,000 per query. SourceOfficial documentation ↗ | ||||||
| GET | /v1/data_sources/{id} | Retrieve a data source's schema (its columns) | read | read_content | New | |
Reads the column definitions of one data source; no rows. Acts ondata source Permission (capability) read_contentVersionIntroduced 2025-09-03 Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/data_sources | Add a data source (table) to an existing database | write | insert_content | New | |
Adds one schema/table to a shared database. Acts ondata source Permission (capability) insert_contentVersionIntroduced 2025-09-03 Webhook event data_source.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v1/data_sources/{id} | Update a data source's schema, title, or trash state | write | update_content | New | |
Changes a data source's columns; dropping a column affects every row in it. Acts ondata source Permission (capability) update_contentVersionIntroduced 2025-09-03 Webhook event data_source.schema_updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/databases | Create a database with an initial data source | write | insert_content | Current | |
Creates one database (and its first data source) under a shared page. Acts ondatabase Permission (capability) insert_contentVersionAvailable since the API’s base version Webhook event database.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/databases/{id} | Retrieve a database container and its data-source list | read | read_content | Current | |
Reads a database's metadata and its child data sources; not the schema or rows. Acts ondatabase Permission (capability) read_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v1/databases/{id} | Update a database's title, description, or container settings | write | update_content | Current | |
Edits container-level settings of one database; the schema lives on its data source. Acts ondatabase Permission (capability) update_contentVersionAvailable since the API’s base version Webhook event database.movedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/databases/{id}/query | Query a database (legacy, use the data-source query instead) | read | read_content | Deprecated | |
Deprecated in 2025-09-03; superseded by Query a data source. Acts ondatabase Permission (capability) read_contentVersionDeprecated 2025-09-03 Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Blocks (content)Read, add, edit, and remove the content blocks that make up a page.6 | ||||||
| GET | /v1/blocks/{id} | Retrieve a single content block | read | read_content | Current | |
Reads one block; does not return its children. Acts onblock Permission (capability) read_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/blocks/{id}/children | List a block's direct child blocks | read | read_content | Current | |
Lists one level of children; nested content needs further calls. Acts onblock Permission (capability) read_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v1/blocks/{id}/children | Append new content blocks inside a block or page | write | insert_content | Current | |
Adds new blocks under one parent (up to 100 per call); does not edit existing blocks. Acts onblock Permission (capability) insert_contentVersionAvailable since the API’s base version Webhook event page.content_updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v1/blocks/{id} | Update a single block's content in place | write | update_content | Current | |
Edits one block, replacing the fields sent; its children aren't changed. Acts onblock Permission (capability) update_contentVersionAvailable since the API’s base version Webhook event page.content_updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v1/blocks/{id} | Move a block (and its children) to Trash | write | update_content | Current | |
Archives one block and its nested children; recoverable from Trash. Acts onblock Permission (capability) update_contentVersionAvailable since the API’s base version Webhook event page.content_updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/blocks/meeting_notes/query | Query meeting-notes blocks | read | read_content | New | |
Reads meeting-notes blocks the connection can access. Acts onblock Permission (capability) read_contentVersionIntroduced 2026-05-11 Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
SearchFind pages and databases across everything shared with the connection.1 | ||||||
| POST | /v1/search | Search pages and data sources by title | read | read_content | Current | |
Searches everything shared with the connection, bounded to shared items, but workspace-wide in reach. Acts onpage, data source Permission (capability) read_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitSubject to a query result limit; signalled via request_status. SourceOfficial documentation ↗ | ||||||
CommentsRead existing comments and add new ones to pages and blocks.2 | ||||||
| POST | /v1/comments | Add a comment to a page, block, or discussion | write | insert_comments | Current | |
Adds one comment to a shared page, block, or thread. Acts oncomment Permission (capability) insert_commentsVersionAvailable since the API’s base version Webhook event comment.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/comments | List open comments on a page or block | read | read_comments | Current | |
Lists un-resolved comments on one page or block. Acts oncomment Permission (capability) read_commentsVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
PeopleLook up the workspace's members and bots.3 | ||||||
| GET | /v1/users | List all workspace members and bots | read | user_info | Current | |
Returns the whole member directory; emails only if the with-email level is granted. Acts onuser Permission (capability) user_infoVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/users/{id} | Retrieve a single user by ID | read | user_info | Current | |
Reads one user's profile; email only with the with-email level. Acts onuser Permission (capability) user_infoVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/users/me | Retrieve the connection's own bot user | read | — | Current | |
Returns the connection's own identity; needs no specific capability. Acts onuser Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
FilesUpload files so they can be attached to pages, blocks, or properties.5 | ||||||
| POST | /v1/file_uploads | Start a file upload | write | insert_content | Current | |
Begins an upload; the file isn't attached anywhere until it's attached. Acts onfile upload Permission (capability) insert_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/file_uploads/{id}/send | Upload the bytes of a file | write | insert_content | Current | |
Sends file contents for a pending upload (multipart form data). Acts onfile upload Permission (capability) insert_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/file_uploads/{id}/complete | Finish a multi-part file upload | write | insert_content | Current | |
Finalises a multi-part upload after all parts are sent. Acts onfile upload Permission (capability) insert_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/file_uploads/{id} | Retrieve a file upload's status | read | read_content | Current | |
Reads the status of one upload. Acts onfile upload Permission (capability) read_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/file_uploads | List file uploads | read | read_content | Current | |
Lists uploads created by the connection. Acts onfile upload Permission (capability) read_contentVersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
ViewsCreate and manage saved views, like tables, boards and calendars, of a data source.5 | ||||||
| POST | /v1/views | Create a view on a data source | write | insert_content | New | |
Creates one saved view of a data source; requires insert and update content. Acts onview Permission (capability) insert_contentVersionIntroduced 2026-03-19 Webhook event view.createdRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/views/{id} | Retrieve a view | read | read_content | New | |
Reads one view's configuration. Acts onview Permission (capability) read_contentVersionIntroduced 2026-03-19 Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| PATCH | /v1/views/{id} | Update a view's filter, sorts, or settings | write | update_content | New | |
Edits one view's presentation; doesn't change who can see the underlying data. Acts onview Permission (capability) update_contentVersionIntroduced 2026-03-19 Webhook event view.updatedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| DELETE | /v1/views/{id} | Delete a view | write | update_content | New | |
Removes one saved view (a dedicated reference page was not confirmed at last verify). Acts onview Permission (capability) update_contentVersionIntroduced 2026-03-19 Webhook event view.deletedRate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| GET | /v1/databases/{id}/views | List a database's views | read | read_content | New | |
Lists the views belonging to one database. Acts onview Permission (capability) read_contentVersionIntroduced 2026-03-19 Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
AuthenticationOAuth endpoints used to connect a workspace and manage a connection's token.3 | ||||||
| POST | /v1/oauth/token | Exchange an OAuth code for an access token, or refresh one | write | — | Current | |
Used during connection setup; authenticates with client credentials, not a Notion capability. Acts ontoken Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/oauth/introspect | Check a token's active status and scope | read | — | Current | |
Validates a stored token without making a data call. Acts ontoken Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
| POST | /v1/oauth/revoke | Revoke an access token | write | — | Current | |
Invalidates a connection's token. Acts ontoken Permission (capability)None required VersionAvailable since the API’s base version Webhook eventNone Rate limitStandard limits apply SourceOfficial documentation ↗ | ||||||
Notion delivers a lightweight signal that carries the event name and the affected object's ID rather than its content, so the object is re-fetched through the API. Subscriptions are set up inside Notion itself, not through an endpoint.
| Event | What it signals | Triggered by |
|---|---|---|
page.created | Fires when a page (or database row) is created. | /v1/pages |
page.content_updated | Fires when a page's block content changes (aggregated within a short window). | /v1/blocks/{id}/children/v1/blocks/{id}/v1/blocks/{id} |
page.properties_updated | Fires when a page's property values change. | /v1/pages/{id} |
page.deleted | Fires when a page is moved to Trash. | /v1/pages/{id} |
page.undeleted | Fires when a page is restored from Trash. | /v1/pages/{id} |
page.locked | Fires when a page is locked. | /v1/pages/{id} |
page.unlocked | Fires when a page is unlocked. | /v1/pages/{id} |
page.moved | Fires when a page is moved to a new parent (no REST endpoint moves a page; this comes from in-app moves). | In-app only |
database.created | Fires when a database is created. | /v1/databases |
database.moved | Fires when a database is moved to a new parent. | /v1/databases/{id} |
database.deleted | Fires when a database is moved to Trash. | /v1/databases/{id} |
database.undeleted | Fires when a database is restored from Trash. | /v1/databases/{id} |
data_source.created | Fires when a data source is added to a database. | /v1/data_sources |
data_source.content_updated | Fires when the rows of a data source change. | /v1/pages/v1/pages/{id} |
data_source.schema_updated | Fires when a data source's columns (schema) change. | /v1/data_sources/{id} |
data_source.moved | Fires when a data source is moved to a new parent. | /v1/data_sources/{id} |
data_source.deleted | Fires when a data source is moved to Trash. | /v1/data_sources/{id} |
data_source.undeleted | Fires when a data source is restored from Trash. | /v1/data_sources/{id} |
comment.created | Fires when a comment is added. | /v1/comments |
comment.updated | Fires when a comment is edited (no REST endpoint edits a comment; this comes from in-app edits). | In-app only |
comment.deleted | Fires when a comment is deleted (no REST endpoint deletes a comment; this comes from in-app deletes). | In-app only |
view.created | Fires when a view is created. | /v1/views |
view.updated | Fires when a view's settings change. | /v1/views/{id} |
view.deleted | Fires when a view is deleted. | /v1/views/{id} |
Several constraints shape any Notion integration, covering how often it can call, how it pages through results, and how large a single request can be. Limits tied to a single endpoint appear in that row's detail in the reference above.
Each connection gets about 3 requests per second on average, with short bursts allowed above that. A separate per-workspace pool sits on top, and the size of that pool scales with the plan. Going over returns 429 rate_limited with a Retry-After header that gives the number of seconds to wait. A 529 service_overload is handled the same way, by backing off and retrying.
Results are paged through with opaque cursors. A request sends page_size (the default and maximum is 100) and start_cursor, and the response returns results, has_more and next_cursor. Query endpoints also stop at 10,000 results, signalled by request_status.incomplete_reason set to query_result_limit_reached.
A request holds up to 1,000 block elements or 500 KB. Rich text and URLs cap at 2,000 characters; block, relation and people arrays at 100 items each; multi-select at 100 options.
The status codes an agent should handle, and what to do about each.
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | validation_error | The request body or parameters were malformed or failed validation. | Check the request against the endpoint's schema: property names, types and required fields. |
| 400 | missing_version | The request did not include a Notion-Version header. | Send a Notion-Version header on every request, for example 2026-03-11. |
| 401 | unauthorized | The token is missing, malformed or invalid. | Confirm the Authorization header carries a valid Bearer token, and refresh or reconnect if it has expired or been revoked. |
| 403 | restricted_resource | The connection lacks the capability needed for this action. | Grant the required capability (read, insert, update, comments or user information) on the integration. |
| 404 | object_not_found | The object doesn't exist, or it exists but isn't shared with the connection. Notion deliberately makes the two cases indistinguishable. | Check the ID, and confirm the page or database is shared with the integration. |
| 409 | conflict_error | The transaction could not be completed, usually because of a concurrent edit. | Retry the request. |
| 429 | rate_limited | Too many requests. | Honour the Retry-After header, which is in seconds, and back off before retrying. |
| 529 | service_overload | Notion is temporarily overloaded. | Back off and retry, the same way as for a 429. |
Notion issues a new version only when a change breaks backwards compatibility, and new features ship continuously on the current version. This timeline shows both the versions that may require a migration and the features added since.
This version adds a per-workspace request pool on top of the per-connection rate limit.
This version launches the developer portal and personal access tokens.
This version adds an endpoint to query meeting-notes blocks, plus an agent parent type.
This version caps query endpoints at 10,000 results.
This version brings the update and delete comment endpoints to general availability, plus multi-value select filters.
This version adds endpoints and webhooks for saved views, plus status-property writes.
This version renames several fields and a block type, and it is the current version an integration pins.
This version adds endpoints to create, read and update page content as Markdown.
This version makes a database a container that can hold multiple data sources, and rows now live on the data source.
Pre-2025 versions covered page property-item reads, block parents, relation single and dual properties (2022-06-28), and rollup and rich-text renames (2021).
Older versions keep working. An integration pins one with the Notion-Version header and moves up on its own schedule.
Notion's full changelog ↗2025-09-03 version, when a database became a container that can hold multiple data sources. Rows now live on a data source, so the query goes to the data source instead with POST /v1/data_sources/{id}/query. See Query a data source.Retry-After header, which gives the number of seconds to wait, then backs off and retries. A 529 service_overload is handled the same way. Notion allows roughly 3 requests per second per connection on average, with short bursts above that.https://mcp.notion.com/mcp that exposes Notion as standard MCP tools to agents. It connects through Notion's OAuth flow and is governed by the same sharing and capabilities as the REST API. See the MCP guide.Bollard AI sits between a team's AI agents and Notion. Grant each agent exactly the access it needs, read or write, database by database, and every call is checked and logged.