notion

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
We drive the Notion API with
curl + jq
. The user's OAuth bearer token is in
$NOTION_TOKEN
; every call needs it plus the
Notion-Version
header.
Notion-Version is currently
2022-06-28
(the most recent stable). Bump this header when Notion ships a new version.
The user's connection only sees the pages and databases they explicitly shared with the integration when they authorized. If a search or page read returns nothing, the most likely cause is "the page was never shared with the integration" — surface that hint to the user.
我们通过
curl + jq
调用Notion API。用户的OAuth bearer token存储在
$NOTION_TOKEN
中;每次调用都需要该token以及
Notion-Version
请求头。
当前的Notion-Version为
2022-06-28
(最新稳定版本)。当Notion发布新版本时,需更新该请求头。
用户的连接仅能访问他们在授权时明确共享给集成应用的页面和数据库。如果搜索或页面读取未返回任何内容,最可能的原因是“该页面从未共享给集成应用”——请向用户提示这一点。

Recipes

操作示例

Verify auth (always run first)

验证授权(务必首先执行)

sh
curl -sS https://api.notion.com/v1/users/me \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  | jq '{id, name, type, bot: (.bot != null)}'
sh
curl -sS https://api.notion.com/v1/users/me \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  | jq '{id, name, type, bot: (.bot != null)}'

Search the workspace

搜索工作区

sh
curl -sS https://api.notion.com/v1/search \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d '{"query": "Q1 budget", "page_size": 10}' \
  | jq '.results[] | {id, type: .object, url, title: (.properties.title // .properties.Name)?.title?[0]?.plain_text // .child_page?.title}'
sh
curl -sS https://api.notion.com/v1/search \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d '{"query": "Q1 budget", "page_size": 10}' \
  | jq '.results[] | {id, type: .object, url, title: (.properties.title // .properties.Name)?.title?[0]?.plain_text // .child_page?.title}'

Read a page (metadata only)

读取页面(仅元数据)

sh
curl -sS "https://api.notion.com/v1/pages/PAGE_ID" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28"
sh
curl -sS "https://api.notion.com/v1/pages/PAGE_ID" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28"

Read a page's full content

读取页面完整内容

sh
curl -sS "https://api.notion.com/v1/blocks/PAGE_ID/children?page_size=100" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  | jq '.results[] | {type, content: (.[.type] // {})}'
sh
curl -sS "https://api.notion.com/v1/blocks/PAGE_ID/children?page_size=100" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  | jq '.results[] | {type, content: (.[.type] // {})}'

Append a paragraph to a page

向页面追加段落

sh
curl -sS -X PATCH "https://api.notion.com/v1/blocks/PAGE_ID/children" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc --arg text "Appended via the assistant." '
    {children: [{
      object: "block",
      type: "paragraph",
      paragraph: {rich_text: [{type:"text", text:{content:$text}}]}
    }]}')"
sh
curl -sS -X PATCH "https://api.notion.com/v1/blocks/PAGE_ID/children" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc --arg text "Appended via the assistant." '
    {children: [{
      object: "block",
      type: "paragraph",
      paragraph: {rich_text: [{type:"text", text:{content:$text}}]}
    }]}')"

Query a database

查询数据库

sh
curl -sS -X POST "https://api.notion.com/v1/databases/DATABASE_ID/query" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {"property": "Status", "select": {"equals": "Open"}},
    "sorts":  [{"property": "Updated", "direction": "descending"}],
    "page_size": 25
  }'
sh
curl -sS -X POST "https://api.notion.com/v1/databases/DATABASE_ID/query" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d '{
    "filter": {"property": "Status", "select": {"equals": "Open"}},
    "sorts":  [{"property": "Updated", "direction": "descending"}],
    "page_size": 25
  }'

Create a page in a database

在数据库中创建页面

sh
curl -sS -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc \
        --arg db "DATABASE_ID" \
        --arg title "New entry" \
        '{
          parent: {database_id: $db},
          properties: {
            Name:   {title: [{text: {content: $title}}]},
            Status: {select: {name: "Open"}}
          }
        }')"
sh
curl -sS -X POST "https://api.notion.com/v1/pages" \
  -H "Authorization: Bearer $NOTION_TOKEN" \
  -H "Notion-Version: 2022-06-28" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc \
        --arg db "DATABASE_ID" \
        --arg title "New entry" \
        '{
          parent: {database_id: $db},
          properties: {
            Name:   {title: [{text: {content: $title}}]},
            Status: {select: {name: "Open"}}
          }
        }')"

Notes

注意事项

  • Notion's pagination is cursor-based: append
    start_cursor=$cursor
    to paginate, using the
    next_cursor
    from each response. Stop when
    has_more
    is
    false
    .
  • Most write failures (400/404) come from a property type mismatch — e.g. sending
    {"select": "Open"}
    instead of
    {"select": {"name": "Open"}}
    . Read the database schema once via
    GET /v1/databases/<id>
    if unsure.
  • Notion的分页采用游标机制:在请求中追加
    start_cursor=$cursor
    进行分页,使用每个响应中的
    next_cursor
    值。当
    has_more
    false
    时停止分页。
  • 大多数写入失败(400/404错误)源于属性类型不匹配——例如,传递
    {"select": "Open"}
    而非
    {"select": {"name": "Open"}}
    。若不确定,请通过
    GET /v1/databases/<id>
    读取一次数据库架构。

Record the output

记录输出结果

After you successfully publish and obtain the live result URL, call the built-in
publish_artifact
tool ONCE so the user can track this deliverable in My Outputs:
publish_artifact(kind="document", channel="notion", title="<title>", url="<the REAL returned URL>", status="delivered")
Use the real returned URL — never fabricate one. Call it once per published item, only after delivery is confirmed; skip it (or use
status="failed"
) if publishing failed. See
_shared/artifacts.md
.
成功发布并获取实时结果URL后,调用内置的
publish_artifact
工具一次,以便用户在「我的输出」中跟踪该交付物:
publish_artifact(kind="document", channel="notion", title="<title>", url="<the REAL returned URL>", status="delivered")
请使用真实返回的URL——切勿伪造。每个已发布的项目仅调用一次,且仅在确认交付后调用;若发布失败,请跳过调用(或使用
status="failed"
)。详见
_shared/artifacts.md