PromptOwl + ContextNest Docs

REST API Reference

Updated Open in ChatGPTOpen in Claude

A concise reference to the ContextNest Community (hosted-nest) REST API. It is faithful to the server's API.md; only endpoints that actually exist are listed here. For the deeper cnst_ key model see Authentication & API Keys; to point an agent at a nest over MCP see Connect an Agent.

  • Base URL: http://localhost:3838 (default; override the port with PORT).
  • Bodies: JSON unless noted.
  • Errors: { "error": "message" } with an appropriate HTTP status.

Authentication

Two methods, evaluated in order:

  1. Cookie session — cnst_session=<id>, set by /auth/login and /auth/register. The browser default.
  2. Bearer API key — Authorization: Bearer cnst_<token>, issued by POST /auth/keys. Use for scripts and external tools.
curl -H 'Authorization: Bearer cnst_<your-token>' http://localhost:3838/nests

In AUTH_MODE=open, most read endpoints bypass auth (everyone is the anonymous admin). A license gate also applies: any non-GET request, or any governance path, requires a valid PromptOwl license (503 License required otherwise).

Permission tiers

For any /nests/:nestId/... request the middleware computes an effective permission — owner | admin | write | read | none — and enforces a required level by path:

Path class Required
/collaborators, /visibility admin
Stewardship actions (/approve, /reject, /submit-review, /cancel-review) read (handler enforces fine-grained steward gating)
Other non-GET write
GET read

Open mode treats everyone as owner.

Auth & keys

Method Path Purpose
POST /auth/register Self sign-up / claim an invited account (gated by MANUAL_SIGN_IN).
POST /auth/login Password login → session cookie.
POST /auth/logout Clear the session cookie.
POST /auth/keys Mint an API key (named; label required, unique, ≤ 60 chars). Plaintext shown once.
GET /auth/keys List the caller's keys (id, prefix, label, nest_id, timestamps) — never plaintext.
POST /auth/keys/rotate Replace one key (by key_id) and return its new plaintext.
DELETE /auth/keys/:keyId Revoke one key.
POST /auth/password Change the caller's password.
POST /auth/invite (admin) Create an invited user; returns a temporary password once.
GET /auth/teammates (admin) All users + key counts.
POST /auth/admin/reset-password/:userId (admin) In-platform password reset.
DELETE /auth/users/:userId (admin) Remove a user.
GET /auth/oidc/login · /auth/oidc/callback · /auth/oidc/logout Generic OIDC SSO flow.

See Authentication & API Keys for the full key semantics.

Nests

A nest = a context vault (a folder of markdown documents + governance state).

Method Path Purpose
GET /nests List owned + shared nests.
POST /nests Create a nest — { name, description? }.
GET /nests/:nestId Get one nest + the caller's permission.
DELETE /nests/:nestId Delete a nest (owner only).
GET /nests/:nestId/settings Read governance settings.
PATCH /nests/:nestId/settings (admin/owner) stewardship_enabled, allow_self_approve, prime_only_review, prime_tags.
PATCH /nests/:nestId/visibility (admin) `{ "visibility": "public"
GET /nests/unsynced (server-admin) Folders under DATA_ROOT not yet nests.
POST /nests/unsynced/sync (server-admin) Convert an unsynced folder into a nest.
DELETE /nests/unsynced/sync (server-admin) Delete an unsynced folder outright.
GET /nests/:nestId/overview Nest-level summary stats.
GET /nests/:nestId/census Everything a nest overview needs — counts by tag/type/status, folder tree, authors, recent edits.

Nodes (documents)

A node id is the relative path without .md, e.g. nodes/api-design. A document filed in a folder has the id nodes/<folder>/<slug> — the folder field on create nests it, each /-separated segment slugified independently (max 8 levels, each ≤ 100 chars).

Method Path Purpose
GET /nests/:nestId/nodes List readable docs. Query: type, tag, status, approved_only, limit, folder, content.
POST /nests/:nestId/nodes Create — { title, content, tags?, type?, folder?, status?, schedule?, prime? }. 409 if the derived id is taken.
GET /nests/:nestId/nodes/:nodeId Full node content (JSON).
PATCH /nests/:nestId/nodes/:nodeId Edit — { title?, content?, tags?, changeNote?, schedule?, prime? }. Optional X-Base-Version header → 409 on conflict.
DELETE /nests/:nestId/nodes/:nodeId Delete (write). 423 if a pending review freezes it for a non-approver.
POST /nests/:nestId/nodes/:nodeId/move Refile to another folder; carries version history, reviews, grants, etc. to the new id.
POST /nests/:nestId/nodes/:nodeId/revert Restore an earlier version as a new version — { targetVersion }.
POST /nests/:nestId/assets Multipart image/video upload (field file). Returns { file, url, markdown }.
GET /nests/:nestId/assets/:file Serve asset bytes (immutable cache).

Node read formats

The single-node GET supports content negotiation on top of the default JSON:

Param / header Effect
?content=1 (on the list) Include document bodies (off by default — the listing is served from the metadata index).
?format=markdown text/markdown — YAML frontmatter + body (the export shape).
?format=raw Raw node body as text, no JSON envelope. Content-Type varies by node type (document/agent/skill → markdown, artifact → html, tool/table → plain).
Accept: text/markdown (header) Same as ?format=raw when no format param is present (presence-based; ignores q-values).
?frontmatter=1 With raw only: prepend the stored YAML frontmatter block.

Public readers on a visibility: public nest receive the approved snapshot body, never an unapproved draft.

Folders

Method Path Purpose
GET /nests/:nestId/folders The nest's folder tree alone (no document opened). Query: ?folder=<path>, ?recursive=0.
POST /nests/:nestId/delete-folder (owner/admin) Delete every document under a folder prefix.

The folder tree returns rows shaped { path, count, total } — count = documents filed directly in that folder, total = the whole subtree beneath it. Folders are not stored objects; they exist only as segments of the node ids beneath them.

Collaborators, grants & teams

Method Path Purpose
GET/POST /nests/:nestId/collaborators (write+) List / add a direct nest collaborator (read/write/admin, escalation-capped).
PATCH/DELETE /nests/:nestId/collaborators/:collabId (admin) Re-role / remove.
GET/POST /nests/:nestId/grants Share a single document or one folder — { target_type, target, email, role }.
DELETE /nests/:nestId/grants/:id Revoke a grant.
GET/POST/PATCH/DELETE /teams, /teams/:teamId, /teams/:teamId/members[/:userId] Reusable owner-managed groups (admin/editor/viewer roles).
GET/POST/DELETE /nests/:nestId/teams[/:teamId] Share / unshare a team onto the nest.

A grant gives one person access to one document or everything under one folder without a nest-wide collaborator row. write outranks read when grants overlap; a grantee sees only the nodes their grants cover. Managing grants is owner / nest admin / server admin.

Stewardship & review

Method Path Purpose
GET/POST /nests/:nestId/stewards List / assign stewards by scope (document/tag/nest), role reviewer/editor/viewer.
DELETE /nests/:nestId/stewards/:stewardId Soft-remove a steward.
POST /nests/:nestId/stewards/sync Re-import from <nest>/.context/stewards.yaml.
GET /nests/:nestId/nodes/:nodeId/stewards Resolved stewards for one node (priority document > tag > nest).
GET /nests/:nestId/nodes/:nodeId/{can-access,can-approve,can-edit} Permission probes for one node.
POST /nests/:nestId/nodes/:nodeId/submit-review Move a node to pending_review.
POST /nests/:nestId/nodes/:nodeId/approve · /reject · /cancel-review Reviewer actions (reject/cancel need a note).
GET /nests/:nestId/review-queue All reviews for the nest. Query: status, limit, offset.
GET /nests/:nestId/nodes/:nodeId/reviews Full review history for one node.
GET /nests/:nestId/feed Activity feed — pending changes interleaved with comment activity.
POST /nests/:nestId/nodes/:nodeId/request-deletion (editor) Flag one document for deletion.
POST /nests/:nestId/request-deletion (editor, nest-scope) Flag a folder or the whole nest.
GET /nests/:nestId/deletion-requests Pending / declined deletion requests.
POST /nests/:nestId/deletion-requests/:id/delete · /decline Honour / decline a request.
GET /me/drafts · /me/work The caller's unsubmitted drafts / their governance inbox across nests.

See the governance model for what stewardship, roles, and prime documents mean.

Versions

Method Path Purpose
GET /nests/:nestId/nodes/:nodeId/versions Version metadata + per-version change-log diffs (bodies omitted).
GET /nests/:nestId/nodes/:nodeId/versions/:version One version's full body, reconstructed on demand.

Comments

Method Path Purpose
GET /nests/:nestId/nodes/:nodeId/comments List comments (optional `?status=open
POST /nests/:nestId/nodes/:nodeId/comments Leave a comment — { body, version?, anchor?, parentId? }.
POST /nests/:nestId/nodes/:nodeId/comments/:commentId/resolve Mark resolved.

Comments are a standalone collaboration primitive (Word/Docs-style), not part of the version chain. Any caller with read access may leave or resolve one.

Glossary & edge types

Method Path Purpose
GET/POST/DELETE /nests/:nestId/definitions[/:id] Per-nest glossary — one row per (nest, term), upsert by term.
GET/POST/DELETE /nests/:nestId/edge-types[/:id] Edge-type registry (feature-flagged — 404 unless FEATURE_WORKFLOW_PLANE is on).

Query, search & retrieval (read-only consumers)

These power LLM context retrieval and are open-mode friendly.

Method Path Purpose
GET /nests/:nestId/search?q=<term> Full-text search within a nest.
GET /search?q=<term>&limit=20 Same match across every nest the caller can see; each hit stamped with its nest.
POST /nests/:nestId/context One-call retrieval → markdown ready to prepend to a prompt, plus trace + node manifest. Body: prompt or selector, max_tokens?, hops?, include_drafts?. Requires a license.
GET /nests/:nestId/context Return CONTEXT.md content.
GET /nests/:nestId/export?format=markdown LLM-pointed plain-text view — every accessible node as frontmatter + body, joined by ---. Approved-only for every caller. Optional selector, max_tokens. A GET, so it works on public nests without credentials.
GET /nests/:nestId/export?format=bundle Download a portable .zip to move the nest to another host. Optional ?includeDrafts=1. No separate import endpoint — unzip and use the folder importer (POST /nests/import).
POST /nests/:nestId/query Graph query (Cypher-ish).
GET /nests/:nestId/graph Ontology graph for the graph view (links, stewardship overlay, coverage gaps).
GET /nests/:nestId/runnables Every runnable (agent/skill) node with its schedule and body — an orchestrator surface.
POST /nests/:nestId/reindex (write+) Force-rebuild the nest's document index; returns { indexed }.
POST /nests/:nestId/publish Publish the nest (snapshots + index).

MCP transport

Path Purpose
ALL /nests/:nestId/mcp Per-nest Model Context Protocol endpoint (JSON-RPC over HTTP).
ALL /mcp · GET /index Server-level cross-nest MCP + index.

The transport is read-tier (MCP Streamable HTTP is always POST), so each mutating tool re-checks its own permission inside the handler. Gate rejections return a JSON-RPC error envelope, not {error} JSON. See Connect an Agent.

Admin / operator

Method Path Purpose
GET/POST/DELETE /admin/super-admins[/:email] (server-admin) Grant / revoke server-wide superadmins.
GET /admin/trace (server-admin) Cross-tenant operator activity trail.
GET /nests/:id/trace (owner / nest admin) The per-nest slice of the activity trace.
GET/PATCH /admin/settings (superadmin) Runtime settings (sign-in gate, logo, OIDC, connectors, feature flags).

Error shapes

Status When
400 Validation error
401 Auth required
403 Permission denied (Insufficient permissions, steward mismatch)
404 Nest / node / steward not found, or no permission
409 Conflict (key exists, version conflict, duplicate)
423 Node frozen by a pending review
429 Rate limit
503 License missing

Sources

  • API.md (Community server repo) — the complete endpoint reference this page condenses.
  • CONFIGURATION.md (Community server repo) — auth modes and the license gate.