Public API
API reference
Every number on this site comes from this API. Versioned, rate-limited (60 req/min/IP), and shipped under CC0 for the data.
Conventions
- Base URL
- https://whoearns.live
- Auth
- None — public, read-only.
- Rate limit
- 60 requests / min / IP. Exceeding returns
429 Too Many Requests. - Errors
- JSON:
{ error: { code, message, requestId, details? } }.
Endpoints
- GET
/healthzLiveness + readiness probeReports DB connectivity + RPC heartbeat freshness. Returns 200 with body `{status: "ok" | "degraded"}`. Used by k8s probes.
https://whoearns.live/healthz - GET
/v1/epoch/currentCurrent Solana epoch snapshotFirst/last/current slot, `slotsElapsed`, and `isClosed` for the running epoch. Updated every `EPOCH_WATCH_INTERVAL_MS` tick.
https://whoearns.live/v1/epoch/current - GET
/v1/leaderboardTop-N validators by a chosen ranking metricRanked list for the most recent closed epoch. Five sort modes: `performance` (DEFAULT — `(block_fees + block_tips) / slots_assigned` DESC, stake-neutral + commission-neutral skill), `total_income` (block_fees + block_tips DESC, stake-biased), `income_per_stake` (operator revenue per stake, DESC), `skip_rate` (ASC, reliability), `median_fee` (DESC, per-block packing). Rows without ingested fee data are filtered out; rows without a stake snapshot fall out of `income_per_stake` only. Rows with `slots_assigned < 30` are included but flagged as low-sample.
Query parameters (3)
- limit (integer)
- How many rows to return. Clamped server-side to 500. Default 100.
- epoch (integer)
- Override target epoch. Defaults to the most recent closed epoch. 404 if the epoch is unknown.
- sort (enum)
- `performance` | `total_income` | `income_per_stake` | `skip_rate` | `median_fee`. Default `performance`. 400 on unknown values.
https://whoearns.live/v1/leaderboard?limit=25&sort=performance - GET
/v1/validators/{idOrVote}/current-epochA validator's running-epoch statsSame row as the history endpoint filtered to the current epoch. `idOrVote` accepts either a vote pubkey or an identity pubkey; the resolver picks whichever matches our `validators` table.
https://whoearns.live/v1/validators/5BAi9YGCipHq4ZcXuen5vagRQqRTVTRszXNqBZC6uBPZ/current-epoch - GET
/v1/validators/{idOrVote}/epochs/{epoch}A validator's stats for one epochSame record shape as `current-epoch`, but pinned to the requested epoch. `idOrVote` accepts either a vote pubkey or an identity pubkey.
https://whoearns.live/v1/validators/5BAi9YGCipHq4ZcXuen5vagRQqRTVTRszXNqBZC6uBPZ/epochs/963 - GET
/v1/validators/{idOrVote}/historyPer-epoch history for a validatorRows returned newest-first. Each row carries `isFinal`, `hasSlots`, `hasIncome`, and an optional `cluster` block for median comparison context.
Query parameters (1)
- limit (integer)
- Row count. Clamped server-side to 200. Default 50.
https://whoearns.live/v1/validators/5BAi9YGCipHq4ZcXuen5vagRQqRTVTRszXNqBZC6uBPZ/history?limit=20
Need more detail?
Full response shapes, field-level docs, and enum values live in the OpenAPI 3.1 spec at /openapi.yaml. Paste that URL into Hoppscotch, Scalar, or your own OpenAPI viewer for a full interactive reference.