关于 notion-api
notion-api 是通过 Notion REST API 操作 Notion 工作区的技能,适用于发起 API 请求的 Agent 或脚本。它涵盖搜索及页面、区块、数据库、数据源、用户和评论操作,并说明认证与安全要求。
主要功能
- 01搜索页面和数据库
- 02读取及修改页面与区块
- 03查询和管理数据库
- 04操作数据源与用户
- 05处理评论和分页
- 06保护令牌并确认变更
适用场景
- 01查找工作区中的页面或数据库
- 02读取并更新页面内容
- 03查询数据库记录
- 04通过 API 调用管理评论
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ intellectronica/ agent-skills --skill notion-api安装后在 Claude Code 中输入/notion-api确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/block-types.mdfilters-and-sorts.mdproperty-types.mdrich-text.md详细介绍
Notion API 技能
此技能可通过 Notion REST API 与 Notion 工作区交互。可使用 curl 和 jq 直接调用 REST API,也可根据任务编写临时脚本。
身份验证
API 密钥处理
- 环境变量:检查环境中是否存在
NOTION_API_TOKEN - 用户提供的密钥:如果用户在上下文中提供了 API 密钥,则使用该密钥
- 没有可用密钥:如果两者都没有,则使用 AskUserQuestion(或等效方式)向用户索取 API 密钥
重要:除了在 Authorization 标头中,绝不要在任何地方显示、记录或发送 NOTION_API_TOKEN。确认其是否存在;如果缺少则询问;在请求中使用它,但绝不要回显或泄露它。
请求标头
所有请求都需要以下标头:
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json"
验证身份验证
通过获取机器人用户来测试 API 密钥:
curl -s "https://api.notion.com/v1/users/me" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
基础 URL 和约定
- 基础 URL:
https://api.notion.com - API 版本:
2025-09-03(必需标头) - 数据格式:所有请求和响应正文均为 JSON
- ID:UUIDv4 格式(请求中可省略连字符)
- 时间戳:ISO 8601 格式(
2020-08-12T02:12:33.231Z) - 属性名称:
snake_case - 空值:使用
null,不要使用空字符串
速率限制
- 平均值:每个集成每秒 3 个请求
- 突发请求:允许短时间超过此限制
- 速率受限响应:HTTP 429,带有
Retry-After标头 - 策略:收到 429 响应时实施指数退避
请求大小限制
| 类型 | 限制 |
|---|---|
| 每个负载的最大块元素数 | 1000 |
| 最大负载大小 | 500KB |
| 富文本内容 | 2000 个字符 |
| URL | 2000 个字符 |
| 公式 | 1000 个字符 |
| 电子邮件地址 | 200 个字符 |
| 电话号码 | 200 个字符 |
| 多选选项 | 100 项 |
| 关联 | 100 个关联页面 |
| 人员提及 | 100 位用户 |
| 每个请求的块数组 | 100 个元素 |
破坏性操作确认
重要:在执行任何会修改或删除数据的操作之前,必须征求用户确认。包括:
- 更新页面或块
- 删除/归档页面或块
- 修改数据库架构
- 创建页面(如果要创建多个页面或批量创建)
- 任何批量操作
对于一组逻辑相关的操作,只需确认一次。
核心 API 端点
搜索
搜索所有可访问的页面和数据库:
curl -s -X POST "https://api.notion.com/v1/search" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"query": "search term",
"filter": {"property": "object", "value": "page"},
"sort": {"direction": "descending", "timestamp": "last_edited_time"},
"page_size": 100
}' | jq
筛选值:"page" 或 "data_source"(也可省略以搜索两者)
页面
获取页面
curl -s "https://api.notion.com/v1/pages/{page_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
注意:此操作返回页面属性,而非内容。要获取内容,请使用页面 ID 调用“获取块子项”。
创建页面
curl -s -X POST "https://api.notion.com/v1/pages" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"page_id": "parent-page-id"},
"properties": {
"title": {
"title": [{"text": {"content": "Page Title"}}]
}
},
"children": [
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [{"type": "text", "text": {"content": "Paragraph content"}}]
}
}
]
}' | jq
父级选项:
{"page_id": "..."}- 在页面下创建{"database_id": "..."}- 在数据库中创建(旧版){"data_source_id": "..."}- 在数据源中创建(API v2025-09-03+)
更新页面
curl -s -X PATCH "https://api.notion.com/v1/pages/{page_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"properties": {
"title": {"title": [{"text": {"content": "Updated Title"}}]}
},
"icon": {"type": "emoji", "emoji": "📝"},
"archived": false
}' | jq
其他更新选项:cover、is_locked、in_trash
归档(删除)页面
curl -s -X PATCH "https://api.notion.com/v1/pages/{page_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"archived": true}' | jq
获取页面属性项
对于引用数超过 25 个的属性:
curl -s "https://api.notion.com/v1/pages/{page_id}/properties/{property_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
块(页面内容)
获取块子项
curl -s "https://api.notion.com/v1/blocks/{block_id}/children?page_size=100" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
使用页面 ID 作为 block_id 获取页面内容。检查每个块的 has_children,以查看是否有嵌套内容。
追加块子项
curl -s -X PATCH "https://api.notion.com/v1/blocks/{block_id}/children" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"children": [
{
"object": "block",
"type": "heading_2",
"heading_2": {
"rich_text": [{"type": "text", "text": {"content": "New Section"}}]
}
},
{
"object": "block",
"type": "paragraph",
"paragraph": {
"rich_text": [{"type": "text", "text": {"content": "Content here"}}]
}
}
]
}' | jq
每个请求最多 100 个块,最多支持 2 层嵌套。
请求正文中的位置选项:
- 默认:追加到末尾
"position": {"type": "start"}- 插入到开头"position": {"type": "after_block", "after_block": {"id": "block-id"}}- 插入到指定块之后
获取块
curl -s "https://api.notion.com/v1/blocks/{block_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
更新块
curl -s -X PATCH "https://api.notion.com/v1/blocks/{block_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"paragraph": {
"rich_text": [{"type": "text", "text": {"content": "Updated content"}}]
}
}' | jq
更新操作会替换指定字段的整个值。
删除块
curl -s -X DELETE "https://api.notion.com/v1/blocks/{block_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
将块移至回收站(可恢复)。
数据库
获取数据库
curl -s "https://api.notion.com/v1/databases/{database_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
返回数据库结构,包括数据源和属性。
查询数据库
curl -s -X POST "https://api.notion.com/v1/databases/{database_id}/query" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"filter": {
"property": "Status",
"select": {"equals": "Done"}
},
"sorts": [
{"property": "Created", "direction": "descending"}
],
"page_size": 100
}' | jq
完整的筛选和排序文档请参阅 references/filters-and-sorts.md。
创建数据库
curl -s -X POST "https://api.notion.com/v1/databases" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"page_id": "parent-page-id"},
"title": [{"type": "text", "text": {"content": "My Database"}}],
"is_inline": true,
"initial_data_source": {
"properties": {
"Name": {"title": {}},
"Status": {
"select": {
"options": [
{"name": "To Do", "color": "red"},
{"name": "In Progress", "color": "yellow"},
{"name": "Done", "color": "green"}
]
}
},
"Due Date": {"date": {}}
}
}
}' | jq
更新数据库
curl -s -X PATCH "https://api.notion.com/v1/databases/{database_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"title": [{"text": {"content": "Updated Title"}}],
"description": [{"text": {"content": "Database description"}}]
}' | jq
数据源(API v2025-09-03+)
数据源是数据库中的单个表。从 API 版本 2025-09-03 起,数据库可以包含多个数据源。
创建数据源
curl -s -X POST "https://api.notion.com/v1/data_sources" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"type": "database_id", "database_id": "database-id"},
"title": [{"type": "text", "text": {"content": "New Data Source"}}],
"properties": {
"Name": {"title": {}},
"Description": {"rich_text": {}}
}
}' | jq
用户
列出所有用户
curl -s "https://api.notion.com/v1/users?page_size=100" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
获取用户
curl -s "https://api.notion.com/v1/users/{user_id}" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
获取机器人用户(自身)
curl -s "https://api.notion.com/v1/users/me" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
评论
获取评论
curl -s "https://api.notion.com/v1/comments?block_id={block_id}&page_size=100" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" | jq
对于页面级评论,请将页面 ID 用作 block_id。
创建评论
在页面上:
curl -s -X POST "https://api.notion.com/v1/comments" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"page_id": "page-id"},
"rich_text": [{"type": "text", "text": {"content": "Comment content"}}]
}' | jq
回复讨论:
curl -s -X POST "https://api.notion.com/v1/comments" \
-H "Authorization: Bearer $NOTION_API_TOKEN" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"discussion_id": "discussion-id",
"rich_text": [{"type": "text", "text": {"content": "Reply content"}}]
}' | jq
注意:API 无法开启新的行内讨论串,也无法编辑或删除现有评论。
分页
支持分页的端点会返回:
has_more:布尔值,表示是否还有更多结果next_cursor:下一页的游标results:项目数组
遍历所有结果:
- 发起初始请求(省略
start_cursor) - 检查响应中的
has_more - 如果为
true,提取next_cursor,并在下一个请求中将其作为start_cursor传入 - 重复以上步骤,直到
has_more为false
带游标的请求示例:
{
"page_size": 100,
"start_cursor": "v1%7C..."
}
错误处理
| HTTP 状态 | 代码 | 描述 |
|---|---|---|
| 400 | invalid_json | 请求正文不是有效的 JSON |
| 400 | invalid_request_url | URL 格式错误 |
| 400 | invalid_request | 不支持此请求 |
| 400 | validation_error | 请求正文与预期架构不匹配 |
| 400 | missing_version | 缺少 Notion-Version 标头 |
| 401 | unauthorized | Bearer 令牌无效 |
| 403 | restricted_resource | 令牌缺少权限 |
| 404 | object_not_found | 资源不存在,或未与集成共享 |
| 409 | conflict_error | 事务期间发生数据冲突 |
| 429 | rate_limited | 超出速率限制(请检查 Retry-After 标头) |
| 500 | internal_server_error | 意外的服务器错误 |
| 503 | service_unavailable | Notion 不可用,或超过 60 秒超时 |
| 503 | database_connection_unavailable | 数据库无响应 |
| 504 | gateway_timeout | 请求超时 |
最佳实践
- 存储 ID:创建页面/数据库时,保存返回的 ID,以便后续更新
- 使用属性 ID:通过 ID 而非名称引用属性,以提高稳定性
- 批量操作:将多个小型操作合并为更少的请求
- 遵守速率限制:对 429 响应实施指数退避
- 检查
has_more:始终处理列表端点的分页 - 更新前先验证:更新前获取当前状态
- 使用环境变量:切勿将 API 密钥硬编码
- 妥善处理错误:检查响应状态码和错误消息
- 架构大小:数据库架构应保持在 50KB 以下,以获得最佳性能
- 属性限制:包含超过 25 个页面引用的属性需要单独获取
参考资料
特定主题的详细文档请参阅:
references/block-types.md- 所有受支持的区块类型及其结构references/property-types.md- 数据库属性类型和值格式references/filters-and-sorts.md- 数据库查询筛选和排序语法references/rich-text.md- 富文本对象结构和注释