Check in
Claim the connected player's daily reward, as the daily command does in Discord.
POST /v1/player/checkin · for player session
Use it when the player presses the daily reward button. It takes no body. It earns coins and requires no proof and no spending hold: the member could claim it in Discord. 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
Example
curl -X POST https://ceejay.communitystudios.xyz/api/v1/player/checkin \
-H "Authorization: Bearer $CEEJAY_PLAYER_SESSION"The TypeScript example uses connect.hub.checkIn 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.
{
"success": true,
"data": {
"reward": 50,
"streak": 5,
"balance": 1500,
"nextCheckInAt": "2026-10-09T10:00:00.000Z",
"savedByStreakSaver": false
}
}Claimed too soon
Claiming the reward too soon returns 409 with the code checkin_cooldown, with nextCheckInAt and retryAfter: treat it as "already claimed". A retry after a lost response gets the same result, so the request is safe to repeat. A game should not retry it automatically. CEEJAY does not send the member a direct message.
{
"error": "The daily reward was already claimed. Try again later",
"code": "checkin_cooldown",
"requestId": "req_5f0c2a9b7d3e41f8a6b0c1d2",
"nextCheckInAt": "2026-10-09T10:00:00.000Z",
"retryAfter": 43200
}Limits
20 writes a minute for one player session, shared by Start, Verify and Answer a quest task, Buy a shop item, Claim an item and Check in. 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
| Status | code | error | When |
|---|---|---|---|
400 | bad_request | The request body must be a JSON object | A body was sent, and it is JSON but not an object: null, text, a number or a list. Send none, or {} |
401 | connection_ended | This connection has ended | The 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 |
409 | hub_not_enabled | This game does not show the community's quests, shop and rank | The game loop is disabled for the game. Do not show the community's quests, shop or rank in the game |
409 | sharing_needed | The member has not consented to sharing their data with this game | The 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 |
409 | membership_required | The member has to be in the server to use this | The 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 |
409 | economy_disabled | The community has switched its economy off | The community has disabled its economy |
409 | checkin_cooldown | The daily reward was already claimed. Try again later | The daily reward has already been claimed. The body includes nextCheckInAt and retryAfter |
413 | body_too_large | The request body is larger than 16 KB | The body is larger than 16 KB. Nothing was changed |
503 | bot_unavailable | This could not be done right now and nothing was changed. Try again in a few seconds | CEEJAY'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 |
504 | bot_timeout | The 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 repeat | The 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.

