Trophies API

Trophy persistence service for HTMLGameKit games. Stores trophy unlocks per game per player with server-generated anonymous identities, unlock timestamps, and global rarity statistics.

Endpoints

MethodRouteDescription
GET/t/{game_id}Get unlocked trophies for the current player
PUT/t/{game_id}/{trophy_id}Record a trophy unlock
GET/t/{game_id}/allTrophy stats across all players (counts + rarity)

Player Identity

Players are identified by a UUID sent via the Authorization: Bearer {uuid} request header. On first contact (no header), the server generates a new UUID and returns it in the player field of the JSON response body. The client should store this and replay it on subsequent requests.

There is no authentication — identity is anonymous and persistent via the UUID alone.

API Reference

GET /t/{game_id} cached

Fetch all unlocked trophies for the current player in a game. Responses are served from an in-memory LRU cache when available.

Request headers:

HeaderRequiredDescription
Authorization: Bearer {uuid}NoPlayer UUID. If omitted, a new UUID is generated.

Response: 200 OK

{
  "player": "550e8400-e29b-41d4-a716-446655440000",
  "game": "my-game",
  "trophies": [
    { "id": "first-win", "unlocked_at": "2026-04-05 12:34:56" },
    { "id": "speed-demon", "unlocked_at": "2026-04-05 12:40:10" }
  ]
}

If the player has no trophies, trophies is an empty array. The player field always contains the UUID (generated or echoed back).

PUT /t/{game_id}/{trophy_id}

Record a trophy unlock. Idempotent — unlocking the same trophy twice is safe.

Request headers:

HeaderRequiredDescription
Authorization: Bearer {uuid}NoPlayer UUID. If omitted, a new UUID is generated.

Response:

StatusMeaning
201 CreatedTrophy was newly unlocked
200 OKTrophy was already unlocked (no-op)
409 ConflictTrophy ID is reserved (e.g. all)

No request body is needed. The response body contains {"player": "{uuid}"}. The cache for this player+game is invalidated on successful unlock.

GET /t/{game_id}/all

Get aggregate trophy statistics across all players for a game, including unlock counts and rarity percentages.

Response: 200 OK

{
  "game": "my-game",
  "total_players": 1250,
  "trophies": [
    { "trophy_id": "first-win", "count": 1100, "rarity": 88.0 },
    { "trophy_id": "speed-demon", "count": 150, "rarity": 12.0 },
    { "trophy_id": "perfectionist", "count": 12, "rarity": 0.96 }
  ]
}

rarity is the percentage of players who have unlocked the trophy, rounded to two decimal places. Trophies are ordered by count descending.

Examples

# Unlock a trophy
curl -X PUT https://trophies.htmlgamekit.dev/t/my-game/first-win \
  -H "Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000"

# Get unlocked trophies for a player
curl https://trophies.htmlgamekit.dev/t/my-game \
  -H "Authorization: Bearer 550e8400-e29b-41d4-a716-446655440000"

# Get a new player UUID (omit the header)
curl https://trophies.htmlgamekit.dev/t/my-game

# Get global trophy stats + rarity
curl https://trophies.htmlgamekit.dev/t/my-game/all