Skip to main content

FinOps Costs

Read platform cost figures: cost per month, day, or any hourly, daily, weekly, or monthly point; cost by resource type, resource, organization, user, or namespace; the most expensive resources; CPU and memory efficiency; anomalies; the forecast; rightsizing savings; the dashboard's figures; and cost data collection health. Every figure comes from the same hourly cost record that budgets are charged from (see Where the figures come from).

All endpoints are read-only and require an API key in the X-API-Key header with the finops:read scope.

Every figure is scoped to the key's user: a platform administrator sees every cost on the platform, including the platform baseline; on a multi-tenant platform an organization's owners and admins see their organization's costs; anyone else sees the costs of their own workloads. Filters narrow within that scope and never widen it.

Amounts are US dollars, except the spend fields of the dashboard statistics, which are integer US cents. Days, weeks, and months are UTC.


Windows​

Endpoints that take a window or period accept:

ValueMeaning
Nh, Nd, Ny (for example 24h, 7d, 1y)The last N hours, days (24 hours each), or years (365 days each), in whole hours counted back from the current hour. The current hour is not included.
mtdThis UTC calendar month so far
lastweekThe previous UTC calendar week, Monday to Monday
lastmonthThe previous UTC calendar month
start,endTwo ISO 8601 instants or dates. A bare start date is its 00:00 UTC; a bare end date is included.

Each hour's cost is added once the hour ends. An unknown window returns 400 validation-error.

Change on the previous period: where a response compares with the previous period, that period has the same length and ends where the window starts. The comparison is null when the recorded cost data does not cover all of the previous period, or when there was no cost in it.

Resource types: a resourceType filter takes a resource type such as app, addon, workflow, workspace, fine-tuning, self-hosted-model, automl, model-registry (model serving), build (image builds), data-forge, tool, mcp-gateway, scheduled-job, or project-job; platform-scaling (platform capacity caused by organizations' workloads) or platform:<organization ID> (one organization's); or platform (the platform baseline, which belongs to no organization).

Groupings: a groupBy takes resource_type, resource_id (each resource), org, user, or namespace.


Cost Point Object​

{
"date": "2026-09-01T00:00:00Z",
"total": 1234.56
}

GET /api/v1/finops/costs/monthly​

Cost per calendar month (UTC).

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
monthsintegerNoThe last N calendar months, this one included (default: 12, at least 1)
yearintegerNoOne calendar year's months instead (for example 2026)

Response 200 OK

{
"data": {
"months": [
{ "date": "2026-08-01T00:00:00Z", "total": 8123.45 },
{ "date": "2026-09-01T00:00:00Z", "total": 7420.1 }
],
"summary": {
"averageMonthly": 7771.78,
"highestMonth": { "date": "2026-08-01T00:00:00Z", "total": 8123.45 },
"lowestMonth": { "date": "2026-09-01T00:00:00Z", "total": 7420.1 }
},
"start": "2025-10-01T00:00:00Z",
"end": "2026-09-29T14:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}

Months with no recorded cost are not listed, and the average is over the months listed.


GET /api/v1/finops/costs/daily​

Cost per UTC day over a date range.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
startDatestringNoFirst day (YYYY-MM-DD or ISO 8601). Give with endDate
endDatestringNoLast day, included. Without both dates, the last 30 days
resourceTypestringNoOnly this resource type

Response 200 OK

{
"data": {
"days": [
{ "date": "2026-09-28T00:00:00Z", "total": 410.22 }
],
"summary": {
"totalPeriod": 12306.6,
"dailyAverage": 410.22,
"previousPeriod": 11980.4,
"changePercent": 2.72,
"trend": "stable"
},
"start": "2026-08-30T14:00:00Z",
"end": "2026-09-29T14:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}

changePercent compares with the previous period of the same length. trend is increasing (more than 5% up), decreasing (more than 5% down), stable, or null when there is no comparison.


GET /api/v1/finops/costs/forecast​

Daily cost projected forward from a straight line fit to the last 90 whole days of daily cost, with 95% prediction bounds. Days with no recorded cost are left out of the fit. With fewer than 3 days of history there is no projection.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
monthsintegerNoMonths to project, 30 days each (1 to 12, default: 3)

Response 200 OK

{
"data": {
"historical": [
{ "date": "2026-09-28", "cost": 410.22 }
],
"predictions": [
{
"date": "2026-09-29",
"predicted": 415.3,
"lowerBound": 362.8,
"upperBound": 467.8
}
],
"analysis": {
"trend": "increasing",
"monthlyGrowthRate": 0.021,
"confidence": "medium"
}
},
"meta": { "requestId": "req_abc123" }
}

monthlyGrowthRate is the line's growth over 30 days as a fraction of the average day (null with no projection). trend follows its sign. confidence is high, medium, or low, from how many of the 90 days have cost and how steady the daily cost was.


GET /api/v1/finops/costs/services​

Cost by resource type (apps, workflows, workspaces, models, idle node capacity, shared services, storage, and so on) over a window or a date range.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
periodstringNoA window (default: 30d). Ignored when startDate and endDate are given
startDatestringNoStart of a date range (YYYY-MM-DD or ISO 8601). Give with endDate
endDatestringNoEnd of the range (a bare date is included)

Response 200 OK

{
"data": {
"items": [
{
"groupKey": "self-hosted-model",
"name": "Self-hosted models",
"totalCost": 4321.0,
"cpuCost": 100.0,
"ramCost": 50.0,
"gpuCost": 4136.0,
"storageCost": 25.0,
"networkCost": 10.0,
"changePercent": 4.5
}
],
"totalCost": 9120.4,
"periodStart": "2026-08-30T14:00:00Z",
"periodEnd": "2026-09-29T14:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}

Items are most expensive first. changePercent compares with the previous period of the same length.


GET /api/v1/finops/costs/anomalies​

Resources whose cost on the last whole day moved from their usual day. A resource's usual day is its average daily cost over the earlier days of the lookback, counting only days it had cost, so a resource that stopped is not flagged.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
daysintegerNoDays to look back (default: 7)
sensitivitystringNolow (the day moved by at least 100%), medium (50%, the default), or high (25%)

Response 200 OK

{
"data": {
"anomalies": [
{
"timestamp": "2026-09-28T00:00:00Z",
"resource": "ingest-pipeline",
"resourceId": "Wf8kLp2qZx7mNc4vR",
"resourceType": "workflow",
"expectedCost": 12.4,
"actualCost": 31.9,
"deviation": 1.5726,
"direction": "spike",
"severity": "high"
}
],
"period": { "days": 7, "sensitivity": "medium" }
},
"meta": { "requestId": "req_abc123" }
}

deviation is how far the day moved, as a fraction of the usual day. direction is spike or drop. severity is high when the day moved by at least twice the sensitivity's threshold, otherwise medium. Anomalies are largest first.


GET /api/v1/finops/costs/savings​

Rightsizing savings over the last 30 days: resources whose pods used under 40% of the CPU and memory they requested, with the potential saving (the cost of the unused share of their CPU and memory).

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
categorystringNorightsizing, the only category
minSavingsnumberNoOnly recommendations saving at least this much (USD)

Response 200 OK

{
"data": {
"recommendations": [
{
"resource": "workflow-worker-abc",
"resourceId": "Wf8kLp2qZx7mNc4vR",
"resourceType": "workflow",
"category": "rightsizing",
"currentCost": 200.0,
"potentialSavings": 60.0,
"efficiency": 0.3,
"recommendation": "Its pods used 30% of the CPU and memory they requested. Lower the requests to match usage."
}
],
"totalPotentialSavings": 60.0,
"window": { "start": "2026-08-30T14:00:00Z", "end": "2026-09-29T14:00:00Z" }
},
"meta": { "requestId": "req_abc123" }
}

Recommendations are largest saving first.


GET /api/v1/finops/dashboard​

A FinOps overview: the last 30 days' statistics, daily cost over the last 30 days, the last 6 calendar months, and the 5 most expensive resources.

Scope: finops:read

Response 200 OK

{
"data": {
"stats": { "...": "Dashboard statistics, as GET /finops/dashboard/stats" },
"costTrend": { "...": "Daily cost, as GET /finops/costs/trends" },
"monthlyCosts": {
"months": [
{ "date": "2026-09-01T00:00:00Z", "total": 7420.1 }
],
"summary": {
"averageMonthly": 7420.1,
"highestMonth": { "date": "2026-09-01T00:00:00Z", "total": 7420.1 },
"lowestMonth": { "date": "2026-09-01T00:00:00Z", "total": 7420.1 }
}
},
"topDrivers": [ { "...": "Top driver, as GET /finops/costs/top-drivers" } ]
},
"meta": { "requestId": "req_abc123" }
}

GET /api/v1/finops/dashboard/stats​

The dashboard's statistics for a window.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
periodstringNoA window (default: 30d)

Response 200 OK

{
"data": {
"totalSpend": 1230660,
"previousPeriodSpend": 1198040,
"spendTrend": 2.72,
"monthToDateSpend": 1159830,
"activeResources": 42,
"exhaustedBudgets": 1,
"anomalies": 2,
"budgetAlerts": 3,
"efficiencyScore": 38,
"start": "2026-08-30T14:00:00Z",
"end": "2026-09-29T14:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}
FieldDescription
totalSpend, previousPeriodSpendCost for the window and for the previous period of the same length, in cents. previousPeriodSpend is null when the recorded data does not cover all of that period
spendTrendPercent change on the previous period, or null
monthToDateSpendCost this UTC calendar month so far, in cents
activeResourcesTenant resources that had cost in the window
exhaustedBudgetsBudgets in scope that reached their pause threshold
anomaliesCost anomalies in the window, at medium sensitivity
budgetAlertsexhaustedBudgets plus anomalies
efficiencyScoreCPU and memory used as a percent of requested, or null with no measured pods

GET /api/v1/finops/dashboard/top-drivers​

The most expensive resources over a window. The same as GET /finops/costs/top-drivers, with the window named period.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
limitintegerNoHow many (default: 10, at most 100)
periodstringNoA window (default: 30d)

Response 200 OK

A list of top drivers, as GET /finops/costs/top-drivers.


GET /api/v1/finops/costs/realtime​

Each resource's cost over a recent window (by default the last complete hour), with its parts and efficiency.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
windowstringNoA window (default: 1h)
namespacestringNoOnly this Kubernetes namespace

Response 200 OK

{
"data": {
"items": [
{
"name": "dev-dashboard",
"namespace": "org-acme",
"cpuCost": 0.021,
"ramCost": 0.009,
"gpuCost": 0,
"pvCost": 0.002,
"networkCost": 0,
"totalCost": 0.034,
"cpuEfficiency": 0.22,
"ramEfficiency": 0.41,
"efficiency": 0.315,
"resourceType": "app",
"resourceId": "hT7kQw2pLm9xRz4vB",
"orgId": "acme",
"userId": "okRpaKPh8B9asdKb2"
}
],
"totalCost": 1.87,
"window": "1h",
"start": "2026-09-29T13:00:00Z",
"end": "2026-09-29T14:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}

pvCost is the resource's storage cost. Efficiency fields are usage as a fraction of requests, null where no measured pod ran.


GET /api/v1/finops/costs/historical​

Cost per group over a date range.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
startDatestringNoFirst day (YYYY-MM-DD or ISO 8601). Give with endDate
endDatestringNoLast day, included. Without both dates, the last 30 days
groupBystringNoA grouping (default: resource_type)
orgIdstringNoOnly this organization
userIdstringNoOnly this user

Response 200 OK

{
"data": {
"items": [
{
"group": "workflow",
"groupLabel": "Workflows",
"totalCost": 812.4,
"cpuCost": 420.1,
"ramCost": 188.3,
"storageCost": 96.2,
"networkCost": 12.8,
"gpuCost": 0
}
],
"totalCost": 9120.4,
"startDate": "2026-09-01T00:00:00Z",
"endDate": "2026-09-29T00:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}

GET /api/v1/finops/costs/breakdown​

Cost per group with its parts, its change on the previous period, and its efficiency. The Cost Explorer's breakdown table uses the same figures.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
windowstringNoA window (default: 30d)
groupBystringNoA grouping (default: resource_type)
resourceTypestringNoOnly this resource type
orgIdstringNoOnly this organization
userIdstringNoOnly this user
namespacestringNoOnly this Kubernetes namespace

Response 200 OK

{
"data": {
"items": [
{
"group": "hT7kQw2pLm9xRz4vB",
"groupLabel": "dev-dashboard",
"totalCost": 24.6,
"computeCost": 21.3,
"cpuCost": 12.9,
"ramCost": 5.6,
"sharedCost": 2.8,
"gpuCost": 0,
"storageCost": 2.1,
"networkCost": 1.2,
"loadBalancerCost": 0,
"externalCost": 0,
"previousCost": 22.1,
"trend": 11.31,
"cpuEfficiency": 0.22,
"ramEfficiency": 0.41,
"efficiency": 0.315,
"resourceType": "app",
"resourceTypeLabel": "Apps",
"orgId": "acme",
"userId": "okRpaKPh8B9asdKb2",
"namespace": "org-acme"
}
],
"totalCost": 9120.4,
"groupBy": "resource_id",
"start": "2026-08-30T14:00:00Z",
"end": "2026-09-29T14:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}
FieldDescription
group, groupLabelThe group's key and name
totalCostCost for the window
computeCostcpuCost plus ramCost plus sharedCost (the node overhead shared into them)
gpuCost, storageCost, networkCost, loadBalancerCost, externalCostThe other parts of the cost
previousCost, trendCost in the previous period and the percent change on it. previousCost is null when the recorded data does not cover all of that period; trend is also null when there was no cost in it
cpuEfficiency, ramEfficiency, efficiencyCPU, memory, and their average used as a fraction of requested, null where no measured pod ran
resourceType, resourceTypeLabel, orgId, userId, namespaceWith groupBy=resource_id only: the resource's type, and its organization, user, and namespace when it has one

Items are most expensive first.


GET /api/v1/finops/costs/efficiency​

CPU (core-hours) and memory (byte-hours) that pods used against what they requested, overall and per group.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
windowstringNoA window (default: 30d)
groupBystringNoA grouping (default: resource_type)
resourceTypestringNoOnly this resource type
namespacestringNoOnly this Kubernetes namespace

Response 200 OK

{
"data": {
"cpuRequestedCoreHours": 1840.5,
"cpuUsedCoreHours": 512.3,
"ramRequestedByteHours": 9876543210000,
"ramUsedByteHours": 4123456789000,
"cpuEfficiency": 0.278345,
"ramEfficiency": 0.417498,
"efficiency": 0.347922,
"groupBy": "resource_type",
"byGroup": [
{
"group": "app",
"groupLabel": "Apps",
"cpuRequestedCoreHours": 720.0,
"cpuUsedCoreHours": 158.4,
"ramRequestedByteHours": 3865470566400,
"ramUsedByteHours": 1352914698240,
"cpuEfficiency": 0.22,
"ramEfficiency": 0.35,
"efficiency": 0.285
}
],
"start": "2026-08-30T14:00:00Z",
"end": "2026-09-29T14:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}

Groups are ordered by requested CPU, largest first. Cost that no pod of its own ran (a share of idle node capacity or of shared services) has no efficiency.


GET /api/v1/finops/costs/trends​

Cost per hour, day, week (weeks start on Monday), or month (UTC) over a window, with the window's total, daily average, and change on the previous period.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
windowstringNoA window (default: 30d)
granularitystringNohourly, daily (default), weekly, or monthly
groupBystringNoBreak each point down by this grouping
resourceTypestringNoOnly this resource type

Response 200 OK

{
"data": {
"points": [
{
"timestamp": "2026-09-28T00:00:00Z",
"cost": 410.22,
"breakdown": [
{ "group": "self-hosted-model", "groupLabel": "Self-hosted models", "cost": 190.4 },
{ "group": "app", "groupLabel": "Apps", "cost": 88.7 }
]
}
],
"totalCost": 12306.6,
"previousPeriodCost": 11980.4,
"changePercent": 2.72,
"dailyAverage": 410.22,
"granularity": "daily",
"start": "2026-08-30T14:00:00Z",
"end": "2026-09-29T14:00:00Z"
},
"meta": { "requestId": "req_abc123" }
}

breakdown is present only with groupBy, most expensive first. Points with no recorded cost are not listed.


GET /api/v1/finops/costs/top-drivers​

The most expensive resources over a window.

Scope: finops:read

Query Parameters

ParameterTypeRequiredDescription
windowstringNoA window (default: 30d)
limitintegerNoHow many (default: 10, at most 100)

Response 200 OK

{
"data": [
{
"name": "llama-70b",
"resourceId": "d-7c1e9a",
"resourceType": "self-hosted-model",
"resourceTypeLabel": "Self-hosted models",
"orgId": "acme",
"totalCost": 2890.5,
"computeCost": 210.3,
"cpuCost": 120.1,
"ramCost": 60.4,
"sharedCost": 29.8,
"gpuCost": 2640.0,
"storageCost": 35.2,
"networkCost": 5.0,
"loadBalancerCost": 0,
"externalCost": 0,
"previousCost": 2750.0,
"trend": 5.11,
"cpuEfficiency": 0.41,
"ramEfficiency": 0.63,
"efficiency": 0.52
}
],
"meta": { "requestId": "req_abc123" }
}

Fields are as in GET /finops/costs/breakdown, with name for the resource's name.


GET /api/v1/finops/data-health​

Cost data collection health. Platform administrators only; other keys get 403 forbidden.

Scope: finops:read

Response 200 OK

FieldDescription
statushealthy, degraded, or stale
lastScrapeAtWhen cost data was last collected
lastDataAtThe latest complete cost hour
recordCountHow many cost records there are
coverage7d, coverage30dCoverage of the last 7 and 30 days, as a percent
gapsPeriods with missing cost data

MCP tools​

The same reads are available to agents as MCP tools: get_finops_costs_monthly, get_finops_costs_daily, get_finops_cost_forecast, get_finops_costs_by_service, get_finops_cost_anomalies, get_finops_savings_recommendations, get_finops_dashboard, get_finops_dashboard_stats, get_finops_dashboard_top_drivers, get_finops_costs_realtime, get_finops_costs_historical, get_finops_cost_breakdown, get_finops_cost_efficiency, get_finops_cost_trends, get_finops_cost_top_drivers, and get_finops_data_health.