Market prices for the GPU models this tenant actually runs
const url = 'https://api.flotera.com/api/v1/marketplaces/market';const options = { method: 'GET', headers: {cookie: '__Host-erm_session=<__Host-erm_session>'}};
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.flotera.com/api/v1/marketplaces/market \ --cookie __Host-erm_session=<__Host-erm_session>Per GPU model and marketplace: how many offers, and the min/median/max price per GPU-hour in USD.
The card list comes from the tenant’s own telemetry, so the answer is about their fleet and nothing else. Prices come from a shared cache — public offers are identical for everyone, and fetching them per tenant would multiply the load on the marketplace by the number of customers.
rented_share is null when the marketplace did not report occupancy in
that sample. Null and zero are different answers and must not be
collapsed: zero would claim the market has stopped.
gpu_model narrows the answer to one card class from
catalog_gpu_models — the popular-card catalog the index polls
regardless of the fleet, plus the fleet’s own classes. This is how the
panel calculator asks about a card the tenant does not own yet. A model
outside that set is rejected with 422: it would produce an honest but
forever-empty answer, so such a request is a typo, not a question.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Normalized card class to ask about instead of the whole fleet. Accepts marketplace spellings too — the server normalizes («RTX 4090» → «rtx 4090»).
Responses
Section titled “Responses”Market overview.
object
When each marketplace’s offers were last sampled. null means it has never been sampled, and then a missing row for a card says “we have not looked yet” — NOT “nobody offers this card”. The two answers lead a fleet owner to opposite decisions, so the UI must not collapse them.
object
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.
RFC 3339 UTC with microsecond precision, or null.
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.
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.
Card classes the rows cover — the tenant’s fleet (from its own telemetry) by default, the single selected class when gpu_model was passed. Whether a missing row means “not sampled yet” or “not offered” is answered by sources.
Everything the gpu_model filter accepts: the popular-card catalog the market index polls regardless of the fleet, plus this fleet’s own classes, sorted. The panel calculator builds its card selector from this list. Optional — APIs older than the filter do not send it.
object
Normalized card name, comparable across marketplaces.
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.
Offers WE observed in our own sample. Tier-B sources publish no order book, so their rows are reported-only: offers is 0, every sample-side price is null, and only the reported_* block is populated.
Decimal string or null when unknown.
Lower quartile — what undercutting the market costs. The minimum alone is a single outlier and is useless as a target.
Decimal string or null when unknown.
Upper quartile — what asking above the market means.
Decimal string or null when unknown.
Share of listed machines currently rented, 0..1. null means the marketplace does not report occupancy in this sample — which is NOT zero. Vast is null: its rented field reads false on every offer, even for a query that explicitly asks for rented ones.
The marketplace’s response hit our page limit, so the quartiles above describe a slice of the market rather than the market. null means no sample has been recorded yet — not “complete”.
RFC 3339 UTC with microsecond precision, or null.
Share of ALL cards of this model rented on the marketplace right now, 0..1 — the marketplace’s OWN market-wide figure (Vast’s gpu metrics aggregate), not our sample. Deliberately separate from rented_share: the two describe different populations measured by different parties, and merging them would make the row lie about its provenance. null — the marketplace does not publish this figure.
The same figure averaged over the marketplace’s own 30-day window.
Cards of this model listed on the whole marketplace.
Of them, currently free to rent.
The marketplace’s own market floor for this model. Vast does not publish it; for RunPod the minimum is the ONLY figure the venue publishes at all, so without this field its row would be empty.
The marketplace’s own market ceiling for this model.
The marketplace’s own median price for this model. Its sampling method is not published, so this is a cross-check next to our median_usd_per_gpu_hour, never a substitute for it.
When the marketplace’s aggregate was last read.
Example
{ "sources": [ { "marketplace": "vast", "price_sample": "all", "last_fetch_status": "ok" } ], "rows": [ { "marketplace": "vast" } ]}Missing/invalid credentials (code=unauthorized).
RFC 9457 problem document with a stable machine code.
object
Stable machine-readable error code (03 §2.4).
UUID (v7 for new entities; v4 accepted during migration).
object
JSON Pointer to the offending field.
Example
{ "type": "https://ermeon.com/problems/validation", "code": "unauthorized"}Authenticated but not permitted. code=forbidden — role/scope mismatch; code=feature_not_entitled — the plan does not include the capability; code=account_frozen — the account is frozen and this operation is declared x-ermeon-frozen: deny. The three are deliberately distinct: only the last one is fixed by a top-up (13 §5.6).
RFC 9457 problem document with a stable machine code.
object
Stable machine-readable error code (03 §2.4).
UUID (v7 for new entities; v4 accepted during migration).
object
JSON Pointer to the offending field.
Example
{ "type": "https://ermeon.com/problems/validation", "code": "unauthorized"}Request failed validation (code=validation_failed), with per-field errors.
RFC 9457 problem document with a stable machine code.
object
Stable machine-readable error code (03 §2.4).
UUID (v7 for new entities; v4 accepted during migration).
object
JSON Pointer to the offending field.
Example
{ "type": "https://ermeon.com/problems/validation", "code": "unauthorized"}A dependency the endpoint needs is not configured or is temporarily unavailable (code=unavailable). The rest of the API keeps working — an absent external integration must not take the service down.
RFC 9457 problem document with a stable machine code.
object
Stable machine-readable error code (03 §2.4).
UUID (v7 for new entities; v4 accepted during migration).
object
JSON Pointer to the offending field.
Example
{ "type": "https://ermeon.com/problems/validation", "code": "unauthorized"}