Notion
Verified@steipete
npx machina-cli add skill @steipete/notion --openclawnotion
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
Overview
Use the Notion API to create, read, update pages, databases (data sources), and blocks. This skill covers authentication, the required Notion-Version header, and common operations like search, get, create, update, and appending blocks to pages.
How This Skill Works
Authenticate with a Bearer token from your integration and store the key locally (e.g., ~/.config/notion/api_key). All requests require the Notion-Version header (the skill uses 2025-09-03) and target endpoints such as /v1/pages, /v1/data_sources, and /v1/blocks/{page_id}/children. Typical flows include searching for pages or data sources, fetching pages or blocks, creating pages in a data source, querying or creating data sources, updating page properties, and adding blocks to pages.
When to Use It
- Automate creating items in a Notion database (data source) from external data sources.
- Programmatically fetch and render page content and blocks for apps or dashboards.
- Update page properties (e.g., Status) to reflect workflow progress.
- Create new databases and attach them under a parent page for structured storage.
- Query and sort data sources by fields like Status and Date to surface relevant items.
Quick Start
- Step 1: Create an integration at https://notion.so/my-integrations and copy the API key (starts with ntn_ or secret_).
- Step 2: Save it to ~/.config/notion/api_key (e.g., echo "ntn_your_key_here" > ~/.config/notion/api_key).
- Step 3: Run a sample curl request (e.g., search or create a page in a data source) using the Authorization Bearer $NOTION_KEY and Notion-Version: 2025-09-03.
Best Practices
- Store the API key securely (e.g., ~/.config/notion/api_key) and protect the file.
- Keep the Notion-Version header consistent across requests (this skill uses 2025-09-03).
- Share the target pages/databases with your integration so actions are permitted.
- Use the correct property formats when creating/updating databases (e.g., Title, Status, Date).
- Separate data-source (database) operations from block/content operations and use the appropriate endpoints.
Example Use Cases
- Create a new database with Name, Status, and Date properties and seed rows.
- Update an item's Status on a page via PATCH to /v1/pages/{page_id}.
- Add a new paragraph block to a page using the /v1/blocks/{page_id}/children endpoint.
- Query a data source with a Status filter and Date sort to surface Active items.
- Retrieve a page's content (blocks) to render in another tool or app.