REST API¶
The API listens on port 8080 of the operator pod (exposed by the kimo Service in a Helm install). All endpoints except /api/v1/health require authentication, which is handled by the active scoring backend — for the generic backend that means Authorization: Bearer <apiKey>.
All CRs live in the default namespace in the current release.
Health¶
GET /api/v1/health
Unauthenticated. Returns {"status": "ok"}.
Templates¶
GET /api/v1/templates
GET /api/v1/templates/{name}
List and fetch ChallengeTemplate objects — what a platform uses to render its challenge list. 404 if the named template doesn't exist.
Instances¶
Create an instance¶
POST /api/v1/instances
{
"template": "demo-web",
"team": "team-alpha",
"player": "alice",
"powChallenge": "a1b2...",
"powNonce": 1048113
}
templateandteamare required;playeris required in spirit forperPlayertemplates (it becomes part of the instance name).powChallenge/powNonceare required only when the template has PoW enabled — see Proof of work.- Instance names are deterministic:
<template>-<team>[-<player>], which makes a second create for the same team a409instead of a duplicate pod.
Responses: 201 with the created instance · 400 missing fields · 404 unknown template · 409 template not ready or instance already exists · 428 PoW required/invalid · 429 template's maxInstances reached.
List / get / delete¶
GET /api/v1/instances?team=<team>&challenge=<template>
GET /api/v1/instances/{name}
DELETE /api/v1/instances/{name}
List supports filtering by team and challenge labels. Delete removes the instance and everything it owns (pod, service, network policy) and emits an instance.deleted event to the backend; returns 204.
The interesting field on a fetched instance is status:
{
"phase": "Running",
"endpoint": "demo-web-team-alpha.default.svc:8080",
"startedAt": "2026-08-23T15:24:31Z",
"expiresAt": "2026-08-23T16:24:31Z"
}
Extend an instance¶
PATCH /api/v1/instances/{name}/extend
{"ttl": "2h"}
Sets the instance's TTL override. The TTL is measured from startedAt, not from now — extending to 2h means the instance lives two hours total. Takes effect within one reconcile; an instance already in Expiring recovers to Running if the new expiry is in the future. 400 for an unparsable duration, 404 for an unknown instance.
Proof of work¶
GET /api/v1/pow/challenge?template=<name>
Returns a single-use puzzle for a PoW-enabled template:
{"challenge": "a1b2c3...", "difficulty": 20, "expiresAt": "2026-08-23T15:30:00Z"}
Webhooks¶
POST /api/v1/webhooks/configure
{"url": "https://scoreboard.example.com/events", "secret": "hmac-secret"}
Registers a webhook for lifecycle events (generic backend only — backends that don't support runtime webhook registration return an error). Events are signed with X-KIMO-Signature (hex HMAC-SHA256 of the request body using secret).