Skip to content

Usage reporting API

Self-hosted relays report what they served with POST /v1/usage. MOQOM rates each record, charges your prepaid balance, and tells the relay whether to keep admitting new sessions.

Endpoint POST https://api.moqom.cloud/v1/usage
Auth Authorization: Bearer mqk_… with a relay key
Batch size At most 5,000 records per request
Body At most 1 MiB; unknown fields rejected
Idempotency Per record, by id

Backend keys are refused here (401); relay keys are refused everywhere else.

{
"records": [
{
"id": "relay-eu-1:2026-10-06T09:15:00Z:bea/41d07a9e",
"tenant": "t_3f9a0c1d2e4b5a69",
"room": "live/42",
"participant": "bea/41d07a9e",
"role": "broadcast_audience",
"tier": "full_hd",
"seconds": 60,
"egress_bytes": 104857600,
"ingress_bytes": 0
}
]
}
Field Type Required Rules
id string yes 1–200 characters. Unique per participant-interval from your relay. Makes the record idempotent.
tenant string no Optional with a relay key. If present it must equal the key’s tenant, or the request is rejected.
room string no Room name. Shown as the ledger entry’s reference.
participant string no Participant identifier, for your own reconciliation.
role string yes host, audience, or broadcast_audience
tier string yes audio, hd, full_hd, 2k, 2k_plus — see Tiers
seconds integer yes Connected time in this interval, 0–86400
egress_bytes integer yes Bytes sent to this participant, ≥ 0
ingress_bytes integer yes Bytes received from this participant, ≥ 0

Tier is chosen by the sum of pixels of every video stream the participant received at once — audio-only is audio; up to 1280×720 is hd; up to 1920×1080 full_hd; up to 2560×1440 2k; above that 2k_plus.

The id is what makes retries safe: a record whose id has already been charged for your tenant is counted as a duplicate and charged nothing. A good id combines relay, interval start and participant, e.g. relay-eu-1:2026-10-06T09:15:00Z:bea/41d07a9e. Never reuse an id for a different interval.

The whole request is rejected with 400 (and nothing is charged) if any record:

  • has an empty or over-long id,
  • has an unknown role or tier,
  • has negative quantities or seconds above 86,400,
  • names a different tenant from the relay key’s.

There are more than 5,000 records → 400 at most 5000 records per report.

200 OK

{
"charged": 1,
"duplicates": 0,
"unbilled": 0,
"total": { "micros": 977, "display": "$0.000977" },
"admitted": true
}
Field Meaning
charged Records charged in this request
duplicates Records whose id was already charged — safe to ignore
unbilled Records accepted but not charged (e.g. exempt test tenants)
total Sum charged by this request
admitted Whether the tenant may admit new sessions. When false, stop admitting new sessions until it returns to true.
  • On a network error, timeout or 5xx: retry the same batch with the same ids. Duplicates are free.
  • On 400: fix the batch; retrying unchanged will fail again.
  • On 401: the relay key is wrong or revoked.

Self-hosted records are charged the per-GiB platform fee on egress_bytes only, capped by the per-minute ceiling for the record’s role and tier:

charge = min( platform_fee_per_gib × egress_GiB , ceiling(role, tier) × seconds / 60,000 )

where ceiling is the price per 1,000 participant-minutes from GET /v1/rates. The example above — 100 MiB at a $0.01/GiB fee — is about $0.000977, well under the Full HD broadcast-audience ceiling for one minute ($0.00458). See Self-hosted fee.

After a batch is charged, auto top-up runs if the balance fell below your threshold.