Create a Cluster
Choose a name, Kubernetes version, and resource limits. Optional high availability must be chosen at creation and cannot change later. You can resize or upgrade an existing cluster. See High availability.
For the complete request and response schema, see the Reference: clusters section.
Request
Section titled “Request”POST /api/v1/tenants/{tenant}/clustersexport KUPE_TENANT="<tenant>"
curl -X POST \ -H "Authorization: Bearer $KUPE_API_KEY" \ -H "Content-Type: application/json" \ "https://api.kupe.cloud/api/v1/tenants/$KUPE_TENANT/clusters" \ -d '{ "name": "prod", "version": "1.31", "resources": { "cpu": "4", "memory": "16Gi", "storage": "100Gi" } }'Fields
Section titled “Fields”| Field | Required | Mutable | Description |
|---|---|---|---|
name |
Yes | No | Unique cluster name. |
displayName |
No | No | Deprecated. Accepted for backward compatibility and ignored; the cluster name is the display name everywhere (console, CLI, kubeconfig contexts). Responses echo name here. |
version |
No | Yes | Kubernetes version such as 1.31. |
resources |
No | Yes | CPU, memory, and storage limits in Kubernetes quantity format (4, 16Gi, 100Gi). |
alerts |
No | Yes | Alert configuration overrides, if you are already managing them through the API. |
Response
Section titled “Response”201 Created with the cluster object and an ETag header for use with later PATCH requests:
{ "name": "prod", "displayName": "prod", "version": "1.31", "resources": { "cpu": "4", "memory": "16Gi", "storage": "100Gi" }, "status": { "phase": "Pending" }, "resourceVersion": "12345", "createdAt": "2026-04-06T12:00:00Z"}The cluster is provisioned asynchronously: status.phase starts at Pending and progresses
through Provisioning to Running.
Wait for the cluster to be ready
Section titled “Wait for the cluster to be ready”Poll the GET endpoint until
status.phase reaches Running. The script below has a 15-minute timeout and exits non-zero
if it times out, so it is safe to use in CI:
export KUPE_TENANT="<tenant>"export KUPE_CLUSTER="prod"
TIMEOUT_SECONDS=900 # 15 minutesINTERVAL=10ELAPSED=0
while [ "$ELAPSED" -lt "$TIMEOUT_SECONDS" ]; do PHASE=$(curl -s \ -H "Authorization: Bearer $KUPE_API_KEY" \ "https://api.kupe.cloud/api/v1/tenants/$KUPE_TENANT/clusters/$KUPE_CLUSTER" \ | jq -r '.status.phase') echo "Phase: $PHASE (elapsed ${ELAPSED}s)"
case "$PHASE" in Running) echo "Cluster is ready" exit 0 ;; Degraded) # Degraded means the cluster needs attention; it may still recover on # its own. There is no terminal Failed/Error phase, so keep polling and let # the timeout below decide when to give up. echo "Cluster is Degraded, still waiting..." >&2 ;; esac
sleep "$INTERVAL" ELAPSED=$((ELAPSED + INTERVAL))done
echo "Timed out waiting for cluster after ${TIMEOUT_SECONDS}s" >&2exit 1Get connection details
Section titled “Get connection details”Once the cluster is Running, fetch its API endpoint and CA certificate:
curl -s \ -H "Authorization: Bearer $KUPE_API_KEY" \ "https://api.kupe.cloud/api/v1/tenants/$KUPE_TENANT/clusters/$KUPE_CLUSTER/connection-details"This endpoint returns connection details, not a full interactive user kubeconfig blob. See Reference: cluster connection details for the exact response shape.
Permissions
Section titled “Permissions”Only members with the admin role can create clusters. A 403 Forbidden is returned for
readonly keys or members.