Skip to main content

REST API

REST API

The versioned REST API is at /api/v1. Authenticate with a bearer token.

curl -fsS https://blueprintr.io/api/v1/docs \
  -H "Authorization: Bearer $BLUEPRINTR_TOKEN"

Routes

{ref} is a folium slug or id. Personal keys only means a bpk_user_… key. An organisation key on those routes is refused with 403, not a 404.

RouteScopeDoes
GET /docsread:foliumsFoliums you can author
GET /docs/{ref}read:foliumsThe page tree. ?status=all includes drafts
GET /docs/{ref}/pagesread:foliumsFlat page list
POST /docs/{ref}/pageswrite:foliumsCreate a page
GET /docs/{ref}/pages/{path}read:foliumsOne page by its reader path
GET /docs/{ref}/page/{pageId}read:foliumsOne page by id
PATCH /docs/{ref}/page/{pageId}write:foliumsEdit content or metadata
DELETE /docs/{ref}/page/{pageId}write:foliumsArchive a page and its subtree
POST /docs/{ref}/page/{pageId}/movewrite:foliumsReparent or reorder
POST /docs/{ref}/page/{pageId}/publishwrite:foliumsPublish or retract one page
GET /docs/{ref}/searchread:foliumsSearch within the folium
GET /docs/{ref}/diagnosticsread:foliumsThe last run
POST /docs/{ref}/diagnosticswrite:foliumsRun the rules now
GET /docs/{ref}/versionswrite:foliumsPublished versions
POST /docs/{ref}/versionswrite:foliumsSnapshot the published set as a version

Version routes are edit-gated in both directions, including the GET. The list alone tells a public reader how a document has been managed.

Creating and editing a page

curl -fsS -X POST https://blueprintr.io/api/v1/docs/handbook/pages \
  -H "Authorization: Bearer $BLUEPRINTR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "title": "Deploying",
        "parentId": null,
        "kind": "doc",
        "content": "# Deploying\n\nOne command.",
        "description": "How a release reaches production.",
        "icon": "rocket",
        "hideInNav": false,
        "status": "draft"
      }'

Strings past their ceiling are clamped rather than rejected, matching what the app itself does. Only shape errors come back as errors, because those are the ones a caller can fix.

PATCH takes any subset of title, description, content, icon and hideInNav.

PATCH will not accept status, kind or slug. A content edit must never publish a draft somebody held back, as a side effect of one stray field. Publishing has its own route so it has its own audit line; a kind change turns a content page into a pointer; a slug change is a URL move, which is what /move is for.

Publishing

curl -fsS -X POST \
  https://blueprintr.io/api/v1/docs/handbook/page/$PAGE_ID/publish \
  -H "Authorization: Bearer $BLUEPRINTR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"published": true}'

REST publishes and retracts. Its MCP twin, update_folium_page, accepts status:"draft" only: it can retract, never publish.

A personal REST key is a human's own credential, minted behind step-up on a password-backed account and usually driven by a CLI that human just ran. An autonomous agent should not be what makes a draft world-readable.

POST /versions answers 202 Accepted with status:"submitted-for-review" when the folium requires publish approval and you are not a documentation admin. A change request was filed, so treat it as a success.

Deleting

DELETE is a soft archive of the whole subtree, not a hard delete. When the page has children, the first attempt is refused and tells you how many:

curl -fsS -X DELETE \
  "https://blueprintr.io/api/v1/docs/handbook/page/$PAGE_ID?confirmSubtree=1" \
  -H "Authorization: Bearer $BLUEPRINTR_TOKEN"

Without ?confirmSubtree=1 a one-page delete can never take a section with it.

There is no delete tool on the MCP server at all. Deletion is offered here because a personal key is a human's own credential and a docs CLI cannot push one without it.

Concurrent writes

Every write accepts baseUpdatedAt: the folium's updatedAt as you last read it. Send it and a write that would land on top of someone else's is refused with 409. Omit it and the write is last-writer-wins.

PATCH, POST /publish and POST /move take it in the JSON body. DELETE has no body, so it takes it as a query parameter:

DELETE /api/v1/docs/handbook/page/{id}?baseUpdatedAt=2026-09-05T23:04:11.882Z

Responses include both updatedAt (the page) and foliumUpdatedAt (the document). Feed the latter back into your next write.

Page bodies in bulk

Page bodies are served through the MCP server rather than one REST call per page, because MCP accepts many tool calls per HTTP request. A two-hundred-page folium is ten round trips instead of two hundred.

Both surfaces return the author's markdown verbatim, and neither applies the anonymous audience filter, so a read, edit and write round trip cannot drop an audience-gated block.

Errors

Standard status codes, and two conventions particular to this API.

CodeMeans
403The key kind is wrong: an org key on a personal-key route
404Not found, or found and not yours. Telling you which would itself be a disclosure
409baseUpdatedAt is stale. Re-read, reapply, retry
202Accepted but not done: a version publish went to review instead

The CLI does all of this

blueprintr-docs is built on these routes, validates offline against the server's own rules first, and refuses to delete anything. For authoring documentation from a text editor, use it rather than writing a client.