Skip to main content

How Docs Work

This page explains the document model and the mechanics behind every Docs operation: how documents nest into a tree, how access is scoped, how to browse the hierarchy lazily, how markdown content is read and written asynchronously, and how full-text search works. For a quick orientation and copy-paste examples, start with the Docs introduction.

The document model

A document has:

  • Title — its name.
  • Body — the rich-text content, read and written as markdown.
  • Parent — an optional reference to another document, which is what builds the tree.
  • Icon and Cover — optional emoji/icon and cover image.

Documents nest through their parent, forming a hierarchy:

Project Notes
├── Kickoff
│ └── Action Items (parent = Kickoff)
└── Retrospective (parent = Project Notes)

Documents without a parent sit at the root.

Access model

Access follows ownership and sharing. With a Personal Access Token, the API only returns documents the authenticated user owns or that have been shared with them as a participant. Deleting a document is restricted to its owner and is a recoverable soft-delete.

Browsing the tree

The tree endpoint walks the hierarchy breadth-first:

  • Call it without a parentId for root-level documents, or pass a document id to fetch that subtree.
  • Control how deep it descends with depth (1–10, default 3).

Each node carries a hasChildren flag, which makes lazy-loading explorers easy — only fetch a deeper level when a user expands a node. The tree is capped at 500 documents per response; when it truncates, the response includes nextParentIds so you can continue fetching the remaining branches.

Reading and writing content

Content is always markdown. Read it from the document's …/md endpoint, which returns { "content": "…" } (an empty string when the document has no body).

To write content, POST to the same path with an operation and content:

  • replace — overwrite the entire body.
  • append — add to the end.
  • prepend — add to the beginning.

Content updates are asynchronous: the API queues the change and returns HTTP 202 Accepted. The new content appears a moment later. Creating a document with initial content follows the same async path — the page is created immediately and its body is filled in shortly after.

Managing documents

  • CreatePOST a title, with an optional parent (for nesting) and optional initial content.
  • Update metadataPATCH to change the title, icon, or cover.
  • Delete — soft-deletes the document (owner only; recoverable).

Searching

The search endpoint runs full-text search across every document you can access. Pass q for the query and optionally control sortBy (createdAt / updatedAt, default updatedAt), sortOrder (asc / desc, default desc), and limit (1–50, default 20).

Results come back with highlighted matches in the title and body, plus each hit's ancestor chain (parents), so you can show where a result lives in the tree.

tip

For search that spans documents and other entity types (channels, todos, drive files, and more) in one call, use the global Search API instead.

Authentication & scope

Docs endpoints require a Personal Access Token (cp_pat_) with the access_docs scope. A token missing the scope gets a 403. See Authentication.

Reference