REST API: save states

Save states are JSON documents stored per player, per game, per slot. Slots run from 0 to save_slots - 1 as declared in the manifest. Each save increments a version number.

Authentication: player token / session (own states) or developer key with states:read / states:write plus player_id.

GET /games/{slug}/states

List slots without the payload.

{ "data": { "states": [{ "slot": 0, "label": "Chapter 3", "version": 12, "size_bytes": 2048, "created_at": "…", "updated_at": "…" }] },
  "meta": { "save_slots": 3 } }

GET /games/{slug}/states/{slot}

Full state. 404 not_found when the slot is empty.

{ "data": { "state": { "slot": 0, "label": "Chapter 3", "version": 12, "size_bytes": 2048, "state": { "level": 7, "coins": 42 }, "updated_at": "…" } } }

PUT /games/{slug}/states/{slot}

{ "state": { "level": 8, "coins": 50 }, "label": "Chapter 4", "expected_version": 12 }
  • state is required and may be any JSON value. Limit 256 KB (413 state_too_large).
  • label is optional, up to 80 characters.
  • expected_version is optional. When it does not match the stored version the call fails with 409 version_conflict and error.current_version; reload and merge.

Returns 201 on first save, 200 afterwards: { slot, version, size_bytes, created }.

DELETE /games/{slug}/states/{slot}

Returns { deleted: true|false }.

With a developer key

Add player_id as a query parameter (GET/DELETE) or JSON field (PUT):

curl -X PUT "https://allgameclub.com/api/v1/games/my-game/states/0" \
  -H "Authorization: Bearer agk_…" -H "Content-Type: application/json" \
  -d '{"player_id": 42, "state": {"level": 8}}'

Or use the explicit developer routes /dev/games/{slug}/players/{id}/states[/{slot}].

Design notes

  • Keep states small and flat; store derived data in the game, not on the server.
  • Include a format or schema number inside your state so old saves can be migrated.
  • Use slot labels for "Continue" menus; updated_at tells you which save is newest.

Last updated October 11, 2026.