Managed Kubernetes API
Managed Kubernetes clusters in Norway, Sweden and Denmark. WAYSCloud runs the control plane, private worker nodes, load balancers, scheduled and on-demand backups, and upgrades; you get cluster-admin and a kubeconfig.
Authenticate with a Personal Access Token carrying the kubernetes:read or kubernetes:write scope. Cluster creation and deletion are asynchronous: the API answers 202 and status moves through provisioning_step until running — poll GET /v1/kubernetes/clusters/{cluster_id}. Prices are per month with hourly node rates; see GET /v1/kubernetes/plans. Errors come as {"detail": {"code", "message"}}.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /v1/kubernetes/plans | List cluster and node plans |
GET | /v1/kubernetes/regions | Regions where Kubernetes is available |
GET | /v1/kubernetes/versions | Kubernetes version lifecycle |
POST | /v1/kubernetes/estimate | Monthly estimate for the cluster plan and node pools (storage, backup, LB and extra IPs billed separately) |
GET | /v1/kubernetes/clusters | List clusters |
POST | /v1/kubernetes/clusters | Create a cluster (asynchronous; poll status until running) |
GET | /v1/kubernetes/clusters/{cluster_id} | Get a cluster |
DELETE | /v1/kubernetes/clusters/{cluster_id} | Delete a cluster (asynchronous) |
GET | /v1/kubernetes/clusters/{cluster_id}/history | Audit history |
POST | /v1/kubernetes/clusters/{cluster_id}/node-pools | Add a node pool |
POST | /v1/kubernetes/clusters/{cluster_id}/node-pools/{pool_name}/scale | Scale a node pool |
DELETE | /v1/kubernetes/clusters/{cluster_id}/node-pools/{pool_name} | Delete a node pool |
POST | /v1/kubernetes/clusters/{cluster_id}/node-pools/{pool_name}/upgrade | Converge a node pool to the cluster version |
GET | /v1/kubernetes/clusters/{cluster_id}/kubeconfig | Admin kubeconfig (YAML) |
PUT | /v1/kubernetes/clusters/{cluster_id}/api-access | Set the API allow-list |
POST | /v1/kubernetes/clusters/{cluster_id}/ips | Allocate a public IPv4 |
DELETE | /v1/kubernetes/clusters/{cluster_id}/ips/{address} | Release a public IPv4 |
PUT | /v1/kubernetes/clusters/{cluster_id}/ips/{address}/ptr | Set reverse DNS (name must already resolve to the address) |
GET | /v1/kubernetes/clusters/{cluster_id}/backup-policy | Get Backup Policy |
PUT | /v1/kubernetes/clusters/{cluster_id}/backup-policy | Set Backup Policy |
GET | /v1/kubernetes/clusters/{cluster_id}/backups | List Backups |
POST | /v1/kubernetes/clusters/{cluster_id}/backups | Backup Now |
POST | /v1/kubernetes/clusters/{cluster_id}/backups/{backup_id}/restore | Restore Backup |
GET | /v1/kubernetes/clusters/{cluster_id}/restores | List Restores |
GET | /v1/kubernetes/clusters/{cluster_id}/backup-usage | Actually stored backup bytes, retention and accrued cost |
GET | /v1/kubernetes/clusters/{cluster_id}/volumes | Extra persistent volumes with type, capacity and cost |
POST | /v1/kubernetes/clusters/{cluster_id}/volumes | Create a persistent volume through the cluster's CSI flow |
POST | /v1/kubernetes/clusters/{cluster_id}/volumes/{volume_id}/resize | Grow a persistent volume |
DELETE | /v1/kubernetes/clusters/{cluster_id}/volumes/{volume_id} | Delete a persistent volume (and its data) |
GET | /v1/kubernetes/clusters/{cluster_id}/namespaces | Namespaces in the cluster |
GET | /v1/kubernetes/clusters/{cluster_id}/upgrade | Available upgrades |
POST | /v1/kubernetes/clusters/{cluster_id}/upgrade | Request a Kubernetes upgrade |
POST | /v1/kubernetes/clusters/{cluster_id}/upgrade-preflight | Pre-upgrade check |
GET | /v1/kubernetes/clusters/{cluster_id}/upgrade-jobs | List upgrade jobs |
GET | /v1/kubernetes/clusters/{cluster_id}/upgrade-jobs/{job_id} | Get an upgrade job |
DELETE | /v1/kubernetes/clusters/{cluster_id}/upgrade-jobs/{job_id} | Cancel a queued upgrade |
GET | /v1/kubernetes/clusters/{cluster_id}/maintenance-window | Get the maintenance window |
PUT | /v1/kubernetes/clusters/{cluster_id}/maintenance-window | Set the maintenance window |
DELETE | /v1/kubernetes/clusters/{cluster_id}/maintenance-window | Remove the maintenance window |
GET /v1/kubernetes/plans
List cluster and node plans
Example:
curl https://api.wayscloud.services/v1/kubernetes/plans \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/regions
Regions where Kubernetes is available
Example:
curl https://api.wayscloud.services/v1/kubernetes/regions \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/versions
Kubernetes version lifecycle
Every version WAYSCloud tracks, with its lifecycle state: status, whether new clusters may be created, the create cutoff, the supported-until date, the upgrade-required deadline and the recommended upgrade target. Dates move with time; new provider versions appear only after qualification.
Example:
curl https://api.wayscloud.services/v1/kubernetes/versions \
-H "X-API-Key: YOUR_API_KEY"POST /v1/kubernetes/estimate
Monthly estimate for the cluster plan and node pools (storage, backup, LB and extra IPs billed separately)
Request Body:
| Field | Type | Description |
|---|---|---|
plan_code | string | |
region | string | Region code: no (Norway), se (Sweden) or dk (Denmark). Lowercase is canonical; any case is accepted. The regions endpoint lists where clusters can be ordered. |
node_pools | array | Required. |
currency | string |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/estimate \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'GET /v1/kubernetes/clusters
List clusters
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters \
-H "X-API-Key: YOUR_API_KEY"POST /v1/kubernetes/clusters
Create a cluster (asynchronous; poll status until running)
Request Body:
| Field | Type | Description |
|---|---|---|
name | string | Required. Cluster name (lowercase, digits, hyphens) |
region | string | Region code: no (Norway), se (Sweden) or dk (Denmark). Lowercase is canonical; any case is accepted. The regions endpoint lists where clusters can be ordered. |
plan_code | string | Cluster plan: k8s-cluster-dev |
version | string | Kubernetes minor version (see GET /versions) |
node_pools | array | Required. |
api_ip_filter | array | CIDRs allowed to reach the Kubernetes API; an empty list means only WAYSCloud can reach it |
ssh_key_ids | array |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'GET /v1/kubernetes/clusters/
Get a cluster
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id} \
-H "X-API-Key: YOUR_API_KEY"DELETE /v1/kubernetes/clusters/
Delete a cluster (asynchronous)
Request Body:
| Field | Type | Description |
|---|---|---|
confirm_name | string | Required. Type the cluster name to confirm |
Example:
curl -X DELETE https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id} \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'GET /v1/kubernetes/clusters/{cluster_id}/history
Audit history
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/history \
-H "X-API-Key: YOUR_API_KEY"POST /v1/kubernetes/clusters/{cluster_id}/node-pools
Add a node pool
Request Body:
| Field | Type | Description |
|---|---|---|
name | string | Pool name (DNS label) |
plan_code | string | Required. Node plan, e.g. k8s-node-2c4g |
count | integer | Required. |
labels | object | |
taints | array | |
ssh_key_ids | array | Customer SSH key ids for this pool (POST /node-pools only; at create the cluster-level list applies) |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/node-pools \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'POST /v1/kubernetes/clusters/{cluster_id}/node-pools/{pool_name}/scale
Scale a node pool
Request Body:
| Field | Type | Description |
|---|---|---|
count | integer | Required. Node count per pool (1–16); scale-to-zero is not supported |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/node-pools/{pool_name}/scale \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'DELETE /v1/kubernetes/clusters/{cluster_id}/node-pools/
Delete a node pool
Example:
curl -X DELETE https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/node-pools/{pool_name} \
-H "X-API-Key: YOUR_API_KEY"POST /v1/kubernetes/clusters/{cluster_id}/node-pools/{pool_name}/upgrade
Converge a node pool to the cluster version
Replaces the pool's nodes so their kubelets run the cluster's current Kubernetes version. The pool keeps its name, size, labels, taints and plan, and capacity never drops below the configured count. Runs in the background; poll the cluster until the pool status is running again.
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/node-pools/{pool_name}/upgrade \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/clusters/{cluster_id}/kubeconfig
Admin kubeconfig (YAML)
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/kubeconfig \
-H "X-API-Key: YOUR_API_KEY"PUT /v1/kubernetes/clusters/{cluster_id}/api-access
Set the API allow-list
Request Body:
| Field | Type | Description |
|---|---|---|
cidrs | array | Required. |
Example:
curl -X PUT https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/api-access \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'POST /v1/kubernetes/clusters/{cluster_id}/ips
Allocate a public IPv4
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/ips \
-H "X-API-Key: YOUR_API_KEY"DELETE /v1/kubernetes/clusters/{cluster_id}/ips/
Release a public IPv4
Example:
curl -X DELETE https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/ips/{address} \
-H "X-API-Key: YOUR_API_KEY"PUT /v1/kubernetes/clusters/{cluster_id}/ips/{address}/ptr
Set reverse DNS (name must already resolve to the address)
Request Body:
| Field | Type | Description |
|---|---|---|
ptr_record | string | Required. |
Example:
curl -X PUT https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/ips/{address}/ptr \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'GET /v1/kubernetes/clusters/{cluster_id}/backup-policy
Get Backup Policy
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/backup-policy \
-H "X-API-Key: YOUR_API_KEY"PUT /v1/kubernetes/clusters/{cluster_id}/backup-policy
Set Backup Policy
Request Body:
| Field | Type | Description |
|---|---|---|
enabled | boolean | |
schedule_cron | string | 5-field cron, cluster local time |
retention_days | integer | |
include_volumes | boolean | |
namespaces | object | Restrict to these namespaces; null = all customer namespaces |
Example:
curl -X PUT https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/backup-policy \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'GET /v1/kubernetes/clusters/{cluster_id}/backups
List Backups
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/backups \
-H "X-API-Key: YOUR_API_KEY"POST /v1/kubernetes/clusters/{cluster_id}/backups
Backup Now
Request Body:
| Field | Type | Description |
|---|---|---|
namespaces | object |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/backups \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'POST /v1/kubernetes/clusters/{cluster_id}/backups/{backup_id}/restore
Restore Backup
Request Body:
| Field | Type | Description |
|---|---|---|
namespaces | object |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/backups/{backup_id}/restore \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'GET /v1/kubernetes/clusters/{cluster_id}/restores
List Restores
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/restores \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/clusters/{cluster_id}/backup-usage
Actually stored backup bytes, retention and accrued cost
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/backup-usage \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/clusters/{cluster_id}/volumes
Extra persistent volumes with type, capacity and cost
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/volumes \
-H "X-API-Key: YOUR_API_KEY"POST /v1/kubernetes/clusters/{cluster_id}/volumes
Create a persistent volume through the cluster's CSI flow
Request Body:
| Field | Type | Description |
|---|---|---|
name | string | Required. PersistentVolumeClaim name (DNS label) |
namespace | string | Required. Existing namespace in the cluster |
storage_type | string | Required. standard (Standard SSD) |
size_gb | integer | Required. |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/volumes \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'POST /v1/kubernetes/clusters/{cluster_id}/volumes/{volume_id}/resize
Grow a persistent volume
Request Body:
| Field | Type | Description |
|---|---|---|
size_gb | integer | Required. New requested size; only growth is supported |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/volumes/{volume_id}/resize \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'DELETE /v1/kubernetes/clusters/{cluster_id}/volumes/
Delete a persistent volume (and its data)
Example:
curl -X DELETE https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/volumes/{volume_id} \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/clusters/{cluster_id}/namespaces
Namespaces in the cluster
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/namespaces \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/clusters/{cluster_id}/upgrade
Available upgrades
Lists the versions this cluster can upgrade to. Upgrades are sequential: the response normally contains only the next minor version.
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/upgrade \
-H "X-API-Key: YOUR_API_KEY"POST /v1/kubernetes/clusters/{cluster_id}/upgrade
Request a Kubernetes upgrade
Upgrades the cluster one minor version at a time. mode: immediate (default; begins now), next_maintenance_window (waits for the configured maintenance window) or scheduled (scheduled_at must fall inside a maintenance-window occurrence). strategy: rolling-update or manual; omitted means manual. With backup_before_upgrade the upgrade waits for a fresh backup first. Immediate upgrades without a backup return the cluster record; all other requests return the queued job.
Request Body:
| Field | Type | Description |
|---|---|---|
version | string | Required. |
mode | string | immediate |
scheduled_at | object | Required for mode=scheduled: an ISO-8601 timestamp with a timezone offset, inside a configured maintenance window |
strategy | object | rolling-update |
backup_before_upgrade | boolean | Take a backup first and continue only when it completes |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/upgrade \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'POST /v1/kubernetes/clusters/{cluster_id}/upgrade-preflight
Pre-upgrade check
Read-only checks before an upgrade, with the same input model as the upgrade request. errors block the upgrade (health, conflicts, skew, target, window, backup setup, provider capacity); warnings are advisory (e.g. a stale backup) and the caller decides. Every call is audited.
Request Body:
| Field | Type | Description |
|---|---|---|
version | string | Required. |
mode | string | immediate |
scheduled_at | object | Required for mode=scheduled: an ISO-8601 timestamp with a timezone offset, inside a configured maintenance window |
strategy | object | rolling-update |
backup_before_upgrade | boolean | Whether the upgrade will take a fresh backup first; suppresses the backup-freshness warning |
Example:
curl -X POST https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/upgrade-preflight \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'GET /v1/kubernetes/clusters/{cluster_id}/upgrade-jobs
List upgrade jobs
Upgrade requests for this cluster, newest first, with their state machine status.
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/upgrade-jobs \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/clusters/{cluster_id}/upgrade-jobs/
Get an upgrade job
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/upgrade-jobs/{job_id} \
-H "X-API-Key: YOUR_API_KEY"DELETE /v1/kubernetes/clusters/{cluster_id}/upgrade-jobs/
Cancel a queued upgrade
Cancels an upgrade that has not started yet (status queued or preflight). A running upgrade cannot be cancelled.
Example:
curl -X DELETE https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/upgrade-jobs/{job_id} \
-H "X-API-Key: YOUR_API_KEY"GET /v1/kubernetes/clusters/{cluster_id}/maintenance-window
Get the maintenance window
The cluster's recurring maintenance window. The returned start and end carry the window timezone's UTC offset; when the cluster is inside its window now, they describe the current occurrence, otherwise the next one.
Example:
curl https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/maintenance-window \
-H "X-API-Key: YOUR_API_KEY"PUT /v1/kubernetes/clusters/{cluster_id}/maintenance-window
Set the maintenance window
Create or replace the cluster's recurring maintenance window: timezone (IANA, e.g. Europe/Oslo), weekdays (MON..SUN; full names accepted), local start HH:MM and duration in elapsed minutes (30–480). A window that crosses a daylight-saving change keeps its real duration.
Request Body:
| Field | Type | Description |
|---|---|---|
enabled | boolean | Whether the window is active |
timezone | string | Required. IANA timezone, e.g. Europe/Oslo |
days | array | Required. Weekdays the window is open: MON..SUN (full names accepted) |
start | string | Required. Local start time HH:MM in the configured timezone |
duration_minutes | integer | Required. Window length in elapsed minutes (30–480) |
Example:
curl -X PUT https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/maintenance-window \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{...}'DELETE /v1/kubernetes/clusters/{cluster_id}/maintenance-window
Remove the maintenance window
Removes the cluster's recurring maintenance window.
Example:
curl -X DELETE https://api.wayscloud.services/v1/kubernetes/clusters/{cluster_id}/maintenance-window \
-H "X-API-Key: YOUR_API_KEY"