Notion API for creating and managing pages, databases, and blocks. Use when the user wants to create a Notion page, query a Notion database, update Notion properties, search Notion, add content to Notion, manage Notion blocks, or interact with Notion data sources and workspaces via the API.
Install
npx skillscat add elizaos/eliza/notion Install via the SkillsCat registry.
We need to produce a 2-3 sentence plain-text summary, objective, factual, no marketing, no superlatives, no calls to action, natural prose, no bullet points, no headings, no markdown. At most 60 words. No quotes. Just the summary text. We need to describe what the skill does: Notion API for creating/managing pages, databases, blocks. Problem it solves: enables programmatic interaction with Notion workspace without manual UI. When to use: when an agent or developer needs to create, query, update Notion data via API. We must keep under 60 words. Let's craft ~45 words.
notion
Use the Notion API to create/read/update pages, data sources (databases), and blocks.
Setup
- Create an integration at https://notion.so/my-integrations
- Copy the API key (starts with
ntn_orsecret_) - Store it:
mkdir -p ~/.config/notion
echo "ntn_your_key_here" > ~/.config/notion/api_key- Share target pages/databases with your integration (click "..." → "Connect to" → your integration name)
API Basics
All requests need:
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-Versionheader is required. This skill uses2025-09-03(latest). In this version, databases are called "data sources" in the API.
Common Operations
Search for pages and data sources:
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:
curl "https://api.notion.com/v1/pages/{page_id}" \
-H "Authorization: Bearer $NOTION_KEY" \
-H "Notion-Version: 2025-09-03"Get page content (blocks):
curl "https://api.notion.com/v1/blocks/{page_id}/children" \
-H "Authorization: Bearer $NOTION_KEY" \
-H "Notion-Version: 2025-09-03"Create page in a data source:
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": {"database_id": "xxx"},
"properties": {
"Name": {"title": [{"text": {"content": "New Item"}}]},
"Status": {"select": {"name": "Todo"}}
}
}'Query a data source (database):
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"}]
}'Create a data source (database):
curl -X POST "https://api.notion.com/v1/data_sources" \
-H "Authorization: Bearer $NOTION_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"page_id": "xxx"},
"title": [{"text": {"content": "My Database"}}],
"properties": {
"Name": {"title": {}},
"Status": {"select": {"options": [{"name": "Todo"}, {"name": "Done"}]}},
"Date": {"date": {}}
}
}'Update page properties:
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:
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 - Two IDs: Each database now has both a
database_idand adata_source_id- Use
database_idwhen creating pages (parent: {"database_id": "..."}) - Use
data_source_idwhen querying (POST /v1/data_sources/{id}/query)
- Use
- Search results: Databases return as
"object": "data_source"with theirdata_source_id - Parent in responses: Pages show
parent.data_source_idalongsideparent.database_id - Finding the data_source_id: Search for the database, or call
GET /v1/data_sources/{data_source_id}
Notes
- Page/database IDs are UUIDs (with or without dashes)
- The API cannot set database view filters — that's UI-only
- Rate limit: ~3 requests/second average
- Use
is_inline: truewhen creating data sources to embed them in pages