---
name: notion
description: Use when building integrations with Notion workspaces, automating
  content workflows, querying databases, managing pages and blocks, handling
  webhooks, or connecting external tools to Notion. Agents should reach for this
  skill when users request API access to Notion data, need to create or update
  pages/databases programmatically, set up real-time event subscriptions, or
  build custom connections.
metadata:
  mintlify-proj: notion
  version: "1.0"
---

# Notion API Skill

## Product summary

The Notion API is a REST API that lets you read, create, and update pages, databases, users, comments, and files in a Notion workspace. Agents use it to automate workflows, sync data, build custom integrations, and connect external tools to Notion. The API supports three authentication models: personal access tokens (PATs) for user-scoped access, internal connections for workspace-owned automations, and OAuth 2.0 for public apps. The primary documentation is at https://developers.notion.com/reference/intro. Key endpoints live under `https://api.notion.com/v1/`. Use the `Notion-Version: 2026-03-11` header for the latest API version. The JavaScript SDK (`@notionhq/client`) is available for Node.js projects.

## When to use

Reach for this skill when:
- A user asks to create, read, or update pages, databases, or blocks in Notion
- You need to query a database or search workspace content
- You're building a webhook subscription to react to Notion changes (page updates, new comments, schema changes)
- You need to upload files or manage file attachments
- You're setting up an internal connection for a workspace automation
- You're implementing OAuth 2.0 for a public app that other Notion users will install
- You need to manage Custom Agents or retrieve agent session data
- You're connecting Notion to an external system via the API
- You need to work with the Model Context Protocol (MCP) to connect an AI tool to Notion

## Quick reference

### Authentication models

| Model | Use case | Credential | Scope |
|-------|----------|-----------|-------|
| Personal Access Token (PAT) | Scripts, CLI, Workers, trusted tools | Static bearer token | One user in one workspace |
| Internal Connection | Team-owned workspace automations | Internal API token | Single workspace, bot identity |
| OAuth 2.0 (Public) | Apps for other Notion users | Access + refresh tokens | Any workspace (or selected set) |

### Core endpoints

| Task | Method | Endpoint |
|------|--------|----------|
| Create a page | POST | `/v1/pages` |
| Retrieve a page | GET | `/v1/pages/{page_id}` |
| Update page content (markdown) | PATCH | `/v1/pages/{page_id}/markdown` |
| Query a data source | POST | `/v1/data_sources/{data_source_id}/query` |
| Create a database | POST | `/v1/databases` |
| Retrieve a database | GET | `/v1/databases/{database_id}` |
| Search workspace | POST | `/v1/search` |
| Create a comment | POST | `/v1/comments` |
| Upload a file | POST | `/v1/files` |
| List webhooks | GET | `/v1/webhooks` |

### Required headers

```
Authorization: Bearer {TOKEN}
Notion-Version: 2026-03-11
Content-Type: application/json
```

### Common request patterns

**Create a page with markdown:**
```json
{
  "icon": { "emoji": "📝" },
  "markdown": "# Title\n\nContent here"
}
```

**Query a data source with filter:**
```json
{
  "result_type": "page",
  "filter": {
    "property": "Status",
    "select": { "equals": "Done" }
  }
}
```

**Paginate results:**
```json
{
  "page_size": 100,
  "start_cursor": "next_cursor_from_previous_response"
}
```

## Decision guidance

### When to use PAT vs Internal Connection vs OAuth

| Scenario | Use PAT | Use Internal | Use OAuth |
|----------|---------|--------------|-----------|
| Personal script or CLI tool | ✅ | | |
| Workspace automation (team-owned) | | ✅ | |
| App for other Notion users | | | ✅ |
| Marketplace listing | | | ✅ |
| Single workspace, no user selection | | ✅ | |
| Multiple workspaces, same user | ✅ | | |

### When to use markdown vs blocks

| Approach | Best for | Tradeoff |
|----------|----------|----------|
| Markdown | Simple content (headings, lists, paragraphs, links) | Less control; API converts to blocks |
| Blocks (children) | Complex layouts, precise formatting, toggles, embeds | More verbose; full control |

### When to query vs retrieve

| Method | Use case |
|--------|----------|
| Query data source | Find pages matching filters/sorts; paginate large result sets |
| Retrieve page | Get a known page ID directly; read full page content |
| Search | Find pages by title across workspace; discover content |

## Workflow

1. **Choose authentication:** Decide between PAT (personal use), internal connection (workspace automation), or OAuth (public app). Create the credential in the Developer portal.

2. **Set up headers:** Include `Authorization: Bearer {TOKEN}`, `Notion-Version: 2026-03-11`, and `Content-Type: application/json` in every request.

3. **Identify the resource:** Get the page ID, database ID, or data source ID from the Notion URL (32-character string; format as `8-4-4-4-12` with hyphens).

4. **Check permissions:** For internal connections, verify the page is shared with the connection via "Add connections" in Notion. For OAuth, users select pages during authorization. For PATs, use your own Notion permissions.

5. **Make the request:** Use the appropriate endpoint (create, retrieve, update, query). Include required parameters (parent, properties, filter, etc.).

6. **Handle pagination:** If `has_more` is true, use `next_cursor` to fetch the next page of results.

7. **Handle rate limits:** If you receive HTTP 429, read the `Retry-After` header and wait before retrying. Respect per-connection and per-workspace limits.

8. **Verify the response:** Check the response object's `id`, `object` type, and content to confirm the operation succeeded.

## Common gotchas

- **Token exposure:** Never commit tokens to version control. Use environment variables or secret managers.
- **Missing Notion-Version header:** Requests without this header may use an older API version. Always include `Notion-Version: 2026-03-11`.
- **Page not shared:** Internal connections fail silently if the page isn't shared. Always share pages via "Add connections" in Notion.
- **Empty strings not allowed:** Use `null` instead of `""` to unset string properties.
- **Rate limits are shared:** A workspace's rate limit is shared across all connections. One connection's burst can rate-limit others.
- **Webhook events are aggregated:** Events like `page.content_updated` are batched to reduce noise. Use non-aggregated events like `comment.created` for testing.
- **Markdown newlines in JSON:** Use `\n` escape sequences in JSON strings, not literal newlines. In cURL, wrap the body in single quotes.
- **Deleting child pages:** By default, updates refuse to delete child pages. Set `allow_deleting_content: true` to permit deletion.
- **Data source vs database:** The API treats databases and data sources as separate objects. Query the data source, not the database.
- **Async operations:** Large markdown updates can return HTTP 202 with an async task. Poll the task status before assuming completion.
- **Size limits:** Rich text content is capped at 2000 characters; relations at 100 items per request; payloads at 1000 blocks or 500KB.

## Verification checklist

Before submitting work:

- [ ] Token is set as an environment variable, not hardcoded
- [ ] `Notion-Version: 2026-03-11` header is included in all requests
- [ ] For internal connections, the page is shared with the connection in Notion
- [ ] Request body matches the endpoint's schema (check required fields)
- [ ] Pagination is handled if `has_more` is true
- [ ] Rate limit retries use `Retry-After` header and exponential backoff
- [ ] Error responses are checked for `code` and `message` fields
- [ ] Markdown content uses `\n` for newlines, not literal newlines
- [ ] No empty strings; use `null` to unset values
- [ ] For large operations, check for async task responses (HTTP 202)

## Resources

- **Comprehensive page navigation:** https://developers.notion.com/llms.txt
- **API Reference:** https://developers.notion.com/reference/intro
- **Getting Started Guide:** https://developers.notion.com/guides/get-started/overview
- **Working with Databases:** https://developers.notion.com/guides/data-apis/working-with-databases

---

> For additional documentation and navigation, see: https://developers.notion.com/llms.txt