Get the authoritative month-to-date cost breakdown
const url = 'https://api.aetherplatform.cloud/api/v1/organizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/billing/breakdown';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Organization UUID.
Responses
Section titled “Responses”The authoritative cost breakdown.
object
Flat monthly committed fees: fixed pools, control plane, packages and package overage, public API endpoints and load balancers (see SubscriptionLine.kind).
object
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.
Server-priced usage at list price: one line per node pool, resource type and node size, followed by the storage lines.
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
The node pool’s name; on a storage line, the display name of what is stored (the registry, or a cluster’s volumes).
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.
The key a discount’s scope is matched against. For a usage line it is the line’s resource_type.
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.
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.
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.
Server-computed per-resource-hour rate from the rate card.
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.
The line at list price, before any discount.
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.
Server-computed line cost (quantity × unit_price_eur); the net, gross_amount_eur − discount_eur.
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.
Example
{ "subscriptions": [ { "kind": "node_pool" } ], "autoscaling": [ { "resource_type": "vcpu" } ]}Missing or invalid credentials.
object
object
A stable, machine-readable error code.
object
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.
The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.
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.
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).
object
object
A stable, machine-readable error code.
object
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.
The payment provider’s decline code. Present only on 402 payment_declined; it is its own field and is never folded into message.
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.
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" }}