DCS / DEVELOPERS

Your infrastructure.
Your workflow.

Provision a private Kubernetes cluster from the terminal or your application. Use the same organisation permissions as the dashboard.

Start building → Download OpenAPI

01 / COMMAND LINE

From sign-in to cluster

The developer kit is available from the DCS repository. Use your own organisation, resource-group, network and cluster IDs in these examples.

# From a DCS repository checkout (Node.js 20.11+)
npm ci
npm run build -w @distributed-cloud-services/sdk
npm run dcs -- --help

# Bash / zsh: read the password without echo, then send it on stdin.
read -r -s DCS_PASSWORD
printf '%s' "$DCS_PASSWORD" | npm run --silent dcs -- login \
  --url https://dcsloud.com --email [email protected] --password-stdin
unset DCS_PASSWORD

npm run dcs -- organisations list
npm run dcs -- organisations use 7
npm run dcs -- resource-groups list
npm run dcs -- networks list --resource-group 12
npm run dcs -- clusters create my-app --resource-group 12 --network 4 --nodes 1
# Use the ID returned by create:
npm run dcs -- clusters wait 36 --timeout 600
npm run dcs -- clusters kubeconfig 36 --output ./my-app.kubeconfig

Create returns a pending resource. Wait reports success only when the cluster is active. If a write times out, inspect the resource before submitting it again.

Connect your device to the cluster’s private network using Dashboard → Connect, then run kubectl --kubeconfig ./my-app.kubeconfig get nodes. Downloading credentials alone does not establish connectivity.

02 / TYPESCRIPT & JAVASCRIPT

Build into your application

The typed Node.js client handles session rotation, request timeouts and cluster polling. It uses HTTPS and keeps authenticated requests out of caches.

import { DcsClient } from '@distributed-cloud-services/sdk';

const client = new DcsClient({
  baseUrl: 'https://dcsloud.com',
  token: process.env.DCS_TOKEN,
});
await client.useOrganisation(7);
const cluster = await client.createCluster({
  name: 'my-app', resource_group_id: 12, network_id: 4, node_count: 1,
});
await client.waitForCluster(cluster.id, { timeoutMs: 600_000 });
// Store credentials privately; never print the connection object.
const connection = await client.clusterConnection(cluster.id);

Sessions and permissions

DCS currently stores one normal session per account. CLI sign-in or organisation selection can replace another session. The CLI stores credentials in a private local directory; use the SDK’s onToken callback to persist rotations in your own credential store.

Service-account tokens, Terraform integration and independent device sessions are not included in this release. Existing organisation and resource-group permissions apply to every request.

03 / API REFERENCE

One contract for the workflow

Base path: /api/v1. Send Authorization: Bearer <token> after login. This reference covers the developer kit’s customer endpoints. Internal service APIs are not part of this contract.

POST/auth/loginSign in with an existing DCS account

Returns an unscoped session. Select an organisation next. One current normal session is stored per user; login can replace a dashboard or CLI session. OAuth-only accounts use the dashboard. This kit does not introduce service-account credentials.

{
  "operationId": "login",
  "summary": "Sign in with an existing DCS account",
  "description": "Returns an unscoped session. Select an organisation next. One current normal session is stored per user; login can replace a dashboard or CLI session. OAuth-only accounts use the dashboard. This kit does not introduce service-account credentials.",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Session"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "security": [],
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/Credentials"
        }
      }
    }
  }
}
GET/organisations/my-organisationList your organisation memberships

{
  "operationId": "listOrganisations",
  "summary": "List your organisation memberships",
  "description": "",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Membership"
            }
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  }
}
POST/organisations/switchSelect an organisation

Checks current membership and replaces the session token. Use the JSON body token instead of any intermediate X-Access-Token header.

{
  "operationId": "useOrganisation",
  "summary": "Select an organisation",
  "description": "Checks current membership and replaces the session token. Use the JSON body token instead of any intermediate X-Access-Token header.",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Session"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrganisationSelection"
        }
      }
    }
  }
}
GET/resource-groupsList accessible resource groups

Requires an active organisation; results are filtered by resource-group access.

{
  "operationId": "listResourceGroups",
  "summary": "List accessible resource groups",
  "description": "Requires an active organisation; results are filtered by resource-group access.",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ResourceGroup"
            }
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "rg:view"
}
POST/resource-groupsCreate a resource group

{
  "operationId": "createResourceGroup",
  "summary": "Create a resource group",
  "description": "",
  "responses": {
    "201": {
      "description": "Created; provisioning may still be pending.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ResourceGroup"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "rg:create",
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/ResourceGroupInput"
        }
      }
    }
  }
}
GET/network/organisations/{organisationId}/resource-groups/{resourceGroupId}/networksList networks in a resource group

organisationId must match the active organisation. These are provider VNETs used for cluster provisioning.

{
  "operationId": "listNetworks",
  "summary": "List networks in a resource group",
  "description": "organisationId must match the active organisation. These are provider VNETs used for cluster provisioning.",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Network"
            }
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "network:view",
  "parameters": [
    {
      "name": "organisationId",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    },
    {
      "name": "resourceGroupId",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    }
  ]
}
POST/network/organisations/{organisationId}/resource-groups/{resourceGroupId}/networksAllocate a network in a resource group

Allocates real network infrastructure. No idempotency key support; inspect state after ambiguous failures.

{
  "operationId": "createNetwork",
  "summary": "Allocate a network in a resource group",
  "description": "Allocates real network infrastructure. No idempotency key support; inspect state after ambiguous failures.",
  "responses": {
    "201": {
      "description": "Created; provisioning may still be pending.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Network"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "network:create",
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/NetworkInput"
        }
      }
    }
  },
  "parameters": [
    {
      "name": "organisationId",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    },
    {
      "name": "resourceGroupId",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    }
  ]
}
GET/proxmox/compute-limitsRead organisation compute allocations

Support sessions are rejected. enabled=false means no quota policy is configured. usageComplete=false means some retained allocations have unknown sizes.

{
  "operationId": "computeLimits",
  "summary": "Read organisation compute allocations",
  "description": "Support sessions are rejected. enabled=false means no quota policy is configured. usageComplete=false means some retained allocations have unknown sizes.",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ComputeLimits"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "Organisation owner/admin"
}
GET/clustersList accessible clusters

{
  "operationId": "listClusters",
  "summary": "List accessible clusters",
  "description": "",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Cluster"
            }
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "compute:view"
}
POST/clustersProvision a K3s cluster

Asynchronous creation. network_id must belong to resource_group_id. Poll GET /clusters/{id} until active or error. A 201 is not readiness. Names are unique per organisation. No automatic retry or idempotency key support.

{
  "operationId": "createCluster",
  "summary": "Provision a K3s cluster",
  "description": "Asynchronous creation. network_id must belong to resource_group_id. Poll GET /clusters/{id} until active or error. A 201 is not readiness. Names are unique per organisation. No automatic retry or idempotency key support.",
  "responses": {
    "201": {
      "description": "Created; provisioning may still be pending.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Cluster"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "compute:create",
  "requestBody": {
    "required": true,
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/CreateCluster"
        }
      }
    }
  }
}
GET/clusters/{id}Inspect cluster status

{
  "operationId": "getCluster",
  "summary": "Inspect cluster status",
  "description": "",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Cluster"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "compute:view",
  "parameters": [
    {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    }
  ]
}
DELETE/clusters/{id}Delete a cluster

Destructive provider cleanup. Protected platform clusters cannot be deleted. Inspect cluster status before repeating an interrupted request.

{
  "operationId": "deleteCluster",
  "summary": "Delete a cluster",
  "description": "Destructive provider cleanup. Protected platform clusters cannot be deleted. Inspect cluster status before repeating an interrupted request.",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "properties": {
              "success": {
                "type": "boolean"
              }
            },
            "required": [
              "success"
            ]
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "compute:delete",
  "parameters": [
    {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    }
  ]
}
GET/clusters/{id}/kubeconfigDownload private cluster connection details

Returns credentials only when the cluster is active and the private control-plane identity is ready. Write kubeconfig to a private file. The returned endpoint requires private-network connectivity; never disable certificate verification.

{
  "operationId": "clusterConnection",
  "summary": "Download private cluster connection details",
  "description": "Returns credentials only when the cluster is active and the private control-plane identity is ready. Write kubeconfig to a private file. The returned endpoint requires private-network connectivity; never disable certificate verification.",
  "responses": {
    "200": {
      "description": "Success",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/ClusterConnection"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "compute:configure",
  "parameters": [
    {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    }
  ]
}
POST/clusters/{id}/access-keyCreate a short-lived private-network device key

Creates a sensitive enrollment credential. Limited to five requests per minute per IP. Never print it to logs; repeated calls generate additional keys.

{
  "operationId": "createDeviceKey",
  "summary": "Create a short-lived private-network device key",
  "description": "Creates a sensitive enrollment credential. Limited to five requests per minute per IP. Never print it to logs; repeated calls generate additional keys.",
  "responses": {
    "201": {
      "description": "Created; provisioning may still be pending.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/DeviceKey"
          }
        }
      }
    },
    "default": {
      "description": "Failure. Inspect HTTP status, message/error, request ID and Retry-After.",
      "headers": {
        "X-Request-ID": {
          "description": "Server-generated correlation ID for support.",
          "schema": {
            "type": "string"
          }
        },
        "X-Access-Token": {
          "description": "Replacement session token, when automatically refreshed. Persist before the next request.",
          "schema": {
            "type": "string"
          }
        },
        "Retry-After": {
          "description": "Suggested retry delay in seconds or an HTTP date. Never blindly retry a write.",
          "schema": {
            "type": "string"
          }
        }
      },
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/Error"
          }
        }
      }
    }
  },
  "x-dcs-permission": "compute:configure",
  "parameters": [
    {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    }
  ]
}
Request and response schemas
{
  "Error": {
    "type": "object",
    "properties": {
      "message": {
        "type": "string"
      },
      "error": {
        "type": "string"
      },
      "code": {
        "type": "string"
      },
      "success": {
        "type": "boolean"
      }
    }
  },
  "Credentials": {
    "type": "object",
    "properties": {
      "email": {
        "type": "string",
        "format": "email"
      },
      "password": {
        "type": "string",
        "writeOnly": true
      }
    },
    "required": [
      "email",
      "password"
    ]
  },
  "Session": {
    "type": "object",
    "properties": {
      "token": {
        "type": "string"
      }
    },
    "required": [
      "token"
    ]
  },
  "OrganisationSelection": {
    "type": "object",
    "properties": {
      "organisation_id": {
        "type": "integer",
        "minimum": 1
      }
    },
    "required": [
      "organisation_id"
    ]
  },
  "Membership": {
    "type": "object",
    "properties": {
      "organisation": {
        "type": "object",
        "properties": {
          "organisation_id": {
            "type": "integer",
            "minimum": 1
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "organisation_id",
          "name"
        ]
      },
      "role": {
        "type": "string"
      }
    },
    "required": [
      "organisation",
      "role"
    ]
  },
  "ResourceGroup": {
    "type": "object",
    "properties": {
      "resource_group_id": {
        "type": "integer",
        "minimum": 1
      },
      "organisation_id": {
        "type": "integer",
        "minimum": 1
      },
      "name": {
        "type": "string"
      }
    },
    "required": [
      "resource_group_id",
      "organisation_id",
      "name"
    ]
  },
  "ResourceGroupInput": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "minLength": 1
      }
    },
    "required": [
      "name"
    ]
  },
  "Network": {
    "type": "object",
    "properties": {
      "id": {
        "type": "integer",
        "minimum": 1
      },
      "organisation_id": {
        "type": "integer",
        "minimum": 1
      },
      "resource_group_id": {
        "type": "integer",
        "minimum": 1
      },
      "network_name": {
        "type": "string"
      }
    },
    "required": [
      "id",
      "organisation_id",
      "resource_group_id"
    ]
  },
  "NetworkInput": {
    "type": "object",
    "properties": {
      "network_name": {
        "type": "string",
        "minLength": 1,
        "maxLength": 255
      }
    },
    "required": [
      "network_name"
    ]
  },
  "Cluster": {
    "type": "object",
    "properties": {
      "id": {
        "type": "integer",
        "minimum": 1
      },
      "name": {
        "type": "string"
      },
      "organisation_id": {
        "type": "integer",
        "minimum": 1
      },
      "resource_group_id": {
        "type": "integer",
        "minimum": 1
      },
      "network_id": {
        "type": [
          "integer",
          "null"
        ]
      },
      "status": {
        "type": "string",
        "enum": [
          "pending",
          "provisioning",
          "configuring",
          "active",
          "inactive",
          "error"
        ]
      },
      "provider": {
        "type": "string"
      },
      "has_kubeconfig": {
        "type": "boolean"
      },
      "status_message": {
        "type": "string"
      },
      "status_updated_at": {
        "type": "string"
      }
    },
    "required": [
      "id",
      "name",
      "organisation_id",
      "resource_group_id",
      "status"
    ]
  },
  "CreateCluster": {
    "type": "object",
    "properties": {
      "name": {
        "type": "string",
        "pattern": "^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$",
        "maxLength": 48
      },
      "resource_group_id": {
        "type": "integer",
        "minimum": 1
      },
      "network_id": {
        "type": "integer",
        "minimum": 1
      },
      "node_count": {
        "type": "integer",
        "minimum": 1,
        "maximum": 5,
        "default": 1
      }
    },
    "required": [
      "name",
      "resource_group_id",
      "network_id"
    ]
  },
  "ClusterConnection": {
    "type": "object",
    "properties": {
      "kubeconfig": {
        "type": "string"
      },
      "server": {
        "type": "string",
        "format": "uri"
      },
      "loginServer": {
        "type": "string",
        "format": "uri"
      }
    },
    "required": [
      "kubeconfig",
      "server",
      "loginServer"
    ]
  },
  "DeviceKey": {
    "type": "object",
    "properties": {
      "key": {
        "type": "string"
      },
      "expiresAt": {
        "type": "string"
      },
      "loginServer": {
        "type": "string"
      }
    },
    "required": [
      "key",
      "expiresAt",
      "loginServer"
    ]
  },
  "ComputeAllocation": {
    "type": "object",
    "properties": {
      "vms": {
        "type": "number",
        "minimum": 0
      },
      "containers": {
        "type": "number",
        "minimum": 0
      },
      "vcpus": {
        "type": "number",
        "minimum": 0
      },
      "memoryMiB": {
        "type": "number",
        "minimum": 0
      },
      "diskGiB": {
        "type": "number",
        "minimum": 0
      }
    },
    "required": [
      "vms",
      "containers",
      "vcpus",
      "memoryMiB",
      "diskGiB"
    ]
  },
  "ComputeLimits": {
    "type": "object",
    "properties": {
      "enabled": {
        "type": "boolean"
      },
      "usageComplete": {
        "type": "boolean"
      },
      "usage": {
        "$ref": "#/components/schemas/ComputeAllocation"
      },
      "limits": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/ComputeAllocation"
          },
          {
            "type": "null"
          }
        ]
      }
    },
    "required": [
      "enabled",
      "usageComplete",
      "usage",
      "limits"
    ]
  }
}

04 / TROUBLESHOOTING

Understand a failed request

StatusNext step
400Check request fields and select an organisation.
401Sign in again; the session may have expired or been replaced.
403 / 404Check organisation and resource-group access. Resources outside your scope may be hidden.
409Inspect current state, duplicate names or compute limits.
429 / 503Observe Retry-After when present. Inspect resource state before retrying a write.

Keep the X-Request-ID response header when reporting a problem. The CLI includes it in errors when provided by Core. Do not include passwords, tokens, device keys or kubeconfigs in support reports.