Skip to content

Versioned fleet dashboard snapshot

GET
/dashboard/summary
curl --request GET \
--url https://api.flotera.com/api/v1/dashboard/summary \
--cookie __Host-erm_session=<__Host-erm_session>

Single consistent snapshot instead of several independent aggregate calls. Served from dash:v1:{tenant}:summary (soft freshness 60 s, hard TTL 5 min + jitter) with PG/ClickHouse fallback. Billing balance shown here is not cached with the generic dashboard TTL.

If-None-Match
string
<= 256 characters

Return 304 Not Modified when the entity tag still matches.

Snapshot.

Media typeapplication/json

Consistent fleet snapshot for the dashboard (single call, 60 s refresh).

object
generated_at
required

When this snapshot was computed.

string format: date-time
data_as_of
required

Source watermark the snapshot is based on.

string format: date-time
version
required

Snapshot form version (cache-shape version).

integer
stale
required

True when serving stale-while-revalidate data.

boolean
stale_reason
string | null
<= 256 characters
tenant_id
required

UUID (v7 for new entities; v4 accepted during migration).

string format: uuid
revenue_today_usd
required

What reaches the owner today: the measured gross (deal price × time) less the marketplace rates recorded in the tenant’s cost basis, deducted per marketplace and summed afterwards. A marketplace whose commission is unset is NOT deducted, and the snapshot then carries partial_reason rates_unset: — the figure is an upper bound, never a silent full amount.

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

Decimal string or null when unknown.

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

The measurement before any deduction. gross = revenue + fees by construction.

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

What the marketplaces keep, derived at read time from the cost basis rather than stored in the fact. Zero means either no rentals or rates that deduct nothing — see partial_reason.

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

Decimal string or null when unknown.

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

Today after marketplace fees and electricity. Unlike net_profit_14d_usd it does NOT deduct the Ermeon tariff: the tariff is read from the billing ledger over the 14-day window only, and there is no daily figure to subtract here.

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

Net USD per GPU-hour over earning GPUs (the headline product metric). “Net” here is after marketplace fees only — neither electricity nor the Ermeon tariff is deducted, unlike net_profit_14d_usd.

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

Profit over the 14-day window after everything the system can name: marketplace fees, electricity and the Ermeon tariff.

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

Decimal string or null when unknown.

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

Decimal string or null when unknown.

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

Ermeon tariff charged over the same 14-day window as electricity_14d_usd. Zero is a real zero (nothing was charged — e.g. the free first server); null means the billing ledger could not be read.

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

The OWNER’s operating expenses over the same 14-day window — premises, connectivity, maintenance — not an Ermeon charge. The monthly amount comes from tenant settings (operational_usd_per_month) and is apportioned to the window by calendar days. Null means the owner has not entered it, which is not zero: unentered expenses are unknown, not absent. Whatever is reported here is also already subtracted from net_profit_14d_usd, so the two always agree.

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

Current fleet power draw, kW.

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

Decimal string or null when unknown.

string | null
/^-?[0-9]+(\.[0-9]{1,6})?$/
gpus_total
required
integer
gpus_earning
required
integer
servers_total
required
integer
servers_online
required
integer
fleet
required

Complete partition of the fleet by server: the buckets always sum to servers_total. Earning buckets require the server to be reachable — a machine whose agent went silent is counted as offline, never as working or idle.

object
rented_vast
required
integer
rented_clore
required
integer
rented_other
required

Rented on a marketplace that is not assigned yet; still a rental.

integer
mining
required
integer
idle
required

Online but not earning — the state the $1/month idle tariff bills.

integer
offline
required

Not reporting (and not in maintenance or error); these hours are not billed.

integer
maintenance
required
integer
error
required
integer
fleet_classes

The same partition, per GPU class, largest fleet first. Optional during rollout: snapshots written by an older projector do not carry it. Per-bucket sums across classes equal the buckets of fleet, and machines sum to servers_total — the panel relies on both.

Array<object>

One GPU class of the fleet with the same breakdown as fleet. A null gpu_model is the no-hardware bucket: the agent reported zero GPUs — offline means a machine that was never configured, online means the cards have vanished from the bus.

object
gpu_model
required
string | null
machines
required
integer
gpus
required
integer
breakdown
required

Complete partition of the fleet by server: the buckets always sum to servers_total. Earning buckets require the server to be reachable — a machine whose agent went silent is counted as offline, never as working or idle.

object
rented_vast
required
integer
rented_clore
required
integer
rented_other
required

Rented on a marketplace that is not assigned yet; still a rental.

integer
mining
required
integer
idle
required

Online but not earning — the state the $1/month idle tariff bills.

integer
offline
required

Not reporting (and not in maintenance or error); these hours are not billed.

integer
maintenance
required
integer
error
required
integer
power_kw

Draw of the class machines currently reporting, kW; absent sensors yield null.

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

Decimal value serialized as a string, never a JSON number.

string
/^-?[0-9]+(\.[0-9]{1,6})?$/
alerts
required
object
total_open
required
integer
total_critical
required
integer
billing_locked
required
boolean
Example
{
"generated_at": "2026-07-25T10:15:30.123456Z",
"data_as_of": "2026-07-25T10:15:30.123456Z",
"revenue_today_usd": "12.340000",
"effective_rate_usd_gpu_h": "12.340000",
"fleet_classes": [
{
"revenue_today_usd": "12.340000"
}
]
}
ETag
string
<= 256 characters

Entity tag of the returned snapshot/resource version.

Not modified; the cached representation is still valid.

Missing/invalid credentials (code=unauthorized).

Media typeapplication/problem+json

RFC 9457 problem document with a stable machine code.

object
type
required
string format: uri
title
required
string
<= 256 characters
status
required
integer
>= 100 <= 599
code
required

Stable machine-readable error code (03 §2.4).

string
Allowed values: unauthorized forbidden csrf_rejected not_found conflict idempotency_conflict validation_failed rate_limited payload_too_large unsupported_agent_version temporarily_unavailable offline_queue_full online_queue_full plan_required server_limit_reached feature_not_entitled account_in_grace account_frozen payment_pending payment_expired payment_amount_mismatch change_already_pending change_already_applied change_effective reserve_not_covered direction_changed
detail
string
<= 2048 characters
instance
string
<= 512 characters
request_id

UUID (v7 for new entities; v4 accepted during migration).

string format: uuid
errors
Array<object>
<= 100 items
object
path
required

JSON Pointer to the offending field.

string
<= 512 characters
code
required
string
<= 64 characters
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).

Media typeapplication/problem+json

RFC 9457 problem document with a stable machine code.

object
type
required
string format: uri
title
required
string
<= 256 characters
status
required
integer
>= 100 <= 599
code
required

Stable machine-readable error code (03 §2.4).

string
Allowed values: unauthorized forbidden csrf_rejected not_found conflict idempotency_conflict validation_failed rate_limited payload_too_large unsupported_agent_version temporarily_unavailable offline_queue_full online_queue_full plan_required server_limit_reached feature_not_entitled account_in_grace account_frozen payment_pending payment_expired payment_amount_mismatch change_already_pending change_already_applied change_effective reserve_not_covered direction_changed
detail
string
<= 2048 characters
instance
string
<= 512 characters
request_id

UUID (v7 for new entities; v4 accepted during migration).

string format: uuid
errors
Array<object>
<= 100 items
object
path
required

JSON Pointer to the offending field.

string
<= 512 characters
code
required
string
<= 64 characters
Example
{
"type": "https://ermeon.com/problems/validation",
"code": "unauthorized"
}