Skip to content

API Reference

Cost Trends

Cost over time at hourly, daily, weekly or monthly granularity: five scope-specific endpoints that share one query model and one response shape.

Last updated


Cost-trend endpoints return time-series cost data for one resource scope: cluster, namespace, workload, node-group, or the whole organization. Five endpoints, a common parameter set (the node-group endpoint omits cost_mode — see exception), one response shape (CostTrendSeries).

Endpoints

ScopeEndpointRequired scopecost_mode
ClusterGET /v1/clusters/{cluster_id}/cost-trendclusters:readdefault fully_loaded
NamespaceGET /v1/clusters/{cluster_id}/namespaces/{namespace}/cost-trendnamespaces:readdefault workload_only
WorkloadGET /v1/clusters/{cluster_id}/workloads/by-uid/{workload_uid}/cost-trendworkloads:readdefault workload_only
Node-groupGET /v1/clusters/{cluster_id}/node-groups/{name}/cost-trendnodes:readrejected (422 INVALID_COST_MODE)
OrganizationGET /v1/organizations/dashboard/cost-trendorganization:readdefault fully_loaded

Path-parameter notes:

  • cluster_id, workload_uid are UUIDs.
  • namespace is the human-readable Kubernetes namespace name (not metadata.uid).
  • name (node-group) is the node_group label value. URL-encode characters such as : and ,.

Query parameters

Four of the five endpoints share the same parameter set. The node-group endpoint accepts the same parameters except cost_mode — see the note below.

ParameterRequiredTypeDefaultDescription
startyesinteger (unix epoch seconds, UTC)—Window start.
endyesinteger (unix epoch seconds, UTC)—Window end. Must be greater than start. Window must not exceed 5 years.
typenoenumrun_raterun_rate: each bucket's burn rate projected to a full month. breakdown: actual cost summed per bucket.
granularitynoenumautoauto, hourly, daily, weekly, monthly. See granularity rules.
cost_modenoenumscope-dependent (table above)fully_loaded or workload_only. Not accepted on the node-group endpoint — see node-group exception.
basisnoenumlegacylegacy or all. See Cost basis.

Node-group cost_mode exception

The node-group cost-trend endpoint rejects ?cost_mode= with 422 INVALID_COST_MODE, even when the value is fully_loaded or workload_only. Nodes carry a single physical cloud bill, so a node-group aggregate (the union of nodes sharing a node_group label) is mode-invariant. meta.cost_mode is omitted from the response.

This matches the rejection rule on the node-group listing and detail endpoints — see Cost Modes.

Granularity rules

GranularityBehavior
auto (default)Resolves to hourly for windows up to 14 days (inclusive) when hourly data answers the request exactly (see below), otherwise daily. The resolved value appears in data.granularity.
hourlyCapped at 60-day windows. Requests with a larger window return 422 VALIDATION_ERROR.
daily, weekly, monthlyNo window cap below the 5-year ceiling.

Hourly data answers a request exactly only when all of these hold:

  • type=run_rate (the default).
  • basis=legacy (the default).
  • On the cluster and organization endpoints, cost_mode=fully_loaded (the default). The namespace and workload endpoints serve hourly in both modes.

Asking for granularity=hourly outside these cases returns 422 VALIDATION_ERROR with details[0].field set to granularity; auto uses daily for them at any window length. So a total never changes because a window crossed the 14-day line.

Response

json
1{
2  "data": {
3    "kind": "CostTrend",
4    "scope": "cluster",
5    "scope_ref": {
6      "cluster_id": "c1a2b3c4-d5e6-7890-abcd-ef1234567890"
7    },
8    "start": "2026-05-01T00:00:00Z",
9    "end": "2026-05-08T00:00:00Z",
10    "granularity": "hourly",
11    "type": "run_rate",
12    "points": [
13      {
14        "bucket_start": "2026-05-01T00:00:00Z",
15        "total_cost": { "amount": "12.4700", "currency": "USD" }
16      },
17      {
18        "bucket_start": "2026-05-01T01:00:00Z",
19        "total_cost": { "amount": "12.5100", "currency": "USD" }
20      }
21    ]
22  },
23  "meta": {
24    "request_id": "0196f1c2-c994-7705-b234-4b214a91a07f",
25    "applied_at": "2026-05-21T10:30:00Z",
26    "cost_mode": "fully_loaded"
27  }
28}

Top-level fields

FieldTypeDescription
kindstringAlways "CostTrend".
scopeenumcluster, namespace, workload, node-group, or organization. Matches the endpoint called.
scope_refobjectIdentifies the entity. Field presence varies by scope (see scope_ref shape). Omitted for organization.
startstringRFC 3339 UTC anchor of the window start.
endstringRFC 3339 UTC anchor of the window end.
granularityenumPost-resolution value. Always one of hourly, daily, weekly, monthly. Never auto.
typeenumEchoes the requested type (run_rate or breakdown).
pointsarrayOne entry per bucket. Always an array — empty windows serialize as [], never null.
excluded_cluster_idsstring[]Present only on organization scope. The clusters left out of the series because they have not reported for 15 minutes, sorted. [] when none.

scope_ref shape

ScopeFields
clustercluster_id
namespacecluster_id, namespace
workloadcluster_id, workload_uid
node-groupcluster_id, node_group
organizationomitted

Bucket fields

FieldTypeDescription
bucket_startstringRFC 3339 UTC anchor of the bucket (start of hour, day, week, or month).
total_costMoney{amount, currency}. amount is a decimal string.
components, unallocated, basis, partialThe bucket's cost block fields.

Empty-result behavior

A key that may read no cluster at all gets 403 CLUSTER_ACCESS_DENIED with details[0].reason set to no_cluster_in_scope, on every endpoint including the organization one. The cluster, namespace, workload and node-group endpoints check the path's cluster first, in the order described in Routes under a cluster. A window with no cost returns 200 OK with points: [].

Errors

HTTPerror.codeCause
400INVALID_CLUSTER_IDcluster_id is not a valid UUID.
401UNAUTHORIZEDMissing or invalid Bearer token.
403FORBIDDENAPI key lacks the scope this endpoint requires.
403CLUSTER_ACCESS_DENIEDAPI key cannot reach the cluster in the path, or may read no cluster at all (no_cluster_in_scope).
404CLUSTER_NOT_FOUNDNo cluster with the path's ID exists in your organization.
404NAMESPACE_NOT_FOUND / WORKLOAD_NOT_FOUND / NODE_GROUP_NOT_FOUNDPath-bound resource does not exist in the cluster.
422VALIDATION_ERRORstart or end missing (details[0] is { "field": "start", "reason": "required" }), workload_uid is not a valid UUID, start/end is not a numeric epoch timestamp, end ≤ start, window > 5 years, granularity=hourly with a window > 60 days, granularity=hourly on a request hourly data cannot answer exactly (see granularity rules), or an unknown enum value.
422INVALID_COST_MODEcost_mode is not fully_loaded or workload_only, OR cost_mode was supplied to the node-group endpoint (which rejects the parameter — see exception).
429RATE_LIMITEDPer-key quota exceeded. Honor Retry-After.
500INTERNAL_ERRORUnhandled server error.
504UPSTREAM_TIMEOUTThe window was too expensive to compute in time. Narrow start/end or use a coarser granularity, then retry.

See Error Handling for the full catalog and retry guidance.

Examples

Hourly run-rate for one cluster, last seven days

bash
END=$(date -u +%s)
START=$(( END - 7*86400 ))   # portable on macOS and Linux

curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/clusters/c1a2b3c4-d5e6-7890-abcd-ef1234567890/cost-trend?start=$START&end=$END&type=run_rate&granularity=hourly"

Monthly breakdown for an organization, last year

bash
END=$(date -u +%s)
START=$(( END - 365*86400 ))

curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/organizations/dashboard/cost-trend?start=$START&end=$END&type=breakdown&granularity=monthly"

Workload trend with explicit cost mode

bash
curl -H "Authorization: Bearer ka_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  "https://public-api.kubeadapt.io/v1/clusters/c1a2b3c4-d5e6-7890-abcd-ef1234567890/workloads/by-uid/b9f1a342-7c5e-4d8a-9e2b-1234567890ab/cost-trend?start=1748736000&end=1749340800&granularity=daily&cost_mode=fully_loaded"

See also

  • API Overview: base URL, envelope shape, the full endpoint index.
  • Cost Modes: the fully_loaded vs workload_only contract and per-scope defaults.
  • Permission Scopes: the scopes that gate each cost-trend endpoint.
  • Error Handling: the full error code catalog and recommended retry behavior.