Market analytics¶
Five read only routes publish what the console's Burst Capacity page shows for a Kubernetes cluster: the price it takes to win nodes, what the nodes you hold are assessed, and where your demand sits.
| Route | What it serves |
|---|---|
GET /api/k8s/market/ladder |
the price to win ladder: per job size in nodes, the minimum bid that won that many nodes at each clearing, and the newest tick's quote |
GET /api/k8s/market/spend |
the rate assessed on each node you hold this hour, and the sum |
GET /api/k8s/market/paid |
the mean rate your nodes were assessed per bucket, and how many nodes |
GET /api/k8s/market/bidhistory |
the limit price in force over time |
GET /api/k8s/market/demand |
your cluster's GPUs by band: bidding, provisioning, scheduled, reserved |
Contract: GET /api/k8s/openapi.json.
All five take an org API token and resolve the cluster the way the
limit price read does: a token bound to a Kubernetes cluster reads its
own; an org wide token resolves when the organization holds one
Kubernetes cluster and otherwise passes ?cluster=<name> or gets a
409 ambiguous-cluster. A token bound to a VM cluster is refused with
422 bad-request. A cluster outside your organization is a 404, the
same as one that does not exist.
Money is USD per node-hour on every route, like the
price feed. Divide by the response's own
gpus_per_node to compare with a per GPU-hour limit price.
The windowed routes (ladder, paid, bidhistory, demand) take
?hours= (default 24, clamped to 1 to 8760 hours) and return t0
(epoch seconds of the first bucket) and step (bucket width in
seconds, growing with the window: max(300, span / 400)). The demand
window caps at 720 hours, the 30 days its store keeps. Within one
window the series share the grid: a paid bucket and a demand bucket at
the same offset from t0 describe the same interval, and demand
carries one extra bucket at the window's end.
Feeds arm per market
enabled: false means the feed is not armed for your cluster's
market and the data comes empty, not an error. The limit price
history has no market gate: the declaration is your organization's
own record.
The price to win ladder¶
curl -H "Authorization: Bearer $NC_TOKEN" \
"https://nationalcompute.com/api/k8s/market/ladder?hours=24"
The ladder is the outsider's quote: for each job size k in whole
nodes, the minimum bid a fresh cluster with no standing position needed
to win k nodes at that clearing. It is the honest entry cost for a job
of k nodes, and it is quoted per node-hour as the whole job's total
divided by k.
sizeslists the sizes that quoted at least once in the window;priceholds one series per size, keyed by the size as a string.rungslists every size the ladder quotes, whatever the window.nowis the newest tick's quote per rung andnow_tsthat tick.now[k]isnullwhere no bid at any price wins that size right now. Two causes: every node the job would need sits inside a protection window, or the island has fewer nodes than the size asks for. The console shows that rung as Preemption Protected.nowisnullas a whole when no tick landed in the window.- A
nullin apriceseries means no tick quoted that size in that bucket. A quote is never held forward into a later bucket.
The MCP server's market_read source=ladder returns this
body unchanged.
What your nodes are assessed¶
curl -H "Authorization: Bearer $NC_TOKEN" \
https://nationalcompute.com/api/k8s/market/spend
nodes maps each node you hold to the rate the newest auction assessed
it, total_usd_hr is their sum, and site_rates is the anonymous range
assessed across the whole market that tick as {lo, hi} (null when
nothing cleared). These are the rates the meter bills for the current
hour (billing).
GET /api/k8s/market/paid is the same figure over time: price[] is
the mean rate across your nodes per bucket and nodes[] the mean number
of nodes billed, both null where you held nothing.
Your limit price over time¶
GET /api/k8s/market/bidhistory returns price[], the limit price in force
at each bucket instant, per node-hour (the limit price PUT's per GPU-hour
figure times gpus_per_node). It is null before the first declaration
and while the limit price is withdrawn.
Your demand by band¶
GET /api/k8s/market/demand returns bands, four series of GPUs per
bucket: bidding (requests waiting on the market), provisioning
(granted, nodes joining), scheduled (running), and reserved (the
cluster's live Base Load block,
reported beside the three bands and never subtracted from them).