Skip to main content

Base URL: https://<first-master-ip>:31007 (see k7 api status / k7 api endpoint).

Transport#

The NodePort is served over HTTPS by default. On the default install the certificate is signed by a playbook-minted cluster CA at /etc/k7/tls/ca.crt on the node — copy it to your client and trust it (curl --cacert ca.crt …, Client(..., verify_ssl="ca.crt"), k7 config set api.ca ca.crt). Clusters installed with --api-hostname present a Let’s Encrypt certificate; --api-tls-cert/--api-tls-key an operator-supplied one; --api-insecure-http serves plain http://. Disabling verification on an https:// URL is rejected by the CLI and SDK. See Security model.

Authentication#

Two kinds of credential are accepted:

Tokens starting k7_ (and the X-API-Key header) always take the API-key path; anything else on Authorization: Bearer is validated as an OIDC JWT against the configured issuer (RS256/ES256, iss, aud, exp, sub required). A bad key is never retried as OIDC.

Every principal resolves to a role: read-only or user inside one tenant, or operator / admin cluster-wide. API keys carry their role (k7 generate-api-key --role …); OIDC subjects get theirs from the role bindings (PUT /api/v1/role-bindings). One PERMISSIONS table maps every route to the roles that may call it. Checks compose — route role, then tenant, then the key’s namespace / node narrowing — and the first failure is a 403 naming the missing role or scope. See Tenants, roles and OIDC.

All endpoints return standard HTTP codes. 401 Unauthorized if the credential is missing, invalid or expired. 403 Forbidden if the role does not cover the route (a read-only key calling exec, a user key reading GET /api/v1/nodes/storage), if a tenant key touches another tenant’s namespace or an all-namespaces operation, or if a create exceeds a tenant quota (QuotaExceeded). In production mode, keys without a tenant or cluster role (pre-0.5 unscoped_legacy keys) get 403 on every route until re-issued.

Every response carries X-Request-ID (echoed in the audit log) and X-K7-Mode (production or development).

Response envelope#

Successful responses:

Errors:

Common error codes:

  • BadRequest (400): Invalid input or missing parameters
  • Unauthorized (401): Missing or invalid API key
  • Forbidden (403): role, tenant or namespace/node scope does not cover the request
  • QuotaExceeded (403): tenant quota hit — message names the dimension, limit, usage and request
  • LimitNotEnforceable (400): a configured tenant limit (diskIO, network on k7d / k7d-fc, disk quota on k7d / k7d-fc) cannot be enforced by the backend, so the create is refused rather than running unlimited
  • NotFound (404): Resource was not found
  • Conflict (409): Resource already exists
  • UnprocessableEntity (422): Validation failed
  • TenantConflict (500): a namespace is claimed by two Tenant objects (only possible by hand-written CRs)
  • InternalServerError (500): Unhandled error
  • PrometheusUnavailable (502): /usage could not query Prometheus
  • 503 Service Unavailable: the API refuses rather than guesses — key-store snapshot older than 60 s, OIDC JWKS refresh failed, quota Lease not acquired within 5 s (QuotaLockTimeout / QuotaLockLost), a transient create failure such as the registry allowlist’s DNS not resolving, or a usage spool above its high-water mark with --metering-require-delivery (UsageSpoolFull)

Headers#

Required headers for requests with body:

Authentication headers (either):

Resources#

  • Sandboxes: create, list, get, delete, delete-all, pause, resume, fork
  • Exec: run a command in a sandbox and get stdout/stderr/exit_code
  • Metrics: CPU and memory usage per sandbox
  • Snapshots: list, inspect, create, delete, restore, GC
  • Identity: who am I, OIDC discovery, API keys, role bindings
  • Tenants: namespaces, quotas, defaults, dedicated nodes; usage showback
  • Nodes: storage pools, dedication; remote install (opt-in)

Endpoints at a glance#

MethodPathDescription
POST/api/v1/sandboxesCreate sandbox
GET/api/v1/sandboxesList sandboxes
GET/api/v1/sandboxes/{name}Get one sandbox
DELETE/api/v1/sandboxes/{name}Delete one sandbox
DELETE/api/v1/sandboxesDelete all in namespace
POST/api/v1/sandboxes/{name}/execRun a command, get stdout/stderr/exit
GET/api/v1/sandboxes/{name}/logsSnapshot of pod logs (no streaming yet)
POST/api/v1/sandboxes/{name}/pauseScale to 0, optionally snapshot the PVC
POST/api/v1/sandboxes/{name}/resumeScale back to 1
POST/api/v1/sandboxes/{name}/forkClone source into a new sandbox (kql: disk clone; k7d / k7d-fc: warm CoW fork)
POST/api/v1/sandboxes/{name}/snapshotSnapshot a running sandbox without pausing it
GET/api/v1/snapshotsList VolumeSnapshots managed by k7
GET/api/v1/snapshots/{name}Inspect one VolumeSnapshot
DELETE/api/v1/snapshots/{name}Delete a VolumeSnapshot
POST/api/v1/snapshots/{name}/restoreBoot a new sandbox from a standalone VolumeSnapshot
POST/api/v1/snapshots/gcSweep stale kind=fork snapshots
GET/api/v1/sandboxes/metricsCPU/memory metrics per sandbox
GET/api/v1/nodes/storagePer-node storage-pool utilization (kfd thin-pool + k7d disk pool). operator / admin
POST/api/v1/nodes/{name}/dedicateLabel + taint a node for a tenant ({"tenant": "acme"}). operator / admin
POST/api/v1/nodes/{name}/undedicateRemove the dedication. operator / admin
GET/api/v1/auth/whoamiPrincipal, role(s), tenant and scopes of the caller
GET/api/v1/auth/oidcOIDC discovery for k7 login (issuer, client id, scopes); 404 when OIDC is off
POST/api/v1/keysMint an API key (admin). Same fields as k7 generate-api-key
GET/api/v1/keysList keys (admin)
DELETE/api/v1/keys/{name}Revoke a key (admin)
GET/api/v1/role-bindingsOIDC subject → role bindings and deny-subjects (admin)
PUT/api/v1/role-bindingsReplace them (admin)
GET/api/v1/tenantsList tenants with quotas and reconciled usage (operator / admin)
POST/api/v1/tenantsCreate a tenant (admin)
GET/api/v1/tenants/{name}Get one tenant
PATCH/api/v1/tenants/{name}Replace spec sections (admin)
DELETE/api/v1/tenants/{name}Delete a tenant (admin)
GET/api/v1/usageShowback from Prometheus (tenant, from, to, group_by); a tenant key only sees its own tenant
POST/api/v1/installRemote node install via the k7-node-installer pool (admin; 404 unless installed with --api-remote-install)
GET/api/v1/install/{operation}Per-node status of a remote install operation
Info

Health endpoints:

  • GET / → basic API info
  • GET /health → health check; also reports mode, key_store sync state, oidc_issuer, tenant_status_error and metering flush state (details)