Get Player Balance
Read a player's currency balances in your title by email, or many players in one batch call. These are server-to-server reads authenticated with your X-Game-Secret-Key.
Call these from your server only. They take your title's secret key, which must never ship in a game or app client. To show a balance in the client, have the client ask your server, or use the player-token route the SDKs wrap (GET /api/sdk/balance, see In-App Verification).
By email
GET /api/player-balances/player/by-email/{email}, with the email URL-encoded.
curl
curl -sS "https://invo.network/api/player-balances/player/by-email/bo%40example.com" \ -H "X-Game-Secret-Key: $GAME_SECRET"
Node (server)
const res = await fetch(
`https://invo.network/api/player-balances/player/by-email/${encodeURIComponent(email)}`,
{ headers: { 'X-Game-Secret-Key': process.env.INVO_GAME_SECRET } }
);
if (res.status === 404) { /* no player with that email in your title yet */ }
const body = await res.json();Python (server)
import os, requests, urllib.parse
r = requests.get(
"https://invo.network/api/player-balances/player/by-email/" + urllib.parse.quote(email),
headers={"X-Game-Secret-Key": os.environ["INVO_GAME_SECRET"]}, timeout=10)200 response
{
"player": {
"player_id": 12345,
"player_name": "Bo",
"player_email": "bo@example.com",
"date_joined": "2026-03-01T12:00:00+00:00"
},
"balances": [
{
"currency_id": 1,
"currency_name": "Gold Coins",
"available_balance": "1500.00",
"reserved_balance": "50.00",
"total_balance": "1550.00"
}
],
"summary": { "total_value": "1550.00", "currency_count": 1, "has_funds": true },
"last_updated": "2026-10-09T12:00:00+00:00"
}- •
available_balanceis what the player can spend now;reserved_balanceis held for a send or transfer still in flight;total_balanceis the two together. - • Only balances in the calling title are returned.
- •
404Player not found: no player with that email in your title.
Many players: batch
POST /api/player-balances/batch with player_emails and/or player_ids. Up to 100,000 players per request in total; a larger request answers 400 with requested and maximum.
Request
POST https://invo.network/api/player-balances/batch
X-Game-Secret-Key: <your secret>
Content-Type: application/json
{ "player_emails": ["bo@example.com", "ada@example.com"], "player_ids": [12345] }200 response
{
"results": [
{
"player": { "player_id": 12345, "player_email": "bo@example.com", "player_name": "Bo" },
"balances": [
{ "currency_id": 1, "currency_name": "Gold Coins",
"available_balance": "1500.00", "total_balance": "1550.00" }
],
"total_value": "1550.00"
},
{ "player": { "player_email": "ada@example.com" }, "error": "Player not found", "balances": [] }
],
"summary": { "total_requested": 3, "total_found": 2, "total_not_found": 1 },
"retrieved_at": "2026-10-09T12:00:00+00:00"
}A batch row carries available_balance and total_balance per currency (no reserved_balance; it is the difference) and total_value at the row's top level. A player that is not in your title comes back with error and an empty balances.
Freshness and rate limits
- • By-email reads are cached for up to 5 minutes; batch reads are not cached. INVO clears a player's cached balance whenever its own purchase, item purchase, send and transfer paths change it, so you do not need to call anything after those.
- • Right after a write, read
new_balanceon the write's response rather than reading the balance again. See the write-response contract. - • Rate limits: by email, 2,000 per minute per title and 100 per minute per calling IP; batch, 50 per minute per title and 10 per minute per calling IP. The full table is on Rate Limits. On a
429, wait theRetry-Afterseconds.
Errors
| Status | Meaning |
|---|---|
| 400 | Invalid email, no players named, a batch over 100,000, or a body that is not JSON. |
| 401 | Missing or invalid X-Game-Secret-Key. |
| 403 | The title is not active (its status is not live or testing). |
| 404 | No player with that email in your title (by-email only). |
| 429 | A rate limit. Wait Retry-After seconds. |
| 503 | The balance service is temporarily unavailable. Retry with backoff. |