API reference
All /api/* routes (except setup-status and setup) require a valid
session cookie — log in via the web UI, or POST /api/login directly.
| Method & path | Auth | Body | Result |
|---|---|---|---|
GET /api/setup-status |
none | — | {needs_setup} |
POST /api/setup |
none, once only | {username, password} |
creates the first admin account + session |
POST /api/login |
none | {username, password} |
session cookie |
POST /api/logout |
session | — | 204 |
GET /api/session |
session | — | {id, username, role} |
GET /api/agents |
session | — | list of agents (with live online status) |
GET /api/agents/{id} |
session | — | one agent |
DELETE /api/agents/{id} |
session, admin | {"confirm": true} |
204 — deletes the agent record, force-closing its live session if connected |
GET /api/agents/{id}/shell |
session | — (WebSocket upgrade) | bridges to a live PTY on the agent |
GET /api/enrollment-tokens |
session, admin | — | list of tokens |
POST /api/enrollment-tokens |
session, admin | {label, max_uses, ttl_seconds} |
{..., token} — raw value shown once |
DELETE /api/enrollment-tokens/{id} |
session, admin | {"confirm": true} |
204 — revokes the token |
GET /api/audit-log |
session, admin | — (query: ?limit=N) |
list of audit entries, newest first |
Destructive endpoints (DELETE /api/agents/{id},
DELETE /api/enrollment-tokens/{id}) require an explicit
{"confirm": true} in the request body — a bare DELETE with no body (or
{"confirm": false}) is rejected with 400.
The shell WebSocket
GET /api/agents/{id}/shell?cols=N&rows=N upgrades to a WebSocket. Binary
messages carry terminal I/O in both directions. A JSON text message
{"type": "resize", "cols": N, "rows": N} (client → server) adjusts the
PTY's size mid-session.
The endpoint enforces same-origin by default (the Origin header must be
unset or match the Host header) — it isn't meant to be embedded
cross-origin.