> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agentkit`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Notion

**Authentication:** OAuth 2.0
**Categories:** Project Management, Files, Documents
## What you can do

Connect this agent connector to let your agent:

- **Read pages and databases** — retrieve page content and query database entries
- **Create pages** — add new pages and database rows with full content
- **Update content** — edit existing page blocks, properties, and database fields
- **Search** — find pages and databases across the user's Notion workspace

## Authentication

This connector uses **OAuth 2.0**. Scalekit acts as the OAuth client: it redirects your user to Notion, obtains an access token, and automatically refreshes it before it expires. Your agent code never handles tokens directly — you only pass a `connectionName` and a user `identifier`.

You supply your Notion **Connected App** credentials (Client ID + Secret) once per environment in the Scalekit dashboard.

Before calling this connector from your code, create the Notion connection in **AgentKit** > **Connections** and copy the exact **Connection name** from that connection into your code. The value in code must match the dashboard exactly.

## Set up the connector

Register your Scalekit environment with the Notion connector so Scalekit handles the authentication flow and token lifecycle for you. The connection name you create will be used to identify and invoke the connection programmatically. Then complete the configuration in your application as follows:

1. ### Set up auth redirects

    - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** > **Create Connection**. Find **Notion** and click **Create**. Copy the redirect URI. It looks like `https:///sso/v1/oauth//callback`.

      > Image: Copy redirect URI from Scalekit dashboard

    - Go to [Notion Integrations](https://www.notion.so/profile/integrations) and click **New integration**.

    - Fill in the integration name and select your workspace. In the **OAuth Domain & URIs** section, paste the redirect URI from Scalekit and click **Submit**.

      > Image: Add redirect URI in Notion integration settings

2. ### Get client credentials

    - In your Notion integration settings, go to the **Secrets** tab.

    - Copy the **OAuth client ID** and **OAuth client secret**.

3. ### Add credentials in Scalekit

    - In [Scalekit dashboard](https://app.scalekit.com), go to **AgentKit** > **Connections** and open the connection you created.

    - Enter your credentials:
      - Client ID (OAuth client ID from above)
      - Client Secret (OAuth client secret from above)
      - Permissions (capabilities — see [Notion capabilities reference](https://developers.notion.com/reference/capabilities))

      > Image: Add credentials in Scalekit dashboard
    - Click **Save**.

## Code examples

Connect a user's Notion account and make API calls on their behalf — Scalekit handles OAuth and token management automatically.

## Proxy API Calls

  ### Node.js

```typescript

const connectionName = 'notion'; // get your connection name from connection configurations
const identifier = 'user_123';  // your unique user identifier

// Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENV_URL,
  process.env.SCALEKIT_CLIENT_ID,
  process.env.SCALEKIT_CLIENT_SECRET
);
const actions = scalekit.actions;

// Authenticate the user
const { link } = await actions.getAuthorizationLink({
  connectionName,
  identifier,
});
console.log('🔗 Authorize Notion:', link);
process.stdout.write('Press Enter after authorizing...');
await new Promise(r => process.stdin.once('data', r));

// Make a request via Scalekit proxy
const result = await actions.request({
  connectionName,
  identifier,
  path: '/v1/users/me',
  method: 'GET',
});
console.log(result);
```

  ### Python

```python

from dotenv import load_dotenv
load_dotenv()

connection_name = "notion"  # get your connection name from connection configurations
identifier = "user_123"     # your unique user identifier

# Get your credentials from app.scalekit.com → Developers → Settings → API Credentials
scalekit_client = scalekit.client.ScalekitClient(
    client_id=os.getenv("SCALEKIT_CLIENT_ID"),
    client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
    env_url=os.getenv("SCALEKIT_ENV_URL"),
)
actions = scalekit_client.actions

# Authenticate the user
link_response = actions.get_authorization_link(
    connection_name=connection_name,
    identifier=identifier
)
# present this link to your user for authorization, or click it yourself for testing
print("🔗 Authorize Notion:", link_response.link)
input("Press Enter after authorizing...")

# Make a request via Scalekit proxy
result = actions.request(
    connection_name=connection_name,
    identifier=identifier,
    path="/v1/users/me",
    method="GET"
)
print(result)
```

## Tool list

Use the exact tool names from the **Tool list** below when you call `execute_tool`. If you're not sure which name to use, list the tools available for the current user first.

## Tool list

### `notion_block_delete`

Delete (archive) a Notion block by its ID. This also deletes all child blocks within it.

Parameters:

- `block_id` (`string`, required): The ID of the block to delete

### `notion_block_update`

Update the text content of an existing Notion block. Supports paragraph, heading, list item, quote, callout, and code blocks.

Parameters:

- `block_id` (`string`, required): The ID of the block to update
- `text` (`string`, required): New text content for the block
- `type` (`string`, required): The block type (must match the existing block type)
- `language` (`string`, optional): Programming language for code blocks

### `notion_comment_create`

Create a comment in Notion. Provide a comment object with rich_text content and either a parent object (with page_id) for a page-level comment or a discussion_id to reply in an existing thread.

Parameters:

- `comment` (`object`, required): Comment object containing a rich_text array. Example: {"rich_text":[{"type":"text","text":{"content":"Hello"}}]}
- `discussion_id` (`string`, optional): Existing discussion thread ID to reply to.
- `notion_version` (`string`, optional): Optional override for the Notion-Version header (e.g., 2022-06-28).
- `parent` (`object`, optional): Parent object for a new top-level comment. Shape: {"page_id":"<uuid>"}.
- `schema_version` (`string`, optional): Internal override for schema version.
- `tool_version` (`string`, optional): Internal override for tool implementation version.

### `notion_comment_retrieve`

Retrieve a single Notion comment by its `comment_id`. LLM tip: you typically obtain `comment_id` from the response of creating a comment or by first listing comments for a page/block and selecting the desired item’s `id`.

Parameters:

- `comment_id` (`string`, required): The identifier of the comment to retrieve (hyphenated UUID). Obtain it from Create-Comment responses or from a prior List-Comments call.
- `notion_version` (`string`, optional): Optional Notion-Version header override (e.g., 2022-06-28).
- `schema_version` (`string`, optional): Internal override for schema version.
- `tool_version` (`string`, optional): Internal override for tool implementation version.

### `notion_comments_fetch`

Fetch comments for a given Notion block. Provide a `block_id` (the target page/block ID, hyphenated UUID). Supports pagination via `start_cursor` and `page_size` (1–100). LLM tip: extract `block_id` from a Notion URL’s trailing 32-char id, then insert hyphens (8-4-4-4-12).

Parameters:

- `block_id` (`string`, required): Target Notion block (or page) ID to fetch comments for. Use a hyphenated UUID.
- `notion_version` (`string`, optional): Optional Notion-Version header override (e.g., 2022-06-28).
- `page_size` (`integer`, optional): Maximum number of comments to return (1–100).
- `schema_version` (`string`, optional): Internal override for schema version.
- `start_cursor` (`string`, optional): Cursor to fetch the next page of results.
- `tool_version` (`string`, optional): Internal override for tool implementation version.

### `notion_data_fetch`

Fetch data from Notion using the workspace search API (/search). Supports pagination via start_cursor.

Parameters:

- `page_size` (`integer`, optional): Max number of results to return (1–100)
- `query` (`string`, optional): Text query used by /search
- `schema_version` (`string`, optional): Optional schema version to use for tool execution
- `start_cursor` (`string`, optional): Cursor for pagination; pass the previous response's next_cursor
- `tool_version` (`string`, optional): Optional tool version to use for execution

### `notion_data_source_fetch`

Retrieve a Notion database's schema, title, and properties using the Notion 2025-09-03 API. Unlike notion_database_fetch, this returns a data_sources array — each entry contains a data_source_id required by notion_data_source_query and notion_data_source_insert_row. Use this as the first step when working with merged, synced, or multi-source databases. For standard single-source databases, notion_database_fetch is sufficient. LLM guidance: extract data_sources[0].id (or the relevant source) from the response and pass it to the query or insert tools.

Parameters:

- `database_id` (`string`, required): The target database ID in UUID format with hyphens.

### `notion_data_source_insert_row`

Create a new row (page) in a Notion data source using the 2025-09-03 API. Required for merged, synced, or multi-source databases — these require parent.data_source_id instead of parent.database_id which the older notion_database_insert_row uses. Provide the data_source_id from notion_data_source_fetch (data_sources[].id) and a properties object mapping column names to Notion property value shapes. Optionally attach child blocks (page content), an icon, or a cover image. LLM guidance: step 1 — call notion_data_source_fetch to get the data_source_id; step 2 — build the properties object using exact column names from the schema (use 'title' key for title-type fields); step 3 — call this tool.

Parameters:

- `data_source_id` (`string`, required): The ID of the data source to insert a row into. Retrieve from notion_database_fetch response under data_sources[].id.
- `properties` (`object`, required): Object mapping column names (or property ids) to property values. Example: {"title": {"title": [{"text": {"content": "Task A"}}]}, "Status": {"select": {"name": "Todo"}}}
- `child_blocks` (`array`, optional): Optional array of Notion blocks to append as page content.
- `cover` (`object`, optional): Optional page cover object. Example: {"type":"external","external":{"url":"https://example.com/cover.jpg"}}
- `icon` (`object`, optional): Optional page icon object. Example: {"type":"emoji","emoji":"📝"}

### `notion_data_source_query`

Query rows (pages) from a Notion data source using the 2025-09-03 API. Required for merged, synced, or multi-source databases — these cannot be queried via notion_database_query as that tool uses the older /databases/{id}/query endpoint which does not support multiple data sources. Provide the data_source_id obtained from notion_data_source_fetch (data_sources[].id). Supports filtering by property values, sorting, and cursor-based pagination. LLM guidance: step 1 — call notion_data_source_fetch with the database_id to retrieve the data_source_id; step 2 — pass that id here along with an optional filter, sorts, and page_size.

Parameters:

- `data_source_id` (`string`, required): The ID of the data source to query. Retrieve from notion_database_fetch response under data_sources[].id.
- `filter` (`object`, optional): Notion filter object to narrow results. Example: {"property": "Status", "select": {"equals": "Done"}}. Supports compound filters with 'and'/'or' arrays.
- `page_size` (`integer`, optional): Maximum number of rows to return (1-100).
- `sorts` (`array`, optional): Order the results. Each item must include either property or timestamp, plus direction.
- `start_cursor` (`string`, optional): Cursor to fetch the next page of results.

### `notion_database_create`

Create a new database in Notion under a parent page. Provide a parent object with page_id, a database title (rich_text array), and a properties object that defines the database schema (columns).

Parameters:

- `parent` (`object`, required): Parent object specifying the page under which the database is created. Example: {"page_id": "2561ab6c-418b-8072-beec-c4779fa811cf"}
- `properties` (`object`, required): Database schema object defining properties (columns). Example: {"Name": {"title": {}}, "Status": {"select": {"options": [{"name": "Todo"}, {"name": "Doing"}, {"name": "Done"}]}}}
- `title` (`array`, required): Database title as a Notion rich_text array.
- `schema_version` (`string`, optional): Internal override for schema version.
- `tool_version` (`string`, optional): Internal override for tool implementation version.

### `notion_database_fetch`

Retrieve a Notion database's full definition, including title, properties, and schema. Required: database_id (hyphenated UUID). LLM tip: Extract the last 32 characters from a Notion database URL, then insert hyphens (8-4-4-4-12).

Parameters:

- `database_id` (`string`, required): The target database ID in UUID format with hyphens.

### `notion_database_insert_row`

Insert a new row (page) into a Notion database. Required: `database_id` (hyphenated UUID) and `properties` (object mapping database column names to Notion **property values**). Optional: `child_blocks` (content blocks), `icon` (page icon object), and `cover` (page cover object).

LLM guidance:
- `properties` must use **property values** (not schema). Example:
  {
    "title": { "title": [ { "text": { "content": "Task A" } } ] },
    "Status": { "select": { "name": "Todo" } },
    "Due": { "date": { "start": "2025-09-01" } }
  }
- Use the **exact property key** as defined in the database (case‑sensitive), or the property **id`.
- `icon` example (emoji): {"type":"emoji","emoji":"📝"}
- `cover` example (external): {"type":"external","external":{"url":"https://example.com/image.jpg"}}
- Runtime note: the executor/host should synthesize `parent = {"database_id": database_id}` before sending to Notion.

Parameters:

- `database_id` (`string`, required): Target database ID (hyphenated UUID).
- `properties` (`object`, required): Object mapping **column names (or property ids)** to **property values**.

️ **CRITICAL: Property Identification Rules:**
- For title fields: ALWAYS use 'title' as the property key (not 'Name' or display names)
- For other properties: Use exact property names from database schema (case-sensitive)
- DO NOT use URL-encoded property IDs with special characters

 **Recommended Workflow:**
1. Call fetch_database first to see exact property names
2. Use 'title' for title-type properties
3. Match other property names exactly as shown in schema

Example:
{
  "title": { "title": [ { "text": { "content": "Task A" } } ] },
  "Status": { "select": { "name": "Todo" } },
  "Due": { "date": { "start": "2025-09-01" } }
}
- `_parent` (`object`, optional): Computed by host: `{ "database_id": "<database_id>" }`. Do not supply manually.
- `child_blocks` (`array`, optional): Optional array of Notion blocks to append as page content (paragraph, heading, to_do, etc.).
- `cover` (`object`, optional): Optional page cover object. Example external: {"type":"external","external":{"url":"https://example.com/cover.jpg"}}.
- `icon` (`object`, optional): Optional page icon object. Examples: {"type":"emoji","emoji":"📝"} or {"type":"external","external":{"url":"https://..."}}.
- `schema_version` (`string`, optional): Optional schema version override.
- `tool_version` (`string`, optional): Optional tool version override.

### `notion_database_property_retrieve`

Query a Notion database and return only specific properties by supplying one or more property IDs. Use when you need page rows but want to limit the returned properties to reduce payload. Provide the database_id and an array of filter_properties (each item is a property id like "title")

Parameters:

- `database_id` (`string`, required): Target database ID (hyphenated UUID).
- `property_id` (`string`, optional): property ID to filter results by a specific property. get the property id by querying database.
- `schema_version` (`string`, optional): Optional schema version override.
- `tool_version` (`string`, optional): Optional tool version override.

### `notion_database_query`

Query a Notion database for rows (pages) using the 2022-06-28 API. Works for standard single-source databases. NOTE: If you encounter an 'Invalid request URL' error or are working with a merged, synced, or multi-source database, use the newer data source tools instead — call notion_data_source_fetch with the database_id to get the data_source_id, then call notion_data_source_query with that id. Provide database_id (hyphenated UUID). Optional: filter (Notion filter object), page_size (default 10), start_cursor for pagination, and sorts. LLM guidance: extract the last 32 characters from a Notion database URL and insert hyphens (8-4-4-4-12) to form database_id. Sort rules: each sort item MUST include either property OR timestamp (last_edited_time/created_time), not both.

Parameters:

- `database_id` (`string`, required): Target database ID (hyphenated UUID).
- `filter` (`object`, optional): Notion filter object to narrow results. Example: {"property": "Status", "select": {"equals": "Done"}}. Supports compound filters with 'and'/'or' arrays.
- `page_size` (`integer`, optional): Maximum number of rows to return (1–100).
- `schema_version` (`string`, optional): Optional schema version override.
- `sorts` (`array`, optional): Order the results. Each item must include either property or timestamp, plus direction.
- `start_cursor` (`string`, optional): Cursor to fetch the next page of results.
- `tool_version` (`string`, optional): Optional tool version override.

### `notion_database_update`

Update a Notion database's title, description, or property schema.

Parameters:

- `database_id` (`string`, required): The ID of the database to update
- `description` (`string`, optional): New description for the database
- `properties` (`object`, optional): Property schema updates (add, rename, or reconfigure columns)
- `title` (`string`, optional): New title for the database

### `notion_page_content_append`

Append blocks to a Notion page or block. IMPORTANT: This tool uses a simplified block format — do NOT pass raw Notion API block objects. Each block takes a 'type' and a 'text' string (plain text only). The tool internally converts these into the Notion API format. Supported types: paragraph, heading_1, heading_2, heading_3, bulleted_list_item, numbered_list_item, code, quote, callout, divider. For code blocks, add a 'language' field. Dividers require only the 'type' field. Example: [{"type": "heading_1", "text": "My Title"}, {"type": "paragraph", "text": "Some content"}, {"type": "code", "text": "print('hi')", "language": "python"}, {"type": "divider"}].

Parameters:

- `block_id` (`string`, required): The ID of the page or block to append content to
- `blocks` (`array`, required): Array of blocks to append. Each block uses a simplified format with 'type' and 'text' fields — NOT the raw Notion API format. Do not pass Notion block objects with rich_text arrays.

### `notion_page_content_get`

Retrieve the content (blocks) of a Notion page or block. Returns all child blocks with their type and text content.

Parameters:

- `block_id` (`string`, required): The ID of the page or block whose children to retrieve
- `page_size` (`number`, optional): Number of blocks to return (max 100)
- `start_cursor` (`string`, optional): Cursor for pagination from a previous response

### `notion_page_create`

Create a page in Notion either inside a database (as a row) or as a child of a page. Use exactly one parent mode: provide database_id to create a database row (page with properties) OR provide parent_page_id to create a child page. When creating in a database, properties must use Notion property value shapes and the title property key must be "title" (not the display name). Children (content blocks), icon, and cover are optional. The executor should synthesize the Notion parent object from the chosen parent input.

Target rules:
- Use database_id OR parent_page_id (not both)
- If database_id is provided → properties are required
- If parent_page_id is provided → properties are optional

Parameters:

- `_parent` (`object`, optional): Computed by the executor: {"database_id": "..."} OR {"page_id": "..."} derived from database_id/parent_page_id.
- `child_blocks` (`array`, optional): Optional blocks to add as page content (children).
- `cover` (`object`, optional): Optional page cover object.
- `database_id` (`string`, optional): Create a page as a new row in this database (hyphenated UUID). Extract from the database URL (last 32 chars → hyphenate 8-4-4-4-12).
- `icon` (`object`, optional): Optional page icon object.
- `notion_version` (`string`, optional): Optional Notion-Version header override.
- `parent_page_id` (`string`, optional): Create a child page under this page (hyphenated UUID). Extract from the parent page URL.
- `properties` (`object`, optional): For database rows, supply property values keyed by property name (or id). For title properties, the key must be "title".

Example (database row):
{
  "title": { "title": [ { "text": { "content": "Task A" } } ] },
  "Status": { "select": { "name": "Todo" } },
  "Due": { "date": { "start": "2025-09-01" } }
}
- `schema_version` (`string`, optional): Optional schema version override.
- `tool_version` (`string`, optional): Optional tool version override.

### `notion_page_get`

Retrieve a Notion page by its ID. Returns the page properties, metadata, and parent information.

Parameters:

- `page_id` (`string`, required): The ID of the Notion page to retrieve

### `notion_page_search`

Search Notion pages by text query. Returns matching pages with their titles, IDs, and metadata. Optionally sort by last_edited_time or created_time, and paginate with start_cursor.

Parameters:

- `page_size` (`integer`, optional): Maximum number of pages to return (1–100).
- `query` (`string`, optional): Text to search for across Notion pages.
- `sort_direction` (`string`, optional): Direction to sort results.
- `sort_timestamp` (`string`, optional): Timestamp field to sort results by.
- `start_cursor` (`string`, optional): Cursor to fetch the next page of results.

### `notion_page_update`

Update a Notion page's properties, archive/unarchive it, or change its icon and cover.

Parameters:

- `page_id` (`string`, required): The ID of the Notion page to update
- `archived` (`boolean`, optional): Set to true to archive (delete) the page, false to unarchive it
- `cover` (`object`, optional): Page cover image to set
- `icon` (`object`, optional): Page icon to set
- `properties` (`object`, optional): Page properties to update using Notion property value shapes

### `notion_user_list`

List all users in the Notion workspace including people and bots.

Parameters:

- `page_size` (`number`, optional): Number of users to return (max 100)
- `start_cursor` (`string`, optional): Cursor for pagination from a previous response


---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
