Limits & security
Limits
| Limit | Value |
|---|---|
spendCoins amount per call | 1..10000 |
earnCoins amount per call | 1..100 |
earnCoins per user per hour | 2000 coins |
saveProgress payload size | 100 KB encoded |
| SDK messages per minute | 60 |
| Reason format | ^[a-z0-9_]+$, ≤ 64 chars |
| Bridge response timeout | 30 s |
All limits are enforced on the server with the same values shown above — the client can't raise them, even by calling the backend directly.
Why your game can't cheat
- Coins are server-authoritative. Your game can only request a spend or earn; the server validates it and applies the change. The balance never lives in the game.
- Identity comes from the authenticated session. The game never sends a user id.
The coin RPCs derive the player from the signed-in session and reject any request
that targets a different account (
forbidden), so a player can't grant or drain anyone's coins — including their own outside of gameplay. - Spends are atomic. Rapid or concurrent calls can't double-spend.
- Saves are per-player. Row-level security ties every save to the signed-in player; no one can read or write another player's save.
- Inert outside the app. With no app session there's nothing to spend — see App-only & offline.
Platform note
Coins and progress sync are live in the native app (Android/iOS) and on the web
for games served from the Gamma Games origin. A game loaded from a third-party
origin on the web can't be wired to the host securely, so the SDK reports
isInApp === false there and your offline fallback runs — see
App-only & offline.
Ask:View .md