Daily charge journal
const url = 'https://api.flotera.com/api/v1/billing/usage/days?limit=50&range=7d';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/billing/usage/days?limit=50&range=7d' \ --cookie __Host-erm_session=<__Host-erm_session>One row per closed UTC day: how many managed server-days were billable, at what frozen plan rate, and the charge that was posted. This replaces the hourly journal — a day is the settlement unit (14 §2.2, §2.6).
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Query Parameters
Section titled “Query Parameters”Page size.
Named period over UTC days, deliberately not LedgerRange: the settlement unit here is the UTC day (14 §2.2), while the ledger’s ranges are expanded in the tenant timezone. Resolving one with the other would put a day in a period it was not charged in.
Named period, expanded server-side into UTC days. Mutually exclusive with from/to and with day (422 otherwise).
UTC calendar day.
One UTC day, returned with its composition in server_summary and exception rows in servers. Neither is included in list responses: they are the explanation of one charge, not a column of the journal.
Point lookup inside one day’s breakdown: a literal name substring (LIKE metacharacters are escaped) or an exact server UUID. Requires day (422 otherwise); an empty or blank value is ignored. With this filter servers carries the matches instead of exceptions.
UTC calendar day.
First UTC day of the closed interval [from, to].
UTC calendar day.
Last UTC day of the closed interval [from, to].
Responses
Section titled “Responses”Daily usage rows, newest day first.
object
One closed UTC day. charge_usd is what the ledger actually posted for that day, including the month-to-date rounding carry, so the rows sum to the ledger and not to a re-computed estimate (D-12).
object
UTC calendar day.
Frozen assignment price the day was charged at.
Decimal value serialized as a string, never a JSON number.
no_op — nothing was billable that day and no entry was written; shadow — the run computed the day without moving the balance; failed — the day could not be priced and the cursor did not move.
Machine code of why a failed day was not priced, e.g. no_plan_assignment. Always null on any other status.
A blocked day stops the settlement chain — the cursor must advance day by day, so every later day stays uncalculated too. Without the reason on the wire, the owner sees a red chip and no way to tell an empty day from a stalled one, and the only visible symptom of a stalled chain is money that never arrives.
RFC 3339 UTC with microsecond precision, or null.
Exception rows, present only when a single day was requested; null in list responses. Carries only the servers whose day needs explaining — not billable, or present for less than the whole billable window — because on a large fleet the full roster is thousands of identical lines; server_summary replaces it. Partial-but-billable rows sort first: chronically silent servers are homogeneous, while partial days are that day’s story. With server= the array carries search matches instead. Capped at 200; server_summary.exceptions is the uncapped count.
One server’s evidence for one closed UTC day: the frozen counters the billable/not decision was taken from (14 §2.4), plus what this server contributed to the day’s charge.
object
null when the server has since been removed from the registry.
Distinct accepted batches observed inside the billable window.
Union of presence intervals clipped to the billable window.
This server’s share of the day’s charge, null when the server was not billable. Shares are the split of the posted amount, so they sum to it exactly — they are not a re-computation of the daily rate.
How many servers reported that day and how. Computed by the server: both the billable criteria and the billable window are settlement rules (14 §2.4), and a client-side copy would eventually explain a charge with different arithmetic.
object
Servers that reported that day, billable or not.
Presence union covered the whole billable window, second to second. Exact equality on purpose: presence union absorbs small reconnects, so real fleets show either zero gap or a large one, and any tolerance here would be an invented threshold.
Registration and first inventory accepted that day (criterion 3).
Rows matching the exception predicate (not billable, or partial presence) before the servers cap is applied.
Example
{ "items": [ { "charge_usd": "12.340000", "status": "posted" } ]}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"}