about / api
REST API
The API may change dramatically, so there are no guarantees about backwards compatibility. All responses are JSON and every endpoint is a public
GET request.ENDPOINTS
GET
/api/leaderboard
Fetch the top scores/times for a game mode. One entry per player by default (each player's personal best), or every submitted score when
duplicates=true.| Name | Type | Default | Description |
|---|---|---|---|
mode | integer | 2 | Mode id (see the mode table below). Non-integer values fall back to the default; unknown/out-of-range ids return an empty scores array. |
subMode | integer | (none) | Filters to a sub-mode. Only meaningful for Four Wide (values 0–3 = 3/4/5/6 Residual; scores submitted before sub-modes existed count as 0). Omit the parameter to get all sub-modes combined. |
duplicates | boolean | false | Only the literal string true enables it. When false, results are aggregated to one best row per player; when true, every score is returned (a player may appear multiple times). |
amount | integer | 100 | Number of rows to return. Hard-capped at 100. |
Response
{
"scores": [
{
"username": "Alice",
"time": 42317,
"pieces": 100,
"pps": 2.36,
"date": 1718000000000,
"replay": 8421
}
]
}
A
score field is added to each entry for score-based modes (PC Mode, The Almost Death, Four Wide, Hyper, T-Spin Rush, T-Spin Puzzle, All-Spin Puzzle). Time-only modes (40 Lines, Digger, Survival) omit it.Modes
| id | Name | Slug(s) | Has score |
|---|---|---|---|
1 | PC Mode | pc-mode, pc | yes |
2 | 40 Lines | 40-lines, 40l | no |
3 | Digger | digger | no |
4 | Survival | survival | no |
5 | The Almost Death | the-almost-death, tad | yes |
6 | Four Wide | four-wide, 4w | yes |
7 | Hyper | hyper | yes |
8 | T-Spin Rush | t-spin-rush | yes |
9 | T-Spin Puzzle | t-spin-puzzle | yes |
10 | All-Spin Puzzle | all-spin-puzzle | yes |
The first slug listed is the canonical one. Each slug can also be used as a path parameter (see below).
GET
/api/leaderboard/
:modeSlug
Same as
/api/leaderboard, but the mode is chosen by a slug in the path instead of the mode query param. An unknown slug falls back to the mode query param (default 2).| Name | Type | Default | Description |
|---|---|---|---|
:modeSlugpath | string | — | A mode slug from the table above (e.g. 40-lines). |
subMode | integer | (none) | Same as above. |
duplicates | boolean | false | Same as above. |
amount | integer | 100 | Same as above. Hard-capped at 100. |
Response
Identical shape to
/api/leaderboard: { "scores": [ ... ] }.
GET
/api/profile
Player profile: stats, achievements, personal best scores and recent games. Returns an empty body if
player is missing or unknown.| Name | Type | Default | Description |
|---|---|---|---|
player | string | — | Required. The player's username. |
games | integer | 10 | Number of recent games to include. Hard-capped at 100. |
Response
Top-level fields:
achievements, best-scores (keyed by mode name), positions, recent-scores (array), stats, submitted-scores (score counts keyed by mode id, 0 = total).
GET
/api/replay
Retrieve a recorded game replay by its numeric id. Returns an empty body if the id is missing, not a number, or no matching replay exists.
| Name | Type | Default | Description |
|---|---|---|---|
id | integer | — | Required. The replay id. |
Response
{
"id": 8421,
"username": "Alice",
"mode": 2,
"time": 42317,
"pieces": 100,
"pps": 2.36,
"date": 1718000000000,
"replay": "...",
"serverReplay": "..."
}
GET
/api/stats
Global server statistics: current world records, the number of submitted scores per mode, and player activity. Takes no parameters.
Response
Top-level fields:
records (array of world records, each with username, mode, score or time, date, replay), submitted-scores (score counts keyed by mode id, 0 = total), and players (activity counters: online now, and unique players today, week, month, and allTime)./replay/data and /profile/data are legacy aliases of /api/replay and /api/profile respectively.