Announce a maintenance window
const url = 'https://api.flotera.com/api/v1/marketplaces/links/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/vast/maintenance';const options = { method: 'PUT', headers: { cookie: '__Host-erm_session=<__Host-erm_session>', 'Content-Type': 'application/json' }, body: '{"starts_at":"2026-04-15T12:00:00Z","hours":"example","category":"power"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request PUT \ --url https://api.flotera.com/api/v1/marketplaces/links/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/vast/maintenance \ --header 'Content-Type: application/json' \ --cookie __Host-erm_session=<__Host-erm_session> \ --data '{ "starts_at": "2026-04-15T12:00:00Z", "hours": "example", "category": "power" }'The platform notifies the renters itself, so the machine can be taken down without the reliability penalty an unannounced disconnect carries.
Windows longer than 24 hours are refused: that is a shutdown, and a shutdown is done by withdrawing the offer. A renter promised a day will not wait a week.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”UUID (v7 for new entities; v4 accepted during migration).
Supported marketplace. The database constrains the same two values, so a third one is a migration rather than a new string.
Marketplace identifier. Closed set: adding one is a migration, not a new string, because the database constrains the same two values.
Header Parameters
Section titled “Header Parameters”Idempotency key, 1–128 ASCII, unique per (tenant_id, operation, key) for at least 24 hours. Retrying with the same body replays the stored response; a different body returns 409 idempotency_conflict.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Duration in hours, fractional; a string for the same reason money is.
Unknown values are recorded as other rather than refused.
Responses
Section titled “Responses”Window announced; the link carries the platform’s new state.
object
UUID (v7 for new entities; v4 accepted during migration).
Supported marketplace. The database constrains the same two values, so a third one is a migration rather than a new string.
How the link was established. agent is not produced by anything yet: automatic binding needs an agent on the machine.
stale means the machine stopped appearing in the marketplace response. The link is kept, not deleted: a manual binding was approved by a person, and a machine delisted for an hour will come back.
RFC 3339 UTC with microsecond precision.
RFC 3339 UTC with microsecond precision, or null.
What the marketplace knows about this machine, normalised.
The raw answer is stored as the platform sent it — a foreign format changes without notice, and parsing it on the way in would silently drop fields nobody has thought about yet. What travels here is a normalised projection, so that a client never learns that on Vast the price is called listed_gpu_cost.
Every field may be null, and that is ordinary rather than a fault: an unlisted machine has no prices at all, an unverified one has no scores yet, and a field the platform did not send is not a zero.
object
The hostname the machine reported to the platform.
A fraction, not a percentage: 0.7745 means 77.45 %. Left unrounded on purpose — the platform’s own threshold sits at 95 %, and rounding here would cost the owner the difference between 95 and 94.6.
The card as the PLATFORM names it — RTX 3060, not NVIDIA GeForce….
Card occupancy, one character per card, exactly as the platform prints it. Undocumented on their side, so a string whose length disagrees with the card count means “not understood” and the card map is not drawn at all — an invented layout is worse than none.
The same card as the key of MarketSummary.gpu_model, so that the matching market row can be found. Normalised on the server: a name normalised twice by different rules stops matching itself, and the comparison against the market would then silently read as “no data” instead of a price.
Decimal string or null when unknown.
Decimal string or null when unknown.
Decimal string or null when unknown.
Per TERABYTE. The platform’s API carries this per gigabyte and its own CLI multiplies by 1024 before printing. The conversion lives on the server side so that exactly one place remembers the factor — getting it wrong is a thousandfold error in a price.
For a ROLLING offer this is a derivative, not the owner’s intent: the platform keeps it equal to now + duration and moves it constantly. Whether the offer is rolling is told by ask_duration_seconds.
The offer’s rolling window in seconds; null when the term is a fixed end date. An offer whose window is shorter than a day is filtered out by most renters’ searches.
Decimal string or null when unknown.
Decimal string or null when unknown.
The hardware as the PLATFORM sees it, kept alongside our own measurements on purpose: a disagreement means the machine is being advertised as something it is not.
Whether a maintenance window is announced. A flag of its own rather than something inferred from the dates: the platform’s record shape can change without us, and “is a window announced” must still have an answer when the details cannot be read.
What the platform considers broken. Null means no complaint.
Rentals running right now, one entry per order, as the marketplace describes them. Empty when idle or when the platform gives no per-order breakdown (Vast). The counter above answers “how many cards”; this answers what the tenant actually pays — and on Clore the currency decides the host surcharge.
object
Order type in the platform’s own word — on_demand, spot, fixed_usd.
Order price per day, in the order’s own currency — not converted.
What the owner set in Clore’s own console. Mostly read-only: the platform exposes no write for these, and guessing intent costs more than showing the fact and naming where it is changed.
The exception is the currency set, which the offer editor DOES change:
set_server_settings honours enabled-<currency> when the currency’s
own prices travel with it. That was found live on 2026-08-12 — until
then we told owners the set was console-only, which was wrong.
Every field is nullable — the config call may not have answered, and a dash is more honest than an invented default.
object
Ceiling on a single rental, hours (mrl). Absent from the machine list.
Whether renters may take part of the cards. False means whole machine only.
Whether the renter is allowed to move clocks.
Version the chosen channel expects; a gap means their agent is behind.
The platform’s own quality estimate, USD per day. Not decorative: the token-lock bonus is computed from it.
Currencies the machine accepts.
Currencies whose price the owner pinned in the coin itself. A price edit here leaves them untouched.
Absolute prices per currency, in the currency itself. Not a reference: the absolute figure sent with a currency BEATS the dollar target, so the owner must see what will actually go to the platform in each — and the machine’s own rate is derived from these same numbers.
object
object
object
Renter bids on this machine. An empty array means nobody is bidding — an observation, not a gap. As of 2026-08-12 no machine on the platform had any, so the shape of a non-empty entry comes from the vendor docs rather than a live body, and every field is optional on purpose.
The platform’s own currency table, USD PER COIN — the inverse of a coins-per-dollar rate. These are the figures revenue in a deal currency is now converted with, so the owner is entitled to see the rate they were charged at.
object
Decimal value serialized as a string, never a JSON number.
Measured electricity cost of one GPU-hour on this machine — billing facts over the last 7 days (energy integrated from power telemetry, up to a wall-plug meter, times the owner’s tariff), divided across the machine’s cards. This is the break-even floor a price must clear. null means it cannot be computed — no tariff, no power measurements, or no card count — and an unknown cost is never presented as zero. Computed by the links list; single-link responses (bind, offer edits) return null.
Example
{ "marketplace": "vast", "bind_mode": "manual", "state": "linked", "linked_at": "2026-07-25T10:15:30.123456Z", "remote": { "clore": { "spot": { "bids": [ { "bid": "12.340000" } ], "rates_usd_per_coin": { "additionalProperty": "12.340000" }, "best_bid_usd": "12.340000" } } }}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"}Resource does not exist in this tenant. Foreign identifiers also return 404 (anti-enumeration).
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"}