Engineering Runtime API

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.