API reference
Every route this service exposes, grouped by what it does.
The authoritative machine-readable version of this page is
/openapi.yaml. To call anything here from the browser, use
the explorer.
{prefix} below is either /api/public or /api/v1. Routes shown with
{prefix} exist on both and use the same handler; only the middleware in
front differs.
Policy
The Control Plane stores versioned policy documents. Runtimes fetch the active one and evaluate locally.
| Method | Path | Notes |
|---|---|---|
GET |
{prefix}/policies |
Full list plus the active version |
GET |
{prefix}/policies?active=true |
The single active document — what runtimes call |
GET |
{prefix}/policies/{version} |
One version by name, e.g. v12 |
POST |
{prefix}/policies |
Publish a new version and make it active |
POST requires yaml in the body; version, name, description, and
updated_by are optional. An omitted version is generated from the UTC
timestamp. The YAML is validated before it is stored — invalid policy is
rejected with 400 rather than shipped to runtimes.
Versions are immutable. Re-publishing an existing version returns 409.
Audit records reference the policy version that decided them, so a version that
could be edited would make historical decisions unexplainable. Publishing
deactivates the previous version in the same transaction, so there is always
exactly one active policy per organisation.
Audit
| Method | Path | Notes |
|---|---|---|
POST |
{prefix}/audit |
Ingest one event, or {"events":[…]} for a batch |
GET |
{prefix}/audit |
Query stored events |
Query parameters on GET: q (substring across command, executor, resource,
provider, capability), decision, provider, consumer, limit (default
100, max 1000), offset. The response carries events, total, returned,
limit, and offset — page with offset, and trust total for the count.
The runtime writes its own local audit record first and treats this endpoint as a best-effort mirror. A failed uplink loses nothing that matters: the local record is the system of record.
Catalog
Providers and capabilities are generated from the engineering-runtime
repository at deploy time and embedded in the image. This API never executes
the runtime binary, and never calls GitHub to answer a request.
| Method | Path | Notes |
|---|---|---|
GET |
{prefix}/providers |
Catalog rows with live status merged in |
GET |
{prefix}/provider-names |
Catalog names ∪ providers seen in audit — for filter dropdowns |
GET |
{prefix}/capabilities |
Filter with provider and q |
These are the tenant view. They need an organisation and read the database
to merge status and history. For what the runtime supports — no auth, no
tenant, with the runtime commit it was built from — use the contract view on
/metadata/providers and
/metadata/capabilities. The
Catalog page explains which to pick.
Provider status is not stored in the catalog: it is derived per request. A
provider seen in audit within the last 24 hours reads connected, otherwise
offline, unless a stored row overrides it. last_used comes from the most
recent audit event naming that provider.
Fleet
| Method | Path | Notes |
|---|---|---|
GET |
{prefix}/fleet |
Known runtimes, most recently seen first |
POST |
{prefix}/fleet/heartbeat |
Upsert presence — name required |
POST |
{prefix}/runtime/register |
Optional first-contact registration |
POST |
{prefix}/runtime/heartbeat |
Alias of fleet/heartbeat |
Fleet status is derived from last_seen at read time: online within 15
minutes, idle within 24 hours, offline after that. Nothing marks a runtime
offline on a schedule — a runtime that stops reporting simply ages out, which
is the correct answer when the network, not the runtime, is what failed.
Dashboard
| Method | Path | Notes |
|---|---|---|
GET |
{prefix}/dashboard |
Summary cards for the UIs |
Returns fleet counts, catalog counts, active policy version, 24-hour command totals split by decision, AI-attributed operations, a per-provider breakdown, and the ten most recent audit events.
Auth and management (/api/v1 only)
These have no /api/public equivalent — the public surface has no accounts.
| Method | Path | Notes |
|---|---|---|
POST |
/api/v1/auth/login |
{email, password} → JWT and user |
GET |
/api/v1/auth/me |
Current user for a bearer token |
GET |
/api/v1/organizations |
All organisations |
GET |
/api/v1/users |
Users in the caller's organisation |
GET |
/api/v1/api-keys |
Keys — hashes are never returned |
POST |
/api/v1/api-keys |
Create a key; plaintext shown once |
DELETE |
/api/v1/api-keys/{id} |
Revoke immediately |
GET |
/api/v1/settings |
Organisation settings and edition flags |
See Authentication for how credentials are checked.
Health and version
| Method | Path | Notes |
|---|---|---|
GET |
/health |
Unprefixed — what uptime checks should poll |
GET |
{prefix}/health |
Same payload under either API prefix |
GET |
/version |
Build, commit, Go version, uptime |
Portal and contracts
| Method | Path | Notes |
|---|---|---|
GET |
/ |
This site for browsers, /metadata for API clients |
GET |
/getting-started, /authentication, /reference, /examples |
Documentation pages |
GET |
/swagger |
Interactive explorer |
GET |
/openapi.yaml |
Canonical contract |
GET |
/openapi.json |
Same contract as JSON, with this host in servers |
GET |
/metadata |
Service metadata index |
GET |
/metadata/apis |
Every documented operation, flattened |
GET |
/metadata/versions |
Build and surface versions |
GET |
/metadata/authentication |
What this deployment enforces right now |
GET |
/metadata/catalog |
Contract envelope — version, runtime provenance, counts |
GET |
/metadata/providers |
Provider inventory (contract view — no auth, no tenant) |
GET |
/metadata/capabilities |
Capability inventory; provider and q filters |
Errors
Errors are JSON with an error string.
| Status | Means |
|---|---|
400 |
Malformed body, or a required field is missing |
401 |
Credentials required or rejected |
404 |
No such record, or no active policy |
409 |
Policy version already exists — versions are immutable |
500 |
Server or database failure |
POST /audit answers 202 Accepted, not 200: the event is stored, and the
runtime's local record was already the authoritative one.