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
| Method | Path | Purpose |
|---|---|---|
| GET | /api/health | Constant-time process readiness. Never scans the control plane. |
| GET | /api/control/state | Cached state view: active/recent runs, warnings, event tail, settlement. |
| GET | /api/control/runs | Every run snapshot, newest-first. |
| GET | /api/control/runs/{run_id} | One run by id, or a 404 JSON body. |
| GET | /api/control/lifecycle | Lifecycle run summaries, newest-first. |
| GET | /api/control/lifecycle/{run_id} | Full nested lifecycle state with per-run and per-stage axes. |
| GET | /api/control/events | Server-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.