REST API: scores and leaderboards
Each game can have several boards (main by default). A board ranks players by their best score; every submission is stored, so history and audits are possible.
POST /games/{slug}/scores
{ "score": 4210, "board": "main", "meta": { "level": 9, "duration": 182 }, "play_session": "a1b2…" }
| Field | Rules |
|---|---|
score | integer, required. Use milliseconds or centiseconds for time-based boards with order: asc. |
board | ^[a-z0-9_-]{1,40}$, default main |
meta | optional object, stored as text up to 500 characters |
play_session | optional, attached automatically by the SDK |
player_id | required with developer keys |
Response (201):
{ "accepted": true, "score": 4210, "board": "main", "rank": { "rank": 3, "best": 4210 }, "personal_best": true }
Games with leaderboard.enabled: false answer 404 leaderboard_disabled.
GET /games/{slug}/leaderboard
Query: board (default main), period (all | month | week | day), limit (≤ 100), offset.
{
"data": {
"leaderboard": [
{ "rank": 1, "score": 9120, "entries": 14, "last_played": "2026-10-10 18:22:01",
"player": { "username": "nova", "display_name": "Nova", "country": "SE", "avatar_url": "…" } }
],
"me": { "rank": 17, "best": 4210 }
},
"meta": { "game": "target-rush", "board": "main", "period": "all", "order": "desc", "unit": "points", "limit": 25, "offset": 0 }
}
me is present when the call is authenticated as a player.
GET /games/{slug}/leaderboard/me
Only the player's own rank for a board and period.
GET /games/{slug}/scores/me
The player's last 50 submissions for the game, all boards.
Anti-cheat
Scores are accepted as sent; the platform cannot know your rules. To keep boards honest:
- validate on your own server module if the stakes are high (
games/{slug}/server/routes.php), and submit from there with a developer key; - attach
metathat lets staff spot impossible runs; - staff can remove scores and suspend accounts from the admin area.
Last updated October 11, 2026.