CEEJAYDocs

Get the balance

Read the connected player's coins, daily reward streak, perks and XP boost, and what this device may spend today.

GET /v1/player/balance · for player session

Use it to show the wallet, and to decide whether a Buy button is enabled before the player presses it. It takes no parameters. Send the player session as the bearer token. The request needs the game loop. For the three conditions (game loop enabled for the game, member consent, server membership) and the error each returns, see What has to be true first. The community's economy must also be enabled: otherwise the response is 409 with the code economy_disabled.

Returns

Prop

Type

perks contains:

Prop

Type

spending is the check that Buy a shop item applies, so a game can disable a Buy button beforehand:

Prop

Type

spending.reasonWhen
spend_on_holdA new connection or device is still on hold. holdUntil gives the end time
verified_proof_requiredThis device connected without verification, and the game only lets verified players spend
spending_offThe game's daily limit is 0
nullmaySpend is true

Example

Request
curl "https://ceejay.communitystudios.xyz/api/v1/player/balance" \
  -H "Authorization: Bearer $CEEJAY_PLAYER_SESSION"

The TypeScript example uses connect.hub.getBalance from the Connect client in the TypeScript SDK. The player must be connected first: the client manages and refreshes the player session. It returns the data of the response below.

200 OK
{
  "success": true,
  "data": {
    "balance": 1450,
    "currency": {
      "name": "Coins",
      "emoji": "🪙"
    },
    "streak": 4,
    "canCheckIn": true,
    "nextCheckInAt": null,
    "perks": {
      "streakSaver": 1,
      "questSkip": 0,
      "priorityTicket": 0
    },
    "xpBoost": {
      "multiplier": 1.5,
      "expiresAt": "2026-10-09T10:00:00.000Z"
    },
    "spending": {
      "dailyCap": 5000,
      "spentToday": 300,
      "remainingToday": 4700,
      "resetsAt": "2026-10-09T00:00:00.000Z",
      "holdUntil": null,
      "maySpend": true,
      "reason": null
    }
  }
}
200 OK, a new device that is still on hold
{
  "success": true,
  "data": {
    "balance": 1450,
    "currency": {
      "name": "Coins",
      "emoji": "🪙"
    },
    "streak": 4,
    "canCheckIn": true,
    "nextCheckInAt": null,
    "perks": {
      "streakSaver": 1,
      "questSkip": 0,
      "priorityTicket": 0
    },
    "xpBoost": {
      "multiplier": 1.5,
      "expiresAt": "2026-10-09T10:00:00.000Z"
    },
    "spending": {
      "dailyCap": 5000,
      "spentToday": 300,
      "remainingToday": 4700,
      "resetsAt": "2026-10-09T00:00:00.000Z",
      "holdUntil": "2026-10-09T18:06:40.000Z",
      "maySpend": false,
      "reason": "spend_on_hold"
    }
  }
}

Limits

120 reads a minute for one player session. The three X-RateLimit headers report that count. Every request made with a player session also counts toward 140 a minute. See Rate limits. Over a limit the response is 429 with the code rate_limited, retryAfter and a Retry-After header.

Errors

StatuscodeerrorWhen
401connection_endedThis connection has endedThe connection or this device was ended since the player session was made. Discard the stored tokens and show the player as disconnected. See Renew a player session for the reasons
409hub_not_enabledThis game does not show the community's quests, shop and rankThe game loop is disabled for the game. Do not show the community's quests, shop or rank in the game
409sharing_neededThe member has not consented to sharing their data with this gameThe member has not consented to share their quests, rewards, shop and rank with the game, or must consent again. The body includes manageUrl: send the player there
409membership_requiredThe member has to be in the server to use thisThe Discord account is not in the server. The body includes membership (pending, left or not_member) and, for left and not_member, joinUrl, the URL to send the player to
409economy_disabledThe community has switched its economy offThe community has disabled its economy
503bot_unavailableThis could not be done right now and nothing was changed. Try again in a few secondsCEEJAY's bot could not be reached or was too busy, and nothing was changed. The body includes retryAfter, in seconds: retry after that many seconds
504bot_timeoutThe answer did not arrive in time, and the request may or may not have been done. Send the same request again: it is safe to repeatThe request timed out, so it is not known whether it was processed. Retry the same request: it is safe to repeat

Every error body also includes requestId, and a 400 with the code bad_request identifies the invalid field in field. Match on code; message text can change.

The errors every request of a game shares (the key, the state of the game, the origin, 405, 429, 500) are on the Errors page, and the errors specific to the game loop are under Codes of the game loop.

On this page

Community StudiosPrivacyTerms