# Pages & Blocks

A **page** is a navigable TipTap document under **Your Pages**.

Primary storage: `content` — TipTap JSON `{ "type": "doc", "content": [...] }`.

App node types inside the doc:

- `queryBlock` — live NL search (`attrs.id`, `queryText`, `querySpec`)
- `graphBlock` — bar/donut/stat over query hits
- `customBlock` — markdown/html/cards
- `mediaBlock` — image/video from a bucket file
- `pageEmbed` — nested page (`embeddedPageId`, max depth 3)

Prose nodes use TipTap StarterKit (paragraph, headings, lists, code). Mentions use `@`.

Visibility: `private` (default) or `workspace`.

Scopes: `pages:read`, `pages:write`.

Base: `/workspaces/{workspaceId}/pages`

Session twin: `/api/workspace/{workspaceId}/pages`.

## List / create

`GET .../pages?pinned=1` · `pages:read`

`POST .../pages` · `pages:write`

```json
{
  "name": "Untitled page",
  "bucketId": "...",
  "queryText": "wedding photos of dustin and cass",
  "personIds": ["person_…"],
  "pinned": false,
  "visibility": "private",
  "content": { "type": "doc", "content": [] }
}
```

With `queryText` and no `content`, the server builds a doc with an H1 + `queryBlock`. Empty create gets an empty TipTap doc.

## Get / patch / delete

- `GET .../pages/{pageId}` · includes `content` (and legacy `blocks` if present)
- `PATCH .../pages/{pageId}` — `name`, `description`, `bucketId`, `pinned`, `pinOrder`, `visibility`, `content`
- `DELETE .../pages/{pageId}` · owner only

## Insert nodes (MCP / API helper)

`POST .../pages/{pageId}/blocks` still appends a typed node into `content` (query/graph/custom/page). Prefer editing `content` via PATCH for full TipTap docs.

## Run (paginated)

`GET .../pages/{pageId}/nodes/{nodeId}/results?offset=0&limit=24&bucketId=&cursor=`

`nodeId` is the TipTap node `attrs.id`. Legacy `.../blocks/{blockId}/results` still works.

Returns `{ files, totalInPool, offset, limit, hasMore, nextCursor, poolCap }`.

## Product UI

- **New page** on `/pages`
- TipTap editor on `/pages/{pageId}` — `/` slash commands, `@` mentions, autosave
- Agent **Save as page**
- Sidebar **Your Pages**

## MCP / agent

MCP: `list_pages`, `get_page`, `create_page`, `update_page` (supports `content`), `delete_page`, `add_page_block`, `update_page_block`, `delete_page_block`, `run_page_block`.

In-app agent tools: `create_page`, `list_pages`, `update_page`, `delete_page`, `run_page`.
