| name | notion-manager |
| description | Read and manage your Notion workspace — databases, pages, to-dos, and notes — all through your agent. |
Notion Manager
Read and manage your Notion workspace — databases, pages, to-dos, and notes — all through your agent.
Category: productivity
API Key Required: Yes (Notion Integration Token)
What It Does
Full Notion integration: query databases, create pages, update properties, search across your workspace, manage to-do lists, and pull content. Your agent becomes a Notion power user.
Setup
Step 1: Create a Notion Integration
- Go to https://www.notion.so/my-integrations
- Click "New integration"
- Name it (e.g. "OpenClaw Agent")
- Select the workspace
- Copy the Internal Integration Token
Step 2: Share pages/databases with the integration
In Notion, open any database or page you want the agent to access:
- Click "..." menu (top right)
- Click "Connections" > "Connect to" > select your integration
Important: The integration can ONLY see pages/databases explicitly shared with it.
Store the token:
NOTION_TOKEN=secret_xxx
Step 3: Test connection
curl -s -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" \
"https://api.notion.com/v1/users/me" | python3 -m json.tool
Agent Commands
Base URL: https://api.notion.com/v1
Always include headers:
Authorization: Bearer $NOTION_TOKEN
Notion-Version: 2022-06-28
Content-Type: application/json
Search across workspace
curl -s -X POST -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" -H "Content-Type: application/json" \
"https://api.notion.com/v1/search" \
-d '{"query": "SEARCH_TERM", "page_size": 10}' | python3 -c "
import json,sys
d = json.load(sys.stdin)
for r in d['results']:
title = ''
if r['object'] == 'page':
props = r.get('properties',{})
for p in props.values():
if p['type'] == 'title' and p['title']:
title = p['title'][0]['plain_text']
break
elif r['object'] == 'database':
title = r.get('title',[{}])[0].get('plain_text','')
print(f\"{r['object']:10s} {title:40s} {r['id']}\")
"
Query a database
curl -s -X POST -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" -H "Content-Type: application/json" \
"https://api.notion.com/v1/databases/DATABASE_ID/query" \
-d '{"page_size": 20}'
With filters:
curl -s -X POST -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" -H "Content-Type: application/json" \
"https://api.notion.com/v1/databases/DATABASE_ID/query" \
-d '{
"filter": {
"property": "Status",
"status": {"equals": "In Progress"}
},
"sorts": [{"property": "Created", "direction": "descending"}]
}'
Create a page
curl -s -X POST -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" -H "Content-Type: application/json" \
"https://api.notion.com/v1/pages" \
-d '{
"parent": {"database_id": "DATABASE_ID"},
"properties": {
"Name": {"title": [{"text": {"content": "New task"}}]},
"Status": {"status": {"name": "To Do"}},
"Priority": {"select": {"name": "High"}}
}
}'
Create a page with content
curl -s -X POST -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" -H "Content-Type: application/json" \
"https://api.notion.com/v1/pages" \
-d '{
"parent": {"page_id": "PARENT_PAGE_ID"},
"properties": {
"title": {"title": [{"text": {"content": "Meeting Notes"}}]}
},
"children": [
{"object": "block", "type": "heading_2", "heading_2": {"rich_text": [{"text": {"content": "Summary"}}]}},
{"object": "block", "type": "paragraph", "paragraph": {"rich_text": [{"text": {"content": "Key points from today..."}}]}},
{"object": "block", "type": "to_do", "to_do": {"rich_text": [{"text": {"content": "Follow up with team"}}], "checked": false}}
]
}'
Update a page property
curl -s -X PATCH -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" -H "Content-Type: application/json" \
"https://api.notion.com/v1/pages/PAGE_ID" \
-d '{
"properties": {
"Status": {"status": {"name": "Done"}}
}
}'
Get page content (blocks)
curl -s -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" \
"https://api.notion.com/v1/blocks/PAGE_ID/children?page_size=100" | python3 -c "
import json,sys
d = json.load(sys.stdin)
for b in d['results']:
btype = b['type']
text = ''
if btype in b and 'rich_text' in b[btype]:
text = ''.join(t['plain_text'] for t in b[btype]['rich_text'])
elif btype == 'to_do':
checked = '✅' if b['to_do']['checked'] else '⬜'
text = checked + ' ' + ''.join(t['plain_text'] for t in b['to_do']['rich_text'])
print(f\"{btype:20s} {text}\")
"
Add content to a page
curl -s -X PATCH -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" -H "Content-Type: application/json" \
"https://api.notion.com/v1/blocks/PAGE_ID/children" \
-d '{
"children": [
{"object": "block", "type": "paragraph", "paragraph": {"rich_text": [{"text": {"content": "Added by your agent"}}]}}
]
}'
List databases
curl -s -X POST -H "Authorization: Bearer $NOTION_TOKEN" \
-H "Notion-Version: 2022-06-28" -H "Content-Type: application/json" \
"https://api.notion.com/v1/search" \
-d '{"filter": {"property": "object", "value": "database"}, "page_size": 20}' | python3 -c "
import json,sys
d = json.load(sys.stdin)
for r in d['results']:
title = r.get('title',[{}])[0].get('plain_text','Untitled')
print(f\"{title:40s} {r['id']}\")
"
Examples
User: "What's on my to-do list?"
→ Search for a database with "to-do" or "tasks", query it filtered by Status != Done
User: "Add a task: review marketing plan"
→ Create a page in the tasks database with title and Status: To Do
User: "Mark the design review as done"
→ Search for the page, update Status to Done
User: "Show me my meeting notes from yesterday"
→ Search for pages with "meeting" created yesterday
Constraints
- Integration can only access pages/databases explicitly shared with it
- Rate limit: 3 requests per second
- Page content is retrieved as blocks (may need pagination for long pages)
- Rich text formatting is verbose in the API — keep it simple
- Notion API version must be
2022-06-28 or later