| name | notion |
| description | Notion API for creating and managing pages, databases, blocks, relations, rollups, and multi-workspace profiles via the notioncli CLI tool. |
| homepage | https://github.com/JordanCoin/notioncli |
| metadata | {"openclaw":{"emoji":"📝","requires":{"env":["NOTION_API_KEY"]},"primaryEnv":"NOTION_API_KEY","install":"npm install -g @jordancoin/notioncli"}} |
notioncli — Notion API Skill
A powerful CLI for the Notion API. Query databases, manage pages, add comments, and automate your workspace from the terminal. Built for AI agents and humans alike.
Setup
npm install -g notioncli
notion init --key $NOTION_API_KEY
The init command saves your API key and auto-discovers all databases shared with your integration. Each database gets an alias (a short slug derived from the database title) so you never need to type raw UUIDs.
Tip: In Notion, you must share each database with your integration first: open the database → ••• menu → Connections → Add your integration.
Auto-Aliases
When you run notion init, every shared database is automatically assigned a slug alias:
Found 3 databases:
✅ projects → Projects
✅ tasks → Tasks
✅ reading-list → Reading List
You can then use projects instead of a1b2c3d4-e5f6-... everywhere. Manage aliases manually with:
notion alias list
notion alias add mydb <db-id>
notion alias rename old new
notion alias remove mydb
Commands Reference
Database Discovery
notion dbs
notion alias list
Querying Data
notion query tasks
notion query tasks --filter Status=Active
notion query tasks --filter "Count>10"
notion query tasks --filter "Count>=5" --filter "Status!=Draft"
notion query tasks --filter "Due>=today"
notion query tasks --sort Date:desc
notion query tasks --filter Status=Active --limit 10
notion query tasks --output csv
notion query tasks --output yaml
notion query tasks --output json
notion --json query tasks
Filter operators: = (equals/contains), != (not equal), >, <, >=, <=
Relative dates: today, yesterday, tomorrow, last_week, next_week
Multiple filters combine as AND.
Output formats:
table — formatted ASCII table (default)
csv — header row + comma-separated values
json — full API response as JSON
yaml — simple key/value YAML format
Creating Pages
notion add tasks --name "Buy groceries" --status "Todo"
notion add projects --name "New Feature" --priority "High" --due "2026-03-01"
notion add tasks --prop "Name=Buy groceries" --prop "Status=Todo"
notion add tasks --name "Sprint Notes" --from notes.md
Property names from your database schema become CLI flags automatically. Multi-word properties use kebab-case: --due-date → "Due Date".
Updating Pages
notion update tasks --filter "Name=Ship feature" --status "Done"
notion update workouts --filter "Name=LEGS #5" --notes "Great session"
notion update <page-id> --prop "Status=Done"
notion update tasks --filter "Name=Ship feature" --prop "Status=Done" --prop "Notes=Updated"
Reading Pages & Content
By page ID:
notion get <page-id>
notion blocks <page-id>
By alias + filter:
notion get tasks --filter "Name=Ship feature"
notion blocks tasks --filter "Name=Ship feature"
Deleting (Archiving) Pages
notion delete <page-id>
notion delete tasks --filter "Name=Old task"
notion delete workouts --filter "Date=2026-02-09"
Relations & Rollups
notion relations tasks --filter "Name=Ship feature"
notion relations projects --filter "Name=Launch CLI"
Relations are automatically resolved to page titles in get output. Rollups are parsed into numbers, dates, or arrays instead of raw JSON.
Blocks CRUD
notion blocks tasks --filter "Name=Ship feature"
notion blocks tasks --filter "Name=Ship feature" --ids
notion append tasks "New paragraph" --filter "Name=Ship feature"
notion block-edit <block-id> "Updated text"
notion block-delete <block-id>
Use --ids to get block IDs, then target specific blocks with block-edit or block-delete.
The blocks command displays all block types including:
- 📄 Child pages (subpages nested under the page)
- 🗄️ Child databases
- Headings, paragraphs, lists, to-dos, code blocks, dividers, etc.
Child Pages
List only child pages and databases under a page:
notion children <page-id>
notion children tasks --filter "Name=Ship feature"
Output shows each child page with its full ID for easy navigation:
📄 Chapter 1
ID: 6e174679-5233-4419-a178-a0df9043d345
📄 Chapter 2
ID: a7aa03c5-9e17-41a6-a907-07ec3ae6b567
2 child item(s)
This is useful for navigating Notion page hierarchies programmatically.
Appending Content
notion append <page-id> "Meeting notes: discussed Q2 roadmap"
notion append tasks "Status update: phase 1 complete" --filter "Name=Ship feature"
Appends a paragraph block to the page.
Users
notion users
notion user <user-id>
Comments
notion comments <page-id>
notion comments tasks --filter "Name=Ship feature"
notion comment <page-id> "Looks good, shipping this!"
notion comment tasks "AI review complete ✅" --filter "Name=Ship feature"
Page Inspector
notion props tasks --filter "Name=Ship feature"
notion me
Database Management
notion db-create <parent-page-id> "New DB" --prop "Name:title" --prop "Status:select"
notion db-update tasks --add-prop "Rating:number"
notion db-update tasks --remove-prop "Old Column"
notion db-update tasks --title "Renamed DB"
notion templates tasks
Moving Pages
notion move tasks --filter "Name=Done task" --to archive
notion move tasks --filter "Name=Done task" --to <page-id>
File Uploads
notion upload tasks --filter "Name=Ship feature" ./report.pdf
notion upload <page-id> ./screenshot.png
Supports images, PDFs, text files, documents. MIME types auto-detected from extension.
Search
notion search "quarterly report"
Import
notion import data.csv --to tasks
notion import data.json --to tasks
notion import notes.md --to tasks --title "Sprint Notes"
notion import doc.md --parent <page-id> --title "My Document"
Export
notion export tasks --filter "Name=Sprint Notes"
notion export <page-id>
JSON Output
Add --json before any command to get the raw Notion API response:
notion --json query tasks
notion --json get <page-id>
notion --json users
notion --json comments <page-id>
Common Patterns for AI Agents
1. Discover available databases
notion dbs
notion alias list
2. Query and filter data
notion query tasks --filter Status=Active --sort Date:desc
notion --json query tasks --filter Status=Active
notion query tasks --output csv
3. Create a new entry
notion add tasks --prop "Name=Review PR #42" --prop "Status=Todo" --prop "Priority=High"
4. Update an existing entry (zero UUIDs)
notion update tasks --filter "Name=Review PR #42" --prop "Status=Done"
notion update <page-id> --prop "Status=Done"
5. Read page content (zero UUIDs)
notion get tasks --filter "Name=Review PR #42"
notion blocks tasks --filter "Name=Review PR #42"
notion get <page-id>
notion blocks <page-id>
6. Append notes to a page
notion append tasks "Status update: completed phase 1" --filter "Name=Review PR #42"
notion append <page-id> "Status update: completed phase 1"
7. Collaborate with comments
notion comments tasks --filter "Name=Review PR #42"
notion comment tasks "AI review complete ✅" --filter "Name=Review PR #42"
notion comments <page-id>
notion comment <page-id> "AI review complete ✅"
8. Delete by alias + filter
notion delete tasks --filter "Name=Old task"
notion delete workouts --filter "Date=2026-02-09"
9. Manage database schema
notion db-update tasks --add-prop "Priority:select"
notion db-update tasks --remove-prop "Old Field"
notion db-create <parent-page-id> "New DB" --prop "Name:title" --prop "Status:select"
10. Move pages and upload files
notion move tasks --filter "Name=Done" --to archive
notion upload tasks --filter "Name=Ship feature" ./report.pdf
11. Inspect and debug
notion me
notion props tasks --filter "Name=Ship feature"
notion templates tasks
Property Type Reference
When using --prop key=value, the CLI auto-detects the property type from the database schema:
| Type | Example Value | Notes |
|---|
title | Name=Hello World | Main title property |
rich_text | Notes=Some text | Plain text content |
number | Amount=42.5 | Numeric values |
select | Status=Active | Single select option |
multi_select | Tags=bug,urgent | Comma-separated options |
date | Due=2026-03-01 | ISO 8601 date string |
checkbox | Done=true | true, 1, or yes |
url | Link=https://example.com | Full URL |
email | Contact=user@example.com | Email address |
phone_number | Phone=+1234567890 | Phone number string |
status | Status=In Progress | Status property |
Multi-Workspace Profiles
Manage multiple Notion accounts from one CLI:
notion workspace add work --key ntn_work_key
notion workspace add personal --key ntn_personal
notion workspace list
notion workspace use work
notion workspace remove old
notion query tasks --workspace personal
notion -w work add projects --prop "Name=Q2 Plan"
notion init --workspace work --key ntn_work_key
Aliases are scoped per workspace. Old single-key configs auto-migrate to a "default" workspace.
Notion API 2025 — Dual IDs
The Notion API (2025-09-03) uses dual IDs for databases: a database_id and a data_source_id. notioncli handles this automatically — when you run notion init or notion alias add, both IDs are discovered and stored. You never need to think about it.
Reliability
- Automatic pagination — All list commands fetch every result by default. Use
--limit N to cap.
- Rate limit retry — 429 responses trigger automatic exponential backoff with jitter (up to 5 attempts). No flags needed.
- Input validation — Invalid numbers, dates, URLs, and emails are caught before the API call with clear error messages.
Troubleshooting
- "No Notion API key found" — Run
notion init --key ntn_... or export NOTION_API_KEY=ntn_...
- "Unknown database alias" — Run
notion alias list to see available aliases, or notion init to rediscover
- "Not found" errors — Make sure the database/page is shared with your integration in Notion
- Filter/sort property not found — Property names are case-insensitive; run
notion --json query <alias> --limit 1 to see available properties
- "Invalid number/date/url/email" — Input validation caught a bad value. Check the format (dates: YYYY-MM-DD, URLs: must start with http(s)://, emails: must contain @)