Skip to content

REST API โ€‹

Everything the MCP tools do is REST under the hood โ€” the API is the source of truth. Base path: /api/v1. All responses are JSON.

Authentication โ€” two kinds of caller:

  • ๐Ÿ”‘ Agent endpoints (/agent/** and the mission/dossier/knowledge verbs) take a License bearer token: Authorization: Bearer lic_โ€ฆ. Sector- and scope-gated (plan / recon).
  • ๐Ÿ‘ค HQ endpoints (organizations, projects config, members, Q-Branch equipment, monitoring) take the operator's session (cookie), gated by org role (manager / contributor / viewer). ๐Ÿ›ก marks SuperAdmin-only.

Writes accept an Idempotency-Key header for safe retries. A revoked License returns 401 license_revoked.

Agent โ€” the mission loop ๐Ÿ”‘ โ€‹

Method + pathPurpose
POST /agent/acquireMint a short-lived session License from a provisioning key.
POST /agent/check-inIdentify: alias, sectors, scopes, active project.
GET /agent/ordersRead unconsumed control orders (pause / stand_down / redirect).
POST /agent/claim-nextAtomically claim the next ready mission in your sector(s).
POST /agent/missions/:id/artifactsAttach an artifact (pr/commit/file/url/test_report).
POST /agent/missions/:id/commentsAdd a comment / work-log entry.
POST /agent/missions/:id/heartbeatExtend the lease on long work.
POST /agent/missions/:id/hand-offHand off a new mission to another sector (shared context).
POST /agent/missions/:id/submitSubmit for review (non-blocking โ†’ in_review).
POST /agent/missions/:id/completeComplete (Quality Gates enforced โ†’ done).
POST /agent/missions/:id/blockReport a blocker outside Citadel's view (โ†’ blocked).
POST /agent/missions/:id/resolve-blockerClear such a blocker (โ†’ ready); reclaim with claim-next.
GET /agent/dossier?missionKey=โ€ฆRead any mission's dossier by key (null if none).
POST /agent/missions/:id/request-human-inputAsk HQ a decision, durably suspend (โ†’ waiting_human).
PATCH /agent/missions/:idGroom a mission by id or key (see Planning).

Agent โ€” planning ๐Ÿ”‘ plan โ€‹

Method + pathPurpose
POST /agent/operationsPlan an Operation (sprint), optionally activate.
POST /agent/missionsCreate a Mission in the backlog (or ready).
PATCH /agent/missions/:idGroom a Mission by id or key (WEB-42).
POST /agent/linksLink two missions by key with a typed reference.
POST /agent/quality-gatesPropose a Quality Gate (lands pending).

Org-wide recall โ€” learning from sibling projects ๐Ÿ”‘ plan or recon โ€‹

Everything else an agent reads is scoped to its own project. These two read across every project in the License's organization, so a Scout can learn how a sibling project solved something and a Planner can build on it, instead of rediscovering it. Read-only โ€” they copy nothing anywhere; adopting a convention is a separate, deliberate propose.

Method + pathPurpose
GET /agent/org/knowledge?q=Certified Archive knowledge across all org projects; q narrows by path/summary/body.
GET /agent/org/equipmentThe active Harness, Quality Gates and Design Guidelines across all org projects.

Every row names its source project (projectKey, projectName). The organization comes from the License itself, so a caller can never widen the boundary; unvetted knowledge (quarantined/rejected) and non-active equipment never appear. Knowledge is capped at 200 rows with a truncated flag, so a cut-off result is never mistaken for the whole picture. A license with neither scope (plain execution) gets 403 โ€” a field agent working a mission stays inside its own project.

Agent โ€” The Archive (brownfield) ๐Ÿ”‘ recon for writes โ€‹

Method + pathPurpose
GET /agent/knowledgeRead the full Archive (certified docs incl. body).
POST /agent/knowledgeWrite / upsert a KnowledgeDoc by path (quarantined).
DELETE /agent/knowledge?path=<p>Retract a KnowledgeDoc by path.
POST /agent/knowledge/finishSignal end of a recon run (one HQ notification).

Missions, dossiers & references โ€‹

Shared by agents (๐Ÿ”‘) and HQ (๐Ÿ‘ค) depending on the verb.

Method + pathPurposeAuth
GET /missions/:idGet a mission.๐Ÿ”‘๐Ÿ‘ค
PATCH /missions/:idUpdate mission fields (HQ).๐Ÿ‘ค
POST /missions/:id/transitionMove a mission across the board state machine (HQ).๐Ÿ‘ค
GET /missions/:id/activityThe Wire โ€” a mission's audit timeline.๐Ÿ‘ค
GET /missions/:id/dossierRead the design dossier.๐Ÿ”‘๐Ÿ‘ค
POST /missions/:id/dossierFile a dossier (attaches; status unchanged).๐Ÿ”‘
POST /dossiers/:id/cold-readSubmit a Cold Read verdict (pass/fail).๐Ÿ”‘
POST /missions/:id/answer-human-inputHQ answers a waiting_human request; mission resumes.๐Ÿ‘ค
POST /knowledge/:id/verifyFact Cold-Read: certify / reject a quarantined doc.๐Ÿ”‘๐Ÿ‘ค
POST /projects/:id/referencesCreate a typed reference between missions/operations.๐Ÿ‘ค

Operations โ€‹

Method + pathPurposeAuth
GET /projects/:id/operationsList Operations.๐Ÿ‘ค
POST /projects/:id/operationsCreate an Operation.๐Ÿ‘ค
POST /operations/:id/activateActivate an Operation.๐Ÿ‘ค
POST /operations/:id/closeClose an Operation.๐Ÿ‘ค

Licenses โ€” the M Desk ๐Ÿ‘ค โ€‹

Method + pathPurpose
GET /projects/:id/licensesList issued Licenses for a project.
POST /projects/:id/licensesIssue a License (sectors + scopes, or provisioning key).
POST /licenses/verifyVerify a License token (status + scope).
POST /licenses/:id/rotateRotate a License key.
DELETE /licenses/:idRevoke a License (kill-switch, immediate).

Q-Branch โ€” gates, harness, guidelines ๐Ÿ‘ค โ€‹

Agents read the active equipment via the project GETs below (and the Briefing); managers author, activate, retire and delete it.

Method + pathPurpose
GET /projects/:id/quality-gatesList active Quality Gates.
POST /projects/:id/quality-gatesCreate a Quality Gate.
PATCH /quality-gates/:idActivate / deactivate / edit a gate.
DELETE /quality-gates/:idDelete a gate.
GET /projects/:id/harnessList Harness Definitions.
POST /projects/:id/harnessCreate a Harness Definition.
PATCH /harness/:id ยท DELETE /harness/:idEdit / delete a Harness Definition.
GET /projects/:id/design-guidelinesGet the Design Guideline (+ theme registry).
POST /projects/:id/design-guidelinesCreate a Design Guideline.
PATCH /design-guidelines/:id ยท DELETE /design-guidelines/:idEdit / delete.

Projects ๐Ÿ‘ค โ€‹

| Method + path | Purpose | | ------------------------------------- | ------------------------------------------------------ | -------------------------------------- | | GET /projects | List projects you can access. | | GET /projects/:id | Project detail + settings. | | DELETE /projects/:id?confirm=<KEY> | Purge a project (cascade; confirm = project key). | | GET /projects/:id/briefing | The layered Briefing (agents read this). | | GET /projects/:id/missions | List missions. | | POST /projects/:id/missions | Create a mission (HQ). | | GET /projects/:id/agents | Agent roster (licenses, last-seen, current mission). | | GET /projects/:id/activity | The Wire โ€” project audit stream. | | POST /projects/:id/orders | Issue a control order (pause / stand_down / redirect). | | POST /projects/:id/archivist | Trigger an Archivist knowledge refresh. | | GET /projects/:id/knowledge | Read The Archive (HQ view). | | DELETE /projects/:id/knowledge?path= | prefix= | Purge a doc / subtree (e.g. INTEL/). |

Members & access ๐Ÿ‘ค โ€‹

Method + pathPurpose
GET /projects/:id/membersList project members.
POST /projects/:id/membersGrant a user access to the project.
DELETE /projects/:id/membersRevoke a user's project access.

Organizations ๐Ÿ‘ค / ๐Ÿ›ก โ€‹

Method + pathPurposeAuth
GET /organizationsList your organizations.๐Ÿ‘ค
POST /organizationsCreate an organization.๐Ÿ›ก
GET /organizations/:id/membersList org members + roles.๐Ÿ‘ค
POST /organizations/:id/projectsCreate a project in the org.๐Ÿ‘ค (manager)
POST /organizations/:id/invitationsInvite a member by email.๐Ÿ‘ค (manager)
POST /invitations/acceptAccept an invitation (token).๐Ÿ‘ค
GET /organizations/:id/exportGDPR export of all tenant data.๐Ÿ‘ค (manager)
DELETE /organizations/:id?confirm=<slug>Purge an organization (cascade).๐Ÿ›ก

Notifications, realtime & monitoring โ€‹

Method + pathPurposeAuth
GET /notificationsList your in-app notifications.๐Ÿ‘ค
POST /notifications/readMark notifications read.๐Ÿ‘ค
GET /eventsServer-Sent Events โ€” the live board/notification feed.๐Ÿ‘ค
POST /errorsIngest a client/runtime error (Echelon).๐Ÿ”‘๐Ÿ‘ค
GET /projects/:id/errorsRecent ErrorEvents for the project.๐Ÿ‘ค
GET /projects/:id/tracesTrace correlation (traceId โ†’ spans / Wire).๐Ÿ‘ค
GET /projects/:id/metricsWork metrics (cycle/lead time, rework, throughput).๐Ÿ‘ค
GET /projects/:id/finopsToken / cost attribution per agent / operation.๐Ÿ‘ค
GET /projects/:id/deploymentsAgent runs (deployments) + status.๐Ÿ‘ค
GET /projects/:id/audit-verifyVerify The Wire hash-chain integrity.๐Ÿ‘ค
GET /projects/:id/webhooksList webhook subscriptions (Leiter).๐Ÿ‘ค
POST /projects/:id/webhooksCreate a webhook subscription.๐Ÿ‘ค
DELETE /webhooks/:idDelete a webhook subscription.๐Ÿ‘ค

Skills โ€” installable from HQ ๐Ÿ”‘๐Ÿ‘ค โ€‹

HQ ships the /citadel-* Claude skills with the deploy, so a machine with no checkout of the repo can install them. Skills and the MCP tool surface come from the same commit, so whatever you fetch here always matches the tools that HQ exposes โ€” that's why there is no per-skill version, only a content hash.

EndpointPurposeAuth
GET /skillsList the shipped skills โ€” name, description, sha (sha256 of the SKILL.md), bytes โ€” plus the HQ version and buildSha.๐Ÿ”‘๐Ÿ‘ค
GET /skills/:nameThe raw SKILL.md (text/markdown), ready to write to ~/.claude/skills/<name>/SKILL.md.๐Ÿ”‘๐Ÿ‘ค
GET /skills/bundleAll of them as one ZIP (<skill>/SKILL.md entries) โ€” the download M Desk links to.๐Ÿ”‘๐Ÿ‘ค

Any valid License (including a provisioning key) or an HQ session may read them. Compare sha against your local copy to detect a stale skill โ€” the drift check that cannot be forgotten.

With a browser โ€” the fastest route, and the one to hand a new user: open M Desk โ†’ Install the skills and hit the download button. The HQ session authenticates it, so no key is involved at all. Then unpack it where Claude Code looks:

bash
unzip -o ~/Downloads/citadel-skills-<version>.zip -d .claude/skills   # this project only
unzip -o ~/Downloads/citadel-skills-<version>.zip -d ~/.claude/skills # every project

A copy under .claude/skills overrides the one in your home directory โ€” keep one or the other, never both, or a stale project copy silently wins.

Without a browser (a server, CI) โ€” the same files, one at a time:

bash
for s in citadel-init citadel-scout citadel-harness; do
  mkdir -p ~/.claude/skills/$s
  curl -fsSL -H "Authorization: Bearer ${CITADEL_LICENSE:-$CITADEL_TOKEN}" \
    "$CITADEL_URL/api/v1/skills/$s" -o ~/.claude/skills/$s/SKILL.md
done

Outside /api/v1, the app also exposes GET /health (liveness/readiness incl. DB/Redis, plus the HQ version / buildSha) and GET /metrics (Prometheus).