KubeadaptDocsBack to site
Sign inStart free
DocsAPI ReferenceCLI
    • Discovery
    • Organization
    • Clusters
    • Namespaces
    • Workloads
    • Nodes
    • Node Groups
    • Recommendations
    • Teams
    • Departments
    • Cost Explorer
    • Cost Trends
Docs homev1Api ReferenceClusters

API Reference

Clusters

List and fetch the Kubernetes clusters in your tenant. Filter by provider, region, environment, and status. Default sort is hourly run rate descending.


Two endpoints cover the cluster surface: a paginated list with filters and a single-cluster lookup by UUID. Both return a Cluster body with metadata, capacity, utilization, and cost.

GET /v1/clusters returns the inventory across every cluster the API key is allowed to see. GET /v1/clusters/{cluster_id} returns one cluster's full body. Both require the clusters:read scope. Neither accepts ?cost_mode=; see Cost Modes for details.

Staleness

metadata.is_stale flips to true when the last agent heartbeat is older than 180 seconds or last_seen_at is null. While stale, utilization and cost reflect the last successful agent snapshot, not live data.

  • Stale clusters are excluded from Organization.utilization.counts.connected_clusters. They still count toward clusters. See Organization.
  • Staleness is orthogonal to status. A cluster can be status=active and is_stale=true simultaneously — the agent has gone quiet without the cluster being marked disconnected. Filter on is_stale to detect this, not on status.

List clusters

GET /v1/clusters

Required scope: clusters:read

Returns the cluster inventory across the API key's allowed clusters. Default sort is cost.current_run_rate_hourly DESC.

Filters combine with AND. Each filter is a comma-separated list interpreted as an OR within that filter: provider=aws,gcp means "AWS or GCP", status=active,disconnected means "either status". Pass standard pagination via limit, cursor, and include_total; see Pagination & Filtering for the full cursor contract.

Query parameters

NameTypeDefaultAllowed valuesDescription
limitinteger1001..500Page size.
cursorstring--Opaque pagination token from a previous response.
include_totalbooleanfalsetrue, falseInclude meta.pagination.total_count. Opt-in.
providerstring-aws, gcp, azure, on-prem (csv)Filter by cloud provider.
regionstring--Filter by region (csv).
environmentstring-production, non-production, staging, dev (csv)Filter by environment tag.
statusstring-pending, active, disconnected, error, discovered (csv)Filter by cluster status. Lowercase only.

Enum filters are case-sensitive: provider=AWS returns a 422, not an empty list. The error response echoes the allowed set under error.details[0].allowed.

Example request

bash
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/clusters?provider=aws,gcp&status=active&limit=20&include_total=true"

Example response

json
1{
2  "data": [
3    {
4      "id": "c1a2b3c4-d5e6-7890-abcd-ef1234567890",
5      "kind": "Cluster",
6      "metadata": {
7        "name": "prod-eu-west-1",
8        "provider": "aws",
9        "service": "EKS",
10        "region": "eu-west-1",
11        "availability_zones": ["eu-west-1a", "eu-west-1b", "eu-west-1c"],
12        "environment": "production",
13        "status": "active",
14        "is_stale": false,
15        "k8s_version": "1.29.5",
16        "agent_version": "1.18.2",
17        "discovery_source": "agent",
18        "created_at": "2025-11-08T14:22:31Z",
19        "last_seen_at": "2026-05-21T10:29:42Z"
20      },
21      "capacity": {
22        "cpu": { "total_cores": 256.0, "allocatable_cores": 240.8 },
23        "memory": { "total_bytes": 1099511627776, "allocatable_bytes": 1023820300288 },
24        "gpu": { "total": 8, "allocatable": 8, "model": "NVIDIA A10G" },
25        "storage": { "total_bytes": 21474836480000 },
26        "pods": { "allocatable": 7392 }
27      },
28      "utilization": {
29        "cpu": { "requested_cores": 184.2, "used_cores": 142.7, "utilization_percent": 55.8 },
30        "memory": { "requested_bytes": 769527797760, "used_bytes": 612918427648, "utilization_percent": 55.7 },
31        "gpu": { "utilization_percent": 62.4, "memory_used_bytes": 12884901888, "memory_total_bytes": 21474836480 },
32        "network": { "rx_bytes_total": 84293817394, "tx_bytes_total": 67419283746 },
33        "restarts_total": 142,
34        "oom_kills_total": 6,
35        "counts": {
36          "nodes": 32,
37          "namespaces": 24,
38          "workloads": 412,
39          "deployments": 287,
40          "statefulsets": 64,
41          "daemonsets": 12,
42          "jobs": 38,
43          "cronjobs": 11,
44          "pods": 1247,
45          "running_pods": 1218,
46          "containers": 2891,
47          "running_containers": 2842,
48          "persistent_volumes": 94
49        }
50      },
51      "cost": {
52        "current_run_rate_hourly": { "amount": "147.2400", "currency": "USD" },
53        "last_updated_at": "2026-05-21T10:29:48Z"
54      }
55    },
56    {
57      "id": "a8d3e1b2-f4c6-4789-9bde-2345678901cd",
58      "kind": "Cluster",
59      "metadata": {
60        "name": "staging-us-central1",
61        "provider": "gcp",
62        "service": "GKE",
63        "region": "us-central1",
64        "availability_zones": ["us-central1-a", "us-central1-b"],
65        "environment": "staging",
66        "status": "active",
67        "is_stale": false,
68        "k8s_version": "1.30.1",
69        "agent_version": "1.18.2",
70        "discovery_source": "agent",
71        "created_at": "2026-02-17T11:04:09Z",
72        "last_seen_at": "2026-05-21T10:29:51Z"
73      },
74      "capacity": {
75        "cpu": { "total_cores": 96.0, "allocatable_cores": 88.4 },
76        "memory": { "total_bytes": 412316860416, "allocatable_bytes": 381344419840 },
77        "gpu": { "total": 0, "allocatable": 0, "model": "" },
78        "storage": { "total_bytes": 4294967296000 },
79        "pods": { "allocatable": 2640 }
80      },
81      "utilization": {
82        "cpu": { "requested_cores": 41.6, "used_cores": 28.9, "utilization_percent": 32.7 },
83        "memory": { "requested_bytes": 142473041920, "used_bytes": 98248129024, "utilization_percent": 25.8 },
84        "gpu": { "utilization_percent": 0.0, "memory_used_bytes": 0, "memory_total_bytes": 0 },
85        "network": { "rx_bytes_total": 18293742918, "tx_bytes_total": 12048372619 },
86        "restarts_total": 47,
87        "oom_kills_total": 1,
88        "counts": {
89          "nodes": 12,
90          "namespaces": 9,
91          "workloads": 88,
92          "deployments": 62,
93          "statefulsets": 14,
94          "daemonsets": 8,
95          "jobs": 3,
96          "cronjobs": 1,
97          "pods": 234,
98          "running_pods": 229,
99          "containers": 481,
100          "running_containers": 473,
101          "persistent_volumes": 22
102        }
103      },
104      "cost": {
105        "current_run_rate_hourly": { "amount": "42.1800", "currency": "USD" },
106        "last_updated_at": "2026-05-21T10:29:52Z"
107      }
108    }
109  ],
110  "meta": {
111    "request_id": "req_01J5K4A1B7C9DE2F4G6H8J0K2M",
112    "applied_at": "2026-05-21T10:30:00Z",
113    "pagination": {
114      "next_cursor": "eyJ2IjoxLCJhZnRlcl9pZCI6ImE4ZDNlMWIyLWY0YzYtNDc4OS05YmRlLTIzNDU2Nzg5MDFjZCIsImFmdGVyX3ZhbHVlIjoiNDIuMTgwMCIsInF1ZXJ5X2hhc2giOiJhM2I0YzVkNmU3ZjhnOWEwYjFjMmQzZTRmNWc2IiwiaXNzdWVkX2F0IjoxNzE2Mjg1MDAwfQ",
115      "has_more": true,
116      "limit": 20,
117      "total_count": 6
118    }
119  }
120}

Two elements shown for brevity. next_cursor is displayed for shape clarity; a single-page response sets has_more: false and either omits next_cursor or returns it as an empty string.

Example error response

json
1{
2  "data": null,
3  "meta": {
4    "request_id": "req_01J5K4A1B7C9DE2F4G6H8J0K2N",
5    "applied_at": "2026-05-21T10:30:01Z"
6  },
7  "error": {
8    "code": "CLUSTER_NOT_FOUND",
9    "message": "cluster not found in tenant",
10    "details": [
11      { "field": "cluster_id", "reason": "not_found" }
12    ]
13  }
14}

That code comes back from GET /v1/clusters/{cluster_id} when the UUID is well-formed but no cluster in your tenant matches. See Error Handling for the full mapping.

Common errors

HTTPerror.codeWhen
400BAD_REQUESTMalformed query, bad limit.
400INVALID_CURSORcursor couldn't be decoded.
401UNAUTHORIZEDMissing or invalid Bearer token.
403FORBIDDENToken lacks the clusters:read scope.
410CURSOR_EXPIREDCursor older than 24h or query parameters changed since it was issued.
422VALIDATION_ERROREnum filter value isn't in the allowed set (e.g. provider=aliyun, status=Active).
422INVALID_COST_MODE?cost_mode= was supplied, not accepted on this endpoint.
429RATE_LIMITEDPer-key quota exceeded.
500INTERNAL_ERRORServer-side failure.

Get cluster by ID

GET /v1/clusters/{cluster_id}

Required scope: clusters:read

Returns one cluster's full body, the same shape as a data[] element on the list endpoint.

Path parameters

NameTypeDescription
cluster_idUUIDCluster identifier. Must be a valid UUID, INVALID_CLUSTER_ID (400) otherwise.

Example request

bash
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/clusters/b7e22c91-8d34-4f5a-9c1e-0d8e3a4b5f76"

Example response

Returns a single Cluster object. Same shape as one element of the List clusters response above, wrapped directly under data (no array, no pagination in meta).

json
1{
2  "data": {
3    "id": "b7e22c91-8d34-4f5a-9c1e-0d8e3a4b5f76",
4    "kind": "Cluster",
5    "metadata": { "name": "prod-us-east-1", "provider": "aws", "service": "EKS", "region": "us-east-1", "environment": "production", "status": "active", "is_stale": false, "...": "..." },
6    "capacity": { "...": "..." },
7    "utilization": { "...": "..." },
8    "cost": { "current_run_rate_hourly": { "amount": "98.1200", "currency": "USD" }, "last_updated_at": "2026-05-21T10:29:48Z" }
9  },
10  "meta": {
11    "request_id": "req_01J5K4B3D8F0HJ4K6M8N0P2Q4R",
12    "applied_at": "2026-05-21T10:30:00Z"
13  }
14}

For the complete field list, see the canonical example in List clusters or the OpenAPI spec.

Common errors

HTTPerror.codeWhen
400INVALID_CLUSTER_IDcluster_id isn't a valid UUID.
401UNAUTHORIZEDMissing or invalid Bearer token.
403FORBIDDENToken lacks the clusters:read scope.
403CLUSTER_ACCESS_DENIEDUUID is valid and the cluster exists, but the API key's allowlist excludes it.
404CLUSTER_NOT_FOUNDUUID is well-formed but no cluster in the tenant matches.
422INVALID_COST_MODE?cost_mode= was supplied.
429RATE_LIMITEDPer-key quota exceeded.
500INTERNAL_ERRORServer-side failure.

See also

  • Namespaces, drill from a cluster into its namespaces and their cost breakdown.
  • Workloads, list workloads scoped to one cluster via /v1/clusters/{cluster_id}/workloads.
  • Nodes, node inventory and node-group aggregates per cluster.
  • Organization, the tenant-wide rollup; connected_clusters excludes stale ones.
  • Cost Trends, hourly/daily/weekly/monthly cost time series for a single cluster.

Related

  • Namespaces
  • Nodes
  • Organization
  • Cost Trends
PreviousOrganizationAPI ReferenceNextNamespacesAPI Reference

On this page

  • Staleness
  • List clusters
  • Query parameters
  • Example request
  • Example response
  • Example error response
  • Common errors
  • Get cluster by ID
  • Path parameters
  • Example request
  • Example response
  • Common errors
  • See also
Edit this page
Kubeadapt

Kubernetes FinOps platform. Cost visibility, rightsizing, and capacity planning that pays for itself in 30 days.

Product

  • Cost Monitoring
  • Cost Attribution
  • Workload Rightsizing
  • Recommendations
  • Smart Alerting
  • Best Practices
  • Network Cross-AZ

Resources

  • Documentation
  • Status Page
  • Feature Requests

Company

  • About Us
  • Security
  • Careers
  • Contact

© 2026 Kubeadapt. All rights reserved.

PrivacyTermsSecurity