Usage
Read the usage ledger, summarize GPU time and spend over a window, and report reserved capacity against it.
Introduction
Usage is recorded as an append-only ledger, one row per worker state transition, each carrying the GPU count and the rate that applied. Everything else here is derived from it on read. Pricing explains what is billed and why.
Totals are never stored, so a window that cannot be priced in full fails rather than reporting a smaller number. A total that silently omits usage is a wrong number the caller cannot see is wrong.
List usage events
Append-only billing telemetry. One row per worker state transition.
Events are drawn on when the transition happened, not when it was recorded, so ingest lag never moves one across a boundary. busy never appears: it describes queue occupancy rather than a change in the worker's life, and a worker costs the same whether it is serving or waiting.
Request
limit
integerint32min: 1max: 100default: 20Maximum number of items to return.
cursor
stringOpaque pagination cursor returned by a previous call, as
nextCursoror, on the operations that offer one,prevCursor.
appId
stringmin: 6max: 30Immutable app identifier. Unique among the authenticated organization's live apps: it cannot be changed after creation, and it becomes available again once the app it named reaches
deleted.
from
string (date-time)date-timeInclusive lower bound on event time (RFC 3339).
to
string (date-time)date-timeExclusive upper bound on event time (RFC 3339).
Response
nextCursor
stringnullableCursor for the next page. Null when there are no more items.
data
object[]Array items9 properties each
id
string (uuid)requiredUUID v4
appId
stringrequiredmin: 6max: 30Immutable app identifier. Unique among the authenticated organization's live apps: it cannot be changed after creation, and it becomes available again once the app it named reaches
deleted.
workerId
string (uuid)requiredUUID v4
eventType
stringrequiredStatus the worker transitioned into. The ledger emits a subset of
WorkerStatus.busynever appears (queue occupancy, not a pod lifecycle transition).Possible values9 values
gpuCount
integerrequiredint32
gpuType
stringmin: 1max: 64GPU type the worker held at the transition. Absent when the worker held no GPU.
pricePerSecond
objectCatalog price per GPU per second in force at
occurredAt, resolved from the catalog history. Absent whengpuTypeis absent or the catalog history has no applicable price. This is the positive pay-as-you-go rate whatever covered the time. Reserved capacity is not a discount on it: coverage is reported byGET /v1/usage/summaryand never by a rate of zero.
occurredAt
string (date-time)requireddate-timeWhen the transition happened. This is the event time the
fromandtofilters apply to, and the field to bill on.
createdAt
string (date-time)date-timeWhen the event was recorded. Audit only. May lag
occurredAt.
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Summarize usage
GPU time and spend for the authenticated organization, aggregated over a half-open window and grouped by the dimensions asked for.
Every figure is derived on read from the immutable usage ledger, the effective-dated price catalog and the organization's capacity commitments. Two consequences follow. The window is bounded, because the read folds every event of every worker in it. And a worker whose recorded life cannot be priced fails the request rather than being left out of the totals, because a total that silently omits usage is a wrong number a caller cannot see is wrong. These failures return 500, with no partial totals.
paygSpend is provisional pay-as-you-go accrual, not a settled charge. It excludes whole-second finalization rounding and ledger adjustments. paygEquivalentValue prices the same time at the catalog rate whatever covered it, so the difference between them is what a capacity commitment saved. While commitment coverage is not yet applied by settlement, an organization holding a commitment sees a split here that the credit ledger has not yet applied.
paygSpend is provisional accrual, not a settled charge: it excludes whole-second finalization rounding and ledger adjustments. paygEquivalentValue prices the same time at the catalog rate whatever covered it, so the gap between the two is what a reserved capacity commitment saved.
Request
from
string (date-time)date-timeInclusive lower bound on billable time (RFC 3339). Defaults to 24 hours before
to. The maximum window is 31 days. An explicit zero timestamp (0001-01-01T00:00:00Z) returns422rather than selecting the default.
to
string (date-time)date-timeExclusive upper bound on billable time (RFC 3339). Defaults to now, and a value in the future is read as now. An explicit zero timestamp (
0001-01-01T00:00:00Z) returns422rather than selecting the default.
appId
stringmin: 6max: 30Report only this app's usage. A filter on what is reported, not on what is measured: coverage depends on every app's concurrent GPUs.
gpuType
stringmin: 1max: 64Report only usage of this GPU type. A retired type is accepted, because usage recorded before it was withdrawn is still reportable. A type the catalog has never carried returns
422.
groupBy
string[]Dimensions to group by. An empty list returns one bucket for the whole window. Each dimension appears on the bucket it was requested with and is absent otherwise.
Response
from
string (date-time)requireddate-timeInclusive start of the reported window, as resolved.
to
string (date-time)requireddate-timeExclusive end of the reported window, as resolved.
buckets
object[]requiredArray items7 properties each
appId
stringmin: 6max: 30Present when grouped by
app.
gpuType
stringmin: 1max: 64Present when grouped by
gpuType.
day
stringdateUTC calendar day. Present when grouped by
day. A span crossing midnight is divided between the two days it ran on.
coverage
stringPresent when grouped by
coverage.Possible values2 values
gpuMilliseconds
integerrequiredint64min: 0Billable GPU time, summed over each GPU separately. A worker holding four GPUs for one second contributes four thousand.
paygSpend
objectrequiredProvisional pay-as-you-go accrual for this time, excluding finalization rounding and ledger adjustments. Zero for time a commitment covered.
paygEquivalentValue
objectrequiredThe same time priced at the catalog rate, whatever covered it. The difference from
paygSpendis what reserved capacity saved.
total
objectrequiredThe whole window with no grouping. It carries no dimension fields, and it always equals the sum of
buckets.Properties7 properties
appId
stringmin: 6max: 30Present when grouped by
app.
gpuType
stringmin: 1max: 64Present when grouped by
gpuType.
day
stringdateUTC calendar day. Present when grouped by
day. A span crossing midnight is divided between the two days it ran on.
coverage
stringPresent when grouped by
coverage.Possible values2 values
gpuMilliseconds
integerrequiredint64min: 0Billable GPU time, summed over each GPU separately. A worker holding four GPUs for one second contributes four thousand.
paygSpend
objectrequiredProvisional pay-as-you-go accrual for this time, excluding finalization rounding and ledger adjustments. Zero for time a commitment covered.
paygEquivalentValue
objectrequiredThe same time priced at the catalog rate, whatever covered it. The difference from
paygSpendis what reserved capacity saved.
calculatedAt
string (date-time)requireddate-timeThe instant the figures describe.
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Credit balance
The authenticated organization's Serverless credit pool, read as one snapshot at observedAt. Serverless credit is separate from inference credit.
availableBalance is totalBalance minus heldCredit, and can be negative. Held credit is set aside for capacity that is running or starting. It has not been spent and is unrelated to reserved capacity. An arrears account is invoiced for its usage and holds no prepaid balance, so both balances are null rather than zero.
Until Serverless billing is active for the organization, this returns 404, which is not a zero balance. The balance and the 404 are sent with Cache-Control: no-store.
A 404 here means Serverless billing is not active for the organization yet. It is not a zero balance, and the two are worth telling apart before showing a customer a number.
Response
collectionMode
stringrequiredHow the organization pays for Serverless usage.
prepaidusage draws down credit bought in advance.arrearsusage is invoiced afterwards, so the pool holds no prepaid balance.Possible values2 values
status
stringrequiredFor a prepaid pool:
healthymeans the balance covers the capacity that is running or starting.gracemeans it does not. Capacity beyond what held credit covers cannot be added, and running capacity continues while funding is awaited.drainingmeans the grace period has ended, and running capacity may be stopped until what remains fits the balance.suspendedmeans a refund took the balance below zero, and no capacity can be added until a top-up brings it back to zero or above. An arrears pool has no prepaid balance to restrict it and reportshealthy.Possible values4 values
totalBalance
objectrequirednullableThe prepaid ledger balance, held credit included. Negative when the organization owes credit.
nullfor arrears.
heldCredit
objectrequiredCredit set aside for capacity that is running or starting. It has not been spent, and it is unrelated to reserved capacity.
availableBalance
objectrequirednullabletotalBalanceminusheldCredit: the credit left to spend. Can be negative.nullfor arrears.
observedAt
string (date-time)requireddate-timeWhen these figures were read.
Errors
| Status | When |
401 | Missing or invalid credentials |
404 | Serverless billing is not active for the organization yet |
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Reserved capacity
What the authenticated organization has reserved, what it is using of it now, and what overflowed to pay-as-you-go.
One entry per commitment scope, one GPU type in one region, because compatible terms add together and cover an allocation between them. The terms that make up the scope are listed with their own dates and quantities.
Counts describe recorded billable state at the window end, so a report of a past period describes that period rather than mixing it with the present. A scope with an effective commitment appears even when nothing is using it: an idle reservation is still charged for, and is what the customer most needs to see. Scopes whose terms expired during the period remain with their historical usage and zero committed capacity at the window end.
The fixed commitment charge is not here. Serverless meters usage and does not own that charge. The commerce system invoices it from the contract schedule. Usage that cannot be priced returns 500, with no partial report.
A scope with an effective commitment is reported even when nothing is using it, because an idle reservation is still charged for. The fixed commitment charge itself is billed separately and does not appear in this response.
Request
from
string (date-time)date-timeInclusive lower bound of the reporting period (RFC 3339). Defaults to 24 hours before
to. The maximum window is 31 days. An explicit zero timestamp (0001-01-01T00:00:00Z) returns422rather than selecting the default.
to
string (date-time)date-timeExclusive upper bound of the reporting period (RFC 3339). Defaults to now, and a value in the future is read as now. An explicit zero timestamp (
0001-01-01T00:00:00Z) returns422rather than selecting the default.
Response
data
object[]requiredArray items14 properties each
gpuType
stringrequiredmin: 1max: 64Public catalog code for a supported GPU type (e.g.
h100,rtx-pro-6000). Must match anidreturned byGET /v1/gpu-types(validated at request time against the catalog). This is not the internal database row UUID.
region
stringrequiredThe region a capacity commitment applies to. One value until app placement selects a region.
Possible values1 value
terms
object[]requiredArray items4 properties each
id
string (uuid)requiredUUID v4
gpuCount
integerrequiredint32min: 1Concurrent GPUs this term reserves.
startsAt
string (date-time)requireddate-timeInclusive start of the term.
endsAt
string (date-time)requireddate-timeExclusive end of the term. An amended term ends where its replacement starts, so the two never both apply.
committedGpuCount
integerrequiredint32min: 0Concurrent GPUs reserved at
calculatedAt, across every effective term.
coveredGpuCount
integerrequiredint32min: 0Reserved GPUs in use at
calculatedAt.
unusedGpuCount
integerrequiredint32min: 0Reserved GPUs idle at
calculatedAt. Charged for, because reserved capacity is a promise of access rather than a quantity of GPU time.
paygOverflowGpuCount
integerrequiredint32min: 0Matching GPUs in use at
calculatedAtabove the reserved quantity. These are what a pay-as-you-go charge in this scope can be traced to.
from
string (date-time)requireddate-timeInclusive start of the reported period, as resolved.
to
string (date-time)requireddate-timeExclusive end of the reported period, as resolved.
coveredGpuMilliseconds
integerrequiredint64min: 0Reserved GPU time used over the period.
paygGpuMilliseconds
integerrequiredint64min: 0GPU time in this scope over the period that the reservation did not cover.
paygSpend
objectrequiredProvisional overflow accrual, excluding finalization rounding and ledger adjustments.
coveredValue
objectrequiredThe covered time priced at the catalog rate. What pay-as-you-go would have charged for it, and so what the reservation saved.
calculatedAt
string (date-time)requireddate-timeThe instant the counts describe.
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |