API Reference
Cost Modes
Which endpoints accept ?cost_mode=fully_loaded vs workload_only, which reject it, and how the echo contract works in the response envelope.
?cost_mode= accepts two values — fully_loaded and workload_only — and controls how each response attributes cluster cost. Some endpoints accept it, some reject it, and a third group accepts it but currently returns identical amounts across both modes.
The two modes
| Mode | What it includes | Reconciles to |
|---|---|---|
fully_loaded (default) | Workload compute plus a share of cluster idle and overhead | The cloud bill |
workload_only | Workload compute only | The sum of running workloads |
fully_loaded is the chargeback number; every dollar the cluster ran reaches a workload, a team, or a department. workload_only returns workload compute in isolation.
For the methodology behind the two numbers, see How costs are computed in Core Concepts.
Where the toggle lives
cost_mode is a query parameter on endpoints that accept it:
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
"https://public-api.kubeadapt.io/v1/workloads?cost_mode=workload_only"Both values are lowercase and underscore-separated. Other strings (including loaded, unloaded, uncapped, workload-only, fully-loaded) return 422 INVALID_COST_MODE. When the parameter is absent on an accepting endpoint, the response uses fully_loaded.
The rejection matrix
Every endpoint in the API falls into one of three buckets:
| Endpoint family | ?cost_mode= behavior | Why |
|---|---|---|
/v1/clusters, /v1/clusters/{id} | Rejects with 422 INVALID_COST_MODE | A cluster maps to one physical bill. Mode is meaningless. |
/v1/nodes, /v1/clusters/{id}/nodes, /v1/nodes/{node_uid} | Rejects with 422 | A node has one on-demand or spot price. Mode is meaningless. |
/v1/node-groups, /v1/clusters/{id}/node-groups, /v1/clusters/{id}/node-groups/{name}, /v1/clusters/{id}/node-groups/{name}/cost-trend | Rejects with 422 | Node group cost (instant and time-series) is the sum of physical nodes. Mode is meaningless. |
/v1/recommendations, /v1/recommendations/{id} | Rejects with 422 | Recommendation savings are computed against a specific baseline; mode would mix accounting models. |
/v1/organization (snapshot) | Rejects with 422 | Tenant snapshot is a single billed number. |
/v1/namespaces, /v1/clusters/{id}/namespaces, /v1/clusters/{id}/namespaces/{ns} | Accepts | Both modes currently return the same amount; only the echo fields change. |
/v1/workloads, /v1/clusters/{id}/workloads, /v1/workloads/{uid}, /v1/workloads/{uid}/pods | Accepts | Both modes currently return the same amount; only the echo fields change. |
/v1/organization/dashboard | Accepts (live) | Modes return genuinely different amounts. |
/v1/teams, /v1/teams/{id}, /v1/teams/{id}/assignments | Accepts (live) | Modes return genuinely different amounts. |
/v1/departments, /v1/departments/{id} | Accepts (live) | Modes return genuinely different amounts. |
POST /v1/cost-explorer/query | Accepts (live) | Modes return genuinely different amounts. |
| Cost Trends (cluster, namespace, workload, organization) | Accepts (live) | Modes return genuinely different amounts. Per-resource default varies — see Cost Trends. The node-group cost-trend endpoint is the exception and rejects the parameter (one physical bill per node). |
The echo contract
On endpoints that accept ?cost_mode=, the chosen mode is echoed in two places in the response:
1{
2 "data": {
3 "id": "b9f1a342-7c5e-4d8a-9e2b-1234567890ab",
4 "kind": "Workload",
5 "metadata": { "name": "api-gateway", "namespace": "checkout" },
6 "cost": {
7 "current_run_rate_hourly": { "amount": "12.4800", "currency": "USD" },
8 "cost_mode": "fully_loaded",
9 "last_updated_at": "2026-05-21T10:29:00Z"
10 }
11 },
12 "meta": {
13 "request_id": "req_01J5K3V0Q7Y4XR8A2B3C5D7E9F",
14 "applied_at": "2026-05-21T10:30:00Z",
15 "cost_mode": "fully_loaded"
16 }
17}| Echo location | Meaning |
|---|---|
data.cost.cost_mode (or, on list endpoints, data[i].cost.cost_mode) | The mode that produced THIS resource's number. Each resource self-identifies. |
meta.cost_mode | The request-level mode. Useful when data is empty or you're iterating pages. |
Both fields are always equal on a single response and echo the requested ?cost_mode= value (or fully_loaded when the parameter is absent).
On rejecting endpoints, neither field appears in the response. A cluster object has no cost.cost_mode. The cluster list's meta has no cost_mode.
What 422 looks like
Sending ?cost_mode= to a rejecting endpoint:
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
"https://public-api.kubeadapt.io/v1/clusters?cost_mode=workload_only"1{
2 "data": null,
3 "meta": {
4 "request_id": "req_01J5K3V0Q7Y4XR8A2B3C5D7E9F",
5 "applied_at": "2026-05-21T10:30:00Z"
6 },
7 "error": {
8 "code": "INVALID_COST_MODE",
9 "message": "cost_mode is not supported on this endpoint (one physical bill)",
10 "details": [
11 { "field": "cost_mode", "reason": "not_supported_on_this_endpoint" }
12 ]
13 }
14}Sending a bad value to an accepting endpoint:
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
"https://public-api.kubeadapt.io/v1/workloads?cost_mode=fully-loaded"1{
2 "data": null,
3 "meta": {
4 "request_id": "req_01J5K3V0Q7Y4XR8A2B3C5D7E9G",
5 "applied_at": "2026-05-21T10:30:00Z"
6 },
7 "error": {
8 "code": "INVALID_COST_MODE",
9 "message": "cost_mode must be fully_loaded or workload_only",
10 "details": [
11 {
12 "field": "cost_mode",
13 "reason": "must_be_enum",
14 "allowed": ["fully_loaded", "workload_only"]
15 }
16 ]
17 }
18}Both surface the same INVALID_COST_MODE code with different details[0].reason values. Branch on the reason to distinguish "endpoint does not accept the parameter" from "value is not one of the two enums".
Behavior on namespaces, workloads, and pods
On the namespaces, workloads, and pods endpoints, ?cost_mode=fully_loaded and ?cost_mode=workload_only currently return the same number for cost.current_run_rate_hourly. The cost_mode echo is the only field that differs between the two responses:
1curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
2 "https://public-api.kubeadapt.io/v1/workloads/b9f1a342-7c5e-4d8a-9e2b-1234567890ab?cost_mode=fully_loaded"
3# → cost.current_run_rate_hourly.amount = "12.4800", cost_mode = "fully_loaded"
4
5curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
6 "https://public-api.kubeadapt.io/v1/workloads/b9f1a342-7c5e-4d8a-9e2b-1234567890ab?cost_mode=workload_only"
7# → cost.current_run_rate_hourly.amount = "12.4800", cost_mode = "workload_only"Picking the right mode
| Question | Mode |
|---|---|
| Last month's cluster cost | fully_loaded (matches the invoice) |
| Splitting the cluster bill across teams | fully_loaded |
| Reconciling to the AWS / GCP / Azure bill | fully_loaded |
| Workload cost in isolation (no idle, no overhead) | workload_only |
| Rightsizing comparison across workloads | workload_only |
| Cluster cost at 100% efficiency | Sum of the workload_only column |
See also
- How costs are computed, the methodology behind
fully_loadedandworkload_onlyattribution. - API Overview, the universal envelope and the endpoint index.
- Error Handling, the
INVALID_COST_MODEcode and thedetailspayload shapes. - Organization, the snapshot endpoint that rejects mode and the dashboard endpoint that honors it live.
- Workloads, the largest cost-mode-accepting list family.