Confirm a connect session
Approve or decline a connect session from your own server, for a game that holds no session secret.
POST /v1/games/{game}/connect/sessions/{sessionId}/confirm · requires players:connect
Read the session with Get a connect session, show your player the Discord name it returns, and send the player's decision. A game that holds the session secret sends Confirm connect itself.
Path parameters
Prop
Type
Body parameters
Prop
Type
Returns
The session, in the same shape that Get a connect session returns.
Prop
Type
connection holds:
Prop
Type
status | The session |
|---|---|
pending | Waiting for the member to approve on the connect page |
needs_game_confirmation | The member approved, or the game attached a member's code. Waiting for the game to confirm |
needs_confirmation | A session a member started in Discord that the game has confirmed. The member confirms in Discord |
approved | Both approved. The connection is saved |
declined | The member pressed Cancel, or kept the player they were connected to |
cancelled | The game declined, or a newer session for the same player superseded it |
expired | The 10 minutes have passed |
locked | The code was entered incorrectly five times |
refused | The connection could not be made: see reason |
This list may grow: handle unknown values.
reason | Why the session ended |
|---|---|
member_cancelled | The member pressed Cancel, or kept the player they had |
game_declined | The game declined |
banned | The Discord account is banned from the server |
player_blocked | The community blocked the player |
player_already_connected | The player is connected to another Discord account, and could not be moved |
expired | The 10 minutes passed |
too_many_tries | The code was entered incorrectly five times |
under_age | The player is under age |
null | The session is open or approved, a newer session for the same player superseded it, or the member connected another player in the meantime |
Example
curl -X POST https://ceejay.communitystudios.xyz/api/v1/games/rugby_manager/connect/sessions/kT3v9QmZ1xY7bLw2RfA8cN/confirm \
-H "Authorization: Bearer $CEEJAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"accept": true
}'The TypeScript tab calls ceejay.connect.confirmSession from the TypeScript SDK. It returns the data of the response below.
{
"success": true,
"data": {
"sessionId": "kT3v9QmZ1xY7bLw2RfA8cN",
"status": "approved",
"reason": null,
"expiresAt": "2026-10-08T18:14:11.000Z",
"member": {
"displayName": "Nova",
"avatarUrl": "https://cdn.discordapp.com/avatars/409876543210987654/a1b2c3d4e5f60718293a4b5c6d7e8f90.png"
},
"connection": {
"discordId": "409876543210987654",
"playerId": "p_19",
"proof": "verified",
"connectedAt": "2026-10-08T18:06:40.000Z",
"moved": false,
"previousPlayerId": null
}
}
}What accepting and declining do
accept: true is accepted only while status is needs_game_confirmation.
- For a session your server or the game started, the member has approved by then: the session is finished, the connection is saved and
statusbecomesapproved. - For a session a member started in Discord,
statusbecomesneeds_confirmation, and the member confirms there.
accept: false ends an open session in any state. Its status becomes cancelled and its reason game_declined. A paused game can still decline.
Retrying safely
The request is safe to repeat and takes no idempotencyKey. Confirming twice returns the session as it is. Declining a session that has ended changes nothing and returns the session as it is.
The scope
players:connect lets a server act for a player: it can create a pass, and with a pass any player who is already connected at the verified level can be signed in. Keep it on your own server. It is never part of *: a Full Access key returns 403 here. Tick Act for a player when you make the key.
Limits
The Connect requests of a server have a limit of their own: 600 requests a minute for each game, across all five Connect endpoints. They are not counted against the key's own requests per minute. One API key is also capped at 6,000 requests a minute across all five Connect endpoints. The three X-RateLimit headers report the game's limit of 600 once the request has resolved its game, and the key's limit of 6,000 on a response returned before that: see Rate limits.
Errors
| Status | code | error | When |
|---|---|---|---|
400 | bad_request | The request body must be a JSON object | The body is null, text, a number or a list. A request with no Content-Type header is read as text, so it gets this response too |
400 | bad_request | accept must be true or false | accept is missing or is not true or false |
404 | not_available | This is not available on this instance yet. | Connect is not enabled for this instance. It is enabled per instance. The body adds feature, which is players. Retrying will not change the response |
403 | community_not_active | This community is no longer active on CEEJAY | The community removed CEEJAY from its server |
404 | game_not_found | Game not found | The community has no game with this slug, or the game was removed. A slug that is not 2 to 32 lower-case letters, digits and underscores, starting with a letter, gets this response too |
403 | game_not_allowed | This API key is limited to other games | The key is limited to other games of the community |
403 | audience_not_allowed | A game made for children cannot connect players or send player data | The game is set up as made for children. Such a game connects nobody |
404 | session_not_found | Connect session not found | The game has no session with this ID. A session of another game or community is not found either |
409 | nothing_to_confirm | There is nothing to confirm on this request right now | accept is true and the session is not waiting for the game's confirmation: the member has not approved, or the session has ended |
409 | session_changed | This request changed since it was shown. Read it again | The session changed between the member's approval and this request: another account connected this player, or the member connected another player. Read the session again. When it has ended, start a new one, and the member is shown what changed |
409 | player_blocked | This player cannot be connected until the community lifts a block | The community blocked this player. The session has ended |
409 | player_taken | This player is connected to another Discord account. Connect from the game the player is signed in to | The player is connected to another Discord account and cannot be moved to this one: that connection is verified and this one is not. The session has ended |
409 | game_paused | This game is paused | accept is true and the game is paused or suspended. A decline is still accepted |
Every error body also carries requestId, and a 400 with the code bad_request names the invalid field in field. Match on code, not on the message text, which can change.
The errors every request shares (401, 403 for a missing scope, 405, 429, 500) are on the Errors page.

