Skip to content

Players ​

Force-end player sessions, block and unblock players, and list the players currently connected to games.

A player is registered on the platform the first time you call POST /launch for them. The {external_id} in the path is the player.external_id you sent at launch (percent-encode it when placing it in the URL path, and sign it exactly as encoded — Authentication & signing).

POST /players/{external_id}/logout ​

POST {API_BASE}/operator/v1/players/{external_id}/logout

Immediately ends all of the player's game sessions. Use block to set blocking / unblocking at the same time. Call this when a member logs out of, leaves, is suspended from, or self-excludes from the operator site.

When called, the following happens in order:

  1. The player's status is set according to block (true = blocked, false = active).
  2. All of the player's sessions are revoked and open game screen connections are closed. The game screen switches to the session-expired screen and sends a session.expired event (Game launch flow).
  3. The player leaves their seat at every table. A round in progress is played to completion and then settled, and in buy-in flow games the remaining chips are cashed out. Money is returned through the wallet callbacks (credit) as usual.

Path & request fields ​

The body can be omitted (sign an empty body). If omitted, reason: "operator_logout" and block: false apply.

FieldLocationTypeRequiredDescription
external_idPathstringRequiredOperator-side player ID
reasonBodystringTermination reason. Recorded in the audit log and passed as the reason for closing the game screen connection. Default operator_logout
blockBodybooleantrue blocks the player; false (default) leaves the player active

reason is a free-form string. Using distinct values per purpose, as below, makes entries easy to tell apart in the audit log.

PurposeExample
Site logout / force logout by an admin{"reason": "operator_logout"}
Member suspension / account closure{"reason": "operator_block", "block": true}
Lifting a suspension{"reason": "operator_unblock", "block": false}
Self-exclusion (responsible gaming){"reason": "self_exclusion", "block": true}, or block: false if your site blocks the player separately

block is overwritten on every call

This call always overwrites the player's status with the block value. If you call it for a blocked player without block (or with false), the block is lifted. To only disconnect a blocked player's sessions again, send block: true as well.

  • For a blocked player, POST /launch returns 403 PLAYER_BLOCKED, and launch URLs already issued cannot be used to enter either.
  • Unblocking (block: false) also disconnects the sessions active at that moment. After unblocking, the player can enter with a new launch.
  • An external_id that has never been launched does not exist on the platform, so the response is 404 PLAYER_NOT_FOUND. In your site's member-suspension flow, you may treat this error as success.

Request example ​

http
POST /operator/v1/players/user-10293/logout HTTP/1.1
Host: {API_HOST}
Content-Type: application/json; charset=utf-8
X-Operator: acme
X-Api-Key: ak_5d2c9e0f7a1b3c4d5e6f708192a3b4c5d6e7f809
X-Timestamp: 1792368067512
X-Nonce: 3a7c9e1b5d0f2a4c6e8b0d1f
X-Signature: 6c2e…(64 hex digits)

{ "reason": "operator_block", "block": true }

Response ​

200 OK

json
{ "status": "OK", "sessions_closed": 2 }
FieldTypeDescription
statusstringAlways OK
sessions_closedintegerNumber of sessions disconnected. 0 if the player was not connected

The X-Audit-Id response header gives the audit log number for this operation.

Errors ​

HTTPerror.codeCause
404PLAYER_NOT_FOUNDThis operator has no player with that external_id
500INTERNAL_ERRORFailed to save the status. Retry (sending the same request multiple times yields the same result).

GET /players/online ​

GET {API_BASE}/operator/v1/players/online

Returns this operator's players who are currently connected to a game screen, with the tables each is watching or seated at. Use it for a real-time connected-players list in your admin screens or to find targets for force logout.

  • Only players with a game screen connection (WebSocket) are included. Players whose connection dropped because they closed the window are not listed, even if they still hold a seat at a table.
  • Players who have stayed connected the longest come first. For each player, tables where they are seated come first.
  • The whole list is returned at once, without pagination.

Response ​

200 OK

json
{
  "at": "2026-10-19T08:01:07.512345+08:00",
  "players": [
    {
      "player_id": "pl_019a0f3c7b2e7d41a8c35e9f0b1d2c3a",
      "external_id": "user-10293",
      "nickname": "LuckyAce",
      "currency": "PHP",
      "ip": "203.0.113.25",
      "user_agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 18_0 like Mac OS X) …",
      "connected_at": "2026-10-19T07:42:10.204+08:00",
      "connections": 1,
      "in_lobby": false,
      "tables": [
        {
          "table_id": "tbl_019a0f3c8e1f7a2b9c4d5e6f7a8b9c0d",
          "game_code": "live_holdem",
          "name": "Live Hold'em 25/50",
          "names": { "ko": "라이브 홀덤 25/50", "en": "Live Hold'em 25/50" },
          "seated": true,
          "seat": 2,
          "chips": 312500,
          "buy_in_total": 400000,
          "seated_at": "2026-10-19T07:43:02.911+08:00"
        },
        {
          "table_id": "tbl_019a0f3d1a2b7c3d8e4f5a6b7c8d9e0f",
          "game_code": "live_baccarat",
          "name": "Live Baccarat A",
          "names": { "ko": "라이브 바카라 A", "en": "Live Baccarat A" },
          "seated": false
        }
      ]
    }
  ]
}
FieldTypeDescription
atstringTime this list was generated
players[].player_idstringPlatform player ID (pl_…)
players[].external_idstringOperator-side player ID
players[].nicknamestringName shown on the game screen
players[].currencystringPlayer currency
players[].ipstringConnection IP of the player's browser
players[].user_agentstringUser-Agent of the player's browser
players[].connected_atstringTime of the earliest of the current connections
players[].connectionsintegerNumber of open game screen connections (tabs / windows)
players[].in_lobbybooleanWhether the player is viewing the game lobby screen
players[].tablesarrayTables the player is watching or seated at. [] if none
tables[].table_id / game_code / name / namesTable information (same meaning as in GET /tables)
tables[].seatedbooleanWhether the player is seated at this table
tables[].seatintegerSeat number. Only when seated
tables[].chipsintegerCurrent chips (minor units). Only when seated
tables[].buy_in_totalintegerTotal buy-in and top-up for this seating (minor units). Only when seated
tables[].seated_atstringTime the player sat down. Only when seated

Time fields are in RFC 3339 format; the number of fractional-second digits and the time zone offset are not fixed. Parse them with a standard RFC 3339 parser (Common conventions).

Errors ​

Only authentication and common errors (Error codes).

Docs v1.0.0 · Operator API v1