HTTP API
API overview#
The dashboard is a Flask app, and every page it renders is backed by an endpoint you can call directly.
Four surfaces#
The query API (/api/local/*) is the read path into the store. It is a
declared contract with fixed shapes, arguments and limits, and it is the one to
build on. → Query API
Feature APIs (/api/<feature>) back the dashboard pages — usage, guard,
alerts, crons, channels, health, skills and the rest. They return
presentation-shaped data, and they are the fastest way to get the same answer a
page shows. → Endpoint index
Ingest surfaces accept data:
| Path | Accepts |
|---|---|
/api/v1/runs, /api/v1/runs/<id>/events | Custom runtime ingest |
/v1/traces, /v1/metrics, /v1/logs | OTLP |
/ingest/* | Self-hosted node push |
Control endpoints signal processes. Origin-checked, deliberately narrow. → Pause, stop, kill
Conventions#
Read endpoints are GET; several are POST because they take a filter body
rather than a query string. The index lists the method for
each.
Responses are JSON. Query-API shapes return {"rows": [...]}; feature
endpoints return a shape suited to their page.
Failures degrade rather than raise. A handler that cannot answer returns an
empty result with HTTP 200 rather than a 500, so a dashboard card renders as
empty instead of broken. That is deliberate, and it means an empty response is
not proof of an empty store — check clawmetry status before concluding
nothing happened.
Limits are clamped, not rejected. Asking for a million rows returns the maximum.
Authentication#
Loopback with no token by default. Set CLAWMETRY_API_TOKENS to require one.
→ Authentication
Stability#
The /api/local/* query surface is a versioned contract (q/1): additive
evolution only, and a rename or removal requires a version bump. Build on it.
The feature APIs back UI pages and can change with the UI. Use them for convenience; do not build a long-lived integration on one.
Streams#
Three endpoints are Server-Sent Events:
| Endpoint | Streams |
|---|---|
/api/brain-stream | Live agent activity |
/api/health-stream | Health updates |
/api/logs | The log stream |
curl -N localhost:8900/api/brain-streamConcurrent clients are capped (--max-log-stream-clients,
--max-health-stream-clients, default 10 each), and a reverse proxy in front
must disable buffering or you will see nothing.
Health#
curl -s localhost:8900/healthz
curl -s localhost:8900/api/local/health | jq
curl -s localhost:8900/api/version -X POST -d '{}' -H 'content-type: application/json' | jqGetting started#
# the five most recent sessions
curl -s 'localhost:8900/api/local/sessions?limit=5' | jq '.rows'
# what shapes exist
curl -s localhost:8900/api/local/query -X POST \
-H 'content-type: application/json' -d '{"shape":"?"}' | jq '.allowed_shapes'