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 ReferenceWorkloads

API Reference

Workloads

List, filter, and inspect workloads (Deployments, StatefulSets, DaemonSets, Jobs, CronJobs, CRDs) and their pods across every connected cluster.


A workload in Kubeadapt is anything that owns pods — Deployment, StatefulSet, DaemonSet, Job, CronJob, or a custom-resource kind that fills the same role (Argo Rollout, NATS NatsCluster, GitHub EphemeralRunner, and similar). They share one Workload body. Four endpoints cover the surface: a cross-cluster list, a per-cluster scoped list, a single-workload lookup by Kubernetes metadata.uid, and a paginated pod sub-list for a workload.

All four endpoints accept ?cost_mode= and echo it on cost.cost_mode + meta.cost_mode. Both modes currently return the same amount for workload responses. See Cost Modes for the contract.

The ?kind= filter accepts only Deployment, StatefulSet, and DaemonSet. Job, CronJob, and CRD kinds (Rollout, NatsCluster, EphemeralRunner, and similar) cannot be filtered via this parameter; they still appear in unfiltered list responses with their actual metadata.workload_kind. To narrow to CRDs, omit the filter and check metadata.workload_kind in the response.

List workloads (cross-cluster)

GET /v1/workloads

Required scope: workloads:read

Flat cross-cluster list of every workload the API key can see — Deployments, StatefulSets, DaemonSets, and unfiltered CRDs. Default sort is cost.current_run_rate_hourly descending.

Query parameters

NameTypeDefaultAllowed valuesDescription
limitinteger1001..500Page size.
cursorstring(none)(any)Opaque pagination token from a previous response.
include_totalbooleanfalsetrue, falseInclude meta.pagination.total_count. Opt-in; computing the total count is a separate operation.
cost_modestringfully_loadedfully_loaded, workload_onlyCost attribution mode. See Cost Modes.
cluster_idstring (csv)(none)UUIDsScope to one or more clusters.
namespacestring (csv)(none)(any)Filter by Kubernetes namespace.
kindstring (csv)(none)Deployment, StatefulSet, DaemonSetSee the caveat above. Other kinds appear unfiltered.
has_hpaboolean(none)true, falseFilter by HorizontalPodAutoscaler presence.
teamstring (csv)(none)(any)Filter by team name (resolved via team assignments).
departmentstring (csv)(none)(any)Filter by department name (two-hop via teams).
min_cost_hourlynumber(none)decimalDrop workloads cheaper than this hourly rate.

Example request

bash
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/workloads?kind=Deployment&has_hpa=true&limit=50&include_total=true"

Example response

json
1{
2  "data": [
3    {
4      "id": "b9f1a342-7c5e-4d8a-9e2b-1234567890ab",
5      "kind": "Workload",
6      "metadata": {
7        "name": "api-gateway",
8        "workload_kind": "Deployment",
9        "namespace": "payments",
10        "cluster": {
11          "id": "c1a2b3c4-d5e6-7890-abcd-ef1234567890",
12          "name": "prod-eu-west-1"
13        },
14        "labels": {
15          "app.kubernetes.io/name": "api-gateway",
16          "team": "payments",
17          "department": "engineering"
18        },
19        "service_account_name": "api-gateway",
20        "status": "Available",
21        "status_reason": "MinimumReplicasAvailable",
22        "is_suspended": false,
23        "is_paused": false,
24        "has_hpa": true,
25        "created_at_k8s": "2025-11-14T08:42:11Z",
26        "last_seen_at": "2026-05-21T10:29:48Z"
27      },
28      "capacity": {
29        "cpu": { "limit_cores": 6.0 },
30        "memory": { "limit_bytes": 12884901888 }
31      },
32      "utilization": {
33        "cpu": {
34          "requested_cores": 3.0,
35          "used_cores": 2.18,
36          "utilization_percent": 72.7
37        },
38        "memory": {
39          "requested_bytes": 6442450944,
40          "used_bytes": 4724464025,
41          "utilization_percent": 73.3
42        },
43        "replicas": {
44          "desired": 3,
45          "available": 3,
46          "unavailable": 0,
47          "updated": 3
48        },
49        "counts": {
50          "pods": 47,
51          "running_pods": 47,
52          "containers": 94
53        }
54      },
55      "cost": {
56        "current_run_rate_hourly": { "amount": "2.4000", "currency": "USD" },
57        "cost_mode": "fully_loaded",
58        "last_updated_at": "2026-05-21T10:29:48Z"
59      }
60    },
61    {
62      "id": "f3c2d4e5-8a1b-4c2d-9e3f-0a1b2c3d4e5f",
63      "kind": "Workload",
64      "metadata": {
65        "name": "postgres-primary",
66        "workload_kind": "StatefulSet",
67        "namespace": "data",
68        "cluster": {
69          "id": "d2b3c4d5-e6f7-8901-bcde-f23456789012",
70          "name": "prod-us-east-1"
71        },
72        "labels": {
73          "app.kubernetes.io/name": "postgres",
74          "role": "primary"
75        },
76        "service_account_name": "postgres",
77        "status": "Available",
78        "status_reason": "AllReplicasReady",
79        "is_suspended": false,
80        "is_paused": false,
81        "has_hpa": false,
82        "created_at_k8s": "2025-09-02T14:08:33Z",
83        "last_seen_at": "2026-05-21T10:29:50Z"
84      },
85      "capacity": {
86        "cpu": { "limit_cores": 2.0 },
87        "memory": { "limit_bytes": 8589934592 }
88      },
89      "utilization": {
90        "cpu": {
91          "requested_cores": 1.0,
92          "used_cores": 0.42,
93          "utilization_percent": 42.0
94        },
95        "memory": {
96          "requested_bytes": 4294967296,
97          "used_bytes": 3221225472,
98          "utilization_percent": 75.0
99        },
100        "replicas": {
101          "desired": 1,
102          "available": 1,
103          "unavailable": 0,
104          "updated": 1
105        },
106        "counts": {
107          "pods": 1,
108          "running_pods": 1,
109          "containers": 2
110        }
111      },
112      "cost": {
113        "current_run_rate_hourly": { "amount": "0.8400", "currency": "USD" },
114        "cost_mode": "fully_loaded",
115        "last_updated_at": "2026-05-21T10:29:50Z"
116      }
117    }
118  ],
119  "meta": {
120    "request_id": "req_01J5K3V0Q7Y4XR8A2B3C5D7E9F",
121    "applied_at": "2026-05-21T10:30:00Z",
122    "pagination": {
123      "next_cursor": "eyJ2IjoxLCJhZnRlcl9pZCI6ImI5ZjFhMzQyLTdjNWUtNGQ4YS05ZTJiLTEyMzQ1Njc4OTBhYiIsImFmdGVyX3ZhbHVlIjoiMC44NDAwIiwicXVlcnlfaGFzaCI6ImEzYjRjNWQ2ZTdmOGc5YTBiMWMyZDNlNGY1ZzYiLCJpc3N1ZWRfYXQiOjE3MTYyODUwMDB9",
124      "has_more": true,
125      "limit": 50,
126      "total_count": 386
127    },
128    "cost_mode": "fully_loaded"
129  }
130}

Example error response

json
1{
2  "data": null,
3  "meta": {
4    "request_id": "req_01J5K3V1RQ8Z5XS9B3C4D6E8F0",
5    "applied_at": "2026-05-21T10:30:05Z"
6  },
7  "error": {
8    "code": "WORKLOAD_NOT_FOUND",
9    "message": "no workload with that uid in this tenant",
10    "details": [
11      { "field": "workload_uid", "reason": "not_found" }
12    ]
13  }
14}

Common errors

HTTPerror.codeWhen
400BAD_REQUESTMalformed UUID, bad cursor, limit out of range.
401UNAUTHORIZEDMissing or invalid Bearer token.
403FORBIDDENToken lacks the workloads:read scope.
410CURSOR_EXPIREDCursor older than 24h or filter set changed since it was issued.
422VALIDATION_ERRORkind, has_hpa, min_cost_hourly, or another filter has an unsupported value.
429RATE_LIMITED100 req/min/key by default. Honor Retry-After.

See Error Handling for the full taxonomy.

List workloads in cluster

GET /v1/clusters/{cluster_id}/workloads

Required scope: workloads:read

Same shape as the cross-cluster list, scoped to one cluster by path. The available filters and the default cost-descending sort are identical to GET /v1/workloads.

Path parameters

NameTypeDescription
cluster_idUUIDCluster identifier.

Query parameters

NameTypeDefaultAllowed valuesDescription
limitinteger1001..500Page size.
cursorstring(none)(any)Opaque pagination token.
include_totalbooleanfalsetrue, falseInclude meta.pagination.total_count.
cost_modestringfully_loadedfully_loaded, workload_onlyCost attribution mode.
namespacestring (csv)(none)(any)Filter by namespace.
kindstring (csv)(none)Deployment, StatefulSet, DaemonSetSee the caveat above.
has_hpaboolean(none)true, falseHPA filter.
teamstring (csv)(none)(any)Filter by team name.
departmentstring (csv)(none)(any)Filter by department name.
min_cost_hourlynumber(none)decimalMinimum hourly cost.

Example request

bash
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/clusters/c1a2b3c4-d5e6-7890-abcd-ef1234567890/workloads?namespace=payments,checkout&limit=100"

Example response

Returns an array of Workload objects scoped to the path cluster. Same shape as the cross-cluster list above — metadata.cluster.id will match the path cluster_id on every row, and meta.pagination follows the same cursor rules.

json
1{
2  "data": [
3    {
4      "id": "e5f6a7b8-2c3d-4e5f-8a9b-0c1d2e3f4a5b",
5      "kind": "Workload",
6      "metadata": { "name": "payments-worker", "workload_kind": "Deployment", "namespace": "payments", "...": "..." },
7      "capacity": { "...": "..." },
8      "utilization": { "...": "..." },
9      "cost": { "current_run_rate_hourly": { "amount": "0.5200", "currency": "USD" }, "cost_mode": "fully_loaded", "last_updated_at": "2026-05-21T10:29:51Z" }
10    }
11  ],
12  "meta": {
13    "request_id": "req_01J5K3V2S8A6Y0DT4C5E7F9G1B",
14    "applied_at": "2026-05-21T10:30:10Z",
15    "pagination": { "next_cursor": "", "has_more": false, "limit": 100 },
16    "cost_mode": "fully_loaded"
17  }
18}

For the complete field list, see the canonical example above or the OpenAPI spec.

Common errors

HTTPerror.codeWhen
400INVALID_CLUSTER_IDcluster_id is not a valid UUID.
401UNAUTHORIZEDMissing or invalid Bearer token.
403CLUSTER_ACCESS_DENIEDToken does not include this cluster in its allowlist.
404CLUSTER_NOT_FOUNDCluster UUID well-formed but not present in the tenant.
410CURSOR_EXPIREDCursor older than 24h or filter set changed.
422VALIDATION_ERRORBad filter value (kind=Job, has_hpa=yes, and so on).
429RATE_LIMITEDPer-key quota exceeded.

Get workload by UID

GET /v1/workloads/{workload_uid}

Required scope: workloads:read

Fetch a single workload by its Kubernetes metadata.uid. The uid is the one Kubernetes stamps on the controller object: it survives spec edits (image bumps, env changes) but does not survive deletion and recreation. Names do not survive renames; uids do. Use this endpoint when you need a stable handle for cross-page links, alert payloads, or webhook targets.

Path parameters

NameTypeDescription
workload_uidUUIDThe workload's Kubernetes metadata.uid. Not a Kubeadapt internal id.

Query parameters

NameTypeDefaultAllowed valuesDescription
cost_modestringfully_loadedfully_loaded, workload_onlyCost attribution mode.

Example request

bash
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/workloads/b9f1a342-7c5e-4d8a-9e2b-1234567890ab"

Example response

Returns a single Workload object. Same shape as one element of the cross-cluster list response above, wrapped directly under data (no array, no pagination in meta).

json
1{
2  "data": {
3    "id": "b9f1a342-7c5e-4d8a-9e2b-1234567890ab",
4    "kind": "Workload",
5    "metadata": { "name": "api-gateway", "workload_kind": "Deployment", "namespace": "payments", "...": "..." },
6    "capacity": { "...": "..." },
7    "utilization": { "...": "..." },
8    "cost": { "current_run_rate_hourly": { "amount": "2.4000", "currency": "USD" }, "cost_mode": "fully_loaded", "last_updated_at": "2026-05-21T10:29:48Z" }
9  },
10  "meta": {
11    "request_id": "req_01J5K3V3T9B7Z1EU5D6F8G0H2C",
12    "applied_at": "2026-05-21T10:30:15Z",
13    "cost_mode": "fully_loaded"
14  }
15}

For the complete field list, see the canonical example in List workloads (cross-cluster) or the OpenAPI spec.

Common errors

HTTPerror.codeWhen
400BAD_REQUESTworkload_uid is not a valid UUID.
401UNAUTHORIZEDMissing or invalid Bearer token.
403FORBIDDENToken lacks the workloads:read scope.
404WORKLOAD_NOT_FOUNDUUID well-formed but no workload with that uid in this tenant.
422VALIDATION_ERRORcost_mode outside fully_loaded/workload_only.
429RATE_LIMITEDPer-key quota exceeded.

List pods for workload

GET /v1/workloads/{workload_uid}/pods

Required scope: workloads:read

The only pod-introspection surface in v1. There is no GET /v1/pods, GET /v1/clusters/{cluster_id}/pods, or GET /v1/clusters/{cluster_id}/namespaces/{namespace}/pods — pods are always returned as children of a single workload identified by its Kubernetes uid. A "list every pod in cluster X" query requires walking workloads first and calling this endpoint per workload.

Path parameters

NameTypeDescription
workload_uidUUIDThe owning workload's Kubernetes metadata.uid.

Query parameters

NameTypeDefaultAllowed valuesDescription
limitinteger1001..500Page size.
cursorstring(none)(any)Opaque pagination token.
include_totalbooleanfalsetrue, falseInclude meta.pagination.total_count.
cost_modestringfully_loadedfully_loaded, workload_onlyCost attribution mode.
namespacestring (csv)(none)(any)Filter by namespace.
node_uidstring (csv)(none)UUIDsFilter by host node uid.
phasestring (csv)(none)Pending, Running, Succeeded, Failed, UnknownKubernetes pod phase.
qos_classstring (csv)(none)Guaranteed, Burstable, BestEffortQuality-of-service class.
has_hostpathboolean(none)true, falseFilter by hostPath volume presence.
has_emptydirboolean(none)true, falseFilter by emptyDir volume presence.
host_networkboolean(none)true, falseFilter by hostNetwork=true.

Example request

bash
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/workloads/b9f1a342-7c5e-4d8a-9e2b-1234567890ab/pods?phase=Running&qos_class=Burstable"

Example response

json
1{
2  "data": [
3    {
4      "id": "p1q2r3s4-5t6u-7v8w-9x0y-1z2a3b4c5d6e",
5      "kind": "Pod",
6      "metadata": {
7        "name": "api-gateway-7fbd9d8c4-abc12",
8        "namespace": "payments",
9        "cluster": {
10          "id": "c1a2b3c4-d5e6-7890-abcd-ef1234567890",
11          "name": "prod-eu-west-1"
12        },
13        "workload": {
14          "uid": "b9f1a342-7c5e-4d8a-9e2b-1234567890ab",
15          "kind": "Deployment",
16          "name": "api-gateway"
17        },
18        "node": {
19          "id": "n1a2b3c4-d5e6-7890-abcd-ef0987654321",
20          "name": "ip-10-0-12-34.eu-west-1.compute.internal"
21        },
22        "phase": "Running",
23        "reason": "",
24        "qos_class": "Burstable",
25        "pod_ip": "10.0.12.34",
26        "host_ip": "10.0.0.124",
27        "host_network": false,
28        "priority_class": "production",
29        "has_hostpath": false,
30        "has_emptydir": true,
31        "labels": {
32          "app.kubernetes.io/name": "api-gateway",
33          "pod-template-hash": "7fbd9d8c4"
34        },
35        "created_at_k8s": "2026-05-19T06:18:42Z",
36        "last_seen_at": "2026-05-21T10:29:48Z"
37      },
38      "capacity": {
39        "cpu": { "limit_cores": 2.0 },
40        "memory": { "limit_bytes": 4294967296 }
41      },
42      "utilization": {
43        "cpu": {
44          "requested_cores": 1.0,
45          "used_cores": 0.73,
46          "utilization_percent": 73.0
47        },
48        "memory": {
49          "requested_bytes": 2147483648,
50          "used_bytes": 1610612736,
51          "utilization_percent": 75.0
52        },
53        "counts": {
54          "containers": 2,
55          "running_containers": 2,
56          "ready_containers": 2
57        },
58        "restarts_total": 0,
59        "oom_kills_total": 0
60      },
61      "cost": {
62        "current_run_rate_hourly": { "amount": "0.0840", "currency": "USD" },
63        "cost_mode": "fully_loaded",
64        "last_updated_at": "2026-05-21T10:29:48Z"
65      }
66    }
67  ],
68  "meta": {
69    "request_id": "req_01J5K3V4U0C8A2FV6E7G9H1J3D",
70    "applied_at": "2026-05-21T10:30:20Z",
71    "pagination": {
72      "next_cursor": "eyJ2IjoxLCJhZnRlcl9pZCI6InAxcTJyM3M0LTV0NnUtN3Y4dy05eDB5LTF6MmEzYjRjNWQ2ZSIsImFmdGVyX3ZhbHVlIjoiMC4wODQwIiwicXVlcnlfaGFzaCI6ImQ0ZTVmNmc3aDhpOWowYTFiMmMzZDRlNWY2ZzciLCJpc3N1ZWRfYXQiOjE3MTYyODUwMjB9",
73      "has_more": true,
74      "limit": 100
75    },
76    "cost_mode": "fully_loaded"
77  }
78}

Common errors

HTTPerror.codeWhen
400BAD_REQUESTworkload_uid is not a valid UUID, or another path/query value is malformed.
401UNAUTHORIZEDMissing or invalid Bearer token.
403FORBIDDENToken lacks the workloads:read scope.
404WORKLOAD_NOT_FOUNDNo workload with that uid in this tenant.
410CURSOR_EXPIREDCursor older than 24h or filter set changed.
422VALIDATION_ERRORphase, qos_class, or a boolean filter has an unsupported value. The error detail names the offending field.
429RATE_LIMITEDPer-key quota exceeded.

See also

  • Clusters: the top-level resource that owns every workload returned here.
  • Namespaces: group workloads by Kubernetes namespace and read namespace-level cost.
  • Nodes: resolve the node a pod runs on (metadata.node.id) to its instance type and spot/on-demand status.
  • Recommendations: workload_rightsizing findings for the workloads listed above.
  • Cost Modes: fully_loaded vs workload_only and which endpoints accept each mode.
  • Cost Trends: per-workload cost time series by k8s metadata.uid.

Related

  • API Overview
  • Clusters
  • Recommendations
  • Cost Trends
PreviousNamespacesAPI ReferenceNextNodesAPI Reference

On this page

  • List workloads (cross-cluster)
  • Query parameters
  • Example request
  • Example response
  • Example error response
  • Common errors
  • List workloads in cluster
  • Path parameters
  • Query parameters
  • Example request
  • Example response
  • Common errors
  • Get workload by UID
  • Path parameters
  • Query parameters
  • Example request
  • Example response
  • Common errors
  • List pods for workload
  • Path parameters
  • Query 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