Skip to content

Public aggregated GPU market statistics for the landing page

GET
/public/market-stats
curl --request GET \
--url https://api.flotera.com/api/v1/public/market-stats

The one unauthenticated market surface. Serves aggregated medians, occupancy and 7-day trends per GPU class per market source — data derived exclusively from the shared, tenant-free market cache; no number here is computed from anyone’s fleet.

Deliberately NOT served: offer books, per-host minimum prices, any machine listings. Aggregates read as “we observe the market”; a public mirror of a venue’s search output is grounds for that venue to cut the access this index lives on.

The response is identical for every caller and changes at the market freshness cadence, so it ships Cache-Control: public, max-age=300 (the CDN edge absorbs the traffic) and Access-Control-Allow-Origin: * — public data, no credentials involved.

indicative_monthly_gross_usd is median × 720 h × occupancy. It is neither net nor a promise of income — platform fees and the owner’s electricity are unknown here — and the field name says exactly what was computed.

Aggregated market statistics.

Media typeapplication/json
object
generated_at
required

RFC 3339 UTC with microsecond precision.

string format: date-time
window_days
required
integer
>= 1 <= 90
gpu_models
required

GPU classes in the digest — the deepest markets of the window, chosen by offer depth, never by anyone’s fleet.

Array<string>
<= 32 items
sources
required
Array<object>
<= 8 items
object
marketplace
required

A market DATA source — a superset of MarketplaceName. Tier-B venues (tensordock, runpod, akash) feed the price index only: no accounts, no listings, no rentals — see infrastructure/26-market-intelligence.md §3. Execution paths (accounts, links, offers) keep MarketplaceName; a tier-B name is never valid there.

string
Allowed values: vast clore tensordock runpod akash
last_sampled_at

RFC 3339 UTC with microsecond precision, or null.

string | null format: date-time
price_sample

Which population of machines the prices describe. all includes rented machines; available_only means the query filtered to machines free to rent; reported means there is no sample of ours at all — the venue publishes its own aggregate figures (tier-B sources), computed by an unpublished method.

Without this, comparing marketplaces is misleading. Vast is queried with rentable = true, so its median describes what was NOT taken and skews high; Clore returns the whole market including the attractively-priced machines already rented, and skews low. On live data the gap is a consistent 1.8-2.4x across every card, and how much of it is real cannot be stated. A UI that presents that gap as measured pushes a fleet owner off a marketplace on the strength of a sampling artefact.

string
Allowed values: all available_only reported
last_fetch_status

How the LAST attempt ended, separate from when data was last fresh: an hour-old market looks identical whether the fetcher is healthy (freshness window) or broken (a run of failures).

rate_limited is not folded into failed — hitting a rate limit is normal traffic shaping against someone else’s API, not a fault, and confusing the two sends the operator to reissue a working key.

string
nullable
Allowed values: ok rate_limited failed
rows
required
Array<object>
<= 128 items
object
gpu_model
required
string
<= 128 characters
marketplace
required

A market DATA source — a superset of MarketplaceName. Tier-B venues (tensordock, runpod, akash) feed the price index only: no accounts, no listings, no rentals — see infrastructure/26-market-intelligence.md §3. Execution paths (accounts, links, offers) keep MarketplaceName; a tier-B name is never valid there.

string
Allowed values: vast clore tensordock runpod akash
median_usd_per_gpu_hour

Decimal string or null when unknown.

string | null
/^-?[0-9]+(\.[0-9]{1,6})?$/
occupancy_share

Share of cards rented, 0..1. Null — nobody measured it.

string | null
/^-?[0-9]+(\.[0-9]{1,6})?$/
occupancy_source

Who measured the occupancy — the venue’s own market-wide figure or the share inside our sample. Different populations measured by different parties; a digest that merged them would lie about its provenance.

string
nullable
Allowed values: reported sample
supply_total
integer
nullable
supply_available
integer
nullable
indicative_monthly_gross_usd

Median × 720 h × occupancy, 2 decimal places. Not net, not a promise — present only when both inputs are measured. For a floor-only venue (RunPod publishes just its minimum) it stays null: the market floor times occupancy would promise income from the single cheapest host’s price.

string | null
/^-?[0-9]+(\.[0-9]{1,6})?$/
trend
required

Daily medians over the window, oldest first. Empty for reported -only sources until their history accumulates.

Array<object>
<= 200 items
object
at
required

RFC 3339 UTC with microsecond precision.

string format: date-time
median_usd_per_gpu_hour

Decimal string or null when unknown.

string | null
/^-?[0-9]+(\.[0-9]{1,6})?$/
Example
{
"generated_at": "2026-07-25T10:15:30.123456Z",
"sources": [
{
"marketplace": "vast",
"price_sample": "all",
"last_fetch_status": "ok"
}
],
"rows": [
{
"marketplace": "vast",
"occupancy_source": "reported",
"trend": [
{
"at": "2026-07-25T10:15:30.123456Z"
}
]
}
]
}