# @kentcdodds/notion — agent notes Human setup and intent live in [`README.md`](./README.md). This file is for agents: imports, smoke/dryRun snippets, and edge cases. Auth is OAuth integrations named **`notion`** / **`notion-*`** — never paste tokens. Do not disable live webhooks or jobs. ## Auth / integrations | Call | Resolves to | | --- | --- | | omit both | `notion` (default) | | `account: 'work'` | `notion-work` | | `integration: 'notion-work'` | that exact name | | `account` already `notion-…` | used as-is | Reconnect: `/connect/oauth?provider=notion` or `...?provider=notion-`. ## Import paths | Export | Import | | --- | --- | | overview | `kody:@kentcdodds/notion` | | accounts | `kody:@kentcdodds/notion/accounts` | | smoke-test | `kody:@kentcdodds/notion/smoke-test` | | request | `kody:@kentcdodds/notion/request` | | search | `kody:@kentcdodds/notion/search` | | get-page | `kody:@kentcdodds/notion/get-page` | | get-block-children | `kody:@kentcdodds/notion/get-block-children` | | get-database | `kody:@kentcdodds/notion/get-database` | | get-data-source | `kody:@kentcdodds/notion/get-data-source` | | query-database | `kody:@kentcdodds/notion/query-database` | | create-page | `kody:@kentcdodds/notion/create-page` | | append-block-children | `kody:@kentcdodds/notion/append-block-children` | Prefer static `kody:@kentcdodds/notion/...` imports from `execute`. ## Smoke test (read-only) ```js import smokeTest from 'kody:@kentcdodds/notion/smoke-test' export default async function main() { return await smokeTest() // => { ok: true, tokenType, hasBotOwner } — no workspace/user PII } ``` Optional account listing: ```js import listNotionAccounts from 'kody:@kentcdodds/notion/accounts' export default async function main() { return await listNotionAccounts() } ``` ## dryRun / confirm (writes) Mutating helpers and mutating `request` methods require `confirm: true` after explicit user approval of destination and content. Use `dryRun: true` to preview without calling Notion. ```js import createPage from 'kody:@kentcdodds/notion/create-page' export default async function main() { return createPage({ account: 'personal', parent: { database_id: '00000000-0000-0000-0000-000000000000' }, properties: { Name: { title: [{ text: { content: 'New page' } }] }, }, dryRun: true, }) } ``` ```js import search from 'kody:@kentcdodds/notion/search' export default async function main() { return await search({ query: 'meeting notes', objectType: 'page', account: 'work', }) } ``` ## Edge cases - Notion-Version `2026-03-11`: databases are containers; schema/rows live on **data sources**. `get-database` → `data_sources`; `get-data-source` for properties; query via data source. Helpers that take `databaseId` auto-resolve a **single** data source and error if there are several. - Database-row pages need `parent: { data_source_id }` (or `database_id` for auto-resolve on `create-page`). - Search returns `data_source` objects where databases used to appear — filter with `objectType: 'page' | 'data_source'`. - Block position: `position: { type: 'after_block' | 'start' | 'end', ... }` — flat `after` is gone. Trash field is `in_trash` (no `archived`). - Inline child databases: use `request` `POST /databases` with `is_inline: true` and `initial_data_source.properties` — not append-block-children. - Do not round-trip saved formula `expression` values; keep the human-readable form in your source of truth. - List helpers: `pageSize` 1–100, `startCursor`; responses include `hasMore` / `nextCursor`.