DOCS · SERVER
ALL DOCS FIG. 15 · DWG VC-015

HTTP API

Read-model reference for the local server: health, control-plane state, runs, lifecycle runs, and the SSE event stream.

Canonical source — docs/public/server/http-api.md

HTTP API

The server exposes the control plane as a small JSON API on http://127.0.0.1:3024. Every control route is a read over ~/.vibecrafted/control_plane/ (or $VIBECRAFTED_HOME); nothing under /api/control/* writes.

Endpoints

MethodPathPurpose
GET/api/healthConstant-time process readiness. Never scans the control plane.
GET/api/control/stateCached state view: active/recent runs, warnings, event tail, settlement.
GET/api/control/runsEvery run snapshot, newest-first.
GET/api/control/runs/{run_id}One run by id, or a 404 JSON body.
GET/api/control/lifecycleLifecycle run summaries, newest-first.
GET/api/control/lifecycle/{run_id}Full nested lifecycle state with per-run and per-stage axes.
GET/api/control/eventsServer-Sent Events stream of the control-plane event log.

Run payloads serialise the delivery-proof axes (execution_state, proof_state, delivery_state) and seal only when the snapshot or kernel receipt carries them. Absent axes stay absent — a completed state is never promoted into a delivery claim.

Health

curl -s http://127.0.0.1:3024/api/health
{ "schema": "vibecrafted.health.v1", "status": "ok" }

Health deliberately does not read the control plane: a long retained history can make the state projection expensive without making the process unhealthy.

Board state

/api/control/state is the board slice shared by the dashboard, the MCP vc_board_status tool, and the Slack /vc status command. The response is cached in-process for a short TTL; a stale cache is returned immediately while one background refresh re-reads the durable snapshots.

curl -s http://127.0.0.1:3024/api/control/state | python3 -m json.tool

Truncated example:

{
  "control_plane": "~/.vibecrafted/control_plane",
  "generated_at": "2026-07-30T12:00:00+00:00",
  "active_runs": [
    {
      "run_id": "impl-20260730-a1b2",
      "state": "running",
      "agent": "codex",
      "skill": "implement",
      "root": "~/projects/my-app",
      "health": "healthy",
      "started_at": "2026-07-30T11:41:02+00:00",
      "latest_report": "",
      "lock_present": true
    }
  ],
  "recent_runs": [],
  "warnings": [],
  "events": [
    {
      "ts": "2026-07-30T11:41:02+00:00",
      "run_id": "impl-20260730-a1b2",
      "kind": "launch",
      "message": "worker launched",
      "cursor": 42
    }
  ],
  "settlement_counts": {
    "active": 1,
    "f": 12,
    "x": 1,
    "n": 3,
    "invalid": 0,
    "unclassified": 0,
    "total_settled": 16
  }
}

Runs and lifecycle

# every retained run snapshot
curl -s http://127.0.0.1:3024/api/control/runs | python3 -m json.tool | head

# one run (404 JSON when unknown)
curl -s http://127.0.0.1:3024/api/control/runs/impl-20260730-a1b2

# lifecycle list, then one lifecycle run in full
curl -s http://127.0.0.1:3024/api/control/lifecycle
curl -s http://127.0.0.1:3024/api/control/lifecycle/life-ship-20260730-c3d4

List responses carry a count and the resolved control_plane path, so you can verify which home the server is reading.

Event stream (SSE)

/api/control/events streams the control-plane event log as Server-Sent Events, with : ping keepalives. Resume from a cursor with ?since= or the standard Last-Event-ID header:

curl -N "http://127.0.0.1:3024/api/control/events?since=42"

Each event’s cursor value is the id to resume from after a disconnect.

Scaffold editor surface

The server also hosts a plan-editor surface for scaffold artifacts (/scaffold/editor, GET /api/scaffold/plans|artifacts|changes, POST /api/scaffold/artifact|checkpoint|status). The POST routes save plan artifacts into the artifact store — they do not touch run status. This surface is subject to change; the control routes above are the stable API.