Skip to main content

kairon-ui API reference

Every route kairon-ui serves, generated from the router in internal/uiapi/server.go. The dashboard and kaironctl (for the UI-backed commands) are clients of this API; it adds no privileged side channel over the Kubernetes API.

Transport​

Every route below is served over HTTPS by default, on the dashboard's port (18082 unless configured). With no certificate configured the server generates a self-signed one, so a client either trusts it (curl --cacert cert.pem, KAIRON_UI_CA for kaironctl) or is given a real certificate (ui.tls.secretName). Plain HTTP exists only as the explicit -insecure-http opt-out; see HTTPS. The examples in this guide omit the scheme and host for that reason.

Access model​

AccessMeaning
noneReachable without a token: probes, /metrics, the login and OIDC routes, and the image blob route.
console ticketThe VNC console WebSocket cannot send an Authorization header, so it is gated by a single-use ticket issued by an authenticated call.
sessionNeeds a valid session token (Authorization: Bearer ...).
namespaceNeeds a session and passes the namespace check below.
  • Roles. An account whose role is viewer is limited to GET/HEAD (plus the auth routes). Other roles are operator and the administrator identity.
  • Namespace scoping is opt-in. When it is on, a session without a user name is refused, namespace routes only see the namespaces granted to the user (ui.auth.users[].namespaces, or OIDC group mappings), and /api/v1/nodes* needs administrator access. GET /api/v1/namespaces returns the namespaces the caller may use.
  • Image blobs are unauthenticated by design. GET /images/sha256/{digest} is how kairon-node downloads an uploaded image: it has no UI credentials and verifies the bytes against spec.image.digest. Anyone who can reach kairon-ui and knows a digest can download that image. Image upload and delete (PUT/DELETE /api/v1/images/{name}) need an administrator session; listing (GET /api/v1/images) needs only a session. See machine-image-import.md.
  • Non-GET calls to /api/v1/* are logged by the server (method, path, remote address, status and, for session tokens, the user) when a logger is configured. This is request logging, not the hash-chained MCP audit log.

Probes, metrics and image blobs​

MethodPathAccess
GET/healthznone
GET/images/sha256/{digest}none
GET/metricsnone
GET/readyznone

agent​

Read-only agent-plane routes (see agent plane). The bodies are proposals or facts; nothing is applied to the cluster.

MethodPathAccess
POST/api/v1/agent/anomaliessession
POST/api/v1/agent/asksession
POST/api/v1/agent/claims/stepsession
POST/api/v1/agent/compile-policysession
POST/api/v1/agent/confidentialsession
POST/api/v1/agent/cpu-labelsession
GET/api/v1/agent/diagnose/{namespace}/{kind}/{name}namespace
POST/api/v1/agent/explain-dropssession
POST/api/v1/agent/gatewaysession

atlas​

MethodPathAccess
GET/api/v1/atlas/{path...}session

An allowlisted, read-only proxy to the Atlas gateway for the dashboard Storage page. Returns 501 unless ui.atlas.url is set, and 403 for non-administrators when namespace scoping is on (Atlas data spans tenants). Only an allowlisted set of read paths is proxied (anything else is 404); the Atlas token never reaches the browser. See Atlas storage.

auth​

MethodPathAccess
GET/api/v1/auth/confignone
POST/api/v1/auth/loginnone
POST/api/v1/auth/logoutnone
GET/api/v1/auth/oidc/callbacknone
GET/api/v1/auth/oidc/loginnone
POST/api/v1/auth/passwordsession

POST /api/v1/auth/login returns {token, username, isAdmin, expiresAt}, plus "defaultPassword": true when the submitted password is the well-known lab password Admin@321 and the server was started with KAIRON_UI_DEFAULT_ADMIN_PASSWORD set to exactly that value; the dashboard uses it to show a change-your-password banner. It never blocks the login. GET /api/v1/auth/config may include loginHint (only when at least one named user exists).

config​

MethodPathAccess
GET/api/v1/configsession

disruption-budgets​

MethodPathAccess
GET/api/v1/disruption-budgetsnamespace

fleet​

MethodPathAccess
GET/api/v1/fleet/{resource}namespace
POST/api/v1/fleet/{resource}namespace
DELETE/api/v1/fleet/{resource}/{namespace}/{name}namespace

images​

MethodPathAccess
GET/api/v1/imagessession
DELETE/api/v1/images/{name}session
PUT/api/v1/images/{name}session

instancetypes​

MethodPathAccess
GET/api/v1/instancetypesnamespace

machines​

MethodPathAccess
GET/api/v1/machinesnamespace
POST/api/v1/machinesnamespace
DELETE/api/v1/machines/{namespace}/{name}namespace
GET/api/v1/machines/{namespace}/{name}namespace
POST/api/v1/machines/{namespace}/{name}/agent-execnamespace
POST/api/v1/machines/{namespace}/{name}/diagnosticsnamespace, admin
GET/api/v1/machines/{namespace}/{name}/diagnostics/{token}namespace, admin
GET/api/v1/machines/{namespace}/{name}/diagnostics/{token}/{file}namespace, admin
POST/api/v1/machines/{namespace}/{name}/agent-file/getnamespace
POST/api/v1/machines/{namespace}/{name}/agent-file/putnamespace
GET/api/v1/machines/{namespace}/{name}/consoleconsole ticket
POST/api/v1/machines/{namespace}/{name}/console/ticketnamespace
GET/api/v1/machines/{namespace}/{name}/cpusetnamespace
POST/api/v1/machines/{namespace}/{name}/execnamespace
POST/api/v1/machines/{namespace}/{name}/freezenamespace
GET/api/v1/machines/{namespace}/{name}/frozennamespace
POST/api/v1/machines/{namespace}/{name}/haltnamespace
GET/api/v1/machines/{namespace}/{name}/logsnamespace
GET/api/v1/machines/{namespace}/{name}/network-capturenamespace
POST/api/v1/machines/{namespace}/{name}/network-capturenamespace
GET/api/v1/machines/{namespace}/{name}/network-capture/{token}namespace
GET/api/v1/machines/{namespace}/{name}/network-drop-reasonsnamespace
GET/api/v1/machines/{namespace}/{name}/timelinenamespace
GET/api/v1/machines/{namespace}/{name}/metricsnamespace
POST/api/v1/machines/{namespace}/{name}/forknamespace
POST/api/v1/machines/{namespace}/{name}/backupsnamespace
POST/api/v1/machines/{namespace}/{name}/disksnamespace
POST/api/v1/machines/{namespace}/{name}/nicsnamespace
GET/api/v1/machines/{namespace}/{name}/network-dropsnamespace
GET/api/v1/machines/{namespace}/{name}/network-effectivenamespace
GET/api/v1/machines/{namespace}/{name}/network-flowsnamespace
GET/api/v1/machines/{namespace}/{name}/network-statsnamespace
POST/api/v1/machines/{namespace}/{name}/pausenamespace
GET/api/v1/machines/{namespace}/{name}/pressurenamespace
POST/api/v1/machines/{namespace}/{name}/prioritynamespace
POST/api/v1/machines/{namespace}/{name}/qga/firewall/closenamespace
POST/api/v1/machines/{namespace}/{name}/qga/firewall/opennamespace
GET/api/v1/machines/{namespace}/{name}/qga/fsfreeze-statusnamespace
POST/api/v1/machines/{namespace}/{name}/resumenamespace
ANY/api/v1/machines/{namespace}/{name}/sandbox-http/{port}/{rest...}namespace
POST/api/v1/machines/{namespace}/{name}/startnamespace
POST/api/v1/machines/{namespace}/{name}/stopnamespace
POST/api/v1/machines/{namespace}/{name}/thawnamespace
POST/api/v1/machines/{namespace}/{name}/vm-restore-snapshotnamespace
POST/api/v1/machines/{namespace}/{name}/vm-snapshotnamespace

GET /api/v1/machines, GET /api/v1/migrations and GET /api/v1/snapshots also accept ?namespace=_all: every object of that kind in every namespace the caller may see. With namespace scoping on, a caller without a per-operator identity gets 403, and everyone else is filtered per namespace (administrators see all). No other route treats _all specially.

machinesets​

MethodPathAccess
GET/api/v1/machinesetsnamespace
DELETE/api/v1/machinesets/{namespace}/{name}namespace
PATCH/api/v1/machinesets/{namespace}/{name}/scalenamespace

machinebackuprestores​

MethodPathAccess
GET/api/v1/machinebackuprestoresnamespace

machinebackups​

MethodPathAccess
GET/api/v1/machinebackupsnamespace
DELETE/api/v1/machinebackups/{namespace}/{name}namespace
POST/api/v1/machinebackups/{namespace}/{name}/restorenamespace

machineclaims​

MethodPathAccess
GET/api/v1/machineclaimsnamespace

machinepools​

MethodPathAccess
GET/api/v1/machinepoolsnamespace

migration-policies​

MethodPathAccess
GET/api/v1/migration-policiesnamespace

migrations​

MethodPathAccess
GET/api/v1/migrationsnamespace
POST/api/v1/migrationsnamespace
POST/api/v1/migrations/evacuatesession
GET/api/v1/migrations/{namespace}/{name}namespace
POST/api/v1/migrations/{namespace}/{name}/cancelnamespace
POST/api/v1/migrations/{namespace}/{name}/recovernamespace

namespaces​

MethodPathAccess
GET/api/v1/namespacessession

network-policies​

MethodPathAccess
GET/api/v1/network-policiesnamespace

nodes​

MethodPathAccess
GET/api/v1/nodessession
GET/api/v1/nodes/usagesession
GET/api/v1/nodes/capacitysession
GET/api/v1/nodes/{node}/capabilitiessession
GET/api/v1/nodes/{node}/topologysession
GET/api/v1/nodes/{node}/catalogsession
POST/api/v1/nodes/{node}/catalogsession
POST/api/v1/nodes/{node}/catalog/cleansession
DELETE/api/v1/nodes/{node}/catalog/{name}session
POST/api/v1/nodes/{node}/catalog/{name}/clonesession
POST/api/v1/nodes/{node}/catalog/{name}/exportsession
POST/api/v1/nodes/{node}/catalog/{name}/read-onlysession
POST/api/v1/nodes/{node}/catalog/{name}/renamesession
POST/api/v1/nodes/{node}/egress-checksession
GET/api/v1/nodes/{node}/poolssession
POST/api/v1/nodes/{node}/poolssession
DELETE/api/v1/nodes/{node}/pools/{name}session
GET/api/v1/nodes/{node}/pools/{name}session
POST/api/v1/nodes/{node}/pools/{name}/claimsession
GET/api/v1/nodes/{node}/sandboxessession
GET/api/v1/nodes/{node}/templatessession
POST/api/v1/nodes/{node}/templatessession

overview​

MethodPathAccess
GET/api/v1/overviewsession
GET/api/v1/insightssession
GET/api/v1/selftestsession
POST/api/v1/selftestsession
GET/api/v1/selftest/scenariossession
GET/api/v1/selftest/{id}session
DELETE/api/v1/selftest/{id}session
GET/api/v1/podssession
GET/api/v1/healthsession
GET/api/v1/streamsession

quotas​

MethodPathAccess
GET/api/v1/quotasnamespace

restores​

MethodPathAccess
GET/api/v1/restoresnamespace
POST/api/v1/restoresnamespace
DELETE/api/v1/restores/{namespace}/{name}namespace

security-groups​

MethodPathAccess
GET/api/v1/security-groupsnamespace

snapshot-schedules​

MethodPathAccess
GET/api/v1/snapshot-schedulesnamespace
PATCH/api/v1/snapshot-schedules/{namespace}/{name}/suspendnamespace
POST/api/v1/snapshot-schedules/{namespace}/{name}/triggernamespace

snapshots​

MethodPathAccess
GET/api/v1/snapshotsnamespace
POST/api/v1/snapshotsnamespace

usage.csv​

MethodPathAccess
GET/api/v1/usage.csvnamespace

users​

MethodPathAccess
POST/api/v1/users/{username}/passwordsession

Live data and history​

  • GET /api/v1/stream is a Server-Sent Events feed of Machine and MachineMigration changes the caller may see. Each change event carries type (ADDED, MODIFIED, DELETED), kind, namespace, name and, when known, phase, nodeName and message. A : ping comment arrives every 20 s. Read it with fetch streaming, because it needs the Authorization header.
  • GET .../timeline merges the Machine's Kubernetes Events with its status conditions, newest first.
  • GET .../metrics?range=15m returns the usage samples (CPU percent, memory, disk read and write) kairon-ui recorded every 15 s, up to one hour. The history is in memory, per replica, and lost on restart; cpuPercent is the lifetime average status.resourceUsage reports.
  • GET /api/v1/insights returns deterministic findings for the Overview's attention strip: failed Machines, Machines unschedulable for 5 minutes or more, migrations in NeedsRecovery or in flight for over 30 minutes, nodes that are not Ready with Machines assigned or at least 90% requested, and quotas at 90% or more. Each finding names the page and target to open. Node findings are omitted for non-administrators when namespace scoping is on.
  • GET /api/v1/nodes/{node}/topology returns the node's NodeTopology status (null until kairon-node publishes one) and the spec.topologyAllocation/status.appliedTopology of each Machine on it the caller may see. See topology-aware placement.
  • GET /api/v1/nodes/capacity reports allocatable against requested CPU and memory per node using the scheduler's own accounting. Rows also carry guaranteedMemoryMiB (elastic-memory Machines count their minimum), memoryOvercommitRatio and memoryPressure (the node's KaironMemoryPressure condition); see elastic memory. With ?cpu=4&memory=8Gi each row also says whether a Machine of that size would fit.
  • GET /api/v1/pods lists Kairon's own pods (app.kubernetes.io/name=kairon-*); add scope=all for every pod the caller may see and node=NAME to filter. GET /api/v1/health rolls those pods up per component. Both need the kairon-ui ClusterRole's pods and events read rules, which the chart and deploy/rbac.yaml now grant.

Actions​

  • POST .../fork with {"count": 1-32, "prefix": "..."} forks a Running Machine without volumes, disks or device claims, as kaironctl fork does (without waiting).
  • POST .../disks with {"action": "attach"|"detach", "name": "...", "claim": "pvc"} and POST .../nics with {"action": "add"|"remove", "name": "...", "bridge": "br0"} edit spec.disks and spec.network.extraInterfaces; kairon-node applies them live. NICs need spec.network.mode: tap.
  • POST .../snapshot-schedules/.../trigger requests an immediate run, bypassing spec.suspend, as kaironctl trigger does.
  • POST .../machines/{ns}/{name}/backups with {"quiesce": "auto"|"required"|"never", "name": "..."} creates a MachineBackup (Atlas options stay in kaironctl backup and YAML). POST .../machinebackups/{ns}/{name}/restore with {"machine": "...", "storageClass": "..."} creates a MachineBackupRestore; its disk half waits until the target Machine is halted. DELETE .../machinebackups/{ns}/{name} removes a backup. These need the create/delete rules the chart and deploy/rbac.yaml now grant on machinebackups and machinebackuprestores.

Incident bundles​

These routes relay FluxVM's diagnostics jobs through the node's console relay (see machine-incident-bundle.md). They need an administrator account or the shared KAIRON_UI_TOKEN, which is root-equivalent on every route; other accounts get 403. They return 501 when the node console relay is not configured.

  • POST .../machines/{ns}/{name}/diagnostics with {"pcap_seconds": 0-30, "pcap_filter": "...", "memory_dump": false, "redact": true, "log_lines": 2000} returns 202 and the job (token, state: running). FluxVM's 409 (a job already running) and 400 (memory dump refused: not QEMU, confidential, over the size cap, no disk space) are passed through.
  • GET .../diagnostics/{token} returns the job: state (running, done, failed), sections, size_bytes, sha256 and, with a dump, memory_dump (path on the node, size_bytes, sha256, paused_ms).
  • GET .../diagnostics/{token}/bundle streams the node's tar.gz; .../memory-dump streams the ELF dump. Both are 409 until the job is done. Memory dump downloads are logged.

Self-test​

The dashboard's self-test is a job API over the same engine as kaironctl selftest (see Self-test). Starting, listing, polling and cancelling need a named administrator account, because a run creates and deletes real Machines; the scenario catalogue is readable by any session.

  • POST /api/v1/selftest with {"profile": "quick|standard|full", "only": [...], "skip": [...], "noVm": false, "keep": false} returns 202 and {"id": "..."}. Only one run executes at a time (409 otherwise). A run is limited to 25 minutes.
  • GET /api/v1/selftest/{id}?after=N returns state (running, passed, failed, cancelled), the steps with their status, reason and hint, the log lines from index N, next (use it as the next after) and, once finished, a summary.
  • DELETE /api/v1/selftest/{id} cancels a run; the engine still deletes the Machines it created.
  • GET /api/v1/selftest lists the last five runs without their lines.
  • Runs are kept in memory, per replica, and are lost when kairon-ui restarts.