Cluster Lifecycle & Info

Manage the lifecycle of an imported cluster and read information about it. All paths on this page are relative to:

/api/v1/clusters/{owner}/{cluster}

All endpoints require a token (Authorization: token <YOUR_TOKEN>). {owner} is the organization slug or username that owns the cluster, and {cluster} is the cluster name. Common path parameters used throughout this page:

NameTypeDescription
ownerstringOrganization slug or username that owns the cluster.
clusterstringCluster name.

A documented call looks like:

curl -H "Authorization: token $AKP_TOKEN" \
  https://<akp-host>/api/v1/clusters/appscode/ace/

Cluster details

GET /clusters/{owner}/{cluster}/

Get summary information about a cluster.

  • Auth: token.
  • Response: 200 with a ClusterInfo object.
{
  "id": 2,
  "displayName": "ace",
  "name": "ace",
  "uid": "<uid>",
  "ownerID": 3,
  "externalID": "",
  "ownerName": "appscode",
  "provider": "Generic",
  "vendor": "",
  "infraNamespace": "",
  "isMonitoringCluster": false,
  "endpoint": "https://<akp-host>:6443",
  "location": "",
  "project": "",
  "kubernetesVersion": "v1.36.2+k3s1",
  "nodeCount": 1,
  "createdAt": "2026-07-05T06:49:31Z",
  "age": "8d",
  "clusterManagers": ["ACE", "OCMHub"],
  "status": { "response": { "phase": "Active" } }
}

Key fields: name/displayName/uid identify the cluster, ownerName/ownerID the owning account, provider/vendor/kubernetesVersion/nodeCount describe the Kubernetes cluster, clusterManagers lists the managers (e.g. ACE, OCMHub, Rancher), and status is a Kubernetes-style ClusterStatus object.

Verified: GET returned 200 against appscode/ace (hub) and appscode/arnob-dev (spoke) on 2026-07-14.

PUT /clusters/{owner}/{cluster}/

Update an imported cluster’s import options (display name, provider, kubeconfig).

  • Auth: token + authzCheck(update:cluster) (Cluster_Editor).
  • Request body: an ImportClusterOption.
{
  "displayName": "my-cluster",
  "name": "my-cluster",
  "provider": "Generic",
  "kubeConfig": "<kubeconfig>"
}
FieldTypeRequiredDescription
displayNamestringnoHuman-friendly name.
namestringnoCluster name.
providerstringyesCluster provider (e.g. Generic, GKE, EKS).
kubeConfigstringyesRaw kubeconfig for the cluster.
  • Response: 200 with the persisted cluster info model (ClusterInfoModel, an open/DB-backed object).

DELETE /clusters/{owner}/{cluster}/

Submit a cluster deletion command as an async task. Returns the command to run rather than deleting synchronously.

  • Auth: token + authzCheck(delete:cluster) (Cluster_Editor).
  • Response: 200 with a TaskResponse.
{ "id": "task-1a2b3c", "subject": "tasks.cluster.delete" }

POST /clusters/{owner}/{cluster}/remove

Remove a cluster’s registration from the KubeDB Platform (does not delete the underlying cluster).

  • Auth: token.
  • Response: 200 with an empty body.

Cluster access & discovery

GET /clusters/{owner}/{cluster}/client-config

Get the cluster’s client kubeconfig, returned as a JSON string.

  • Auth: token + authzCheck(view:kube-config) (Cluster_CanViewKubeconfig).
  • Response: 200 with the kubeconfig as a JSON-encoded string.
"apiVersion: v1\nkind: Config\nclusters:\n- cluster: { ... }\n..."

Verified: GET returned 200 against appscode/ace (hub) on 2026-07-14.

GET /clusters/{owner}/{cluster}/available-types

Discover the resource types available in the cluster. Returns a nested mapping of group -> version -> [ { Kind, Resource } ].

  • Auth: token.
  • Response: 200 with a dynamic object.
{
  "": {
    "v1": [
      { "Kind": "ConfigMap", "Resource": "configmaps" },
      { "Kind": "Pod", "Resource": "pods" },
      { "Kind": "Endpoints", "Resource": "endpoints" }
    ]
  },
  "apps": {
    "v1": [
      { "Kind": "Deployment", "Resource": "deployments" }
    ]
  }
}

The empty-string key ("") is the legacy Kubernetes core group.

Verified: GET returned 200 against appscode/ace (hub) and appscode/arnob-dev (spoke) on 2026-07-14.

GET /clusters/{owner}/{cluster}/namespaces/{namespace}/resources

List the objects that exist in one namespace, for a chosen set of API groups. Uses server-preferred namespaced resources, and only resources that support list; group discovery failures for individual groups are skipped rather than failing the request. Objects the caller cannot list (403), resources that are not found (404), and resources that do not support listing (405) are silently omitted. The whole request is bounded by a 30-second timeout, with at most 5 resource types listed concurrently.

  • Auth: token.

Path parameters:

NameTypeDescription
namespacestringNamespace to list.

Query parameters:

NameTypeRequiredDescription
groupsstringyesComma-separated API groups to include. Use core for the legacy Kubernetes core group (sent to the cluster as the empty group). Duplicates and blanks are ignored.

Response: 200 — a flat array of objects:

[
  {
    "group": "kubedb.com",
    "version": "v1",
    "resource": "mongodbs",
    "kind": "MongoDB",
    "name": "mgo",
    "namespace": "demo"
  },
  {
    "group": "",
    "version": "v1",
    "resource": "configmaps",
    "kind": "ConfigMap",
    "name": "kube-root-ca.crt",
    "namespace": "demo"
  }
]

Errors: 400 when namespace is empty or groups resolves to no groups.

Use GET .../available-types first to see which groups the cluster actually serves.

GET /clusters/{owner}/{cluster}/is-server

Check whether this cluster is the KubeDB Platform hub cluster.

  • Auth: token.
  • Response: 200 with {"server": "yes"|"no"}.
{ "server": "yes" }

Verified: GET returned 200 against appscode/ace (hub, "server":"yes") on 2026-07-14.


Database & features

GET /clusters/{owner}/{cluster}/db-status

Get a dynamic map of database feature gates / status for the cluster.

  • Auth: token.
  • Response: 200 with a dynamic map (empty {} when no DB features are present).
{}

Verified: GET returned 200 against appscode/ace (hub) on 2026-07-14.

GET /clusters/{owner}/{cluster}/db-bundle

Get database bundle information — a dynamic map of string to an array of strings.

  • Auth: token.
  • Response: 200 with a dynamic map.
{
  "kubedb": ["MongoDB", "PostgreSQL", "MySQL"]
}

Verified: GET returned 200 against appscode/ace (hub) on 2026-07-14.

GET /clusters/{owner}/{cluster}/feature/factory-values

Get the factory (default) values for one or more features.

  • Auth: token.
  • Query parameters:
NameTypeRequiredDescription
featuresstringyesFeature name(s) to fetch default values for.
  • Response: 200 with a dynamic map of factory feature values.

Verified: GET returned 200 against appscode/ace with ?features=kubedb; returned 400 (missing features query parameter) when the features query parameter is omitted, on 2026-07-14.

POST /clusters/{owner}/{cluster}/update-presets/{preset}

Update the named preset in a spoke cluster by applying the supplied FluxCD HelmRelease object.

  • Auth: token.
  • Path parameters: owner, cluster, plus preset (string, the preset name).
  • Request body: an arbitrary FluxCD HelmRelease Kubernetes object. See the Kubernetes proxy page for how arbitrary Kubernetes objects are passed through verbatim.
  • Response: 200 with an empty body.

Commands & resources

POST /clusters/{owner}/{cluster}/execute-command

Run one of the whitelisted kubectl plugin commands against the cluster (kubectl-kubestash, kubectl-stash, kubectl-dba, kubectl-vault).

  • Auth: token.
  • Request body: an ExecuteCommandPayload.
{ "command": "kubectl-dba version --client" }
FieldTypeRequiredDescription
commandstringyesThe whitelisted command to execute.
  • Response: 200 with a CommandResponse.
{ "stdout": "kubectl-dba version ...", "stderr": "" }

Returns 422 for an invalid or unsupported command.

POST /clusters/{owner}/{cluster}/resources

Create a generic Kubernetes resource in the cluster.

  • Auth: token.
  • Request body: the raw YAML/JSON of any Kubernetes object (parsed into an unstructured object). This is an arbitrary Kubernetes object rather than a fixed schema.
{
  "apiVersion": "v1",
  "kind": "ConfigMap",
  "metadata": { "name": "example", "namespace": "default" },
  "data": { "key": "value" }
}
  • Response: 200 with the created Kubernetes object.

Deploy orders

POST /clusters/{owner}/{cluster}/deploy/{id}

Install a previously generated product deploy order (order.yaml identified by {id}) into the cluster. No request body.

  • Auth: token.
  • Path parameters: owner, cluster, plus id (string, the deploy order ID).
  • Response: 200 (empty body). 404 if the deploy order is not found.

DELETE /clusters/{owner}/{cluster}/deploy/{id}

Uninstall the product deploy order identified by {id} from the cluster. No request body.

  • Auth: token.
  • Path parameters: owner, cluster, plus id (string, the deploy order ID).
  • Response: 200 (empty body). 404 if the deploy order is not found.

Resource history

GET /clusters/{owner}/{cluster}/resource-history

Get the change history for resources from NATS, optionally filtered by query parameters.

  • Auth: token.
  • Query parameters:
NameTypeRequiredDescription
productstringnoFilter by product.
groupstringnoFilter by Kubernetes API group.
resourcestringnoFilter by resource (plural).
ridstringnoFilter by resource ID.
  • Response: 200 with a BadgerEntryList.
{
  "items": [
    {
      "key": "kubedb.com/mongodbs/<uid>",
      "values": [
        {
          "resourceID": { "group": "kubedb.com", "kind": "MongoDB", "name": "mongo-1" },
          "licenseID": "<license-id>",
          "version": 3,
          "timestamp": 1783967505
        }
      ],
      "lastSeen": 1783967505
    }
  ]
}

Each entry has a key, one or more values (each carrying the resource, resourceID, licenseID, version, and timestamp), and a lastSeen timestamp.

Verified: returned 500 (nats: no responders available for request) against appscode/ace — this endpoint depends on the NATS resource-history responder, which was not available on the verification cluster.