Skip to main content
This guide reads last month’s cost and usage per GVC through the API. Use it to report cost per team or environment, or to feed a FinOps tool. The same numbers are in the Console under Cost & Usage. Two APIs are involved:
  • The billing API (billing-ng.cpln.io) prices usage and covers a whole billing account.
  • The usage API (metering.cpln.io) returns raw quantities, such as core-seconds and bytes, for one org.

Prerequisites

  • To query cost for a billing account: the billing_admin or billing_viewer role on the account.
  • To query cost or usage for one org: the readMetrics permission on the org. Members of superusers have it.
  • curl and jq.

Steps

1

Get a token

Log in and print a token for your profile:
For scheduled automation, use a token that does not belong to a person. Use an org service account key with readMetrics for one org, or a billing service account token for a whole billing account.
2

Find your account ID

List your billing accounts and note the id of the one to query:
3

List the GVCs that had usage

List the values of the gvc usage tag across the account. Tag values are read by calendar month, and the month that begins at or after endTime is always included, so this returns GVCs with usage in September or October:
The same query works for workload, location, or metric. For a single org, call POST https://metering.cpln.io/org/ORG_NAME/tags/values/query with the same body.
4

Get cost per GVC

Query September’s priced workload usage, grouped by GVC:
total is in whole units of your account’s currency.
Keep metric and locationType in aggregateBy, plus any other tag your chargeable items price on, such as performanceClass for volume sets. A row is priced only when it carries every tag in its item’s consumptionTags, and an unpriced row shows "total": 0.
To cost a single org, send the same body to POST https://billing-ng.cpln.io/org/ORG_NAME/charges/-query.
5

Break usage down per workload

Query the raw quantities of one GVC’s workloads per day, from the usage API:
CPU is returned in core-seconds and memory in byte-seconds. Divide CPU by 3600 for core-hours. See metrics and units for every metric.

Automate with a Billing Service Account Token

A scheduled export should not run on a person’s token. A billing_admin can create a token that holds only the billing_viewer role:
Store the printed cpln-bsat-... value in your secret store; it is shown only once. Use it as the Bearer token for the account endpoints in the steps above, after the step that finds the account ID: GET /account lists only the accounts a person belongs to. A billing service account token does not work on the usage API or the /org/{org} billing endpoints, so use an org service account key with readMetrics for those. See billing service account tokens to list and revoke tokens.

Download Invoices

List the account’s invoices for a range, then download one as a PDF:
Invoice amounts such as totalCharge are in the smallest currency unit, so 51247 is $512.47. totalCharge is before credits; see invoices for the amount due.

Get Alerted Before Spend Grows

A billing_admin can email every billing_admin the first time the account’s charges for a month reach an amount:
See spend alert to change or remove it.

Troubleshooting

Cause: the token’s principal lacks readMetrics on the org in the path, the org is deactivated, or the token is a billing service account token, which the usage API does not accept.Fix: grant readMetrics on the org with a policy, or use a member of superusers. A new grant can take up to 5 minutes to apply.
Cause: aggregateBy drops a tag the chargeable item prices on, so no rate applies to the row.Fix: add metric and locationType to aggregateBy. Call GET https://billing-ng.cpln.io/chargeable_items to see each item’s consumptionTags.
Cause: a tag-values query (first message) or a charges query (second message, a 500) used a time with minutes or seconds, such as 2026-09-01T10:30:00Z.Fix: send UTC times on the hour, such as 2026-09-01T10:00:00Z.
Cause: hour, day, and week usage is kept for 12 months, and the query starts earlier than that.Fix: use a later startTime, or "timeStep": "month", which is kept indefinitely.
Cause: a groupBy key is missing from a consumption query’s aggregateBy.Fix: add every groupBy key to the aggregateBy of every consumption query.