Skip to content
Back to skills

Notion

BSecurity

Notion API for creating and managing pages, databases, and blocks. Use when user asks to "take notes", "create in Notion", "update Notion page", "query database", or needs to organize information in Notion.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 29, 2026
databasesbashapidatabase

Works with

  • cli
  • api

Security analysis

B88/100
  • criticalSends environment variables or credentials to an external URL

Pro shows the line behind each finding and how to fix it

Scanned September 29, 2026

npx -y skills add Arry8/openclaw-edge --skill notion --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Notion?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Notion
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/arry8-notion/badge)](https://www.skillsdirectory.com/skills/arry8-notion)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: notion
description: Notion API for creating and managing pages, databases, and blocks. Use when user asks to "take notes", "create in Notion", "update Notion page", "query database", or needs to organize information in Notion.
homepage: https://developers.notion.com
metadata:
  {
    "openclaw":
      { "emoji": "📝", "requires": { "env": ["NOTION_API_KEY"] }, "primaryEnv": "NOTION_API_KEY" },
  }
---

# notion

Use the Notion API to create/read/update pages, data sources (databases), and blocks.

## Setup

1. Create an integration at https://notion.so/my-integrations
2. Copy the API key (starts with `ntn_` or `secret_`)
3. Store it:

```bash
mkdir -p ~/.config/notion
echo "ntn_your_key_here" > ~/.config/notion/api_key
```

4. Share target pages/databases with your integration (click "..." → "Connect to" → your integration name)

## API Basics

All requests need:

```bash
NOTION_KEY=$(cat ~/.config/notion/api_key)
curl -X GET "https://api.notion.com/v1/..." \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json"
```

> **Note:** The `Notion-Version` header is required. This skill uses `2025-09-03` (latest). In this version, databases are called "data sources" in many API responses and query flows.

## Common Operations

**Search for pages and data sources:**

```bash
curl -X POST "https://api.notion.com/v1/search" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
  -d '{"query": "page title"}'
```

**Get page:**

```bash
curl "https://api.notion.com/v1/pages/{page_id}" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03"
```

**Get page content (blocks):**

```bash
curl "https://api.notion.com/v1/blocks/{page_id}/children" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03"
```

**Create a database:**

```bash
curl -X POST "https://api.notion.com/v1/databases" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
  -d '{
    "parent": {"type": "page_id", "page_id": "PARENT_PAGE_ID"},
    "title": [{"text": {"content": "My Database"}}],
    "initial_data_source": {
      "properties": {
        "Name": {"title": {}},
        "Status": {"select": {"options": [{"name": "Todo"}, {"name": "Done"}]}}
      }
    }
  }'
```

The response is a [database object](https://developers.notion.com/reference/database) that includes a `data_sources` array. Use the returned `data_sources[0].id` value as the `data_source_id` when creating pages or querying the database contents. If the response is partial and `data_sources` is missing, retrieve the full object with `GET /v1/databases/{database_id}` to find the `data_source_id`.

**Create page in a data source:**

To add items to a database, target its `data_source_id`, not its `database_id`.

```bash
curl -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
  -d '{
    "parent": {"type": "data_source_id", "data_source_id": "DATA_SOURCE_ID"},
    "properties": {
      "Name": {"title": [{"text": {"content": "New Item"}}]},
      "Status": {"select": {"name": "Todo"}}
    }
  }'
```

**Query a data source (database):**

```bash
curl -X POST "https://api.notion.com/v1/data_sources/{data_source_id}/query" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {"property": "Status", "select": {"equals": "Active"}},
    "sorts": [{"property": "Date", "direction": "descending"}]
  }'
```

**Update page properties:**

```bash
curl -X PATCH "https://api.notion.com/v1/pages/{page_id}" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
  -d '{"properties": {"Status": {"select": {"name": "Done"}}}}'
```

**Add blocks to page:**

```bash
curl -X PATCH "https://api.notion.com/v1/blocks/{page_id}/children" \
  -H "Authorization: Bearer $NOTION_KEY" \
  -H "Notion-Version: 2025-09-03" \
  -H "Content-Type: application/json" \
  -d '{
    "children": [
      {"object": "block", "type": "paragraph", "paragraph": {"rich_text": [{"text": {"content": "Hello"}}]}}
    ]
  }'
```

## Property Types

Common property formats for database items:

- **Title:** `{"title": [{"text": {"content": "..."}}]}`
- **Rich text:** `{"rich_text": [{"text": {"content": "..."}}]}`
- **Select:** `{"select": {"name": "Option"}}`
- **Multi-select:** `{"multi_select": [{"name": "A"}, {"name": "B"}]}`
- **Date:** `{"date": {"start": "2024-01-15", "end": "2024-01-16"}}`
- **Checkbox:** `{"checkbox": true}`
- **Number:** `{"number": 42}`
- **URL:** `{"url": "https://..."}`
- **Email:** `{"email": "a@b.com"}`
- **Relation:** `{"relation": [{"id": "page_id"}]}`

## Key Differences in 2025-09-03

- **Databases → Data Sources:** Use `/data_sources/` endpoints for queries and retrieval.
- **Database creation:** Use `POST /v1/databases` with `initial_data_source` to define the first schema.
- **Two IDs:** Each database now has both a `database_id` and a `data_source_id`.
  - Use `data_source_id` when creating pages (`parent: {"type": "data_source_id", "data_source_id": "..."}`) and when querying (`POST /v1/data_sources/{id}/query`).
  - The `database_id` is still accepted for backward compatibility in page parents, but `data_source_id` is the canonical approach in 2025-09-03.
- **Finding the data_source_id:** Call `GET /v1/databases/{database_id}` — the response includes a `data_sources` array with each child's `id` and `name`. Alternatively, search results return databases with their `data_sources` array.
- **Search results:** Databases return as `"object": "database"` with a `data_sources` array; capture the `data_source_id` you need for later writes and queries.
- **Parent in responses:** Pages show `parent.data_source_id` alongside `parent.database_id`.

## Notes

- Page/database IDs are UUIDs (with or without dashes).
- The API cannot set database view filters; that remains UI-only.
- Rate limit: ~3 requests/second average, with `429 rate_limited` responses using `Retry-After`.
- Append block children: up to 100 children per request, up to two levels of nesting in a single append request.
- Payload size limits: up to 1000 block elements and 500KB overall.
- Use `is_inline: true` when creating data sources to embed them in pages.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…