Developer guide

ScorePerch gives your game online leaderboards with two HTTP calls. There are no player accounts: your game creates a random player_id (a UUID) once, stores it, and sends it with a nickname.

1. Get set up

  1. Create a free developer account and verify your email.
  2. Create a game. You get a Game Key (gk_…, public, safe to ship) and a signing secret (gs_…, used to sign score posts).
  3. Add boards — one per level or mode. "Add numbered boards" creates level-1 … level-N in one go. Each board says whether lower is better (times) or higher is better (points), and can reject impossible values.
  4. Optionally turn on the game's public page (/games/{slug}: leaderboards + support) and its generated privacy page (/games/{slug}/privacy), handy as App Store / Google Play URLs.

Accounts can have up to 3 games with up to 200 boards each. ScorePerch is free.

2. Post a result

POST https://scoreperch.com/api/v1/scores
Content-Type: application/json
X-Game-Key: gk_xxxxxxxxxxxxxxxxxxxxxxxx
X-Timestamp: 1767225600
X-Signature: hex( HMAC-SHA256( secret, "{X-Timestamp}.{raw JSON body}" ) )

{
  "player_id":   "8a3f2c1e-5b6d-4e7f-9a0b-1c2d3e4f5a6b",
  "player_name": "Squirrel",
  "board":       "level-12",
  "value":       34,
  "moves":       51,
  "platform":    "ios",
  "app_version": "1.7"
}

You can also post to /api/v1/games/{slug}/scores (the slug identifies the game; X-Game-Key is then optional but must match if sent). value is a whole number in the board's unit (seconds for times). moves is optional and breaks ties (fewer is better). platform is one of ios, android, web, other.

Response (201 for a new personal best, 200 otherwise):

{ "board": "level-12", "player_name": "Squirrel", "is_new_best": true,
  "best": { "value": 34, "display": "0:34", "moves": 51 },
  "rank": 7, "total": 240 }

Only the player's best result per board is kept. The name actually stored is returned in player_name (unsuitable names are replaced).

3. Read a leaderboard

GET https://scoreperch.com/api/v1/games/{slug}/leaderboards/{board}?limit=50&player_id={uuid}

{ "board": { "key": "level-12", "name": "Level 12", "sort": "asc", "unit": "seconds" },
  "entries": [ { "rank": 1, "name": "Ana", "value": 21, "display": "0:21", "moves": 40, "date": "2026-11-03" } ],
  "you": { "rank": 7, "name": "Squirrel", "value": 34, "display": "0:34", "moves": 51, "date": "2026-11-03" },
  "total": 240 }

GET /api/v1/games/{slug}/boards lists the boards. Each game also has a public page at /games/{slug} you can open from your game, e.g. /games/{slug}?board=level-12.

4. Rotating the secret

If a secret leaks, use Regenerate secret in the dashboard. The old secret keeps working for 7 days, so players on older versions of your game can still post while you release an update with the new one.

5. Errors

6. Fair play & privacy

The secret ships inside your game, so signing deters casual cheating but can't stop a determined attacker. Boards have minimum and maximum values, and we remove impossible scores. Never send real names, emails or device identifiers; list ScorePerch in your privacy policy — the generated privacy page does this for you. See the Terms for developers.