Skip to content

Server Tier API

automoto edited this page Oct 26, 2026 · 2 revisions

Server-Tier API

The server tier is the set of /v1/server/… routes. A dedicated game server, or your own backend, calls them with a secret API key only. These routes use no player session token. The caller gives the player_id of the player that it acts for.

All /v1/server/… routes return 403 for a publishable key. A publishable key is in the game binary, so a modified client can do all that the key can do. Keep secret keys on machines that you control.

Server tier and player-session routes

Route family Caller Trust model
Player-session routes (/v1/storage/…, /v1/leaderboards/…, …) The game client, with X-Session-Token. The player acts for themselves. The server trusts the session. It does not trust what the client says about other players.
Server tier (/v1/server/…) A game server or backend, with a secret key. The caller is trusted infrastructure. It can act for any player in its Game Project.

Use the server tier when the write must be server-authoritative:

  • A match ends and the dedicated server reports the score of each player. Clients never get a credential that can submit scores, so they cannot make false results.
  • The server saves match state (inventory, progress) into the cloud save of a player, also after that player disconnects.
  • A backend job reads the saves of a player for support or migration tools.

Use the player-session routes for all that players do for themselves. Examples are their own saves from the client, leaderboard reads, friends, and the profile.

A typical dedicated-server flow uses both tiers:

  1. The client connects to the game server and sends it the session token.
  2. The server calls POST /v1/server/player-sessions/verify with {"session_token":"..."}. The response gives player_id and external_id.
  3. During and after the match, the server submits scores and writes saves for that player_id.

Score submission

curl -s -X POST http://localhost:8080/v1/server/leaderboards/1/scores \
  -H "Authorization: Bearer <secret_api_key>" \
  -H "Content-Type: application/json" \
  -d '{"player_id":42,"score":1500,"metadata":{"ghost":"r-42"}}'

A success returns 201 Created. The leaderboard must be in the key's Game Project. score is required. metadata is an optional JSON object, 2 KiB maximum.

The score operator, the periods, and the attempt cap apply as on the Leaderboards page. The client-submission limits do not apply: the server ignores score_min, score_max, and the client rate limit for server-tier submissions.

Player storage

PUT /v1/server/players/{player_id}/storage/objects/{key}
GET /v1/server/players/{player_id}/storage/objects/{key}
GET /v1/server/players/{player_id}/storage/objects?key_prefix=save-&limit=50

These routes read, write, and list the same objects that the player uses from the client. The key rules, size limits, If-Match behavior, quota, and errors are the same as on Cloud Saves. Send If-Match so that a slow server does not overwrite a newer save. The server tier cannot delete objects. Only the player can delete an object.

Player remote addresses

GET /v1/server/players/{player_id}/remote-addrs reads the addresses that a player shares for direct connections (ip, dns, or iroh). The player must be in the key's Game Project and have a linked account. If not, the server returns 404. Players set their own list with PUT /v1/account/remote-addrs. The server route can only read. See Friends and Presence for the address format.

Common errors

Status Meaning Server action
400 api key has no project pin The key is not pinned to a Game Project. Use a key of the Game Project.
401 The API key is missing or unknown. Fix the key configuration.
403 forbidden The key is publishable, or it does not have the permission. Use the secret key of the Game Project.
403 player disabled The player account is disabled. Stop the action for this player.
403 player banned The player is banned in the Account Tenant. Stop the action for this player.
403 attempt cap reached for this period The player used all attempts on this board for this period. Do not retry until the period resets.
404 player not found The player_id is unknown, deleted, or in a different Game Project. Verify the session again. Check the key's Game Project.
404 leaderboard not found The leaderboard id is unknown or in a different Game Project. Check the leaderboard id.
412 The If-Match version is not the stored version. Read the object again, merge, and retry.
422 score is missing, or metadata is not valid or is too large. Fix the request body.

Each player_id is always in the key's Game Project. A server cannot get to a player in a different Game Project or Account Tenant, also with a valid id.

Full reference: the /v1/server/* operations.

Clone this wiki locally