Leaderboard
The leaderboard ranks members by what they did on the exchange: how much they traded and made, how many contracts and markets they settled, how often they won, their biggest win, their return and their longest winning streak. It is public inside the platform (every ranked row shows a handle and an avatar, never a name, an email or an account id), and you control whether you appear on it.
Metrics
Section titled “Metrics”metric |
What is ranked | value type |
|---|---|---|
volume |
Notional traded: filled quantity × market max_price, whatever the trade price |
dollar string |
profit |
Net profit and loss on markets settled in the period, after fees | dollar string, e.g. "12.5000" |
predictions |
Contracts settled in the period | integer |
markets |
Markets settled in the period, whether won, lost or pushed | integer |
win_rate |
Markets won ÷ markets won or lost. Needs 10 decided markets in the period | number, 0–1 |
biggest_win |
Net profit on your best single market settled in the period | dollar string |
return |
Net profit ÷ volume. Needs $500 of volume and a profit in the period | number, 0–1 |
streak |
Longest run of winning markets in a row in the period; a push does not break it | integer |
Which boards are shown
Section titled “Which boards are shown”STX decides which boards are shown and how many members each lists (10, 25,
50 or 100). Asking for a hidden board is not an error: it comes back empty with
"shown": false. The table above gives how value is written on each board.
STX can keep some account types (for example market makers or STX’s own accounts)
off every board. An account that is self-excluded, in a cool-off period, suspended,
banned, closed, rejected, archived or overdrawn never appears on a board or a
profile page. Only a positive value earns a place on a board: a member with nothing settled
or traded in the period is not listed, and neither is a net loss on profit.
Ranks are dense: two members with the same value share a rank, and the next
distinct value takes the next rank. A board holds at most the configured
number of members per board, never more than 100 rows.
Periods
Section titled “Periods”Every period is a range of calendar days in America/New_York, ending today. A settlement at 23:30 New York time on a Sunday counts for Sunday even though it is already Monday in UTC.
period |
Covers | Resets |
|---|---|---|
daily |
Today | Midnight New York, every day |
weekly |
Monday to today | Midnight New York on Monday |
monthly |
The 1st to today | Midnight New York on the 1st |
yearly |
1 January to today | Midnight New York on 1 January |
all |
Everything | Never |
Every board response carries next_reset_at as a UTC timestamp: local midnight
shifted to UTC, so it moves by an hour across a daylight-saving change while the
board still resets at 00:00 New York. It is null for all.
Boards are rebuilt on a fixed schedule (every 15 minutes by default, on the clock), not
after each trade or settlement; refreshed_at is when the snapshot you are reading was
built. A member who leaves the leaderboard is removed at once.
Categories
Section titled “Categories”category is all (every sport combined) or one sport key: the lowercase sport
name, as in a row’s top_sport (for example basketball). A sport has a board once a
market in it has settled or traded in the period.
An unknown category is not an error. The board is simply empty, because a sport that is between seasons genuinely has nobody on it.
Endpoints
Section titled “Endpoints”| Method | Path | Returns |
|---|---|---|
| GET | /api/v1/leaderboard?period=weekly&category=all&metric=profit&limit=50 |
The top rows of one board |
| GET | /api/v1/leaderboard/me?period=weekly&category=all |
Your own standing, including a rank outside the top 100 |
| GET | /api/v1/me |
Your identity and public profile |
| PATCH | /api/v1/me/profile |
Change handle, avatar or opt-in |
All of period, category, metric and limit are optional and default to
weekly, all, the board STX opens on and the number of members per board. An
unknown period or metric is a 400 naming the field. limit is clamped to
the number of members per board: a board is a fixed top-N, so there is no cursor
and never a next page.
A board row:
{ "rank": 1, "handle": "swift.fox12", "avatar_url": "/avatars/swift.fox12.svg", "top_sport": "basketball", "top_sport_icon_url": "/api/images/categories/standard/basketball-6b422c4a.svg", "value": "300.0000"}top_sport is the sport the member traded most in the period; on a sport board
it is that sport.
Your own standing:
{ "profit": {"rank": 2, "value": "12.5000"}, "volume": {"rank": 1, "value": "400.0000"}, "predictions": {"rank": 3, "value": 7}, "markets": {"rank": 4, "value": 12}, "win_rate_rank": {"rank": 2, "value": 0.7}, "biggest_win": null, "return": null, "streak": {"rank": 6, "value": 3}, "win_rate": 0.7, "settled_markets": 10, "opted_in": true, "period": "weekly", "category": "basketball"}A metric you have nothing positive on is null even while you rank on another,
and so is every board STX hides. The Win rate board’s rank is
win_rate_rank; win_rate is your plain share of decided markets.
win_rate is the share of decided markets you won, and is null until at least
10 markets have been decided in the period. A market you settled at exactly zero
is neither a win nor a loss. When you are unranked (opted out, or no activity
in the period), every metric is null, settled_markets is 0 and opted_in
tells you which of the two it is.
Authentication
Section titled “Authentication”These endpoints, and GET /api/v1/me / PATCH /api/v1/me/profile, accept
either credential:
- The signed Ed25519 headers every other
/api/v1endpoint takes; see request signing. Aread_onlykey can read every leaderboard endpoint;PATCH /api/v1/me/profileneedsread_write. Authorization: Bearer <token>with the session token STX’s own apps sign in with. A session may always update its own profile. An integration signs with its API key.
With no credential, or a bad one, the answer is 401 {"error": "Unauthorized"}.
If any X-STX-ACCESS-* header is present the request is treated as a signed
request and the signing rules apply.
Handles and avatars
Section titled “Handles and avatars”Your handle is the name other members see. It is separate from your sign-in
email and never derived from your name. Every account starts with a generated
adjective.animal1234 handle; you can pick your own:
- 3 to 24 characters: lowercase letters, digits, and
.or_between them. Case is folded, soSwift.Fox12is saved asswift.fox12. - Not already taken, not a reserved word (
admin,support,stx, …) and not on the blocklist. - Changeable once every 30 days.
GET /api/v1/mereportshandle_changeable_at:nullwhen you may change it now, otherwise when the window ends. Sending your current handle again is not a change.
Your avatar is generated from three values you choose and rendered on demand. There is no upload:
{"style": "dots", "seed": "a1b2c3d4", "palette": "ocean"}style is one of dots, rings, stripes, grid, ball, court, stitch,
target, candles, dice; palette one of ember,
forest, ocean, grape, slate, mint, rose, gold; seed any 1–32
characters, and the same three values always render the same image. Every row
carries avatar_url, a path relative to the API host (/avatars/{handle}.svg)
that serves the SVG publicly with a one-day cache and an ETag.
curl -X PATCH https://demo.stxapp.io/api/v1/me/profile \ -H "X-STX-ACCESS-KEY: $KEY_ID" -H "X-STX-ACCESS-TIMESTAMP: $TS" \ -H "X-STX-ACCESS-SIGNATURE: $SIG" -H "Content-Type: application/json" \ -d '{"handle": "swift.fox12", "avatar": {"style": "rings", "seed": "deadbeef", "palette": "gold"}}'The response is the same object GET /api/v1/me returns. A key of the wrong
JSON type is a 400; a handle that is taken, reserved, malformed or changed
too soon is a 422 whose error names the rule.
Joining and leaving
Section titled “Joining and leaving”{"leaderboard_opt_in": false}sent to PATCH /api/v1/me/profile removes you from every public board on the
next snapshot. Your own GET /api/v1/leaderboard/me then reports every rank as
null with opted_in: false; your trading is unaffected. Send true to join.
Each change is recorded with its time.
A new account starts with the jurisdiction’s default. An account opened before the leaderboard existed is not listed until you join; joining also gives you a generated handle and avatar if you do not have one yet.

