notion-cli

module
v0.5.40 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 7, 2026 License: MIT

README

Notion CLI — Wiki in your Terminal

Command-line interface for the Notion API with secure authentication, file uploads, and data source management.

Features

  • Authentication - OAuth browser login or integration token, stored securely in OS keychain
  • Blocks - Manage content blocks with quick helpers for TOC, breadcrumbs, dividers, and columns
  • Bulk Operations - Bulk update or archive database pages with --where filters
  • Comments - List and add comments to pages
  • Data Sources - Create and query Notion data sources (API v2025-09-03)
  • Databases - Create, query, and update databases with full property support
  • Export - Export pages to Markdown or JSON block trees
  • File Uploads - Upload files with automatic chunking for large files (multi-part upload)
  • Fetch by URL - Fetch pages or databases by Notion URL
  • Import - Import Markdown or CSV into Notion
  • jq Integration - Filter JSON output with jq expressions via --query
  • MCP Integration - AI search, SQL queries, and markdown editing via Notion's MCP server
  • Pages - Create, update, move, duplicate, and batch-operate on pages
  • Search - Full-text search across pages and databases with filtering and pagination
  • Skill File - Manage aliases for databases, users, and pages for agent-friendly workflows
  • Webhooks - Verify and parse webhook payloads
  • Workers Passthrough - Run Notion's official Workers CLI via ntn workers ... with pinned versioning

Installation

Homebrew
brew install salmonumbrella/tap/notion-cli
Go Install
go install github.com/salmonumbrella/notion-cli/cmd/notion@latest

Quick Start

1. Authenticate

Choose one of two methods:

Browser (recommended):

ntn auth login

Integration token:

ntn auth add-token
# You'll be prompted securely for the token
2. Test Authentication
ntn auth status
3. Start Using
# Search your workspace
ntn s "project notes"

# Get current user
ntn u me

# Open a page in the browser
ntn o <page-id>

Canonical Subcommand Aliases

All subcommands automatically support these short aliases across every command group:

Subcommand Aliases
list ls
get g, show
create c, mk
update u, up, edit
delete d, rm
search q, query, find

These work everywhere: ntn p g (page get), ntn db q (database query), ntn c ls (comment list), etc.

Root-Level Desire Paths

Common operations are available directly at the root level without specifying a command group:

ntn login                    # Same as: ntn auth login
ntn logout                   # Same as: ntn auth logout
ntn whoami                   # Same as: ntn u me
ntn list                     # Same as: ntn p ls
ntn get <id>                 # Auto-detects entity type (page/db/block)
ntn create                   # Same as: ntn p c (with smart defaults)
ntn delete <id>              # Same as: ntn p d <id>

Command Reference

Every command has a short alias for quick scripting:

Command Aliases Subcommands
page p, pages get, create, update, delete, ls list, props, prop, mv, dup, export, cb create-batch, ub update-batch, sync, enrich
block b, blocks get, ls children, append, update, delete, add, add-toc, add-breadcrumb, add-divider, add-columns
db database, databases get, query, create, update, ls list, bak backup
datasource ds get, query, create, update, ls list, templates
comment c, comments get, ls list, add
user u, users get, ls list, me
file f, files get, upload, ls list
search s, find
schema describe, sc
resolve r, res
open o
fetch
import im csv
bulk update, archive
skill sk init, sync, path, edit
config cfg ls list, get, set-default, edit
workspace ws info
webhook wh verify, parse
api request, status
mcp login, logout, status, search, fetch, create, edit, cm comment, mv move, duplicate, query, mn meeting-notes, tm teams, users, db, tools, call
workers wk local new scaffold + doctor, plus passthrough to official Notion Workers CLI (deploy, runs, exec, etc.)

Authentication (auth)
ntn auth login                  # Authenticate via browser (OAuth)
ntn auth login --no-browser     # Print OAuth URL without auto-opening browser
ntn auth add-token              # Add integration token manually
ntn auth status                 # Check authentication status
ntn auth logout                 # Remove stored credentials
ntn auth switch                 # Switch workspace (--account, --workspace)

Search (s, find)
ntn s                           # Search all pages and databases
ntn s "project notes"           # Search with query
ntn s --fi page                 # Search only pages
ntn s --fi database             # Search only databases
ntn s "project" --li            # Light search (id, object, title, url)
ntn s "project" --all --ro      # Fetch all results (array only)
ntn s "project" --sort recent   # Sort by most recent

Resolve (r, res)

Resolves names to Notion IDs via skill aliases and search:

ntn r "Meeting Notes"           # Return candidate IDs (skill aliases + search)
ntn r "Projects" --type database
ntn r standup                   # Skill alias
ntn r "Tasks" --check           # Silent check (exit code only, no output)

Schema (schema, describe)

Machine-readable command contracts for agents:

ntn schema                      # Indexed agent contracts (JSON by default)
ntn schema comment add          # Flags + light contract + raw request schema
ntn schema page create          # Flags + raw CreatePageRequest schema
ntn schema get                  # Auto-detected lookup contract (light variants for page/database/block)

Open (o)

Opens a Notion page or database in the browser:

ntn o <page-id>                 # Open by ID
ntn o <notion-url>              # Open by URL

Users (u)
ntn u me                        # Get current user
ntn u ls                        # List all workspace users
ntn u ls --li                   # Light list (id, name, email, type)
ntn u g <user-id>               # Get user by ID
ntn get <id-or-name> --li       # Compact auto-detected lookup (page/database/block)

Pages (p)
Basic operations
ntn p g <page-id>                              # Get page
ntn p g <page-id> --li                         # Light page lookup (id, object, title, url; compact JSON by default)
ntn p g <page-id> --enrich                     # Get page with parent_title and child_count
ntn p g <page-id> --editable                   # Get page with only editable properties
ntn p g <page-id> --include-children           # Get page with child blocks
ntn p g <page-id> --include-children --children-depth 2  # Include nested children
ntn p c --pa <id> --props <json>               # Create page
ntn p u <page-id> --props <json>               # Update page
ntn p d <page-id>                              # Delete page (archive)
ntn p mv <page-id> --pa <new-parent-id>        # Move page
ntn p dup <page-id>                            # Duplicate page with content
ntn p ex <page-id> --format markdown           # Export page content
Properties
ntn p props <page-id>                          # List all properties
ntn p props <page-id> --li                     # Compact schema rows (name, id, type, editable, has_value, simple)
ntn p props <page-id> --keys                   # Property names only
ntn p props <page-id> --simple                 # Simplified values
ntn p props <page-id> --types                  # Include property types
ntn p props <page-id> --only-set               # Only properties with values
ntn p props <page-id> --with-values            # Include resolved values
ntn p prop <page-id> <property-id>             # Get a single property
Property shorthand flags

Instead of raw JSON, use shorthand flags for common properties:

ntn p c --pa <id> --title "My Page"            # Set title
ntn p u <page-id> --status "Done"              # Set status property
ntn p u <page-id> --priority "High"            # Set priority property
ntn p u <page-id> --assignee me                # Set assignee (user ID or alias)
ntn p u <page-id> --mention @user-id           # Add mention in rich text
ntn p u <page-id> --rich-text "**bold** text"  # Markdown-aware rich text
ntn p c --request @page.json --dry-run         # Preview raw CreatePageRequest payload
ntn p u <page-id> --dry-run                    # Preview changes without applying
Batch operations
ntn p cb --pa <id> --pages <json>              # Create multiple pages
ntn p ub --pages <json>                        # Update multiple pages
Sync
ntn p sync --pa <parent-id>                    # Sync pages
ntn p sync --pa <parent-id> --dry-run          # Preview sync changes

Databases (db)
Basic operations
ntn db g <database-id>                         # Get database
ntn db ls                                      # List databases
ntn db ls --li                                 # Light list (id, object, title, url)
ntn db ls --title-match "Tasks"                # Filter by title
ntn db c --pa <id> --props <json>              # Create database
ntn db c --request @db.json --dry-run          # Preview raw CreateDatabaseRequest payload
ntn db u <database-id> --props <json>          # Update database
ntn db u <database-id> --dry-run               # Preview update
ntn db bak <database-id>                       # Backup database
Query
ntn db q <database-id>                         # Query all pages
ntn db q <database-id> --ds <id>               # Query specific data source
ntn db q <database-id> --all --ro              # Fetch all results as array
ntn db q <database-id> --page-size 50          # Set page size
ntn db q <database-id> --start-cursor <cursor> # Resume pagination
Filters
# JSON filter
ntn db q <database-id> \
  --fi '{"property":"Status","select":{"equals":"Done"}}'

# Filter from file (avoids shell escaping)
ntn db q <database-id> --fi @filter.json
ntn db q <database-id> --ff filter.json

# Filter from stdin
cat filter.json | ntn db q <database-id> --fi -

# Property shorthand filters (server-side; combined with --filter using AND)
ntn db q <database-id> --status Done
ntn db q <database-id> --assignee me
ntn db q <database-id> --priority High
Sorts
# JSON sorts
ntn db q <database-id> \
  --sorts '[{"property":"Created","direction":"descending"}]'

# Sorts from file
ntn db q <database-id> --sorts-file sorts.json
Client-side select filtering
ntn db q <database-id> \
  --select-property "Category" --select-equals "Engineering"
ntn db q <database-id> \
  --select-property "Status" --select-not "Done"
ntn db q <database-id> \
  --select-property "Category" --select-match "(?i)eng"

Blocks (b)
Basic operations
ntn b g <block-id>                        # Get block
ntn b ls <block-id>                       # List children
ntn b ls <block-id> --li                  # Compact child block summaries under list envelope
ntn b ls <block-id> --plain               # Simplified output (id/type/text)
ntn b ls <block-id> --depth 3             # Recursively fetch nested children
ntn b ls <block-id> --all                 # Fetch all children (paginated)
ntn b ap <parent-id> --ch <json>          # Append blocks
ntn b ap <parent-id> --chf blocks.json    # Append blocks from file
ntn b ap <parent-id> --ch <json> --dr     # Dry-run append
ntn b u <block-id> --content <json>       # Update block
ntn b d <block-id>                        # Delete block
Quick block creation
ntn b add paragraph <parent-id> "Hello world"
ntn b add heading <parent-id> "Title" --level 1
ntn b add bullet <parent-id> "List item"
ntn b add code <parent-id> 'fmt.Println("hi")' --language go
ntn b add todo <parent-id> "Buy milk"
ntn b add callout <parent-id> "Note" --emoji "💡"
ntn b add-toc <parent-id>                   # Table of contents
ntn b add-breadcrumb <parent-id>            # Breadcrumb navigation
ntn b add-divider <parent-id>               # Horizontal divider
ntn b add-columns <parent-id> --columns 3   # Column layout (2-5)
File & image uploads to page body
ntn b add file <parent-id> --file ./report.pdf
ntn b add file <parent-id> --file ./data.txt --caption "Raw data"
ntn b add image <parent-id> --file ./photo.jpg --caption "Team offsite"

Supported file extensions:

Category Extensions
Document .pdf .txt .json .doc .docx .dotx .xls .xlsx .xltx .ppt .pptx .potx
Image .gif .heic .jpeg .jpg .png .svg .tif .tiff .webp .ico
Audio .aac .mp3 .m4a .m4b .mp4 .ogg .wav .wma
Video .mp4 .mov .avi .mkv .webm .mpeg .flv .wmv

Note: .md files are not supported by the Notion API. Rename to .txt before uploading:

cp notes.md notes.txt && ntn b add file <parent-id> --file ./notes.txt

Comments (c)

ntn c uses the REST API. It covers page-level discussion comments, but it does not discover or create inline text-highlight comments. For inline threads, use ntn mcp comment list to discover discussion IDs and ntn mcp comment add to create or reply to them.

ntn c ls <page-id>                       # List comments
ntn c ls <page-id> --li                  # Light list (id, discussion_id, text, created_by)
ntn c ls <page-id> --all                 # List all comments (paginated)
ntn c g <comment-id>                     # Get comment
ntn c a <page-id> --text "Comment"       # Add comment
ntn c a <page-id> --text "Comment" --li -j  # Add comment with light output

# Desire paths (positional arguments)
ntn c <page-id> "Looks great!"           # Add comment (auto-detects)
ntn c a <page-id> "Looks great!"         # Add comment (positional text)

# Inline comments require MCP
ntn mcp cm ls <page-or-url> --include-all-blocks                 # Discover inline discussions + discussion IDs
ntn mcp cm a <block-id> "Please verify [the PR](https://...)" --selection "target text"
ntn mcp cm a <block-id> "@DiluteDev please review\\nPR is up" --discussion-id discussion://... --mention user-id

File Uploads (f)
ntn f up <filepath>                       # Upload file
ntn f up ./receipt.pdf --page <page-id> --prop "Attachments"  # Upload and attach
ntn f g <upload-id>                       # Get upload status
ntn f ls                                  # List file uploads
ntn f ls --li                             # Light list (id, file_name, status, size, timestamps)

Data Sources (ds)
ntn ds t <datasource-or-database-id>        # List templates for a data source
ntn ds t <datasource-or-database-id> --li   # Compact template summaries (id, name, is_default)
ntn ds c --template <name>                  # Create from template
ntn ds g <datasource-id>                    # Get data source
ntn ds q <datasource-id>                    # Query data source
ntn ds q <datasource-id> --li               # Light query rows (id, object, title, url)
ntn ds u <datasource-id> <json>             # Update data source
ntn ds ls                                   # List data sources
ntn ds ls --li                              # Light list (id, object, title, url)

Query with filters, sorts, and selection (same flags as db q):

ntn ds q <datasource-id> \
  --fi '{"property":"Status","status":{"equals":"Active"}}' \
  --sb created_time --desc --limit 20 --ro

Fetch
ntn fetch <notion-url>                    # Auto-detect page or database
ntn fetch <notion-url> --li               # Compact fetch (id, object, title, url)
ntn fetch <notion-url> --type page        # Force page fetch
ntn fetch <notion-url> --type database    # Force database fetch

Import (im)
ntn im --file content.md                  # Import markdown as Notion blocks
ntn im --file content.md --dry-run        # Preview import
ntn im --file content.md --batch-size 50  # Control batch size
ntn im csv --file data.csv                # Import CSV to database
ntn im csv --file data.csv --mapping <json> --dry-run

Bulk Operations (bulk)
ntn bulk update <database-id> \
  --where '{"property":"Status","select":{"equals":"Stale"}}' \
  --set '{"Status":{"select":{"name":"Archived"}}}' \
  --dry-run

ntn bulk archive <database-id> \
  --where '{"property":"Done","checkbox":{"equals":true}}' \
  --limit 100 --dry-run

Skill File (sk)

Manage the skill file that stores aliases for databases, users, and pages:

ntn sk init                              # Initialize by scanning workspace
ntn sk sync                              # Update skill file
ntn sk sync --add-new                    # Add newly discovered items
ntn sk path                              # Print skill file path
ntn sk edit                              # Open skill file in editor

Config (cfg)
ntn cfg ls                               # List workspaces
ntn cfg g                                # Get workspace config
ntn cfg set <workspace>                  # Set default workspace
ntn cfg e                                # Edit config file

Workspace (ws)
ntn ws i                                 # Get current workspace info

Webhooks (wh)
ntn wh verify --secret <secret> --payload payload.json --signature <sig>
ntn wh verify --secret <secret> --payload payload.json   # Compute signature
ntn wh parse --payload payload.json

API

Raw API access and diagnostics:

ntn api request GET /users
ntn api request POST /search --body '{"query":"project"}'
ntn api request POST /databases/<id>/query --body @query.json
ntn api request GET /blocks/<id>/children --paginate
ntn api status                           # Show rate limit status
ntn api status --refresh                 # Refresh rate limit info

MCP Integration (Notion MCP Server)

The ntn mcp command group connects to Notion's official MCP server at https://mcp.notion.com/mcp, providing capabilities not available through the REST API.

Setup
ntn mcp login                            # One-time OAuth login (opens browser)
ntn mcp status                           # Verify connection
ntn mcp logout                           # Remove MCP token
Commands
Command Alias Description
ntn mcp search <query> s Search workspace (add -a for AI search)
ntn mcp fetch <url-or-id> f Fetch page/database as markdown
ntn mcp create c Create pages with markdown content
ntn mcp edit <page-id> e Edit page content or properties
ntn mcp query '<sql>' <url>... q Query databases using SQL
ntn mcp move <id>... -p <id> mv Move pages to new parent
ntn mcp duplicate <page-id> dup Duplicate a page with content
ntn mcp comment list <id> cm ls List page, block, and inline discussions; use this to discover inline discussion IDs
ntn mcp comment add <id> cm a Add or reply to page/block/inline comments with markdown links and mentions
ntn mcp teams tm List workspace teamspaces
ntn mcp users u List workspace users
ntn mcp db create db c Create a database from SQL DDL schema
ntn mcp db update db u Update data source schema with SQL DDL statements
ntn mcp meeting-notes mn Query your meeting notes data source
ntn mcp call <tool-name> [args-json] invoke Invoke any MCP tool directly
ntn mcp tools List all available MCP tools (--schema includes JSON schemas)
MCP Create Flags
ntn mcp c --parent <id> --title "Page Title" --content "Markdown body"
ntn mcp c --parent <id> --file content.md     # Content from file
ntn mcp c --parent <id> --data-source <id> --properties <json>
ntn mcp c --data-source <id> --template-id <template-id> --properties '{"Task":"Follow up"}'
MCP Edit Flags
ntn mcp e <page-id> --replace "new content"                              # Replace all content
ntn mcp e <page-id> --replace-range "start...end" --new "new section"    # Replace selected range
ntn mcp e <page-id> --insert-after "start...end" --new "appended text"   # Insert after selected content
ntn mcp e <page-id> --properties <json>                                  # Edit properties
ntn mcp e <page-id> --apply-template <template-id>                       # Apply template to page
ntn mcp e <page-id> --replace "..." --allow-deleting-content             # Permit deleting child content
MCP Query Flags
ntn mcp q 'SELECT * FROM "collection://abc"' collection://abc
ntn mcp q 'SELECT * FROM "collection://abc" WHERE Status = ?' collection://abc -P '["Done"]'
ntn mcp q -v "https://notion.so/workspace/Tasks-abc?v=def"   # Execute saved view
ntn mcp mn --filter '{"operator":"and","filters":[{"property":"title","filter":{"operator":"string_contains","value":{"type":"exact","value":"standup"}}}]}'
ntn mcp fetch collection://abc                                 # Fetch a specific data source
ntn mcp fetch https://workspace.notion.site/My-Site-abc123     # Fetch a Notion Site page
ntn mcp cm ls <page-id> --include-all-blocks                   # Include block + inline discussions
ntn mcp cm a <block-id> "@Reviewer see [PR 123](https://...)" --selection "target text" --mention user-id
ntn mcp cm a <block-id> "Follow-up\\nAdded tests" --discussion-id discussion://...  # Reply to inline thread
ntn mcp call notion-fetch --args '{"id":"https://www.notion.so/..."}' # Generic MCP tool invocation
Unique MCP Features

These capabilities are only available through the MCP backend:

  • AI Search - Semantic search using Notion's AI (ntn mcp s -a "find action items from last week")
  • SQL Queries - Query databases with SQL syntax instead of Notion filter JSON
  • Connected App Search - Search across Slack, Google Drive, and other connected apps
  • Markdown-Native Editing - Edit pages using markdown content directly
  • Page Moving & Duplication - Move pages between parents and duplicate with full content

Workers Integration (Official CLI Passthrough)

Use this command group when you want official Notion Workers behavior without replacing this CLI:

ntn workers new my-worker
ntn workers status my-worker
ntn workers status my-worker --no-compare
ntn workers upgrade my-worker --dry-run
ntn workers upgrade my-worker --plan
ntn workers upgrade my-worker --force
ntn workers upgrade my-worker --from-metadata --force
ntn workers deploy
ntn workers runs list
ntn workers exec sayHello --local -d '{"name":"World"}'
ntn workers doctor

By default, this proxies to:

npx --yes ntn@<workers_cli_version from internal/workers/compat.json> workers ...

Environment overrides:

  • NTN_WORKERS_CLI_VERSION (default from internal/workers/compat.json)
  • NTN_WORKERS_NPX_BIN (default npx)

Scaffold metadata:

  • ntn workers new writes .ntn-workers-template.json in the project root with pinned template commit and CLI version.
  • ntn workers status [path] reports pinned vs project template commit state (in_sync, behind, ahead, diverged, etc).
  • ntn workers status --no-compare skips GitHub compare API calls and reports local pin mismatch only.
  • ntn workers upgrade [path] targets the CLI's current pinned template commit by default (good for weekly compat pin updates).
  • ntn workers upgrade --plan computes a file-level change preview (add, modify, and extra path counts) without writing files.
  • ntn workers upgrade --from-metadata re-syncs to the commit currently stored in .ntn-workers-template.json.
  • ntn workers upgrade requires --force to apply file overwrites; use --dry-run to preview.

Global Flags

All commands support these flags:

Output
Flag Short Aliases Description
--output -o --out, --format Output format: text, json, ndjson, jsonl, table, yaml
--json -j Shorthand for --output json
--compact-json --cj Emit compact single-line JSON (enabled by default with --light unless overridden)
--quiet Suppress non-essential output
--error-format Error output format: auto, text, json
Filtering & Projection
Flag Short Aliases Description
--query -q --jq, --qr JQ filter expression (supports path aliases)
--query-file --qf Read JQ expression from file (use - for stdin)
--fields --pick, --fds Project fields (comma-separated, key=path to rename)
--jsonpath Extract value using JSONPath
--items-only --results-only, --io, --ro, --i Output just the results array (jq should use .[], not .results[])
--fail-empty --fe Exit with error when results are empty
Sorting & Limiting
Flag Short Aliases Description
--sort-by --sb Sort by field (supports path aliases, e.g. ct for created_time)
--desc Sort descending (use with --sb)
--limit Limit number of results
--latest Shortcut for --sb created_time --desc --limit 1
--recent Shortcut for --sb created_time --desc --limit N
Session & Control
Flag Short Aliases Description
--workspace -w Workspace to use (overrides NOTION_WORKSPACE)
--debug Show API requests/responses on stderr
--sanitize Heuristically redact prompt-injection-like string content in output
--yes -y --no-input Skip confirmation prompts
--help Show help for any command
--version Show version information
Common Per-Command Flags

These flags appear on multiple commands:

Flag Aliases Used by Description
--parent --pa page create/move/dup, db create/update, mcp create Parent page or database ID
--properties --props page create/update, db create/update Properties as JSON
--properties-file --props-file page create/update Read properties from file
--request page create/update, db create, ds create/update, comment add Raw request payload as JSON (@file or - supported)
--request-file page create/update, db create, ds create/update, comment add Read raw request payload from file
--datasource --ds db query, page create/dup Data source ID
--filter --fi db query, ds query, search Filter expression (JSON or @file)
--filter-file --ff db query, ds query Read filter from file
--children --ch block append/update Block children as JSON
--children-file --chf block append Read children from file
--dry-run --dr page create/update/sync, db create/update, ds create/update, comment add, block append/update, bulk, import Preview without applying
--light --li search, get, fetch, user list/get/me, page list/get/properties, block get/children, db list/get/query, ds list/get/query/templates, comment/list/add/get, file list/get Compact lookup payload with stable contracts
--all db query, ds query, search, block children, comment list Fetch all pages
--page-size db query, ds query, search, block children Results per page
--start-cursor db query, ds query, search, block children Resume pagination

Configuration

Environment Variables
  • NOTION_TOKEN - API token (alternative to keyring storage)
  • NOTION_CREDENTIALS_DIR - Credential storage root for keyring fallback files (<dir>/notion-cli/keyring)
  • OPENCLAW_CREDENTIALS_DIR - Shared credentials root used when NOTION_CREDENTIALS_DIR is not set
  • NOTION_KEYRING_PASSWORD - File-keyring passphrase for non-interactive/headless environments
  • NOTION_NO_BROWSER - Set truthy value (1, true, yes, on) to skip browser auto-open in auth login
  • NOTION_WORKSPACE - Default workspace name for multi-workspace support
  • NOTION_OUTPUT - Output format: text (default), json, ndjson, table, or yaml
  • NOTION_API_BASE_URL - Override Notion API base URL (useful for proxies and tests)
  • NOTION_NO_UPDATE_CHECK - Set to any value to disable update checks (also auto-disabled when stdout is not a TTY)
  • NO_COLOR - Set to any value to disable colors (standard convention)

OpenClaw compatibility: when present, ~/.openclaw/.env is auto-loaded at startup. Values from that file are only applied for variables that are not already set in the process environment.

Config File (Optional)

notion-cli supports a YAML configuration file at ~/.config/notion-cli/config.yaml:

output: json
color: always
default_workspace: personal

CLI flags always override config file settings.


Output Formats

Text (default)

Human-readable tables with colors:

$ ntn u me
NAME         EMAIL                  TYPE
Example User     user@example.test       person
JSON
$ ntn u me -o json
# or: ntn u me -j
{
  "id": "user_123",
  "name": "Example User",
  "type": "person"
}
NDJSON / JSONL

Newline-delimited JSON (one object per line):

$ ntn s "project" -o ndjson
{"object":"page", ...}
{"object":"page", ...}
Table

Formatted ASCII table output:

$ ntn db q <database-id> -o table
YAML
$ ntn u me -o yaml

Data always goes to stdout, errors and progress to stderr for clean piping.


JSON Input Shortcuts

Flags that accept JSON also support reading from files or stdin:

# @file syntax
ntn db q <database-id> --fi @filter.json
ntn p u <page-id> --props @props.json

# Dedicated file flags
ntn p u <page-id> --props-file props.json
ntn db q <database-id> --ff filter.json

# Stdin with -
cat filter.json | ntn db q <database-id> --fi -

# Heredoc
cat <<'JSON' | ntn p u <page-id> --props -
{"Status":{"status":{"name":"Done"}}}
JSON

Path Aliases

Path aliases shorten jq/field/jsonpath/sort expressions. Supported in --query/--jq, --fields/--pick, --jsonpath, and --sort-by.

Alias rewrite applies to lowercase dot-path segments. Use quoted bracket keys to force a literal (e.g. .properties["st"]). Queries loaded from --query-file are also normalized.

Canonical key Alias(es)
properties props, pr
rich_text rt
plain_text pt, p
results rs
object ob
parent pa
children ch
has_children hc
created_time ct
last_edited_time lt
created_by cb
last_edited_by lb
archived ar
in_trash it
public_url pu
data_sources ds
data_source_id dsi
database_id dbi
page_id pid
workspace_id wid
discussion_id did
comment_id cid
parent_title ptt
child_count cc
next_cursor nc
has_more hm
start_cursor sc
page_size ps
sorts so
filter fi
query qy
multi_select ms
phone_number ph
time_zone tz
unique_id uid
upload_url uu
expiry_time et
file_name fn
mime_type mt
is_inline ii
initial_data_source ids
verification_token vt
_meta meta
status st
select sl
relation rl
people pe
checkbox cbx
number nu
files fl
content co
text tx
title ti, t
name nm
type ty
url ur
cover cv
icon ic

Examples

Pipeline & Extraction
# Filter JSON output with jq
ntn p g <page-id> -j --jq '.properties.Status'

# Same query using path aliases
ntn p g <page-id> -j --jq '.pr["Invoice Alert"].rt[0].p'

# Read jq from file
ntn p g <page-id> -j --qf ./query.jq

# Project specific fields
ntn db q <database-id> --i --fields id,name,created_time

# Rename fields during projection
ntn db q <database-id> --i --fields id,alert=pr["Invoice Alert"].rt.0.p

# JSONPath extraction
ntn db q <database-id> --jsonpath '$.results[0].id'

# JSONPath with aliases
ntn db q <database-id> --jsonpath '$.rs[0].pr["Invoice Alert"].rt[0].p'
Sorting & Limiting
# Sort by alias
ntn s "project" --sb ct --desc --limit 1

# Latest / recent shortcuts
ntn s "project" --latest
ntn s "project" --recent 5

# Fail if empty (useful in scripts)
ntn s "project" --fe --limit 1
Create a Page with Content
# Create with title shorthand
ntn p c --pa <parent-id> --title "New Page"

# Create with full properties JSON
ntn p c --pa <parent-id> --props '{"title":[{"text":{"content":"New Page"}}]}'

# Add content blocks
ntn b ap <page-id> \
  --ch '[{"object":"block","type":"paragraph","paragraph":{"rich_text":[{"text":{"content":"Hello world"}}]}}]'
Query and Filter Database
ntn db q <database-id> \
  --fi '{"property":"Status","select":{"equals":"Done"}}' \
  -j | jq '.results[].properties.Name'
Bulk Operations
# Mark all "Stale" items as "Archived" (preview first)
ntn bulk update <database-id> \
  --where '{"property":"Status","select":{"equals":"Stale"}}' \
  --set '{"Status":{"select":{"name":"Archived"}}}' \
  --dry-run

# Archive completed tasks
ntn bulk archive <database-id> \
  --where '{"property":"Done","checkbox":{"equals":true}}' \
  --limit 100
Automation
# Delete without confirmation
ntn b d <block-id> -y

# Pipeline
ntn db q <database-id> -j | jq '.results[] | .id'

# Debug mode
ntn --debug u me

Security

Credential Storage

Credentials are stored securely in your system's keychain:

  • macOS: Keychain Access
  • Linux: Secret Service (GNOME Keyring, KWallet)
  • Windows: Credential Manager
Best Practices
  • Use ntn auth login for personal use (browser-based OAuth)
  • Use ntn auth add-token for integration/bot access
  • Never commit tokens to version control
  • Rotate API tokens regularly

Shell Completions

Bash
# macOS (Homebrew):
ntn completion bash > $(brew --prefix)/etc/bash_completion.d/ntn

# Linux:
ntn completion bash > /etc/bash_completion.d/ntn

# Or source directly:
source <(ntn completion bash)
Zsh
ntn completion zsh > "${fpath[1]}/_ntn"
Fish
ntn completion fish > ~/.config/fish/completions/ntn.fish
PowerShell
ntn completion powershell | Out-String | Invoke-Expression

Exit Codes (Automation)

Stable exit codes for scripting:

Code Meaning
0 Success
1 System/internal error
2 User/validation error
3 Auth error
4 Not found
5 Rate limit
6 Temporary failure (circuit breaker)
130 Canceled (Ctrl+C / context canceled)

Development

After cloning, install git hooks:

make setup

This installs lefthook pre-commit and pre-push hooks for linting and testing.

License

MIT

Directories

Path Synopsis
cmd
ntn command
internal
auth
Package auth provides secure token storage and retrieval for the Notion CLI.
Package auth provides secure token storage and retrieval for the Notion CLI.
batch
Package batch provides support for reading JSON arrays and NDJSON files for bulk operations like batch page creation.
Package batch provides support for reading JSON arrays and NDJSON files for bulk operations like batch page creation.
cmd
internal/cmd/list_helper.go
internal/cmd/list_helper.go
iocontext
Package iocontext provides context-based stdout/stderr injection for testable I/O.
Package iocontext provides context-based stdout/stderr injection for testable I/O.
logging
Package logging provides structured logging configuration using slog.
Package logging provides structured logging configuration using slog.
mcp
notion
internal/notion/endpoints.go
internal/notion/endpoints.go
output
Package output provides output formatting functionality for the notion CLI.
Package output provides output formatting functionality for the notion CLI.
richtext
Package richtext provides utilities for building Notion rich text objects with markdown formatting and @mentions.
Package richtext provides utilities for building Notion rich text objects with markdown formatting and @mentions.
skill
Package skill provides functionality for parsing and resolving aliases from Claude skill files.
Package skill provides functionality for parsing and resolving aliases from Claude skill files.
testutil
Package testutil provides testing utilities for the Notion CLI.
Package testutil provides testing utilities for the Notion CLI.
ui
Package ui provides terminal color support and UX polish for notion-cli.
Package ui provides terminal color support and UX polish for notion-cli.
update
Package update provides non-blocking update checking for the CLI.
Package update provides non-blocking update checking for the CLI.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL