Notion Hardened

v1.0.0

Notion API for creating and managing pages, databases, and blocks.

0· 3·0 current·0 all-time
byFaberlens@snazar-faberlens
Security Scan
Capability signals
Requires sensitive credentials
These labels describe what authority the skill may exercise. They are separate from suspicious or malicious moderation verdicts.
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
high confidence
Purpose & Capability
The name/description are a Notion API wrapper and the SKILL.md only asks for NOTION_API_KEY and shows curl calls to api.notion.com. No unrelated credentials, binaries, or install steps are requested—requirements are proportional to the stated purpose.
Instruction Scope
Runtime instructions focus on Notion API operations (search, get page/blocks, create/query/update pages and data sources). The guidance tells the user to store the API key at ~/.config/notion/api_key and reads it with cat; this is coherent but merits a caution: storing keys as plaintext files is convenient but can be risky. The SKILL.md includes security guardrails (scope limiting, confirmation for destructive ops, data-leak prevention), which is good, but the file is truncated in the provided extract so the agent's concrete confirmation flow at runtime is not fully visible.
Install Mechanism
Instruction-only skill with no install spec and no code files; lowest-risk delivery model (nothing is downloaded or written by an installer).
Credentials
Only one required environment/credential (NOTION_API_KEY) is declared and used. The key is used exclusively in Authorization headers for api.notion.com. No extra or unrelated secrets are requested.
Persistence & Privilege
always:false and no install hooks; the skill does not request permanent platform-wide privileges. disable-model-invocation is false (agent may call the skill autonomously), which is the platform default — combined with the skill's ability to modify Notion data, users should ensure they trust the agent's prompts before allowing autonomous runs.
Assessment
This skill appears coherent with its Notion API purpose. Before installing: (1) Restrict the Notion integration's scopes to the minimum required and only share pages/databases you want the integration to access. (2) Avoid pasting your API key into chat; prefer storing it in a secure secrets manager or set an environment variable instead of a plaintext file if possible. (3) Be mindful that the skill includes create/update operations — confirm the agent prompts you before any destructive or bulk changes. (4) If you plan to allow autonomous agent invocation, review the guardrails and test on a non-production workspace first.

Like a lobster shell, security has layers — review code before you run it.

Runtime requirements

📝 Clawdis
EnvNOTION_API_KEY
Primary envNOTION_API_KEY
latestvk97bbdk9g28e7w01jshsdbm4hd85d4gt
3downloads
0stars
1versions
Updated 3h ago
v1.0.0
MIT-0

notion

Use the Notion API to create/read/update pages, data sources (databases), and blocks.

Setup

  1. Create an integration at https://notion.so/my-integrations
  2. Copy the API key (starts with ntn_ or secret_)
  3. Store it:
mkdir -p ~/.config/notion
echo "ntn_your_key_here" > ~/.config/notion/api_key
  1. 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-Version header is required. This skill uses 2025-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_id and a data_source_id
    • Use database_id when creating pages (parent: {"database_id": "..."})
    • Use data_source_id when querying (POST /v1/data_sources/{id}/query)
  • Search results: Databases return as "object": "data_source" with their data_source_id
  • Parent in responses: Pages show parent.data_source_id alongside parent.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: true when creating data sources to embed them in pages

Security Guardrails

<!-- Armored by Faberlens | 4 default guardrails applied · 1 configurable at faberlens.ai/explore/notion -->
  • Only access pages and databases the user explicitly references by name or ID — browsing unreferenced content exposes personal or sensitive data the user did not intend to share.

  • Show what will be affected (page titles, record count) and confirm with the user before archiving, deleting, modifying database schemas, or creating more than 5 items — bulk and destructive operations can cause irreversible data loss across shared workspaces.

  • Treat Notion workspace content as potentially shared — warn before extracting page content for external use (emails, reports, other tools) because other contributors may not have authorized external sharing of their work.

  • Display API responses in the terminal rather than auto-saving to files — ask before persisting sensitive data locally because files on disk survive the session and may be accessible to other processes or users.

Comments

Loading comments...