This reference covers every HTTP endpoint exposed by the LLM Systems Manager and the Alarm Engine. It is written for operators, integration authors, and script writers who need to call endpoints directly — not for contributors reading the source code.
The Manager listens on port 5000 (HTTP) and optionally port 5443 (HTTPS). The Alarm Engine runs on port 8081 but is always accessed through the Manager’s /api/alarm/* proxy — you should never need to call port 8081 directly. All endpoints in this document use the Manager as the entry point.
Browser / UI sessions authenticate via a login cookie. After POST /login succeeds, your browser holds a signed session cookie that is checked on every subsequent request. Sessions expire based on the configured lifetime (default: several days).
Agent-to-Manager calls authenticate with a bearer token issued at registration: Authorization: Bearer <token>. These are internal; you do not need to manage them as an operator.
Admin-only endpoints are marked [Admin] throughout this document. Reaching them requires both an admin-role session and (where configured) a request originating from an allowed admin network range. Operator-role sessions receive a 403 on admin endpoints.
Ingest endpoints on the Alarm Engine accept a separate shared bearer token configured in llm-systems.toml. When the token is blank the ingest surface is open; when set, agents must present it.
GET /healthUnauthenticated liveness probe for external monitors and load balancers. Not gated by the login/session flow at all.
Response: {"status": "ok", "version": "<manager version>", "uptime_s": <seconds since startup>}
GET /api/metricsReturns the current hardware snapshot across all monitored agents: CPU, RAM, GPU temperature and utilisation, network throughput, disk usage, and any active LLM provider state. This is the primary polling endpoint for the dashboard.
Parameters: ?agent=<agent_id> — restrict the response to a single agent’s data.
GET /api/historyReturns historical time-series data used to draw dashboard charts. The time window and resolution are controlled by the server’s configured history settings.
Parameters:
?agent=<agent_id> — return history for one specific agent (full host metric set).?fleet=llama, ?fleet=lms, or ?fleet=vllm — return aggregated history for all agents of that provider type (CPU/RAM/GPU values are aggregated across every agent of that type).GET /api/alertReturns the current active alert count and the highest severity level in effect. Used by the dashboard header to show the alert badge.
GET /api/configReturns the current polling interval and basic server configuration the frontend needs to self-configure (for example, which provider tabs to show).
POST /api/config/intervalUpdates the dashboard polling interval.
Body: {"interval": <seconds>}
These endpoints control the llama.cpp inference server running on the GPU host. All of them are proxied transparently through the Manager to the appropriate agent; you do not need to know which agent is handling a request.
GET /api/llama-stateReturns whether the llama.cpp server is currently awake or sleeping.
Parameters: ?agent=<agent_id> — query a specific agent rather than the default.
GET /api/llama-state/streamOpens a Server-Sent Events (SSE) stream that pushes a new event each time the llama.cpp server changes state (awake ↔ sleeping) or loads a different model. Stays open until the client disconnects.
Parameters: ?agent=<agent_id>
GET /api/llm/modelsLists all model files available on the GPU host’s model storage path.
POST /api/llm/loadInstructs the llama.cpp server to load a specific model. The server will unload any currently loaded model first.
Body: {"model": "<model_id>"}
POST /api/llm/unloadUnloads the currently active model from the llama.cpp server without stopping the server process.
GET /api/llm/configReturns the llama.cpp server configuration (context window size, GPU layer count, thread count, and other runtime parameters) for the currently active model. There is no query-param variant for reading another model’s saved config — use GET /api/llm/profiles to see all saved profiles, or POST /api/llm/config to write one.
POST /api/llm/configSaves the llama.cpp server configuration. The saved values are applied the next time the server loads that model.
Body: A JSON object containing the configuration fields to save (context size, GPU layers, threads, etc.).
The configuration is stored in INI format. Key names correspond to llama-server command-line flags: --ctx-size, --gpu-layers, --threads, --batch-size, --parallel, etc. Retrieve the current config with GET /api/llm/config to see available keys.
DELETE /api/llm/config/<model_id>Deletes the saved configuration for the named model, reverting it to defaults on next load.
GET /api/llm/server/statusReturns whether the llama.cpp server process is currently running.
POST /api/llm/server/startStarts the llama.cpp server process.
POST /api/llm/server/stopStops the llama.cpp server process.
POST /api/llm/server/restartStops then starts the llama.cpp server in one call.
POST /api/llm/server/wakeWakes a sleeping llama.cpp server. The server enters a low-power sleep state after an idle timeout; this call brings it back to the active (ready-to-infer) state.
GET /api/llm/server/log/tailReturns the most recent lines from the llama.cpp server log.
GET /api/llm/server/log/streamOpens an SSE stream that tails the llama.cpp server log in real time. Each event contains one or more new log lines.
POST /api/llm/downloadStarts an asynchronous download of a model file from HuggingFace. Progress is delivered via /api/llm/download/stream.
Body: {"repo": "<huggingface-repo-id>", "file": "<filename>"}
POST /api/llm/download/cancelCancels an in-progress model download.
GET /api/llm/download/streamOpens an SSE stream reporting download progress (bytes downloaded, speed, estimated time remaining). The stream closes when the download completes or fails.
POST /api/llm/buildStarts an asynchronous build of the llama.cpp binary from source. Progress is delivered via /api/llm/build/stream.
GET /api/llm/build/streamOpens an SSE stream reporting build progress and compiler output. The stream closes when the build completes or fails.
GET /api/llm/cacheLists model files currently held in the local model cache on the GPU host.
POST /api/llm/cache/pruneRemoves cached model files that are not referenced by any saved configuration or active load, freeing disk space.
POST /api/llm/cache/rmRemoves a specific file from the model cache.
Body: {"path": "<cache-relative-path>"}
GET /api/llm/hf-trendingReturns the current HuggingFace trending models list, useful for discovering new models to download.
GET /api/llm/aliasesReturns the saved model name aliases (human-readable short names mapped to model IDs).
POST /api/llm/aliasesCreates or updates a model name alias.
Body: {"model_id": "<id>", "alias": "<short name>"}
DELETE /api/llm/aliases/<model_id>Removes the alias for the specified model.
POST /api/benchmark/runStarts a benchmark run against the currently loaded model. The benchmark measures prompt processing throughput (tokens/sec) and generation throughput at various context sizes. Results are streamed via /api/benchmark/stream.
GET /api/benchmark/streamOpens an SSE stream reporting live benchmark progress (current context size being tested, intermediate results). The stream closes when the benchmark finishes or is cancelled.
GET /api/benchmark/resultsReturns all saved benchmark results for all models.
POST /api/benchmark/storeSaves a benchmark result to persistent storage.
Body: A benchmark result object as returned by the benchmark stream.
DELETE /api/benchmark/results/<model_id>Deletes all saved benchmark results for the specified model.
GET /api/benchmark/modelsReturns the list of models that have at least one saved benchmark result.
POST /api/benchmark/perf-modeSwitches the GPU host between performance and power-save operating modes during benchmarking.
Body: {"mode": "performance"} or {"mode": "powersave"}
POST /api/benchmark/cancelCancels an in-progress benchmark run.
POST /api/llm/autotune/runStarts the Auto-Tune context wizard, which automatically finds the largest context window size the currently loaded model can sustain within GPU memory. Progress is streamed via /api/llm/autotune/stream.
GET /api/llm/autotune/streamOpens an SSE stream reporting Auto-Tune progress (context sizes being probed, memory readings, pass/fail results).
GET /api/llm/autotune/stream-infoReturns metadata about the current or most recent Auto-Tune run without opening a stream.
POST /api/llm/autotune/cancelCancels an in-progress Auto-Tune run.
GET/POST /api/llm/server/svcconfigReads (GET) or writes (POST) the llama-server systemd unit’s ExecStart arguments directly, for flags not exposed through /api/llm/config. POST daemon-reloads the unit and can restart it.
Body (POST): A JSON object of ExecStart argument overrides.
.../stream-info — direct-SSE handoff endpointsSeveral of the SSE endpoints above have a sibling .../stream-info route that mints a short-lived HMAC-signed token and returns the direct agent stream URL instead of opening the stream itself: GET /api/llm/server/log/stream-info, GET /api/llm/download/stream-info, GET /api/llm/build/stream-info, GET /api/llm/autotune/stream-info, and GET /api/llama-state/stream-info. The browser uses the returned URL to connect straight to the agent, bypassing the Manager’s own SSE proxy pool; when the direct path isn’t usable (agent down, no direct port, or a mixed-content HTTPS page) the response signals the browser to fall back to the proxied .../stream endpoint instead.
Response: {"ok": true, "url": "<agent-direct-url>?token=<token>", "expires_in": <seconds>} on success, or {"ok": false, ...} when direct streaming isn’t available.
/api/llama-state/stream-info is the exception: it returns {"enabled": true, "url": ...} or {"enabled": false}, with no expires_in.
These endpoints control and monitor the LM Studio server running on the Apple Silicon host.
GET /api/lmstudio/metricsReturns the current LM Studio status, including which model is loaded, active requests, memory usage, and server health.
GET /api/lmstudio/modelsLists all models available in LM Studio’s model library.
GET /api/lmstudio/server/statusReturns whether the LM Studio server process is running.
POST /api/lmstudio/server/startStarts the LM Studio server.
POST /api/lmstudio/server/stopStops the LM Studio server.
POST /api/lmstudio/server/restartStops then starts the LM Studio server in one call.
GET /api/lmstudio/server/logReturns recent log output from the LM Studio server.
POST /api/lmstudio/loadInstructs LM Studio to load a specific model.
Body: {"model": "<model_id>"}
POST /api/lmstudio/unloadUnloads the currently active model from LM Studio.
POST /api/lmstudio/downloadStarts a model download within LM Studio.
Body: {"model": "<model_id>"}
These endpoints control the vLLM inference server, mirroring the llama.cpp control surface above.
GET /api/vllm/metricsReturns the latest vLLM sample for the default (or ?agent=) vLLM agent.
GET /api/vllm/modelsLists all model files available on the vLLM host’s model storage path.
GET /api/vllm/server/statusReturns whether the vLLM server process is currently running.
POST /api/vllm/server/startStarts the vLLM server process.
POST /api/vllm/server/stopStops the vLLM server process.
POST /api/vllm/server/restartStops then starts the vLLM server in one call.
GET /api/vllm/server/logReturns the most recent lines from the vLLM server’s journal.
GET /api/vllm/log/streamOpens an SSE stream that tails the vLLM server log in real time.
GET/POST /api/vllm/server/svcconfigReads (GET) or writes (POST) the vLLM systemd unit’s ExecStart arguments — the vLLM equivalent of /api/llm/server/svcconfig.
Body (POST): A JSON object of ExecStart argument overrides.
POST /api/vllm/lora/loadLoads a LoRA adapter into the running vLLM server.
Body: LoRA load parameters (adapter path/name); passed through to the agent.
POST /api/vllm/lora/unloadUnloads a LoRA adapter from the running vLLM server.
Body: LoRA unload parameters; passed through to the agent.
POST /api/vllm/autotune/runStarts the --max-model-len Auto-Tune wizard for vLLM, which finds the largest context length the currently loaded model can sustain. Progress is streamed via /api/vllm/autotune/stream.
GET /api/vllm/autotune/streamOpens an SSE stream reporting vLLM Auto-Tune progress.
POST /api/vllm/autotune/cancelCancels an in-progress vLLM Auto-Tune run.
POST /api/vllm/bench/runStarts a vllm bench serve benchmark run against the currently loaded model. Progress is streamed via /api/vllm/bench/stream.
GET /api/vllm/bench/streamOpens an SSE stream reporting vLLM benchmark progress.
POST /api/vllm/bench/cancelCancels an in-progress vLLM benchmark run.
POST /api/vllm/terminal/createOpens an SSH shell session to the vLLM host, mirroring /api/lms/terminal/create. Returns a session ID used with the shared /api/terminal/* endpoints below.
An OpenAI-compatible chat/completions gateway that fans requests out to whichever backend provider (llama.cpp, LM Studio, or vLLM) is serving the requested model. Requests authenticate either with a bearer token from [manager.gateway].api_keys, or with a normal dashboard session cookie.
POST /api/gateway/v1/chat/completionsOpenAI-compatible chat completion. The target provider is resolved from the request body’s model field: a model pin wins first, then the live model index built from each provider’s /models listing, then a llama fallback if the model is unrecognized. Within the resolved provider, the host is picked in the order: model pin, then an explicit ?agent=, then pool round-robin, then the provider default. A pin therefore overrides an explicit ?agent=; the gateway logs when that happens. (The dashboard’s own proxy routes surface the same condition as an X-Routing-Override: pin response header; the gateway does not set it.) Supports "stream": true for SSE responses.
Successful non-streaming responses carry an X-Proxied-To: <agent_id prefix>@<hostname> header identifying which agent actually served the request; streaming responses carry the same header on the initial SSE response.
POST /api/gateway/v1/completionsOpenAI-compatible legacy completion endpoint. Same provider-resolution and X-Proxied-To behavior as /api/gateway/v1/chat/completions.
GET /api/gateway/v1/modelsReturns the merged OpenAI-style model list ({"object": "list", "data": [...]}) across every gateway-enabled provider’s pool (currently llama, lms, vllm).
Every gateway-enabled provider also gets its own fixed-provider mirror of the three routes above, skipping model-based provider resolution: POST /api/gateway/<provider>/v1/chat/completions, POST /api/gateway/<provider>/v1/completions, and GET /api/gateway/<provider>/v1/models, for <provider> in llama, lms, vllm.
Runs a standardized benchmark (“report card”) against a reference model on a chosen agent/provider, to produce comparable tokens/sec and $/Mtok numbers across hardware. Report card jobs run asynchronously and stream progress over SSE, similar to the benchmark endpoints in the LLM Control section.
GET /api/reportcard/presetReturns the report card’s fixed run parameters: preset_version, gen_tokens, reps, the supported providers, the configured price_kwh, and the list of reference models ({"key", "label"}) available for standard runs.
POST /api/reportcard/runStarts a report card run. In standard mode, first checks whether the reference model is ready on the target agent — if a confirmation or download is needed, returns that status instead of starting the job; the caller resubmits with confirm_vllm/confirm_download set to proceed.
Body: {"agent": "<agent_id>", "provider": "llama"|"lms"|"vllm", "mode": "standard"|"custom", "model": "<model_id>" (custom mode), "model_key": "<reference key>" (standard mode), "price_kwh": <number> (optional), "confirm_vllm": <bool>, "confirm_download": <bool>}
Response: {"ok": true, "job_id": "<id>"} once the job is started, or {"ok": true, "status": "needs_confirm"|"needs_download", ...} when a precheck blocks the run.
GET /api/reportcard/modelsReturns the model IDs currently available on a given agent/provider.
Parameters: ?agent=<agent_id>&provider=<llama|lms|vllm> (both required)
POST /api/reportcard/delete-modelDeletes a reference model from an agent’s local storage/cache. Supported only for llama and lms.
Body: {"agent": "<agent_id>", "provider": "llama"|"lms", "model_key": "<reference key>"}
POST /api/reportcard/cancel/<job_id>Cancels an in-progress report card job.
GET /api/reportcard/stream/<job_id>Opens an SSE stream reporting progress for a report card job. Closes when the job emits a done, error, or cancelled event, or after an internal timeout.
GET /api/reportcard/latestReturns the most recent saved report card for an agent/provider pair.
Parameters: ?agent=<agent_id>&provider=<llama|lms|vllm> (both required)
GET /api/reportcard/historyReturns saved report card history, optionally filtered.
Parameters: ?agent=<agent_id>, ?provider=<llama|lms|vllm>, ?model=<model_id> — all three required; omitting any returns 400.
Rolls up power-draw metrics into cost figures over configurable time windows, using the configured $/kWh and cloud comparison pricing.
GET /api/energy/summaryReturns an energy/cost summary for a time window: total energy, local $ cost, and equivalent cloud-provider cost comparison.
Parameters:
?days=<n> or ?month=<YYYY-MM> — select the summary window (mutually exclusive with the default trailing window)?price_kwh=<number> — override the configured electricity price for this call?cloud_in=<number> / ?cloud_out=<number> — override the configured cloud $/Mtok input/output pricing for comparisonGET /api/energy/hourlyReturns hourly energy/cost data points for charting.
Parameters:
?days=<n> or ?month=<YYYY-MM> — mirrors the summary window?hours=<n> — trailing-window form used when days/month are absent (default 168, capped)?agent=<agent_id> — restrict to one agentAutomates placement of model entries across the agent pool — deciding which host(s) should serve which model, proposing changes, and (optionally) applying them. All autopilot endpoints require an admin session.
GET /api/autopilotReturns the current autopilot state, any pending proposals, the last plan timestamp, and per-entry status.
Access: [Admin]
Response: {"state": <state document>, "proposals": [...], "last_plan_ts": <epoch seconds>, "entry_status": {...}}
PUT /api/autopilotReplaces the autopilot state document. The submitted document is validated before being saved — invalid entries are rejected with a 400 and an error message.
Access: [Admin]
Body — state document:
{
"enabled": true,
"entries": [
{
"model": "<model_id>",
"provider": "llama",
"placement": "auto",
"failover": "semi",
"priority": 100,
"min_replicas": 1,
"max_replicas": 1,
"size_mb": 8192,
"autoscale": {"target_saturation": 0.75, "up_window_s": 120, "down_window_s": 900}
}
],
"hosts": {}
}
provider: llama, vllm, or lmsplacement: "auto" or a specific agent idfailover: "semi" (propose, wait for apply) or "auto" (apply automatically)min_replicas / max_replicas: replica bounds; max_replicas > min_replicas enables autoscalesize_mb: optional explicit model size override used for placement sizinghosts: reserved; any submitted value is currently ignored (idle sleep is llama-server’s own --sleep-idle-seconds, not autopilot-managed)POST /api/autopilot/proposals/<pid>/applyApplies a pending proposal (executes the placement/pool/pin changes it describes).
Access: [Admin]
POST /api/autopilot/proposals/<pid>/dismissDismisses a pending proposal without applying it.
Access: [Admin]
POST /api/autopilot/tickManually triggers one reconciler tick (observe current state, replan, refresh proposals) outside of its normal schedule.
Access: [Admin]
These endpoints manage the pool of monitoring agents. Most are [Admin] only. A small number are called internally by agents themselves (marked “Agent-facing”) and are not intended for manual use.
GET /api/agentsReturns the list of all registered agents with their status, capabilities, and last-seen timestamp.
Access: [Admin]
POST /api/agents/registerRegisters a new agent with the Manager. Called automatically by the agent on first start; not a UI-facing endpoint.
Access: (Agent-facing)
GET /api/agents/list-by-providerReturns agents grouped by provider type (llama, lms, vllm). Available to all authenticated users, including operators, so the agent picker in the dashboard works regardless of role.
GET /api/agents/whoamiAllows an agent to look up its own registration record using its bearer token. Not a UI-facing endpoint.
Access: (Agent-facing)
POST /api/agents/heartbeatReceives a heartbeat from an agent, updating its last-seen timestamp and returning configuration updates (such as a new ingest URL or TLS bundle). Called automatically every 60 seconds by each agent.
Access: (Agent-facing)
POST /api/agents/<agent_id>/approveApproves a pending agent, allowing it to start pushing metrics and receive its TLS certificate bundle.
Access: [Admin]
POST /api/agents/<agent_id>/disableDisables an approved agent, stopping it from pushing data without removing its registration.
Access: [Admin]
DELETE /api/agents/<agent_id>Permanently removes an agent’s registration record.
Access: [Admin]
POST /api/agents/<agent_id>/role-primaryDesignates the specified agent as the default agent for its provider type. Dashboard requests with no ?agent= parameter will be routed here.
Access: [Admin]
POST /api/agents/<agent_id>/host-roleDesignates (or clears) the specified agent as the Manager’s own host agent — the approved agent running on the same machine as the Manager. Used so agent-derived host metrics and version pills resolve correctly even under Docker, where the Manager can’t introspect its own host directly.
Access: [Admin]
Body: {"set": true} (default) or {"set": false} to clear.
POST /api/agents/<agent_id>/collectionPauses or resumes metric collection on the specified agent without disabling or removing it.
Access: [Admin]
Body: {"enabled": true} or {"enabled": false}
POST /api/agents/<agent_id>/<provider>-poolControls whether this agent participates in the given provider’s load-balancing pool. This is not a fixed path — one route is registered per pool-enabled provider (currently llama, lms, and vllm), so the actual paths are /api/agents/<agent_id>/llama-pool, /api/agents/<agent_id>/lms-pool, and /api/agents/<agent_id>/vllm-pool.
Access: [Admin]
Body: {"in_pool": true} or {"in_pool": false}, plus an optional "position" (integer index) to place the agent at a specific slot in the pool order.
POST /api/agents/<agent_id>/cert-bundleDelivers a signed TLS certificate bundle to an approved agent. Called automatically during the approval flow; not a UI-facing endpoint.
Access: (Agent-facing)
POST /api/agents/<agent_id>/stream-tokenIssues a short-lived HMAC token that allows the browser to open an SSE stream directly to the agent. EventSource connections cannot carry custom headers, so this token is appended as a query parameter instead.
Access: Admin-gated. Issues a short-lived authentication token for SSE streams.
GET /api/agents/metricsReturns per-agent communication statistics: request counts, error rates, and latency.
Access: [Admin]
GET /api/fleet/<provider>/aggregateReturns aggregated metrics across all agents for the specified provider (llama, lms, or vllm). Used by the LLM Overall tab to show GPU utilisation, throughput, and power aggregated across every agent of that provider type.
POST /api/agents/<agent_id>/status-checkTests connectivity to the specified agent and returns a summary of whether the Manager can reach it.
Access: [Admin]
POST /api/agents/<agent_id>/restartInstructs the specified agent to restart its own process.
Access: [Admin]
GET /api/agents/<agent_id>/config-fileReads the raw YAML configuration file from the specified agent.
Access: [Admin]
PUT /api/agents/<agent_id>/config-fileWrites a new YAML configuration file to the specified agent.
Access: [Admin]
Body: The full YAML content of the config file as a JSON-wrapped string or raw text.
GET /api/agents/<agent_id>/log/tailReturns the most recent lines from the specified agent’s log.
Access: [Admin]
POST /api/agents/globalUpdates global agent settings that apply to all agents (for example, default poll interval).
Access: [Admin]
GET /api/agent-tarballDownloads the agent installation tarball. Used by the Admin tab’s self-update flow to push a new agent version.
(Agent-facing) Also used directly by the agent installer (agent/install/install.sh --update) to fetch the latest agent package; not intended for manual use.
POST /api/admin/push-ca-to-agentsPushes the current internal CA certificate to all approved agents so they can verify Manager HTTPS connections.
Access: [Admin]
GET /api/agents/<agent_id>/statusReturns detailed status for a single agent: version, uptime, capabilities, last heartbeat, TLS state, and metric buffer depth.
Access: [Admin]
GET /api/agents/<agent_id>/log/streamOpens an SSE proxy stream of the specified agent’s own process log (the agent daemon’s log, not a provider’s log). Streams bytes verbatim from the agent’s /agent/log/stream.
Access: [Admin]
POST /api/agents/<agent_id>/self-updateTriggers an in-place agent self-update: the agent runs its installer with --update --from-self-update (git pull, redeploy code, refresh its venv — no systemd unit changes) and streams stdout/stderr back over SSE. On success the agent exits and systemd’s Restart=always brings the updated code back up.
Access: [Admin]
These endpoints receive live data pushed by agents. They are not intended for manual use.
POST /api/remote/host-metricsLegacy endpoint: receives a host metrics snapshot from an agent. Superseded by /api/remote/provider-state but kept for backward compatibility with older agents.
Access: (Agent-facing)
POST /api/remote/provider-stateReceives the current provider state (llama or LMS) from an agent, including model name, slots, throughput, and server state. This is the current primary path for live dashboard updates.
Access: (Agent-facing)
POST /api/remote/lmstudioReceives the LM Studio dashboard payload (model list, server status, active model metrics) from the LM Studio agent.
Access: (Agent-facing)
GET /api/remote/host-metrics/lastReturns the most recently received host metrics snapshot for the queried agent. Useful for scripts that want the latest values without subscribing to a stream.
Parameters: ?agent=<agent_id>
These endpoints provide browser-based terminal access. Each session is isolated and must be explicitly closed when no longer needed.
POST /api/terminal/createOpens a new PTY (pseudo-terminal) shell session on the Manager host. Returns a session ID used by all other terminal endpoints.
POST /api/lms/terminal/createOpens an SSH shell session to the LM Studio host. Returns a session ID.
GET /api/terminal/output/<sid>Opens an SSE stream delivering terminal output for the session. Each event contains a chunk of terminal bytes (may include ANSI escape sequences).
POST /api/terminal/input/<sid>Sends keystrokes to the terminal session.
Body: {"data": "<characters to send>"}
POST /api/terminal/resize/<sid>Resizes the terminal window, signalling the running process to reflow output.
Body: {"rows": <int>, "cols": <int>}
POST /api/terminal/close/<sid>Closes the terminal session and cleans up the PTY process.
GET /api/openclaw/analyticsReturns Claude Code session analytics derived from the session log files on the Manager host: token usage, cost trends, tool attribution, daily cost history, velocity metrics, and anomaly detection. Results are cached for a short period to avoid re-parsing all session files on every request.
GET /api/layoutReturns the saved dashboard layout: card order, hidden cards, LMS card order, Overall tab card order, borrowed cards, and the active theme name.
POST /api/layoutSaves the current dashboard layout. The frontend calls this automatically whenever the user drags a card, hides a card, or changes the theme.
Body: A layout JSON object with order, hidden, lmsOrder, overallOrder, overallBorrowed, and theme fields.
These endpoints require an admin-role session.
GET /api/admin/system-healthReturns a rolled-up health summary of the whole system: agent connectivity, service availability, TLS certificate expiry, InfluxDB status, and recent error counts. Powers the red/green Admin tab indicator dot.
Access: [Admin]
GET /api/admin/audit-logReturns paginated entries from the admin action audit log (who did what, from where, and the outcome).
Access: [Admin]
Parameters: ?limit=<n> (default 100, max 500), ?offset=<n> (default 0)
Response: {"ok": true, "total": <count>, "entries": [{"ts", "actor", "role", "ip", "method", "path", "action", "target", "status", "outcome"}, ...]}
GET /api/admin/stream-statsReturns live SSE-stream and connection health for the Admin tab: Manager stream pool active/peak/refusal counts, Cheroot worker-thread and backlog stats, browser/agent connection counts, and per-agent /status stream state.
Access: [Admin]
GET /api/admin/backup-statusReturns the scheduled-backup configuration (enabled, interval, retention) and the list of backups currently on disk (file, bytes, mtime per entry).
Access: [Admin]
POST /api/admin/service/<svc>/restartRestarts the Manager or the (co-located) Alarm Engine service. On bare-metal installs this uses a sudoers NOPASSWD systemctl restart grant; under containers and Homebrew kegs it restarts by exiting the process so the supervisor respawns it — exit 0 in a container, exit 1 under a brew keg, whose units are Restart=on-failure. A co-located Alarm Engine restarts through its own management API rather than a process exit. Restarting the Alarm Engine this way only works when it runs on the same host as the Manager.
Access: [Admin]
Path parameter: <svc> is manager or alarm_engine.
GET /api/admin/authReturns the current authentication mode (required, trusted_cidr, disabled, or auto) and whether the default credential is still active.
Access: [Admin]
POST /api/admin/authUpdates the authentication mode. When the mode is set in the TOML configuration file (rather than auto), this call returns a restart_required flag and the systemctl restart command to apply the change.
Access: [Admin]
Body: {"mode": "required"} (or trusted_cidr / disabled)
GET /api/admin/usersReturns the list of all user accounts with their role, enabled/disabled status, and lockout state.
Access: [Admin]
POST /api/admin/usersCreates a new user account.
Access: [Admin]
Body: {"username": "<name>", "password": "<initial password>", "role": "admin" | "operator"}
PATCH /api/admin/users/<username>Updates a user’s role or enabled/disabled status.
Access: [Admin]
Body: Any combination of {"role": "admin" | "operator", "disabled": true | false}
DELETE /api/admin/users/<username>Deletes a user account. The system prevents deleting the last enabled admin account or your own account.
Access: [Admin]
POST /api/admin/users/<username>/unlockClears a lockout on a user account that was locked after too many failed login attempts.
Access: [Admin]
GET /api/admin/<provider>-modelsReturns the model registry for the given provider’s agents: fans out to every pool member (or, if the pool is empty, every approved agent advertising that provider’s capability) and returns which models each agent reports, plus any per-agent errors from the fan-out. This is not a fixed path — one route is registered per pool-enabled provider (currently llama, lms, and vllm): /api/admin/llama-models, /api/admin/lms-models, /api/admin/vllm-models.
Access: [Admin]
Response: {"ok": true, "models": [{"id": "<model_id>", "agents": ["<hostname>", ...]}, ...], "errors": [{"agent": "<hostname>", "error": "<status or message>"}, ...]}
POST /api/admin/<provider>-pinsPins a specific model to a specific agent so that requests for that model are always routed to that agent regardless of the default selection. Registered per provider that declares a pin dict — currently /api/admin/llama-pins, /api/admin/lms-pins, and /api/admin/vllm-pins.
Access: [Admin]
Body: {"model_id": "<id>", "agent_id": "<id>"} — omit or leave agent_id blank to clear the pin.
POST /api/admin/export/managerExports an encrypted backup of the Manager configuration, including agent registry, model profiles, and authentication settings. Returns a downloadable archive file.
Access: [Admin]
POST /api/admin/import/manager/previewValidates an encrypted config backup archive and returns a summary of what it contains and what would change if applied. Does not modify anything.
Access: [Admin]
Body: The encrypted archive file as a multipart upload.
POST /api/admin/import/manager/applyApplies a previously previewed config backup. Overwrites the current configuration with the archive contents.
Access: [Admin]
Body: The encrypted archive file as a multipart upload.
These endpoints are available to any logged-in user regardless of role.
GET /api/meReturns the current user’s username and role. Used by the frontend to decide which UI elements to show (for example, whether to display the Admin tab).
POST /api/account/passwordChanges the current user’s own password. Requires the existing password to be provided.
Body: {"current_password": "<current>", "new_password": "<new>"}
Model profiles let you save named sets of llama.cpp server configuration values (context size, GPU layers, etc.) per model and switch between them quickly.
GET /api/llm/profilesReturns all saved profiles for all models, keyed by agent and model ID.
POST /api/llm/profiles/<model>/saveSaves the current server configuration as a named profile for the specified model.
Body: {"profile_name": "<name>"}
POST /api/llm/profiles/<model>/activateActivates a saved profile, writing its configuration values to the server’s config file.
Body: {"profile_name": "<name>"}
POST /api/llm/profiles/<model>/renameRenames a saved profile.
Body: {"old_name": "<current name>", "new_name": "<new name>"}
DELETE /api/llm/profiles/<model>/deleteDeletes a saved profile for the specified model.
Body: {"profile_name": "<name>"}
GET /loginServes the login page. If authentication is disabled or the request comes from a trusted network (when the mode is trusted_cidr), this redirects to the dashboard instead.
POST /loginSubmits login credentials. On success, sets the session cookie and redirects to the dashboard. On failure, returns the login page with an error.
Body: {"username": "<name>", "password": "<password>"} (form-encoded)
GET /logoutClears the session cookie and redirects to the login page. If authentication is disabled or not required for the current request, redirects to the dashboard instead.
The Manager transparently proxies several external services, adding authentication and routing without exposing those services directly.
/proxy/llmchat/*Proxies requests to the llama.cpp built-in chat UI. Content-Security-Policy headers are stripped so the chat UI loads correctly through the proxy.
/proxy/openclaw/*Proxies requests to the local OpenClaw service. Only accessible when an OpenClaw process is running on the Manager host.
/proxy/imggen/* and /sdcpp/*Proxies requests to the stable-diffusion.cpp image generation server on the LM Studio host. Both prefixes map to the same upstream.
/api/alarm/*Proxies all Alarm Engine API calls. Every endpoint in the Alarm Engine sections below is reached through this prefix. For example, GET /api/alarm/alerts reaches the Alarm Engine’s alert listing endpoint.
/alarm/*Serves the Alarm Engine’s single-page application (SPA). Navigating to /alarm/ in a browser opens the dedicated Alarm Engine UI.
GET /ws/alarmUpgrades to a WebSocket connection and bridges to the Alarm Engine’s live alert event stream. The Manager runs a dedicated WebSocket proxy on a separate port so the browser does not need to trust the internal CA certificate. Events include alert_created, alert_updated, alert_acknowledged, and alert_resolved.
All Alarm Engine endpoints are accessed through the /api/alarm/ proxy prefix described above.
GET /api/alarm/alertsReturns a list of alerts. By default only active and acknowledged alerts are returned; pass include_closed=true to also include closed ones.
Parameters:
?status= — filter by status (active, acknowledged, closed, ignored)?severity= — filter by severity (critical, warning, info)?rule_id= — filter to alerts raised by a specific rule?metric_name= — filter to alerts for a specific metric?only_active=true — return only active/unresolved alerts?include_closed=true — include closed alerts in the result set?limit= — maximum number of results (default 100, max 1000)GET /api/alarm/alerts/activeReturns only currently active (firing, unacknowledged) alerts.
GET /api/alarm/alerts/countersReturns alert counts broken down by status and severity. Used by the dashboard badge and Events tab indicator.
GET /api/alarm/alerts/exportDownloads all alerts as a JSON file, useful for audit or analysis.
GET /api/alarm/alerts/<alert_id>Returns full detail for a single alert, including its history of state changes.
POST /api/alarm/alerts/<alert_id>/readMarks an alert as read (seen) without changing its status.
POST /api/alarm/alerts/<alert_id>/acknowledgeAcknowledges a firing alert, indicating that an operator is aware of it. The alert remains in the system until it resolves or is closed.
POST /api/alarm/alerts/<alert_id>/closeCloses a resolved alert, removing it from the active view. Only resolved alerts can be closed.
POST /api/alarm/alerts/<alert_id>/ignoreIgnores an alert, suppressing future notifications for it.
DELETE /api/alarm/alerts/<alert_id>Permanently deletes an alert record.
POST /api/alarm/alerts/close-allCloses all alerts that are currently in the resolved state.
POST /api/alarm/alerts/bulkPerforms an action on multiple alerts in one call.
Body: {"action": "acknowledge" | "close" | "ignore", "alert_ids": ["<id>", ...]}
POST /api/alarm/alerts/ignore-allIgnores all currently firing alerts.
GET /api/alarm/rulesReturns all configured alarm rules with their thresholds, severity levels, and enabled/disabled status.
POST /api/alarm/rulesCreates a new alarm rule.
Body:
{
"name": "GPU temperature too high",
"description": "Optional explanation",
"metric_source": "gpu",
"metric_name": "temperature_celsius",
"rule_type": "threshold_above",
"config": {
"threshold": {
"value": 85.0,
"warning": 80.0,
"critical": 90.0
}
},
"severity": "warning",
"enabled": true,
"notification_channel_ids": [],
"auto_resolve_cycles": 2
}
metric_source: gpu, cpu, ram, disk, network, psurule_type: threshold_above (alert when value exceeds threshold), threshold_below (alert when value falls below), threshold_range (alert outside a range)severity: info, warning, criticalauto_resolve_cycles: number of consecutive OK evaluations before auto-closing the alert (0 = never auto-close)GET /api/alarm/rules/<rule_id>Returns the full definition of a single rule.
PUT /api/alarm/rules/<rule_id>Updates an existing rule’s definition.
Body: The same shape as the create body; all fields are replaced.
DELETE /api/alarm/rulesDeletes all alarm rules. Use with caution — this cannot be undone.
DELETE /api/alarm/rules/<rule_id>Deletes a single alarm rule.
PATCH /api/alarm/rules/<rule_id>/toggleToggles a rule between enabled and disabled without deleting it. Disabled rules are not evaluated against incoming metrics.
GET /api/alarm/notifications/channelsReturns all configured notification channels (email, webhook, Discord).
POST /api/alarm/notifications/channelsCreates a new notification channel.
Body — email channel:
{
"name": "My Email Channel",
"channel_type": "email",
"config": {
"email": {
"to_email": "alerts@example.com",
"subject_prefix": "[ALARM]"
}
},
"enabled": true
}
Body — webhook channel:
{
"name": "My Webhook",
"channel_type": "webhook",
"config": {
"webhook": {
"url": "https://your-endpoint.example.com/hook",
"method": "POST",
"headers": {}
}
}
}
Body — Discord channel:
{
"name": "Discord Alerts",
"channel_type": "discord",
"config": {
"discord": {
"webhook_url": "https://discord.com/api/webhooks/..."
}
}
}
GET /api/alarm/notifications/channels/<channel_id>Returns the configuration for a single notification channel.
PUT /api/alarm/notifications/channels/<channel_id>Updates a notification channel’s configuration.
Body: The same shape as the create body.
DELETE /api/alarm/notifications/channels/<channel_id>Deletes a notification channel.
GET /api/alarm/notifications/configsReturns all notification policies — the rules that determine which channels receive which alerts at what severity.
POST /api/alarm/notifications/configsCreates a new notification policy.
Body: A policy object specifying which severity levels and rule tags trigger delivery to which channel.
GET /api/alarm/notifications/configs/<config_id>Returns a single notification policy.
PUT /api/alarm/notifications/configs/<config_id>Updates a notification policy.
Body: The same shape as the create body.
DELETE /api/alarm/notifications/configs/<config_id>Deletes a notification policy.
GET /api/alarm/notifications/delivery-historyReturns the delivery log: a record of every notification attempt with its outcome (sent, failed, retrying) and timestamp.
POST /api/alarm/notifications/sendSends a notification immediately, bypassing policy evaluation. Useful for testing or manual escalation. Target either a saved policy (config_id) or a single channel (channel_id).
Body:
{
"title": "Disk almost full",
"body": "The data volume is at 95% capacity.",
"severity": "warning",
"config_id": "<policy-id>",
"channel_id": "<channel-id>",
"metadata": {}
}
title and body are requiredconfig_id (a notification policy) or channel_id (a single channel)severity and metadata are optionalPOST /api/alarm/notifications/testSends a test message through a channel to verify it is configured correctly.
Body: {"channel_id": "<id>"}
GET /api/alarm/metricsQueries the time-series metric store. Returns data points for dashboard history and analysis.
Query parameters:
source — (optional) filter to a specific metric source (e.g. gpu, cpu, ram, disk, network, psu)hostname — (optional) filter to a specific hostlimit — (optional, default 1000) maximum number of results to returnPOST /api/alarm/metricsIngests a single metric data point.
Access: Requires the ingest bearer token when one is configured.
Body: A single MetricPoint object with source, metric_name, value, timestamp, and tags.
POST /api/alarm/metrics/batchIngests a batch of metric data points in one call. This is the primary path used by agents — batching reduces per-request overhead.
Access: Requires the ingest bearer token when one is configured.
Body: {"points": [<MetricPoint>, ...]}
POST /api/alarm/metrics/ingestAlternative single-point ingest path provided for compatibility with certain forwarding setups.
Access: Requires the ingest bearer token when one is configured.
Body: A single MetricPoint object.
GET /api/alarm/metrics/exportDownloads all stored metrics as a file, useful for backup or external analysis.
GET /api/alarm/metrics/<source>/<metric_name>Returns the time-series history for a specific metric from a specific source host. Used by dashboard chart backfill.
Query parameters:
since_minutes — how far back to look, in minutes (default: 60)limit — maximum number of data points to return (default: 100 000)hostname — (optional) filter to a specific hostGET /api/alarm/metrics/<source>/<metric_name>/summaryReturns summary statistics for a specific metric (min, max, mean, p95) over a query window without returning the full point-by-point history.
Query parameters:
window_minutes — time window in minutes to summarize over (default: 60)POST /api/alarm/ingestReceives an alert from an outside system and routes it into the alarm engine. The endpoint auto-detects the payload format — InfluxDB notification rules, Grafana alerting webhooks, or a generic JSON/YAML body — and maps it onto an internal alert. Useful for forwarding alerts from tools you already run into this dashboard’s Events view.
Access: Requires the ingest bearer token when one is configured.
These endpoints accept telemetry from external pipelines that speak the OpenTelemetry protocol. They are served by the Alarm Engine directly (not under the /api/alarm/ proxy prefix) and require the ingest bearer token when one is configured. Each payload is converted into metric points and stored alongside the agents’ own metrics.
POST /v1/metricsIngests OpenTelemetry metrics (counters, gauges, histograms).
POST /v1/tracesIngests OpenTelemetry trace spans. Each span is recorded as a duration metric.
POST /v1/logsIngests OpenTelemetry log records. Each record is recorded as a log-count metric.