Notion

Notion API integration with managed OAuth. Query databases, create and update pages, manage blocks. Use this skill when users want to interact with Notion wo...

MIT-0 · Free to use, modify, and redistribute. No attribution required.
7 · 7.8k · 11 current installs · 12 all-time installs
MIT-0
Security Scan
VirusTotalVirusTotal
Benign
View report →
OpenClawOpenClaw
Benign
medium confidence
Purpose & Capability
The name and description state a Notion API integration; the SKILL.md exclusively documents calling Maton endpoints (gateway.maton.ai and ctrl.maton.ai) to manage OAuth, query databases, and manipulate pages/blocks. The single required environment variable (MATON_API_KEY) is directly tied to the Maton gateway and is appropriate for this purpose.
Instruction Scope
The runtime instructions are limited to making HTTP requests to Maton-managed endpoints and guiding the user through OAuth via the returned URL. The SKILL.md does not instruct the agent to read arbitrary local files, shell history, other environment variables, or to send data to unexpected third-party endpoints beyond Maton and the official Notion API (proxied).
Install Mechanism
There is no install spec and no code files to write to disk (instruction-only). This is the lowest-risk install model and matches the skill's scope.
Credentials
The skill requests a single environment variable, MATON_API_KEY, which is consistent with a managed OAuth gateway. This is proportionate, but that single secret is powerful: Maton will be able to use it to access your Notion connections and OAuth tokens. No unrelated credentials or config paths are requested.
Persistence & Privilege
always:false and no install actions mean the skill does not request permanent system presence. The default allow-autonomous-invocation setting is unchanged; this is normal but means an agent could call the Maton gateway autonomously if granted permission.
Assessment
This skill appears internally consistent, but it routes all Notion operations through Maton (gateway.maton.ai / ctrl.maton.ai). Before installing, verify you trust maton.ai: review their privacy/security documentation and confirm how they store/use OAuth tokens. Treat MATON_API_KEY as a sensitive secret — use least-privilege or a dedicated account if possible, and be prepared to rotate the key if you stop using the skill. If you require direct control (no third-party proxy), consider using a skill that calls Notion's API directly or a gateway you control. Also note the registry metadata shows no top-level homepage/source; if provenance is important, ask the publisher for more information.

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

Current versionv1.0.6
Download zip
latestvk97dhwejwrsd8aqmn4k5bpth758272e0

License

MIT-0
Free to use, modify, and redistribute. No attribution required.

Runtime requirements

🧠 Clawdis
EnvMATON_API_KEY

SKILL.md

Notion

Access the Notion API with managed OAuth authentication. Query databases, create pages, manage blocks, and search your workspace.

Quick Start

# Search for pages
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'meeting notes'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/notion/v1/search', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('Notion-Version', '2025-09-03')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Base URL

https://gateway.maton.ai/notion/{native-api-path}

Replace {native-api-path} with the actual Notion API endpoint path. The gateway proxies requests to api.notion.com and automatically injects your OAuth token.

Required Headers

All Notion API requests require the version header:

Notion-Version: 2025-09-03

Authentication

All requests require the Maton API key in the Authorization header:

Authorization: Bearer $MATON_API_KEY

Environment Variable: Set your API key as MATON_API_KEY:

export MATON_API_KEY="YOUR_API_KEY"

Getting Your API Key

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your Notion OAuth connections at https://ctrl.maton.ai.

List Connections

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=notion&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Create Connection

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'notion'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Get Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Response:

{
  "connection": {
    "connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80",
    "status": "ACTIVE",
    "creation_time": "2025-12-08T07:20:53.488460Z",
    "last_updated_time": "2026-01-31T20:03:32.593153Z",
    "url": "https://connect.maton.ai/?session_token=...",
    "app": "notion",
    "method": "OAUTH2",
    "metadata": {}
  }
}

Open the returned url in a browser to complete OAuth authorization.

Delete Connection

python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Specifying Connection

If you have multiple Notion connections, specify which one to use with the Maton-Connection header:

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'query': 'meeting notes'}).encode()
req = urllib.request.Request('https://gateway.maton.ai/notion/v1/search', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
req.add_header('Notion-Version', '2025-09-03')
req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If omitted, the gateway uses the default (oldest) active connection.

Key Concept: Databases vs Data Sources

In API version 2025-09-03, databases and data sources are separate:

ConceptUse For
DatabaseCreating databases, getting data source IDs
Data SourceQuerying, updating schema, updating properties

Use GET /databases/{id} to get the data_sources array, then use /data_sources/ endpoints:

{
  "object": "database",
  "id": "abc123",
  "data_sources": [
    {"id": "def456", "name": "My Database"}
  ]
}

API Reference

Search

Search for pages:

POST /notion/v1/search
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "query": "meeting notes",
  "filter": {"property": "object", "value": "page"}
}

Search for data sources:

POST /notion/v1/search
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "filter": {"property": "object", "value": "data_source"}
}

Data Sources

Get Data Source

GET /notion/v1/data_sources/{dataSourceId}
Notion-Version: 2025-09-03

Query Data Source

POST /notion/v1/data_sources/{dataSourceId}/query
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "filter": {
    "property": "Status",
    "select": {"equals": "Active"}
  },
  "sorts": [
    {"property": "Created", "direction": "descending"}
  ],
  "page_size": 100
}

Update Data Source

PATCH /notion/v1/data_sources/{dataSourceId}
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "title": [{"type": "text", "text": {"content": "Updated Title"}}],
  "properties": {
    "NewColumn": {"rich_text": {}}
  }
}

Databases

Get Database

GET /notion/v1/databases/{databaseId}
Notion-Version: 2025-09-03

Create Database

POST /notion/v1/databases
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "parent": {"type": "page_id", "page_id": "PARENT_PAGE_ID"},
  "title": [{"type": "text", "text": {"content": "New Database"}}],
  "properties": {
    "Name": {"title": {}},
    "Status": {"select": {"options": [{"name": "Active"}, {"name": "Done"}]}}
  }
}

Pages

Get Page

GET /notion/v1/pages/{pageId}
Notion-Version: 2025-09-03

Create Page

POST /notion/v1/pages
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "parent": {"page_id": "PARENT_PAGE_ID"},
  "properties": {
    "title": {"title": [{"text": {"content": "New Page"}}]}
  }
}

Create Page in Data Source

POST /notion/v1/pages
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "parent": {"data_source_id": "DATA_SOURCE_ID"},
  "properties": {
    "Name": {"title": [{"text": {"content": "New Page"}}]},
    "Status": {"select": {"name": "Active"}}
  }
}

Update Page Properties

PATCH /notion/v1/pages/{pageId}
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "properties": {
    "Status": {"select": {"name": "Done"}}
  }
}

Update Page Icon

PATCH /notion/v1/pages/{pageId}
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "icon": {"type": "emoji", "emoji": "🚀"}
}

Archive Page

PATCH /notion/v1/pages/{pageId}
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "archived": true
}

Blocks

Get Block Children

GET /notion/v1/blocks/{blockId}/children
Notion-Version: 2025-09-03

Append Block Children

PATCH /notion/v1/blocks/{blockId}/children
Content-Type: application/json
Notion-Version: 2025-09-03

{
  "children": [
    {
      "object": "block",
      "type": "paragraph",
      "paragraph": {
        "rich_text": [{"type": "text", "text": {"content": "New paragraph"}}]
      }
    }
  ]
}

Delete Block

DELETE /notion/v1/blocks/{blockId}
Notion-Version: 2025-09-03

Users

List Users

GET /notion/v1/users
Notion-Version: 2025-09-03

Get Current User

GET /notion/v1/users/me
Notion-Version: 2025-09-03

Filter Operators

  • equals, does_not_equal
  • contains, does_not_contain
  • starts_with, ends_with
  • is_empty, is_not_empty
  • greater_than, less_than

Block Types

  • paragraph, heading_1, heading_2, heading_3
  • bulleted_list_item, numbered_list_item
  • to_do, code, quote, divider

Code Examples

JavaScript

const response = await fetch('https://gateway.maton.ai/notion/v1/search', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
    'Notion-Version': '2025-09-03'
  },
  body: JSON.stringify({ query: 'meeting' })
});

Python

import os
import requests

response = requests.post(
    'https://gateway.maton.ai/notion/v1/search',
    headers={
        'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
        'Notion-Version': '2025-09-03'
    },
    json={'query': 'meeting'}
)

Notes

  • All IDs are UUIDs (with or without hyphens)
  • Use GET /databases/{id} to get the data_sources array containing data source IDs
  • Creating databases requires POST /databases endpoint
  • Delete blocks returns the block with archived: true
  • IMPORTANT: When using curl commands, use curl -g when URLs contain brackets (fields[], sort[], records[]) to disable glob parsing
  • IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.

Error Handling

StatusMeaning
400Missing Notion connection
401Invalid or missing Maton API key
429Rate limited (10 req/sec per account)
4xx/5xxPassthrough error from Notion API

Troubleshooting: API Key Issues

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

Troubleshooting: Invalid App Name

  1. Ensure your URL path starts with notion. For example:
  • Correct: https://gateway.maton.ai/notion/v1/search
  • Incorrect: https://gateway.maton.ai/v1/search

Resources

Files

2 total
Select a file
Select a file to preview.

Comments

Loading comments…