GETTING STARTED
Connecting to this API
Who calls this API, how a Runtime registers, and how to point it at your own app-api origin.
Who calls this API
There is no anonymous or public tier. Every request past /health, /ready and /api/v1/auth/login authenticates with one of exactly two credential kinds:
- Enterprise portal sessions — a person signed in through
app-ui, carrying a short-lived bearer JWT. See Authentication. - Registered Runtimes — a Runtime binary that has completed registration, carrying a scoped
X-API-Key. This is what the rest of this page walks through.
Both kinds authenticate on every request. There is no configuration flag that disables this, and no unauthenticated tier to fall back to.
Register a Runtime
Registration exchanges a one-time registration key (issued by an administrator in the Enterprise portal) for a bound Runtime identity and the organization's current signed governance bundle.
POST /api/v1/runtime/register
X-API-Key: erk_rt_v1_<lookup>_<secret>
Content-Type: application/json
{
"installation_id": "<stable local install identifier>",
"name": "<runtime display name>",
"version": "<runtime version>",
"hostname": "<hostname>",
"os": "<os>",
"nonce": "<32 random bytes, base64url, unpadded>"
}
A fresh 32-byte random nonce is required on every registration attempt — it is bound into the signed receipt below and is how the response proves it was produced for *this* request, not replayed from another one. The registration key itself must already carry the runtime:register scope; see Authentication for the full key-lifecycle rules.
A successful response returns the bound Runtime identity, the organization's active signed governance generation, and a separate signed receipt:
{
"runtime_id": "...",
"name": "...",
"status": "registered",
"bundle": { "envelope": { ... }, "policy": "...", "config": "...", "public_key": "..." },
"receipt": {
"domain": "engineeringruntime.registration-receipt/v1",
"nonce": "...",
"origin": "https://<this app-api host>",
"organization": "...",
"runtime_id": "...",
"installation_id": "...",
"key_id": "sha256:...",
"issued_at": "...",
"signature_alg": "Ed25519",
"signature": "..."
}
}
The receipt is signed independently of the governance bundle — it exists so a Runtime can prove *when* and *from where* it registered without re-parsing the bundle envelope.
Read the active governance bundle
Once registered, a Runtime polls for the current signed policy and configuration generation with a conditional request:
GET /api/v1/sync-bundles/active
X-API-Key: erk_rt_v1_<lookup>_<secret>
If-None-Match: "<epoch>.<revision>-<compositeDigest>"
If nothing has changed since the ETag you last saw, the response is 304 Not Modified with no body. If policy or configuration has been republished, you get 200 with a fresh signed bundle and a new ETag. There is no separate "poll and diff" endpoint — the ETag/If-None-Match pair *is* the change-detection mechanism, and it is cheap to call on every heartbeat cycle.
Point a Runtime at your own app-api origin
This site is a static, read-only reference. It is not the app-api origin your Runtime talks to. Every organization runs its own separately provisioned, independently authenticated app-api deployment; configure your Runtime with that origin's own URL, never this site's own hostname.
Where to go next
- Authentication — exact credential shapes, scopes, rate limits, key lifecycle, and error semantics.
- Examples — copyable request/response pairs for every operation on this page and beyond.
- Concepts — what providers, capabilities, fleet status, policy and configuration actually mean, plus versioning guidance.