NotionのデータベースビューテーブルにcURLからData APIで行を追加してみた
Notionのデータベースビューテーブルでは、レコードの追加は親ページ(データベース)に子ページ(レコード)を追加して実現されています。 呼び出すAPIは https://api.notion.com/v1/pages への POST
リクエストであり、APIに利用するインテグレーションには「コンテンツを挿入」機能が必要です。
初手でインテグレーションの挿入権限は不要と判断し、データベースの更新APIを検討して回り道してしまったので、知見を共有します。
RDBへのSQL操作でも、レコード追加はテーブルへの更新(ALTER
)ではなく、テーブルへのレコード追加(INSERT
)なので、このようなAPI操作は自然です。
なお、 Notionのテーブルはシンプルテーブルとデータベースビューテーブルの2種類があります。本記事のテーブルは後者です。
オブジェクトIDとデータベースとレコードの親子関係を確認
NotionのページやデータベースにはIDが割り振られています。
このIDは(共有)URLから確認できます。
例えば、ページのURLは次のような形をしています
https://www.notion.so/prefix-ランダムな32桁の英数字
この URL末尾の32桁の文字がページIDです。 具体的には、 1429989fe8ac4effbc8f57f56486db54
のような文字列であり、 1429989f-e8ac-4eff-bc8f-57f56486db54
というように 8-4-4-4-12 のブロックに分けることができます。
ページに含まれているテーブルそのものをページとしてオープンすると、同様に、URLに32桁の文字が含まれています。これがデータベースIDです。
同様に、テーブルの各行は新しいページとしてオープンでき、この行単体のビューのURLに含まれる32桁の文字が各行に割り当てられたページIDです。
Notionのデータベースにおいて、ページやデータベースやデータベース内の各レコードは独立したオブジェクトであり、IDが割り振られていることを確認したところで、以降では cURL からテーブルをAPI操作します。
cURLでNotionテーブルにレコード追加
1. API操作用インテグレーションを作成
次のURLの「私のインテグレーション」からAPI操作用のインテグレーションを作成します。
https://www.notion.so/my-integrations
secret_
で始まるトークンを控え、環境変数に設定します。
$ export NOTION_API_KEY=secret_XXX
テーブルに行追加する場合、「機能(Capabilities)」メニューから「コンテンツを挿入(Insert content)」がチェックされていることを確認してください。
前述の通り、行の追加=ページの追加のため、新規作成権限が不足する場合、ページ作成時に以下の様な403エラーが発生します。
{ "object": "error", "status": 403, "code": "restricted_resource", "message": "Insufficient permissions for this endpoint.", "request_id": "5dbaabbd-e70e-4b27-8dbe-f828bf152fdf" }
2. 操作先ページとインテグレーションを接続
NotionでData APIを操作するには、操作対象のページとインテグレーションが接続されている必要があります。
親ページを接続すると、その子ページも操作可能になります。
この設定を忘れると、以下の様な404エラーが発生します。
{ "object": "error", "status": 404, "code": "object_not_found", "message": "Could not find page with ID: YYY. Make sure the relevant pages and databases are shared with your integration.", "request_id": "7c8f83bf-b7ef-4174-88f4-715b082c632e" }
3. cURLからページやデータベースを参照
Notion のData API利用時には、リクエストヘッダー(Authorization: Bearer NOTION_API_KEY
)にトークンを渡します。
ページを参照
ページを参照するには、エンドポイント https://api.notion.com/v1/pages/ に対して、ページIDをURIパスに渡して GET
リクエストします。
テーブル内の行に相当するページを参照します。 レスポンスから、親がデータベースであることもわかります。
$ export PAGE_ID=xxx $ curl 'https://api.notion.com/v1/pages/'"$PAGE_ID" \ -H 'Notion-Version: 2022-06-28' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' # レスポンス { "object": "page", "id": "YOUR_PAGE_ID", ... "parent": { "type": "database_id", "database_id": "6fYYY-..." }, ... "properties": { "作業日": { "id": "CsQO", "type": "date", "date": { "start": "2024-05-19", "end": null, "time_zone": null } }, "数値": { "id": "Uc%3D%7C", "type": "number", "number": 4 }, "備考": { "id": "title", "type": "title", "title": [ { "type": "text", "text": { "content": "aiueo", "link": null }, ... } ] } }, "url": "https://www.notion.so/aiueo-YOUR_PAGE_ID", "public_url": null, "request_id": "c1ee38eb-69a0-4ba4-82a8-99cf38bcb3b1" }
インテグレーション接続した元ページ、すなわち、テーブルの親ページのIDを指定しても、同様に参照できます。
データベーステーブルを参照
データベースを参照するには、エンドポイント https://api.notion.com/v1/databases/ に対して、データベースのIDをURIパスに渡して GET
リクエストします。
デーブルの実データではなく、スキーマ情報を取得できます。親がデータベースを埋め込んでいるページであることもわかります。
$ export DB_ID=YYY $ curl 'https://api.notion.com/v1/databases/'"$DB_ID" \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \ -H 'Notion-Version: 2022-06-28' # レスポンス { "object": "database", "id": "YYY", ... "title": [ { "type": "text", "text": { "content": "テストテーブル", "link": null }, ... } ], "description": [], "is_inline": true, "properties": { "作業日": { "id": "CsQO", "name": "作業日", "type": "date", "date": {} }, "数値": { "id": "Uc%3D%7C", "name": "数値", "type": "number", "number": { "format": "number" } }, "備考": { "id": "title", "name": "備考", "type": "title", "title": {} } }, "parent": { "type": "page_id", "page_id": "ZZZ" }, "url": "https://www.notion.so/YYY", ... "request_id": "4053eb9d-b52c-44a3-a745-f1c49b84c35f" }
4. テーブルに行追加
最後が本題のテーブルへの行追加です。
前述の通り、行追加はデータベースの更新ではなく、親ページ(データベース)への子ページ作成で実現されています。
ページを作成するAPIのドキュメントの1行目を引用します。
Creates a new page that is a child of an existing page or database. https://developers.notion.com/reference/post-page
データベースの更新APIでは、このページ作成APIに誘導されています。
To add a new row to a database, use the Create a page endpoint. https://developers.notion.com/reference/update-a-database
親ページとなるデータベースIDを parent
で指定し、追加するデータをカラム情報(プロパティ)とともにJSONで渡して POST リクエストします。
次の例では、よく使われる Date、 Number、Text のデータ型を用いています。
レスポンスから、データベースオブジェクトの親ページにページオブジェクトの子ページが追加されたことがわかります。
$ export DB_ID=YYY $ curl -X POST 'https://api.notion.com/v1/pages' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \ -H "Content-Type: application/json" \ -H "Notion-Version: 2022-06-28" \ --data '{ "parent": { "database_id": "'$DB_ID'" }, "properties": { "作業日": { "date": { "start": "2024-05-20" } }, "数値": { "number": 4 }, "備考": { "title": [ { "text": { "content": "あいうえお" } } ] } } }' # レスポンス { "object": "page", "id": "WWW", ... "parent": { "type": "database_id", "database_id": "YYY" }, ... "properties": { "作業日": { "id": "CsQO", "type": "date", "date": { "start": "2024-05-20", "end": null, "time_zone": null } }, ... }
親ページのデータベースを GET
すると、スキーマ情報を得られるため、型ごとの記述方法も確認できます。
"数値": { "id": "Uc%3D%7C", "name": "数値", "type": "number", "number": { "format": "number" } },