io.b3os/notion 1.0.0 · knowledge, documents, productivity · MIT

Search, read and write Notion with your own internal integration: find pages and databases, read a page's properties and text, query a database with Notion filters and sorts, create pages, append paragraphs, update properties, archive pages and comment. Uses Notion API version 2022-06-28. The integration only sees pages and databases shared with it (Share, Connections).

Every call's result carries upstream_status and timing: validate_ms, inject_ms, render_ms, upstream_ms, map_ms and total_ms. upstream is the service's time; the others are B3OS's own (call actions). The snippets below show no timing values, because a fixture records none.

Connection

token, type bearer: Notion integration token.

The internal integration secret (ntn_ or secret_) from notion.so/profile/integrations, or an OAuth access token of your own public integration. Share each page or database the actions need with the integration.

How to get one: developers.notion.com.

The credential is sent only to api.notion.com.

Store the credential once as a vault connection for this pack and key, then name its id in a call's connections. Leave the key out and B3OS uses the project's newest connection for the pack and key without a subject (connections).

Hosts it reaches: api.notion.com.

Actions

ActionEffectMCP toolTitle
searchreadnotion__searchSearch pages and databases
get-pagereadnotion__get-pageGet page
get-page-contentreadnotion__get-page-contentGet page content
get-databasereadnotion__get-databaseGet database
query-databasereadnotion__query-databaseQuery database
create-pagewritenotion__create-pageCreate page
append-paragraphswritenotion__append-paragraphsAppend paragraphs
update-page-propertieswritenotion__update-page-propertiesUpdate page properties
archive-pagewritenotion__archive-pageArchive page
add-commentwritenotion__add-commentComment on page

Search pages and databases. Search the pages and databases shared with the integration by title, most recently edited first, optionally only pages or only databases. Returns ids, titles, URLs and edit times; page with next_cursor.

Ref io.b3os/notion/search@1.0.0 · effect read · connection token · MCP tool notion__search

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/search@1", "input": {"query": "roadmap", "page_size": 2}, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Search pages and databases (documented response shape, example values). From the bundle's fixtures/search.json, not a live call.

json
{ "results": [ { "object": "page", "id": "59833787-2cf9-4fdf-8782-e53db20768a5", "title": "Q4 roadmap", "url": "https://www.notion.so/Q4-roadmap-598337872cf94fdf8782e53db20768a5", "created_time": "2026-10-20T15:00:00.000Z", "last_edited_time": "2026-10-25T21:30:00.000Z", "archived": false, "parent_type": "database_id" }, { "object": "database", "id": "d9824bdc-8445-4327-be8b-5b47500af6ce", "title": "Roadmap items", "url": "https://www.notion.so/d9824bdc84454327be8b5b47500af6ce", "created_time": "2026-09-01T10:00:00.000Z", "last_edited_time": "2026-10-25T20:00:00.000Z", "archived": false, "parent_type": "page_id" } ], "has_more": true, "next_cursor": "e6c6f5ff-5e6b-4c5b-9a1e-1c1b0f5e8b7a"}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

get-page

Get page. One page's title, URL, parent, edit times and all property values (status, people, dates, relations, ...) in Notion's shape. Its text is in get-page-content.

Ref io.b3os/notion/get-page@1.0.0 · effect read · connection token · MCP tool notion__get-page

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/get-page@1", "input": {"page_id": "59833787-2cf9-4fdf-8782-e53db20768a5"}, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Get page (documented response shape, example values). From the bundle's fixtures/get-page.json, not a live call.

json
{ "object": "page", "id": "59833787-2cf9-4fdf-8782-e53db20768a5", "title": "Q4 roadmap", "url": "https://www.notion.so/Q4-roadmap-598337872cf94fdf8782e53db20768a5", "created_time": "2026-10-20T15:00:00.000Z", "last_edited_time": "2026-10-25T21:30:00.000Z", "archived": false, "parent_type": "database_id", "properties": { "Status": { "id": "%3AA%3F", "type": "status", "status": {"id": "1", "name": "In progress", "color": "blue"} }, "Owner": {"id": "bQk%5D", "type": "people", "people": []}, "Name": { "id": "title", "type": "title", "title": [ { "type": "text", "text": {"content": "Q4 roadmap", "link": null}, "plain_text": "Q4 roadmap", "href": null, "annotations": { "bold": false, "italic": false, "strikethrough": false, "underline": false, "code": false, "color": "default" } } ] } }}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

get-page-content

Get page content. The blocks of a page (or of any block with children) in order, each with its type (paragraph, heading_1, to_do, bulleted_list_item, code, ...), plain text and whether it has nested children. One level per call: read a nested block by passing its id; page with next_cursor.

Ref io.b3os/notion/get-page-content@1.0.0 · effect read · connection token · MCP tool notion__get-page-content

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/get-page-content@1", "input": {"block_id": "59833787-2cf9-4fdf-8782-e53db20768a5", "page_size": 3}, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Get page content (documented response shape, example values). From the bundle's fixtures/get-page-content.json, not a live call.

json
{ "blocks": [ { "id": "c02fc1d3-db8b-45c5-a222-27595b15aea7", "type": "heading_2", "text": "Goals", "has_children": false, "checked": null }, { "id": "acc7eb06-05cd-4603-a384-5e1e4f1f4e72", "type": "to_do", "text": "Ship checkout v2", "has_children": false, "checked": false }, { "id": "5e4f3a2b-1c0d-4e9f-8a7b-6c5d4e3f2a1b", "type": "child_page", "text": "Launch checklist", "has_children": true, "checked": null } ], "has_more": false, "next_cursor": null}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

get-database

Get database. A database's title, URL, the name of its title property and its property schema, keyed by property name: each property's type and, for select, multi_select and status, the allowed options. Read it before query-database or create-page to know the property names.

Ref io.b3os/notion/get-database@1.0.0 · effect read · connection token · MCP tool notion__get-database

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/get-database@1", "input": {"database_id": "d9824bdc-8445-4327-be8b-5b47500af6ce"}, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Get database (documented response shape, example values). From the bundle's fixtures/get-database.json, not a live call.

json
{ "id": "d9824bdc-8445-4327-be8b-5b47500af6ce", "title": "Roadmap items", "url": "https://www.notion.so/d9824bdc84454327be8b5b47500af6ce", "title_property": "Name", "properties": { "Name": {"id": "title", "name": "Name", "type": "title", "title": {}}, "Status": { "id": "%3AA%3F", "name": "Status", "type": "status", "status": { "options": [ {"id": "1", "name": "Not started", "color": "default"}, {"id": "2", "name": "In progress", "color": "blue"}, {"id": "3", "name": "Done", "color": "green"} ], "groups": [] } }, "Due": {"id": "M%3BBw", "name": "Due", "type": "date", "date": {}} }}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

query-database

Query database. Rows (pages) of a database matching a Notion filter, in a Notion sort order: for example filter {"property": "Status", "status": {"equals": "In progress"}} and sorts [{"property": "Due", "direction": "ascending"}]. Returns each row's title, URL and property values; page with next_cursor.

Ref io.b3os/notion/query-database@1.0.0 · effect read · connection token · MCP tool notion__query-database

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/query-database@1", "input": { "database_id": "d9824bdc-8445-4327-be8b-5b47500af6ce", "filter": {"property": "Status", "status": {"equals": "In progress"}}, "page_size": 1 }, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Query database (documented response shape, example values). From the bundle's fixtures/query-database.json, not a live call.

json
{ "results": [ { "object": "page", "id": "59833787-2cf9-4fdf-8782-e53db20768a5", "title": "Q4 roadmap", "url": "https://www.notion.so/Q4-roadmap-598337872cf94fdf8782e53db20768a5", "created_time": "2026-10-20T15:00:00.000Z", "last_edited_time": "2026-10-25T21:30:00.000Z", "archived": false, "parent_type": "database_id", "properties": { "Status": { "id": "%3AA%3F", "type": "status", "status": {"id": "1", "name": "In progress", "color": "blue"} }, "Owner": {"id": "bQk%5D", "type": "people", "people": []}, "Name": { "id": "title", "type": "title", "title": [ { "type": "text", "text": {"content": "Q4 roadmap", "link": null}, "plain_text": "Q4 roadmap", "href": null, "annotations": { "bold": false, "italic": false, "strikethrough": false, "underline": false, "code": false, "color": "default" } } ] } } }

The first 40 of 44 lines; the fixture file has the rest.

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

create-page

Create page. Create a page with a title and an optional first paragraph, as a child of a page (parent_page_id) or as a row of a database (database_id). For a database row the title goes into the property named by title_property (default Name); to set other columns too, pass properties in Notion's shape including the title property, and title is then ignored. Returns the new page's id and URL. Not idempotent.

Ref io.b3os/notion/create-page@1.0.0 · effect write · connection token · MCP tool notion__create-page

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/create-page@1", "input": { "parent_page_id": "59833787-2cf9-4fdf-8782-e53db20768a5", "title": "Retro notes", "content": "What went well: the release train." }, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Create page (documented response shape, example values). From the bundle's fixtures/create-page.json, not a live call.

json
{ "id": "7a8b9c0d-1e2f-4a3b-8c4d-5e6f7a8b9c0d", "url": "https://www.notion.so/Retro-notes-7a8b9c0d1e2f4a3b8c4d5e6f7a8b9c0d", "created_time": "2026-10-20T15:00:00.000Z"}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

append-paragraphs

Append paragraphs. Append plain-text paragraphs (each up to 2,000 characters, at most 100) to the end of a page or block. Returns the ids of the new blocks. Not idempotent.

Ref io.b3os/notion/append-paragraphs@1.0.0 · effect write · connection token · MCP tool notion__append-paragraphs

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/append-paragraphs@1", "input": { "block_id": "59833787-2cf9-4fdf-8782-e53db20768a5", "paragraphs": ["Decision: ship Thursday.", "Owner: Mona."] }, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Append paragraphs (documented response shape, example values). From the bundle's fixtures/append-paragraphs.json, not a live call.

json
{ "block_ids": [ "9b8a7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d", "8a7b6c5d-4e3f-4a2b-1c0d-9e8f7a6b5c4d" ]}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

update-page-properties

Update page properties. Set property values of a page or database row, in Notion's shape, for example {"Status": {"status": {"name": "Done"}}}. Properties not named keep their values.

Ref io.b3os/notion/update-page-properties@1.0.0 · effect write · connection token · MCP tool notion__update-page-properties

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/update-page-properties@1", "input": { "page_id": "59833787-2cf9-4fdf-8782-e53db20768a5", "properties": {"Status": {"status": {"name": "Done"}}} }, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Update page properties (documented response shape, example values). From the bundle's fixtures/update-page-properties.json, not a live call.

json
{ "object": "page", "id": "59833787-2cf9-4fdf-8782-e53db20768a5", "title": "Q4 roadmap", "url": "https://www.notion.so/Q4-roadmap-598337872cf94fdf8782e53db20768a5", "created_time": "2026-10-20T15:00:00.000Z", "last_edited_time": "2026-10-25T21:30:00.000Z", "archived": false, "parent_type": "database_id", "properties": { "Status": { "id": "%3AA%3F", "type": "status", "status": {"id": "1", "name": "In progress", "color": "blue"} }, "Owner": {"id": "bQk%5D", "type": "people", "people": []}, "Name": { "id": "title", "type": "title", "title": [ { "type": "text", "text": {"content": "Q4 roadmap", "link": null}, "plain_text": "Q4 roadmap", "href": null, "annotations": { "bold": false, "italic": false, "strikethrough": false, "underline": false, "code": false, "color": "default" } } ] } }}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

archive-page

Archive page. Move a page (or database row) to the trash. It can be restored from Notion's trash for 30 days.

Ref io.b3os/notion/archive-page@1.0.0 · effect write · connection token · MCP tool notion__archive-page

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/archive-page@1", "input": {"page_id": "59833787-2cf9-4fdf-8782-e53db20768a5"}, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Archive page (documented response shape, example values). From the bundle's fixtures/archive-page.json, not a live call.

json
{"id": "59833787-2cf9-4fdf-8782-e53db20768a5", "archived": true}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response

add-comment

Comment on page. Add a comment to a page's discussion, plain text up to 2,000 characters. The integration needs the Insert comments capability. Not idempotent.

Ref io.b3os/notion/add-comment@1.0.0 · effect write · connection token · MCP tool notion__add-comment

bash
curl -s https://beta-api.b3os.org/v1/actions/call \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \ -H "Content-Type: application/json" \ -d '{ "ref": "io.b3os/notion/add-comment@1", "input": { "page_id": "59833787-2cf9-4fdf-8782-e53db20768a5", "text": "Looks good to me." }, "connections": {"token": "conn_01m5t6cbgdjs1ketgcqwa2sne8"} }'

Output, labeled fixture: Comment on page (documented response shape, example values). From the bundle's fixtures/add-comment.json, not a live call.

json
{ "id": "3c4d5e6f-7a8b-4c9d-0e1f-2a3b4c5d6e7f", "discussion_id": "f1e2d3c4-b5a6-4978-8f6e-5d4c3b2a1f0e", "created_time": "2026-10-26T08:00:00.000Z"}

When the service answers with an error, the call fails with upstream_error and pack_error.code is one of:

pack_error.codeService statusRetryableMessage
not_found404noNot found, or the page or database is not shared with the integration (Share, Connections).
connection_unauthorized401noNotion rejected the integration token.
forbidden403nobuilt from the service's response
conflict409yesbuilt from the service's response
rate_limited429yesNotion rate limit reached (about 3 requests a second per integration).
invalid_request400nobuilt from the service's response
Ask a question... ⌘I