Docs
Create and manage docs, their versions, and their attachments.
A doc is a page of content in a space, arranged in a tree. Docs are versioned: you edit a draft and publish it, and readers see the published version. This page is the reference for docs, their versions, and their attachments.
See Authentication for the role each level needs.
Replace https://cadence.example.com with your instance's address.
Docs
POST/GET /api/v1/spaces/:space_key/docs, GET /api/v1/docs/:id, PATCH /api/v1/docs/:id, POST /api/v1/docs/:id/archive and .../unarchive, GET /api/v1/spaces/:space_key/docs/search; MCP docs_create, docs_get,
docs_list, docs_move, docs_archive, docs_unarchive, docs_search. Reading
and searching need read; creating, moving, and archiving need member.
A doc has a title, a body, a parent_id (its place in the tree), and a
position among its siblings. Creating a doc makes its first draft; the doc has no
published content until you publish that draft, and docs_get refuses a doc with
no published version.
curl -X POST https://cadence.example.com/api/v1/spaces/OPS/docs \
-H "Authorization: Bearer smc_your_token_here" \
-H "Content-Type: application/json" \
-d '{ "title": "Runbook", "body": "# Runbook\n…" }'There is no docs_update MCP tool: over MCP you edit a doc through its
versions. Over the API, PATCH /api/v1/docs/:id edits the draft
without publishing it, and accepts title, body, parent_id, position, and
expected_updated_at; any other field is refused with unpermitted_fields.
Pass expected_updated_at for optimistic concurrency: if the doc changed since
that timestamp, the edit is refused with 409 and stale_doc, naming who changed
it and when. Omitting the field opts out of the check.
To search docs, pass the query to docs_search as query, or to the search
endpoint as q. Each result is { doc, snippet, rank }, with the doc's body left
out. The last word of the query matches as a prefix, and a query shorter than 2
characters returns nothing. The snippet is one plain-text excerpt of about 5 to
20 words from the doc's published version, with the matched words wrapped in
<mark>. A doc that matched only on its title has no <mark> in its snippet.
A draft's text is not searched. Doc search has no lookup by task key.
For the full matching rules, see Search.
docs_move reparents and reorders a doc: pass parent_id (or null for the
root) and position. A move to another space, or one that would form a cycle, is
refused.
Doc URLs
A doc's web URL is /spaces/:space_key/docs/:id, with an optional slug suffix
derived from its title — /spaces/OPS/docs/8-runbook. The slug is decoration
only; the doc is addressed by its id. Cadence derives the slug once, from the
title the doc was created with, and does not change it when you rename the doc. A
URL carrying any other slug — including one built from the doc's current title
after a rename — redirects to that original slug.
Download a doc
A doc's reading page in the browser has a Download button that saves the doc
as a Markdown file — the doc URL with a .md suffix, for example
/spaces/OPS/docs/8-runbook.md. The file is the doc's title as a top-level #
heading, a blank line, then its body verbatim; the downloaded file is named from
the doc's slug. The body is the doc's current content — its published version, or,
if the doc has never been published, its draft.
The download is read-only: it writes no version and records no activity. Anyone who can read the doc can download it — the same read role as reading it.
This is a browser action, with no API or MCP equivalent — the same shape as Compare versions.
Doc versions
A doc's content lives in versions. MCP docs_versions_create_draft,
docs_versions_update_draft, docs_versions_publish, docs_versions_discard,
docs_versions_fork, docs_versions_get, docs_versions_list,
docs_versions_archive; the web version editor. Reading and listing need
read; the rest need member.
A version is draft, ready, or archived. It moves draft → ready on
publish, and ready → archived when a new version supersedes it; there is no
un-archive — recover an old version by forking it into a new draft. A doc has at
most one draft and at most one ready version at a time.
Saving a doc in the web interface writes the draft and publishes it in one action,
so the reader sees the change at once. Editing over the API (PATCH /api/v1/docs/:id) and over MCP (docs_versions_update_draft) does not
publish — publishing is the separate docs_versions_publish step.
The version lifecycle refuses with:
no draft exists for this doc— updating, publishing, or discarding with no draft.a draft already exists for this doc— creating or forking a second draft.version is not a draft— publishing something that is not a draft (for example, after another publish won the race).version is not ready— archiving a version that is not ready.
Compare versions
The web interface can compare two versions — GET /spaces/:space_key/docs/:doc_id/versions/:id/compare, with an optional against
version — showing a line-by-line diff of the markdown source. There is no API or
MCP equivalent.
Doc attachments
POST/GET/DELETE /api/v1/docs/:id/attachments[/:attachment_id]; MCP
docs_list_attachments, docs_delete_attachment; the web interface. Listing and
fetching need read; creating and deleting need member.
A doc attachment binds to the doc, not to a version, so it survives publishing a new version. Doc attachments write no activity. The same limits as task attachments apply: up to 10 MB, and one of the allowed content types (see Task data).