Skip to content

Get the authoritative month-to-date cost breakdown

GET
/api/v1/organizations/{orgID}/billing/breakdown
curl --request GET \
--url https://api.aetherplatform.cloud/api/v1/organizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/billing/breakdown \
--header 'Authorization: Bearer <token>'

Returns the current UTC month’s authoritative cost breakdown: flat monthly subscriptions (fixed pools, control plane, packages and package overage, public API endpoints and load balancers) plus server-priced usage — one line per node pool, resource type and node size, at list price — with a reconciled subtotal in euros. A pool whose node size changed during the month therefore yields one line per size for the resource that changed; quantity on each line is still size × hours (node_size × node_hours). Storage usage (registry and persistent volumes) rides the same list and has no node dimension. The lines are at list price: gross_amount_eur equals amount_eur and discount_eur is 0 here, because an organization’s discount is priced into the invoice when it is issued, not into this month-to-date view. The subtotal reconciles to UsageSummary.total_eur (to display precision; exact-cents parity lands with invoice generation in Phase 4) — this endpoint is the single source of truth for the month’s bill (unlike /billing/daily-spend, which is autoscaling-only). Each usage line carries the server-computed unit_price_eur (per resource-hour), unit_price_month_eur (the rate card’s per-unit monthly price) and amount_eur.

orgID
required
string format: uuid

Organization UUID.

The authoritative cost breakdown.

Media typeapplication/json
object
org_id
required
string format: uuid
period_start
required
string format: date-time
period_end
required
string format: date-time
subscriptions
required

Flat monthly committed fees: fixed pools, control plane, packages and package overage, public API endpoints and load balancers (see SubscriptionLine.kind).

Array<object>
object
kind
required

Which flat monthly charge this line is. plan is a package fee and plan_overage the resources beyond its allowance (both cluster-scoped, with a null node_pool_id); public_ip is the mandatory public API endpoint every cluster is required to have — one line per cluster per month at the published public_ip rate (€4 at the time of writing), a flat month locked the first time the billing sampler observes the endpoint address, so replacing that address within the month does not add a line; loadbalancer, by contrast, is one line per public load-balancer address, so a cluster with several produces several.

string
Allowed values: node_pool control_plane plan plan_overage public_ip loadbalancer
cluster_id
string | null format: uuid
node_pool_id
string | null format: uuid
name
required
string
amount_eur
required
number format: double
gross_amount_eur
required
number format: double
discount_eur
required
number format: double
autoscaling
required

Server-priced usage at list price: one line per node pool, resource type and node size, followed by the storage lines.

Array<object>

One priced usage line of the cost breakdown: one line per node pool, resource type and node size, at list price. A pool whose nodes changed size during the month yields one line per size for the resource that changed, so every line states a single size and the hours run at it. Storage usage (registry, storage_block, storage_rwx) rides the same list with no node dimension.

object
node_pool_id
string | null format: uuid
pool_name
required

The node pool’s name; on a storage line, the display name of what is stored (the registry, or a cluster’s volumes).

string
resource_type
required

What the line meters. vcpu, memory and disk are node resources (these carry node_size and node_hours); registry, storage_block and storage_rwx are storage usage with no node dimension.

string
Allowed values: vcpu memory disk registry storage_block storage_rwx
charge_kind
required

The key a discount’s scope is matched against. For a usage line it is the line’s resource_type.

string
unit
required
string
node_size
required

The per-node quantity of the resource (4 for a 4-vCPU node, 50 for a 50 GB node disk). Always present; 0 — not omitted — on a line with no node dimension (storage). Contrast InvoiceLineItem.node_size, which is omitted there.

number format: double
node_hours
required

How many node-hours ran at node_size. Always present; 0 — not omitted — on a line with no node dimension (storage). Contrast InvoiceLineItem.node_hours, which is omitted there.

integer format: int64
quantity
required

Billed resource-hours: size × hours, i.e. node_size × node_hours on a node line (its meaning is unchanged by the two fields above); GiB-hours on a storage line.

number format: double
unit_price_eur
required

Server-computed per-resource-hour rate from the rate card.

number format: double
unit_price_month_eur
required

The rate card’s price per unit per MONTH — the published list price (unit_price_eur is this divided by 730 hours). Carried separately because it cannot be recovered from the hourly rate once that has been rounded.

number format: double
gross_amount_eur
required

The line at list price, before any discount.

number format: double
discount_eur
required

The discount on the line. 0 in the cost breakdown today: an organization’s discount is priced in when the invoice is issued (see InvoiceLineItem.discount_cents), not in this month-to-date view.

number format: double
amount_eur
required

Server-computed line cost (quantity × unit_price_eur); the net, gross_amount_eur − discount_eur.

number format: double
subtotal_eur
required

Reconciled month-to-date total (subscriptions + autoscaling). Reconciles to UsageSummary.total_eur to display precision — equal by linearity of the rate card, but float64 round-then-sum vs sum-then-multiply can differ by a few ULPs. Exact-cents parity lands with invoice generation in Phase 4.

number format: double
Example
{
"subscriptions": [
{
"kind": "node_pool"
}
],
"autoscaling": [
{
"resource_type": "vcpu"
}
]
}

Missing or invalid credentials.

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable error code.

string
message
required
string
details
Array<object>
object
field
required
string
code
required
string
message
required
string
status_url

The platform status page (https://status.aetherplatform.cloud). Present on 5xx answers written by the API’s error writer and on no other; absent, not null, on 4xx.

string format: uri
decline_code

The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.

string
invoice_id

Present on exactly these errors of the invoice pay and pay/confirm endpoints: 402 payment_declined, 402 payment_method_required, 409 invoice_already_paid, 409 invoice_not_issued, 409 invoice_below_minimum, 409 payment_not_in_flight, and 409 invoice_void when the void invoice was replaced. It is the id of the live invoice, which after a re-issue is the replacement and not the id in the request URL (on 409 invoice_void from pay/confirm it is the replacement’s id). Absent on every other error — 400 (including discount_code_invalid), 403, 404, the discount_* 409s, 409 invoice_void with no replacement (nothing live to name), every 5xx and 503 code — and never null.

string format: uuid
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": [
{
"field": "example",
"code": "example",
"message": "example"
}
],
"status_url": "https://example.com",
"decline_code": "example",
"invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}
}

Refused by the organization role policy (see Authorization in the API description). error.code is forbidden when the caller is not a member of the organization (or the API token belongs to another organization), insufficient_role when the caller’s organization role is below the operation’s minimum role, and token_not_permitted when the request was authenticated with an API token on an operation API tokens may not use (the API Tokens operations; the handler-gated operations named in the API description: deleting the organization, changing a member’s role or payment_mode, paying an invoice including its confirm step, and discounts; and for a cluster-pinned machine token every operation except the loadbalancer-ips and loadbalancer-vms operations). email_unverified when a portal user’s e-mail address is not verified (see Authentication).

Media typeapplication/json
object
error
required
object
code
required

A stable, machine-readable error code.

string
message
required
string
details
Array<object>
object
field
required
string
code
required
string
message
required
string
status_url

The platform status page (https://status.aetherplatform.cloud). Present on 5xx answers written by the API’s error writer and on no other; absent, not null, on 4xx.

string format: uri
decline_code

The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.

string
invoice_id

Present on exactly these errors of the invoice pay and pay/confirm endpoints: 402 payment_declined, 402 payment_method_required, 409 invoice_already_paid, 409 invoice_not_issued, 409 invoice_below_minimum, 409 payment_not_in_flight, and 409 invoice_void when the void invoice was replaced. It is the id of the live invoice, which after a re-issue is the replacement and not the id in the request URL (on 409 invoice_void from pay/confirm it is the replacement’s id). Absent on every other error — 400 (including discount_code_invalid), 403, 404, the discount_* 409s, 409 invoice_void with no replacement (nothing live to name), every 5xx and 503 code — and never null.

string format: uuid
Examplegenerated
{
"error": {
"code": "example",
"message": "example",
"details": [
{
"field": "example",
"code": "example",
"message": "example"
}
],
"status_url": "https://example.com",
"decline_code": "example",
"invoice_id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0"
}
}