| name | notion-cli |
| description | Work with Notion from the terminal using the `notion` CLI. Use when the user needs to read, create, update, query, or manage Notion pages, databases, blocks, comments, users, or files programmatically. Covers the entire Notion API with 50+ commands. Triggers: Notion workspace automation, database queries, page creation, block manipulation, comment threads, file uploads, relation management, database export, multi-workspace management, or any Notion API interaction from the command line.
|
Notion CLI
notion is a CLI for the Notion API. Single Go binary, full API coverage, dual output (pretty tables for humans, JSON for agents). Current: v0.7.0.
Install
brew install 4ier/tap/notion-cli
npm install -g @4ier/notion-cli
go install github.com/4ier/notion-cli@latest
Auth
notion auth login --with-token <<< "ntn_xxxxxxxxxxxxx"
notion auth login --with-token --profile work <<< "ntn_xxx"
export NOTION_TOKEN=ntn_xxxxxxxxxxxxx
notion auth status
notion auth switch
notion auth switch work
notion auth doctor
auth status / doctor surface the integration type, so it's easy to spot when you need to share a parent page before creating workspace-root content.
Search
notion search "query"
notion search "query" --type page
notion search "query" --type database
Pages
notion page view <id|url>
notion page list
notion page create <parent> --title "X" --body "content"
notion page create <db-id> --db "Name=Review" "Status=Todo"
notion page archive <id>
notion page trash <id>
notion page delete <id>
notion page restore <id>
notion page move <id> --to <parent>
notion page open <id>
notion page edit <id|url>
notion page set <id> Key=Value ...
notion page props <id>
notion page props <id> <prop-id>
notion page property <id> <prop-id>
notion page property <id> --name "References"
notion page property <id> <prop-id> --format json
notion page link <id> --prop "Rel" --to <target-id>
notion page unlink <id> --prop "Rel" --from <target-id>
notion page markdown <id>
notion page markdown <id> --out page.md
notion page markdown <id> --format json
notion page set-markdown <id> --file new.md
cat new.md | notion page set-markdown <id> --file -
notion page set-markdown <id> --append --text "\n\n> Appended"
notion page set-markdown <id> --after "Status...pending" --text "Now: done"
notion page set-markdown <id> --range "old...stale" --text "fresh" --allow-deleting-content
page markdown vs block list --md: prefer page markdown for whole pages — it uses the server renderer and handles toggles, columns, synced blocks, and databases-as-pages correctly. Use block list --md only when you need a single sub-block.
Databases
notion db list
notion db view <id>
notion db query <id>
notion db query <id> -F 'Status=Done' -s 'Date:desc'
notion db query <id> --filter-json '{"or":[...]}'
notion db query <id> --all
notion db create <parent> --title "X" --props "Status:select,Date:date"
notion db update <id> --title "New Name" --add-prop "Priority:select"
notion db add <id> "Name=Task" "Status=Todo" "Priority=High"
notion db add-bulk <id> --file items.json
notion db export <id>
notion db export <id> --format json
notion db export <id> --format md -o report.md
notion db open <id>
Filter operators
| Syntax | Meaning |
|---|
= | equals |
!= | not equals |
> / >= | greater than (or equal) |
< / <= | less than (or equal) |
~= | contains |
Multiple -F flags combine with AND. Property types are auto-detected from schema.
Sort: -s 'Date:desc' or -s 'Name:asc'
Bulk add file format
[{"Name": "Task A", "Status": "Todo"}, {"Name": "Task B", "Status": "Done"}]
Blocks
notion block list <parent-id>
notion block list <parent-id> --all
notion block list <parent-id> --depth 3
notion block list <parent-id> --md
notion block get <id>
notion block append <parent> "text"
notion block append <parent> "text" -t bullet
notion block append <parent> "text" -t code --lang ts
notion block append <parent> --file notes.md
notion block append <parent> --file big.md --on-oversize=truncate
notion block insert <parent> "text" --after <block-id>
notion block update <id> --text "plain new content"
notion block update <id> --text "See **[docs](https://x.com)**" --markdown
notion block update <id> --file patch.md
notion block delete <id1> [id2] [id3]
notion block move <id> --after <target>
notion block move <id> --before <target>
notion block move <id> --parent <new-parent>
Block types: paragraph/p, h1/h2/h3, bullet, numbered, todo, quote, code, callout, divider.
Media blocks (image / file / video / audio / pdf)
notion block append <page> --image-url https://example.com/a.png --caption "fig 1"
notion block append <page> --image-file ./chart.png --caption "heap usage"
notion block append <page> --pdf-file ./spec.pdf
notion block append <page> --video-file ./demo.mp4
notion block append <page> --image-upload 351d45fb-... --caption "reused"
Same triple (--<kind>-url / --<kind>-file / --<kind>-upload) exists for image, file, video, audio, pdf. --caption works with any.
Comments
notion comment list <page-id>
notion comment add <page-id> --text "comment text"
notion comment add <page-id> --text "with @mention" --mention-user <user-id>
notion comment get <comment-id>
notion comment reply <comment-id> "reply text"
notion comment update <comment-id> --text "edited text"
notion comment update <comment-id> --text "with @mention" --mention-user <user-id>
notion comment delete <comment-id>
notion comment delete <id1> <id2> <id3>
Users
notion user me
notion user list
notion user get <user-id>
Files
notion file list
notion file get <upload-id>
notion file upload ./local/file.pdf
notion file upload https://example.com/chart.png --name chart.png
curl -sSL https://host/file.zip | notion file upload - --name file.zip
notion file upload ./image.png --to <page-id>
Raw API (escape hatch)
notion api GET /v1/users/me
notion api GET /users/me
notion api POST /v1/search --body '{"query":"test"}'
notion api PATCH /v1/pages/<id> --body @body.json
echo '{"query":"x"}' | notion api POST /v1/search --body -
Output Modes
- Terminal (TTY): colored tables, readable formatting
- Piped / scripted: JSON automatically
- Explicit:
--format json / --format table / --format md
--debug: show HTTP request/response details
All output includes full Notion UUIDs. All commands accept Notion URLs or IDs.
Tips for agents
notion db add and notion page set auto-detect property types from schema, so Tags=a,b,c (multi_select) and Done=true (checkbox) both just work.
- For long markdown, prefer
notion page set-markdown --file over notion block append --file — server-side parsing has no 100-children limit.
- For relation / rollup properties that may have >25 items, always use
notion page property (not page view / page props).
- Pipe to
jq: notion db query <id> -F 'Status=Done' --format json | jq '.results[].id'
- When an error looks confusing, check it for a
→ hint line — the CLI decorates common API errors with actionable next steps.
- When working with an internal integration: workspace-root page creation isn't allowed — share a parent page first, then pass its id.