Skip to main content

Management API reference

The Management API administers Platform Identity and one exact Product scope. It is intentionally separate from the public Function API. Every protected call authenticates an rk_at_v1_* operator session, reloads its current grants, and checks one explicit capability at Installation, Project, or exact Environment scope.

The CLI is the supported interface for login, linking, development lifecycle, status, and logs. Use the HTTP API for an administration UI/controller only when that integration preserves strict JSON, operation identity, CAS, one-time secret, and reconciliation rules.

Origins and transport

Authentication and Management may share an origin or use two canonical HTTPS origins. Discover them from GET /v1/auth/config; do not assume the login URL is the lifecycle URL. The CLI stores both and rejects redirects, credentials in URLs, ambient proxy substitution, and remote plaintext.

The server listener may use plaintext only on loopback unless a trusted external TLS termination is explicitly configured. Expose it through a protected administrative route with no response caching, bounded request/stream timeouts, and no direct listener access.

Common request contract

Protected requests use exactly one bearer header:

Authorization: Bearer rk_at_v1_...
Accept: application/json

State-changing Product routes that advertise idempotency also require exactly one:

Idempotency-Key: opn_...
Content-Type: application/json

One opn_* identifies one canonical intent. Exact replay returns the original result where the domain supports it; reuse for different path/body/scope/timestamp fails with conflict. CAS fields (expectedRevision, expectedHead, current Release, etc.) prevent a stale operator from silently overwriting newer state.

If a response is lost or a RESULT_UNCERTAIN/timeout-class failure is returned, query the matching operation endpoint or current resource before retrying. A new operation ID means new intent and can duplicate a committed change.

JSON uses camelCase and rejects unknown fields. Ordinary bodies are bounded to 16 KiB; Environment configuration mutations to 72 KiB; Data Admin documents to 12 MiB; publication uses its versioned manifest/artifact bound; object-console upload has a separate bounded body. Authorization is at most 16 KiB. Secret-bearing and Data responses use Cache-Control: no-store.

Authentication and operator sessions

RouteAuthenticationDurable effect / retry
GET /v1/auth/confignonediscover methods and optional Management origin; safe read
GET /v1/auth/oidc/confignonepublic native-client OIDC configuration; safe read
POST /v1/auth/exchangeone-time invitation in bodyconsume invitation and create session atomically; do not replay blindly
POST /v1/auth/oidcexternal bearer and optional first-link authorityverify/link identity and create/reconcile session
POST /v1/auth/refreshrotating refresh token in bodyinvalidates prior refresh on success; uncertain response needs recovery login/reconciliation
GET /v1/auth/meaccess bearerreload current operator/grants
GET /v1/auth/resourcesaccess bearer at authentication originbounded linkable Product Environment catalog
GET /v1/auth/sessionsaccess bearerlist caller's non-secret sessions
DELETE /v1/auth/sessions/{session_id}caller, or installation operators:manageidempotent revocation behavior by session state
PUT /v1/auth/managed/operators/{operator_id}/grantsauthenticated managed gatewaymonotonic source-owned grant reconciliation

Invitation creation, operation lookup, and revocation use /v1/access/invitations, /v1/access/invitation-operations/{operation_id}, and /v1/access/invitations/{invitation_id}. Codes and newly issued confidential material are returned only through their documented one-time response. See Platform operator identity for exact OIDC, invitation, grant, and session bodies and lifetimes.

Environment lifecycle

Base path:

/v1/projects/{project_id}/environments/{environment_id}
RouteCapabilityContract
GET <base>environments:readportable desired/observed state and configuration revisions
POST <base>environments:managecreate complete exact-scope configuration under idempotency
PUT <base>environments:managereplace complete configuration under expected revision
POST <base>/archiveenvironments:managemove desired lifecycle to archived; compact Product serving stops
POST <base>/restoreenvironments:managerestore desired lifecycle; serving resumes only when eligible Channel exists
GET <base>/environment-operations/{operation_id}environments:readreconcile create/update/archive/restore/materialize outcome

Configuration is a complete portable replacement: name, Project-unique slug, logical region, purpose, protection, location, and Workspace-target policy. Provider placement is not a Product field. Desired/observed revisions let an external controller report convergence without claiming a successful API response implies infrastructure materialization. See Environment lifecycle.

Workspace, Release, Channel, and serving

RouteCapabilityPurpose
POST <base>/workspace/publishreleases:publishpublish canonical package with explicit Workspace HEAD CAS
POST <base>/releases/{release_id}releases:publishvalidate/freeze candidate as servable Release
PUT <base>/channels/{channel}channels:promotepoint a Channel through optional exact CAS
POST <base>/channels/{channel}/rollbackchannels:promotemove to an eligible history target with required current CAS
GET <base>/statusreleases:readcoherent Release/Channel snapshot
GET/PUT <base>/serving-policyread / channels:promoteread or completely replace atomic/weighted desired policy
GET <base>/serving-policy-operations/{operation_id}releases:readreconcile desired/materialized serving operation
GET <base>/schemas/compatibilityreleases:readschema/index/Cron hash evidence for desired Release set

PUT serving-policy requires Idempotency-Key, exact current policy revision, complete canonically weighted Release set, and mode. The server rejects incompatible sets before persistence and serves environment:default only from the converged policy. An API success for desired intent and an observed ready revision are distinct signals.

Every selected request/subscription/work item pins one exact Release. See Serving policy and Releases and Workspaces.

Environment variables and secrets

RouteCapabilityResult
GET <base>/configurationconfiguration:readglobal revision and name-ordered variable/secret-reference entries
GET <base>/configuration/historyconfiguration:readnewest-first value-free audit page
PUT <base>/configuration/{NAME}configuration:manageset/rotate exact name under global CAS and idempotency
DELETE <base>/configuration/{NAME}configuration:managedelete exact name under global CAS and idempotency

Example variable update (replace all placeholders with read/generated canonical values):

curl --fail-with-body \
-X PUT \
-H "Authorization: Bearer ${RUNKU_ACCESS_TOKEN}" \
-H "Idempotency-Key: opn_..." \
-H 'Content-Type: application/json' \
--data '{
"expectedRevision": 4,
"kind": "variable",
"value": "enabled",
"changedAtMicros": "1780000000000000"
}' \
'https://management.example.com/v1/projects/prj_.../environments/env_.../configuration/FEATURE_CHECKOUT'

Secret PUT uses "kind":"secret"; its value appears only in the request and is never returned. GET/history expose secret name, kind, revision, and timestamps without plaintext. Names are uppercase ASCII/digit/underscore, cannot start _, and are ≤64 bytes. See Environment variables and secrets.

Application Client credentials

Route groupRead capabilityManage capability
GET/POST <base>/application-clientscredentials:readcredentials:manage for create
GET/POST <base>/application-clients/{client}/credentialscredentials:readcredentials:manage for create
POST .../{credential}/revealcredentials:readre-derive only the allowed verified publishable form
POST .../{credential}/rotatecredentials:manage
POST .../{credential}/revokecredentials:manage
DELETE .../{credential}credentials:manage

Public, secret, and development credentials cannot exchange roles. Confidential material appears only once; store it before acknowledging the operation and reconcile metadata after an uncertain response. See Application identity.

Object Storage administration

Routes under <base>/buckets manage provider-independent buckets, CORS/policy/lifecycle/quota, scoped Product storage keys, object catalog, and bounded console transfers.

OperationCapability
list/get buckets, keys, objects, operation statusstorage:read
create/update/archive bucket; issue/rotate/revoke keystorage:manage + operation id/CAS as defined
console object GETstorage:read
console object PUT/DELETEstorage:manage + operation id

The Runku Object Storage Product endpoint is separate and uses scoped bucket access credentials, not an operator access token. Its protocol is compatible with a bounded S3 subset; native SDK breadth, multipart, and Product-driven provider backup are not implied. See Runku Object Storage.

Runtime catalogs, data, schedules, and Cron

RouteCapabilityBoundary
GET <base>/functionsreleases:readbounded catalog from one verified effective artifact
GET <base>/schema/tablesreleases:readlogical table/index catalog without physical IDs
POST <base>/data/querydata:readbounded logical administrative query
GET <base>/data/documents/{table}/{id}data:readone canonical document
POST <base>/data/documents/{table}data:writedeterministic insert under operation id
PUT/DELETE <base>/data/documents/{table}/{id}data:writeexact document revision/OCC + operation id
GET <base>/scheduledschedules:readbounded durable queue/history without worker identity
GET <base>/crons?target=...cron:readcode declaration + current activation
PUT <base>/crons/{name}/activationcron:activateenable/disable immutable declaration under CAS/idempotency
GET <base>/cron-operations/{operation_id}cron:readreconcile activation outcome

Data Admin bypasses the application's Function API but not schema, scope, identity, CAS, or audit boundaries. Treat writes as production data changes and use the same backup/change approval.

Health, metrics, and logs

RouteCapabilityMeaning
GET /health/livenoneManagement process liveness only
GET /health/readynonebounded authoritative Platform Identity PostgreSQL readiness
GET <base>/instances/healthzenvironments:readsanitized fixed-component Product health
GET <base>/metricsusage:readbounded fixed-name Product aggregate diagnostics
GET <base>/logslogs:readbounded exact-scope log page
GET <base>/logs/followlogs:followNDJSON stream with repeated authorization checks
GET <base>/logs/archive-statuslogs:readarchive coverage/frontier
POST <base>/logs/prunelogs:prunebounded retention plan/apply behind verified frontier

Health is not audit. Metrics are not billing. Logs are not application data authority. A runtime with no Release can be healthy and idle; a log archive outage must block pruning, not Product Mutation commits.

Errors, retries, and audit

HTTP maps stable domain errors to invalid input, unauthenticated, forbidden, not found, conflict, unavailable, uncertain, or internal/corruption classes. Automation branches on stable code and current durable state. Broad guidance:

  • GET reads are safe to retry, recognizing that state can advance;
  • CAS conflict requires a new read and human/controller reconciliation;
  • unavailable before a known commit can use bounded backoff;
  • uncertain mutation requires operation lookup/current-state reconciliation;
  • one-time secret responses require secure capture and metadata reconciliation, never issuance with a new ID as the first recovery action;
  • corruption stops writes and triggers evidence preservation/recovery.

Platform Identity state changes write security audit in the same PostgreSQL transaction. Product domains keep their own operation/audit records. Audit and logs omit bearer values, invitation codes, credential secrets, configuration secrets, request bodies, and customer data.

The complete route/capability table and identity lifecycles are in Platform operator identity; stable CLI behavior is in CLI reference.