Skip to Content
APIEdetabel

Leaderboard

Rankings are computed from a periodic snapshot, refreshed every 60 seconds. Numbers can be up to ~60 seconds stale.

GET /api/v1/leaderboard

Returns the ranked top traders for a category and time window.

Auth: None
Rate limit: v1: 60 req / 60 s per IP
Cache: no-store (privacy flags are evaluated on every request)

Query parameters

ParamTypeDefaultDescription
categorystring"all""all" or a category slug from /categories
windowstring"all""day" | "week" | "month" | "ytd" | "all"
limitinteger50Number of rank slots (1–100)

Response

{ "category": "all", "window": "all", "entries": [ { "isPrivate": true, "rank": 1 }, { "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "handle": "alice", "displayName": "Alice", "avatarUrl": null, "rank": 2, "plCents": 482300, "volCents": 1900000, "winRate": 0.62, "roi": 0.25, "settledCount": 84 } ] }
FieldTypeDescription
categorystringEcho of the requested category
windowstringEcho of the requested window
entriesarrayRanked traders and private rank placeholders, best first
entries[].isPrivatebooleanPresent and true only for a private-profile or opted-out trader; that object contains no fields other than rank
entries[].rankintegerPosition in this leaderboard (1 = top)
entries[].userIdUUID stringPublic entries only: trader user id
entries[].handlestringPublic entries only: trader handle
entries[].displayNamestringPublic entries only: display name
entries[].avatarUrlstring | nullPublic entries only: avatar URL; null if none set
entries[].plCentsintegerPublic entries only: settled profit/loss in EUR-cents
entries[].volCentsintegerPublic entries only: settled trading volume in EUR-cents
entries[].winRatenumberPublic entries only: wins / settled trades, 0–1; 0 when settledCount is 0
entries[].roinumberPublic entries only: plCents / volCents; 0 when volCents is 0
entries[].settledCountintegerPublic entries only: number of settled trades in the window

A trader whose profile or leaderboard appearance is private still occupies an existing snapshot rank, but the public response exposes only { "isPrivate": true, "rank": N }. User id, handle, display name, avatar, and every performance field are omitted.

Errors

StatusBodyWhen
400{ "error": "Unknown category: ..." }Category slug does not exist

GET /api/v1/leaderboard/summary

Returns aggregate stats for a category and window: totals plus the top trader, biggest single win, and the median trader.

Auth: None
Rate limit: v1: 60 req / 60 s per IP
Cache: no-store (the response can contain trader identity)

Query parameters

ParamTypeDefaultDescription
categorystring"all""all" or a category slug from /categories
windowstring"all""day" | "week" | "month" | "ytd" | "all"

Response

{ "category": "all", "window": "all", "traderCount": 312, "totalVolumeCents": 48200000, "openInterestCents": 9100000, "topTrader": { "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "handle": "alice", "displayName": "Alice", "avatarUrl": null, "plCents": 482300 }, "biggestSingleWin": { "userId": "f6a7b8c9-d0e1-2345-f012-456789012345", "handle": "bob", "displayName": "Bob", "avatarUrl": null, "marketId": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "marketTitle": "Reform Party", "eventId": "c3d4e5f6-a7b8-9012-cdef-123456789012", "eventTitle": "Which party will win the most seats?", "plCents": 91000 }, "medianTrader": { "plCents": 1200, "winRate": 0.5, "settledCount": 12 }, "snapshotAt": "2026-01-15T14:30:00.000Z" }
FieldTypeDescription
categorystringEcho of the requested category
windowstringEcho of the requested window
traderCountintegerIdentity-public traders with settled trades in the window; anonymous rank slots are not counted
totalVolumeCentsintegerSettled trading volume in EUR-cents
openInterestCentsintegerOpen interest in EUR-cents
topTraderobject | nullHighest-P/L trader; null when no data
topTrader.plCentsintegerSettled P/L in EUR-cents
biggestSingleWinobject | nullLargest single-market win; null when no data
biggestSingleWin.marketIdUUID stringMarket the win was on
biggestSingleWin.marketTitlestringMarket title
biggestSingleWin.eventIdUUID string | nullParent event id; null for a standalone market
biggestSingleWin.eventTitlestring | nullParent event title; null for a standalone market
biggestSingleWin.plCentsintegerP/L of that win in EUR-cents
medianTraderobject | nullMedian-trader stats; null when no data
medianTrader.plCentsintegerMedian settled P/L in EUR-cents
medianTrader.winRatenumberMedian win rate, 0–1
medianTrader.settledCountintegerMedian settled-trade count
snapshotAtISO 8601 | nullWhen the snapshot was taken; null before the first refresh

topTrader, biggestSingleWin, and medianTrader carry the same userId / handle / displayName / avatarUrl fields as a leaderboard entry. Before the first snapshot is written, every aggregate is 0 or null and snapshotAt is null.


GET /api/v1/leaderboard/me

Returns your own leaderboard entry for a category and window.

Auth: Required
Rate limit: v1-user: 120 req / 60 s per user (keyed on user id)
Cache: no-store

Query parameters

ParamTypeDefaultDescription
categorystring"all""all" or a category slug from /categories
windowstring"all""day" | "week" | "month" | "ytd" | "all"

Response

self is null when you have no settled trades in the window. Otherwise it is a complete public-entry shape, even when you have opted out of the public leaderboard; the authenticated response is only available to you.

{ "self": { "userId": "e5f6a7b8-c9d0-1234-ef01-345678901234", "handle": "alice", "displayName": "Alice", "avatarUrl": null, "rank": 14, "plCents": 23100, "volCents": 140000, "winRate": 0.55, "roi": 0.16, "settledCount": 22 } }

No settled trades:

{ "self": null }

Errors

StatusBodyWhen
400{ "error": "Unknown category: ..." }Category slug does not exist
401{ "error": "Unauthorized" }Missing or invalid token