Skip to content

Cached analytical report

GET
/reports/{kind}
curl --request GET \
--url 'https://api.flotera.com/api/v1/reports/earnings?window=7d&days=30&period=mtd' \
--cookie __Host-erm_session=<__Host-erm_session>

Report cache in front of ClickHouse/PG, keyed by report_version + tenant + kind + normalized_params_hash + data_watermark with distributed single-flight on cache miss. Parameter applicability:

  • earnings: window (7d/14d/30d) — daily gross/fees/net per source;
  • rates: days (1–90) — per-source rates, daily series, utilization;
  • summary: period (mtd/14d/30d) — totals and per-source split;
  • marketplaces: no parameters — 30-day marketplace revenue.
kind
required
string
Allowed values: earnings rates summary marketplaces

Report kind (first-wave set).

If-None-Match
string
<= 256 characters

Return 304 Not Modified when the entity tag still matches.

window
string
default: 7d
Allowed values: 7d 14d 30d

For kind=earnings.

days
integer
default: 30 >= 1 <= 90

For kind=rates.

period
string
default: mtd
Allowed values: mtd 14d 30d

For kind=summary.

Report snapshot.

Media typeapplication/json

Report envelope; data shape depends on kind.

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
kind
required
string
Allowed values: earnings rates summary marketplaces
data
required
One of:

Daily earnings per source for the revenue chart and earning mix.

object
window
required
string
Allowed values: 7d 14d 30d
items
required
Array<object>
<= 200 items
object
day
required

UTC calendar day.

string format: date
source
required
string
<= 32 characters
gross_usd

Decimal string or null when unknown.

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

Decimal string or null when unknown.

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

Decimal string or null when unknown.

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

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

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

Decimal string or null when unknown.

string | null
/^-?[0-9]+(\.[0-9]{1,6})?$/
Example
{
"generated_at": "2026-07-25T10:15:30.123456Z",
"data_as_of": "2026-07-25T10:15:30.123456Z",
"kind": "earnings",
"data": {
"window": "7d",
"items": [
{
"source": "vast",
"net_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"
}

Resource does not exist in this tenant. Foreign identifiers also return 404 (anti-enumeration).

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"
}

Request failed validation (code=validation_failed), with per-field errors.

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"
}