API – submitting scores
Lightweight REST API for high-score registration. No OAuth, no extra dependencies.
Headers
Same secret header on POST and GET. The key is stored as SHA-256; send the plaintext you were shown once.
| Header | Required | Description |
|---|---|---|
X-Api-Key |
yes | Secret issued to the game owner. Never put it in public URLs. Identifies the game — no separate game_id in the body. |
Content-Type |
POST | application/json |
Endpoint — POST /api/scores
{
"player": "PlayerNick",
"score": 12345,
"difficulty": "hard"
}
player(aliasplayer_name) — 1–40 charactersscore— non-negative integerdifficulty(aliaslevel_slug) — level id from the game
201
{
"ok": true,
"id": 42,
"status": "pending",
"game_id": "neon-runner",
"player": "PlayerNick",
"score": 12345,
"difficulty": "hard"
}
status is pending when moderation is enabled (default) or approved when an admin disables moderation.
Endpoint — POST /api/scores/level
Same as POST /api/scores plus the level reached — shown next to the score on the board. Made for games without difficulty levels (arcade style), but works with them too.
{
"player": "PlayerNick",
"score": 12345,
"level": 7
}
player,score— as abovelevel— integer 0–999999, requireddifficulty— required only if the game defines difficulty levels
201
{
"ok": true,
"id": 43,
"status": "pending",
"game_id": "arkanoid",
"player": "PlayerNick",
"score": 12345,
"level": 7,
"difficulty": "default"
}
Endpoint — GET /api/scores / /api/leaderboard
Approved scores only, top 10 per level, score descending then earlier date first. level is null for scores posted without one.
{
"ok": true,
"game_id": "neon-runner",
"game": "Neon Runner",
"levels": [
{
"id": "easy",
"slug": "easy",
"name": "Easy",
"top10": [
{ "rank": 1, "player": "Alice", "score": 99500, "level": null, "date": "2026-09-11" }
]
}
]
}
Example (curl)
curl -X POST https://your-domain.example/api/scores \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_KEY" \
-d '{"player":"SpeedDemon","score":19000,"difficulty":"easy"}'
curl -X POST https://your-domain.example/api/scores/level \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_KEY" \
-d '{"player":"SpeedDemon","score":19000,"level":7}'
curl https://your-domain.example/api/leaderboard \
-H "X-Api-Key: YOUR_KEY"
Notes
- Public boards and GET leaderboard: approved scores only. Ties: higher score, then earlier submitted_at.
- Rate limit on POST: 10 requests / minute / API key and 30 / minute / IP.
- Unpublished games return 404 from the API even with a valid key.
- Aliases accepted: player_name → player, level_slug → difficulty.
- Games without difficulty levels have a single board: omit difficulty (or send "default").
401 missing/invalid key · 404 unpublished · 429 rate limit · 400 validation