Notion
Notionと2つの方法で対話します。どちらの方法でも同じ統合トークンを使用します。利用可能な方法を選んでください。
◆ ntn CLI — Notion公式CLI。短い構文、1行でのファイルアップロード、Workersに必須。2026年5月時点ではmacOS + Linuxのみ(Windowsサポートは「近日対応予定」)。インストールされている場合のデフォルト。
◆ HTTP + curl — Windowsを含むすべての環境で動作。ntnがインストールされていない場合のデフォルトフォールバック。
セットアップ
1. 統合トークンを取得する(両方の経路で必要)
- https://notion.so/my-integrations で統合を作成する
- APIキーをコピーする(
ntn_またはsecret_で始まる) ~/.hermes/.envに保存する:NOTION_API_KEY=ntn_your_key_here- Notionで対象のページ/データベースを統合と共有する:ページメニュー
...→接続先→ 統合名。これを行わないと、APIはそのページに対して404を返します(ページは存在していても)。
2. ntn をインストールする(macOS / Linuxで推奨)
# 推奨
curl -fsSL https://ntn.dev | bash
# またはnpm経由(Node 22+、npm 10+が必要)
npm install --global ntn
ntn --version # 確認
ntn loginはスキップ — 代わりに統合トークンを使用します。 これによりヘッドレスで動作し、ブラウザは不要です:
export NOTION_API_TOKEN=$NOTION_API_KEY # ntnはNOTION_API_TOKENを読み取ります
export NOTION_KEYRING=0 # OSキーチェーンを使用しない
これらのエクスポートをシェルプロファイル(または~/.hermes/.env)に追加して、すべてのセッションで継承されるようにします。
3. 実行時に経路を選択する
if command -v ntn >/dev/null 2>&1; then
# ntnを使用
else
# curlにフォールバック
fi
Windowsユーザー:ネイティブntnがリリースされるまでステップ2は完全にスキップしてください — 経路Bで問題なく動作します。CLIの使い勝手を今すぐ欲しい場合は、WSL2内にntnをインストールしてください。
APIの基本
すべてのHTTPリクエストにNotion-Version: 2025-09-03が必要です。ntnはこれを自動的に処理します。このバージョンでは、ユーザーが「データベース」と呼ぶものは、APIではデータソースと呼ばれます。
経路A — ntn CLI(推奨、macOS / Linux)
Raw APIコール(curlの短縮形)
ntn api v1/users # GET
ntn api v1/pages parent[page_id]=abc123 \ # POST、インラインボディ
properties[title][0][text][content]="Notes"
ntn api v1/pages/abc123 -X PATCH archived:=true # PATCH; :=は非文字列(bool/num/null)
構文メモ:
key=value— 文字列フィールドkey[nested]=value— ネストされたオブジェクトフィールドkey:=value— 型付き代入(ブール値、数値、null、配列)
検索
ntn api v1/search query="page title"
ページメタデータを読み取る
ntn api v1/pages/{page_id}
ページをMarkdownとして読み取る(エージェントに優しい)
ntn api v1/pages/{page_id}/markdown
ページコンテンツをブロックとして読み取る
ntn api v1/blocks/{page_id}/children
Markdownからページを作成する
ntn api v1/pages \
parent[page_id]=xxx \
properties[title][0][text][content]="Notes from meeting" \
markdown="# Agenda\n\n- Q3 roadmap\n- Hiring"
Markdownでページをパッチする
ntn api v1/pages/{page_id}/markdown -X PATCH \
markdown="## Update\n\nShipped the prototype."
データベース(データソース)をクエリする
ntn api v1/data_sources/{data_source_id}/query -X POST \
filter[property]=Status filter[select][equals]=Active
sorts、複数のフィルター句、または複合ロジックを使用した複雑なクエリの場合は、JSONをパイプで渡します:
echo '{"filter": {"property": "Status", "select": {"equals": "Active"}}, "sorts": [{"property": "Date", "direction": "descending"}]}' | \
ntn api v1/data_sources/{data_source_id}/query -X POST --json -
ファイルアップロード(ワンライナー — CLIの最大の利点)
ntn files create < photo.png
ntn files create --external-url https://example.com/photo.png
ntn files list
3ステップのHTTPフロー(アップロード作成→PUTバイト→参照)と比較してください。
便利な環境変数
| 変数 | 効果 |
|---|---|
NOTION_API_TOKEN | 認証トークン(キーチェーンを上書き)— 統合トークンに設定します |
NOTION_KEYRING=0 | OSキーチェーンの代わりに~/.config/notion/auth.jsonにファイルベースの認証情報を保存 |
NOTION_WORKSPACE_ID | ワークスペース選択プロンプトをスキップ |
経路B — HTTP + curl(クロスプラットフォーム、Windowsではデフォルト)
すべてのリクエストは以下のパターンに従います:
curl -s -X GET "https://api.notion.com/v1/..." \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json"
Windows 10以降に付属するcurlはそのまま使用できます。PowerShellユーザーはInvoke-RestMethodも使用できます。
検索
curl -s -X POST "https://api.notion.com/v1/search" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"query": "page title"}'
ページメタデータを読み取る
curl -s "https://api.notion.com/v1/pages/{page_id}" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03"
ページをMarkdownとして読み取る(エージェントに優しい)
ブロックJSONよりもモデルに渡しやすいです。
curl -s "https://api.notion.com/v1/pages/{page_id}/markdown" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03"
ページコンテンツをブロックとして読み取る(構造が必要な場合)
curl -s "https://api.notion.com/v1/blocks/{page_id}/children" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03"
Markdownからページを作成する
POST /v1/pages は markdown ボディパラメータを受け付けます。
curl -s -X POST "https://api.notion.com/v1/pages" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"parent": {"page_id": "xxx"},
"properties": {"title": [{"text": {"content": "Notes from meeting"}}]},
"markdown": "# Agenda\n\n- Q3 roadmap\n- Hiring\n\n## Decisions\n- Ship MVP Friday"
}'
Markdownでページをパッチする
curl -s -X PATCH "https://api.notion.com/v1/pages/{page_id}/markdown" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"markdown": "## Update\n\nShipped the prototype."}'
データベースにページを作成する(型付きプロパティ)
curl -s -X POST "https://api.notion.com/v1/pages" \
-H "Authorization: Bearer $NOTION_API_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"}}
}
}'
データベース(データソース)をクエリする
curl -s -X POST "https://api.notion.com/v1/data_sources/{data_source_id}/query" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"filter": {"property": "Status", "select": {"equals": "Active"}},
"sorts": [{"property": "Date", "direction": "descending"}]
}'
データベースを作成する
curl -s -X POST "https://api.notion.com/v1/data_sources" \
-H "Authorization: Bearer $NOTION_API_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": {}}
}
}'
ページプロパティを更新する
curl -s -X PATCH "https://api.notion.com/v1/pages/{page_id}" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"properties": {"Status": {"select": {"name": "Done"}}}}'
ページにブロックを追加する
curl -s -X PATCH "https://api.notion.com/v1/blocks/{page_id}/children" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{
"children": [
{"object": "block", "type": "paragraph", "paragraph": {"rich_text": [{"text": {"content": "Hello from Hermes!"}}]}}
]
}'
ファイルアップロード(3ステップフロー)
# 1. アップロードを作成
curl -s -X POST "https://api.notion.com/v1/file_uploads" \
-H "Authorization: Bearer $NOTION_API_KEY" \
-H "Notion-Version: 2025-09-03" \
-H "Content-Type: application/json" \
-d '{"filename": "photo.png", "content_type": "image/png"}'
# 2. 上記で返されたupload_urlにバイトをPUT
curl -s -X PUT "{upload_url}" --data-binary @photo.png
# 3. ページ/ブロックペイロードで{file_upload_id}を参照
プロパティタイプ
データベースアイテムの一般的なプロパティ形式:
- タイトル:
{"title": [{"text": {"content": "..."}}]} - リッチテキスト:
{"rich_text": [{"text": {"content": "..."}}]} - セレクト:
{"select": {"name": "Option"}} - マルチセレクト:
{"multi_select": [{"name": "A"}, {"name": "B"}]} - 日付:
{"date": {"start": "2026-01-15", "end": "2026-01-16"}} - チェックボックス:
{"checkbox": true} - 数値:
{"number": 42} - URL:
{"url": "https://..."} - メール:
{"email": "[email protected]"} - リレーション:
{"relation": [{"id": "page_id"}]}
APIバージョン2025-09-03 — データベース vs データソース
- データベースはデータソースになりました。 クエリと取得には
/data_sources/エンドポイントを使用します。 - データベースごとに2つのID:
database_idとdata_source_id。- ページ作成時は
database_id:parent: {"database_id": "..."} - クエリ時は
data_source_id:POST /v1/data_sources/{id}/query
- ページ作成時は
- 検索ではデータベースが
"object": "data_source"として返され、data_source_idフィールドが含まれます。
Notion Workers(高度、ntnが必要)
Workersは、NotionがホストするTypeScriptプログラムです。1つのWorkerで以下の任意の組み合わせを公開できます:
- Syncs — 外部APIからNotionデータベースにデータをスケジュールに従ってプルします(デフォルト30分)。
- Tools — Notionのカスタムエージェント内で呼び出し可能なツールとして表示されます。
- Webhooks — 外部サービス(GitHub、Stripeなど)からのHTTPイベントを受信し、Notion内で動作します。
プラン/プラットフォーム制限:
- CLIはすべてのプランで動作します。WorkersのデプロイにはBusinessまたはEnterpriseプランが必要です。
ntnは2026年5月時点でmacOS/Linuxのみ。WindowsユーザーはWSL2が必要、またはネイティブサポートを待つ必要があります。- 2026年8月11日までは無料。その後はNotionクレジットで従量課金されます。
最小限のWorker
ntn workers new my-worker # スキャフォールディング
cd my-worker
# 編集: src/index.ts
ntn workers deploy --name my-worker
src/index.ts:
import { Worker } from "@notionhq/workers";
const worker = new Worker();
export default worker;
worker.tool("greet", {
title: "Greet a User",
description: "Returns a friendly greeting",
inputSchema: { type: "object", properties: { name: { type: "string" } }, required: ["name"] },
execute: async ({ name }) => `Hello, ${name}!`,
});
Webhook機能
worker.webhook("onGithubPush", {
title: "GitHub Push Handler",
execute: async (events, { notion }) => {
for (const event of events) {
// event.body, event.rawBody (署名検証用), event.headers
console.log("got delivery", event.deliveryId);
}
},
});
デプロイ後:ntn workers webhooks list でNotionが生成したURLが表示されます。そのURLは秘密として扱ってください — 署名検証を追加しない限り、そのURLを知っている人は誰でもイベントをPOSTできます。
Workerライフサイクルコマンド
ntn workers deploy
ntn workers list
ntn workers exec <capability-key> -d '{"name": "world"}'
ntn workers sync trigger <key> # 今すぐ同期を実行
ntn workers sync pause <key>
ntn workers env set GITHUB_WEBHOOK_SECRET=...
ntn workers runs list # 最近の呼び出し
ntn workers runs logs <run-id>
ntn workers webhooks list
Workerを構築するよう指示された場合、ntn workers newでスキャフォールディングし、src/index.tsにコードを書き、ntn workers env setでシークレットを設定し、デプロイします。Notionのドキュメント https://developers.notion.com/workers に完全なAPIサーフェスが記載されています。
Notion Flavored Markdown(/markdownエンドポイントで使用)
標準のCommonMarkに加えて、Notion固有のブロック用のXMLライクなタグ。インデントにはタブを使用します。
CommonMarkを超えるブロック:
<callout icon="🎯" color="blue_bg">
Ship the MVP by **Friday**.
</callout>
<details color="gray">
<summary>Toggle title</summary>
Children indented one tab
</details>
<columns>
<column>Left side</column>
<column>Right side</column>
</columns>
<table_of_contents color="gray"/>
インライン:
- メンション:
<mention-user url="..."/>、<mention-page url="...">Title</mention-page>、<mention-date start="2026-05-15"/> - 下線:
<span underline="true">text</span> - 色:
<span color="blue">text</span>またはブロックレベルで1行目に{color="blue"} - 数式: インライン
$x^2$、ブロック$$ ... $$ - 引用:
[^https://example.com]
色: gray brown orange yellow green blue purple pink red、さらに背景用の *_bg バリアント。
見出し5/6はH4にまとめられます。複数の > 行は個別の引用ブロックとしてレンダリングされます — 複数行の引用には1つの > 内で <br> を使用してください。
適切な経路の選択
| タスク | mac / Linux | Windows |
|---|---|---|
| ページの読み取り/書き込み、検索、データベースのクエリ | ntn api ... | curl |
| エージェントが要約するためのページの読み取り | ntn api v1/pages/{id}/markdown | curl /markdown エンドポイント |
| ファイルのアップロード | ntn files create < file | 3ステップHTTPフロー |
| 1回限りのAPI探索 | ntn api ... | curl |
| Notionがホストする同期/Webhook/エージェントツールの構築 | ntn workers ... | WSL2 + ntn workers ... |
注意事項
- ページ/データベースIDはUUIDです(ダッシュの有無は問わず — どちらも受け付けられます)。
- レート制限: 約3リクエスト/秒の平均。CLIはこれを回避しません。
- APIはデータベースビューフィルターを設定できません — それはUIのみです。
- データソース作成時に
"is_inline": trueを使用すると、ページに埋め込むことができます。 - 常に
-sをcurlに渡して進行状況バーを抑制します(エージェント出力をクリーンに保つため)。 - 読み取り時はJSONを
jqにパイプします:... | jq '.results[0].properties'。 - Notionは現在MCPサーバーも提供しています(
Notion ...)。