Private tables
Reserve one of your own dedicated Live Hold'em tables for a set period as a private table where only players who know the password can sit. Use it for VIP games, event tables and the like.
| Method | Path | Purpose |
|---|---|---|
| GET | /operator/v1/private-tables | Reservable tables and the reservation list |
| POST | /operator/v1/private-tables | Create a reservation |
| DELETE | /operator/v1/private-tables/{private_id} | Cancel a reservation |
Independent mode only
Only independent-mode (independent) operators can use this, and the only eligible tables are your own dedicated live_holdem tables. For prepaid-mode (prepaid) operators, every request returns 403 PRIVATE_FORBIDDEN.
Behavior
A reservation consists of a table, a start time, a duration and a password, and its status changes over time.
Status (status) | Period | Table behavior |
|---|---|---|
reserved | Until 5 minutes before the start | A public table as usual |
standby | From 5 minutes before the start until the start | Standby — newly arriving players need the password to enter |
active | From the start until the end | Private session in progress. The game in progress at the start time becomes the last round of the public game; when that round ends, players seated without the password are settled and removed from the table |
ended | After the end | A public table again |
cancelled | After cancellation | If it was in progress, the table immediately returns to public |
To send a player to a private table, include both table_id and table_password in the game launch request.
- During the reserved period (from 5 minutes before the start until the end), launch fails with
PRIVATE_PASSWORDif the password is wrong. More than 5 attempts per minute for the same player and table result inRATE_LIMITED. - Outside the reserved period,
table_passwordis ignored and the player enters the public table.
Reservations and cancellations are applied immediately to the live table.
GET /operator/v1/private-tables
Returns the reservable tables (your own live dedicated live_holdem tables) and the reservation list. The reservation list contains reservations whose end time passed less than 24 hours ago (including those not yet ended and cancelled ones), sorted by start time with the most recent first, up to 200 entries.
Response example
{
"tables": [
{
"table_id": "tbl_0198c1d2e3f47a5b8c9d0e1f2a3b4c5d",
"name": "Live Hold'em VIP",
"names": { "en": "Live Hold'em VIP", "ko": "라이브 홀덤 VIP" },
"currency": "PHP",
"limits": { "sb": 5000, "bb": 10000, "ante": 0, "min_buy_in": 500000, "max_buy_in": 2000000 }
}
],
"reservations": [
{
"private_id": "prv_0199f4a0b1c27d3e8f4a5b6c7d8e9f0a",
"table_id": "tbl_0198c1d2e3f47a5b8c9d0e1f2a3b4c5d",
"table_name": "Live Hold'em VIP",
"table_names": { "en": "Live Hold'em VIP", "ko": "라이브 홀덤 VIP" },
"currency": "PHP",
"limits": { "sb": 5000, "bb": 10000, "ante": 0, "min_buy_in": 500000, "max_buy_in": 2000000 },
"start": "2026-10-20T12:00:00Z",
"end": "2026-10-20T14:00:00Z",
"minutes": 120,
"password": "vip2026",
"status": "reserved",
"created_at": "2026-10-19T03:21:40.12Z"
}
],
"standby_minutes": 5,
"min_minutes": 30,
"max_minutes": 1440
}Response fields
| Field | Type | Description |
|---|---|---|
tables[] | array | Reservable tables: table_id, name, names (omitted if none), currency, limits (blinds, ante and buy-in range, in minor units) |
reservations[] | array | Reservation list |
reservations[].private_id | string | Reservation ID (prv_…) |
reservations[].table_id / table_name / table_names / currency / limits | The reserved table | |
reservations[].start / end | time | Start and end times |
reservations[].minutes | int | Duration (minutes) — end − start |
reservations[].password | string | Entry password |
reservations[].status | string | reserved / standby / active / ended / cancelled (as of the query time) |
reservations[].created_at / cancelled_at | time | Creation and cancellation times (cancelled_at only for cancelled reservations) |
standby_minutes | int | When standby begins (minutes before the start) — 5 |
min_minutes / max_minutes | int | Reservation duration range — 30 / 1440 |
status is calculated from the clock. After the start time has passed, the actual table may still be in standby until the last round of the public game ends, but the list shows it as active.
TIP
The response contains passwords in plain text. Show them only in admin screens.
Errors
| HTTP | Code | Situation |
|---|---|---|
| 403 | PRIVATE_FORBIDDEN | Prepaid-mode operator |
| 500 | INTERNAL_ERROR | Temporary server error |
POST /operator/v1/private-tables
Creates a reservation.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
table_id | string | Yes | Your own live dedicated live_holdem table |
start | string (RFC 3339) | Yes | Start time. Seconds and below are truncated to align to whole minutes. Up to 30 days from now |
minutes | int | Yes | Duration (minutes). 30 – 1440, a multiple of 30 |
password | string | Yes | 4–20 characters, no spaces, tabs or line breaks (leading and trailing whitespace is trimmed) |
- If
starthas already passed, the reservation starts immediately. The end time remains the requestedstart + minutes, so the actual duration is shorter by that amount. If the end time is within 1 minute from now, it is astarterror. - If the time overlaps another (non-cancelled) reservation on the same table, the response is
409 PRIVATE_OVERLAP.
Request example
curl -X POST {API_BASE}/operator/v1/private-tables \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'X-Operator: acme' -H 'X-Api-Key: ak_live_…' \
-H 'X-Timestamp: 1760839200123' -H 'X-Nonce: 3f5a7c9e1b3d5f7a9c1e3b5d' -H 'X-Signature: a4e2…' \
-d '{"table_id":"tbl_0198c1d2e3f47a5b8c9d0e1f2a3b4c5d","start":"2026-10-20T20:00:00+08:00","minutes":120,"password":"vip2026"}'Response example
200 OK
{
"private_id": "prv_0199f4a0b1c27d3e8f4a5b6c7d8e9f0a",
"table_id": "tbl_0198c1d2e3f47a5b8c9d0e1f2a3b4c5d",
"start": "2026-10-20T20:00:00+08:00",
"end": "2026-10-20T22:00:00+08:00",
"status": "reserved"
}Errors
| HTTP | Code | Situation |
|---|---|---|
| 403 | PRIVATE_FORBIDDEN | Prepaid-mode operator |
| 400 | INVALID_REQUEST (message invalid json) | The body is not JSON, or start is not RFC 3339 |
| 400 | INVALID_REQUEST (details.fields) | Contains all invalid fields — table_id (bad format, not found, closed, another operator's, or not live_holdem), minutes, password, start (missing, end within 1 minute, or more than 30 days ahead) |
| 409 | PRIVATE_OVERLAP | Overlaps another reservation on the same table |
| 500 | INTERNAL_ERROR | Failed to save |
DELETE /operator/v1/private-tables/{private_id}
Cancels a reservation that has not ended. If it is in progress (active), the table immediately returns to public. There is no body (sign an empty body or {}).
Request example
curl -X DELETE {API_BASE}/operator/v1/private-tables/prv_0199f4a0b1c27d3e8f4a5b6c7d8e9f0a \
-H 'X-Operator: acme' -H 'X-Api-Key: ak_live_…' \
-H 'X-Timestamp: 1760839200123' -H 'X-Nonce: 7c9e1b3d5f7a9c1e3b5d7f9a' -H 'X-Signature: 0f6b…'Response example
{ "private_id": "prv_0199f4a0b1c27d3e8f4a5b6c7d8e9f0a", "status": "cancelled" }Cancellations are also recorded for audit and can be reverted from the audit log (response header X-Audit-Id).
Errors
| HTTP | Code | Situation |
|---|---|---|
| 403 | PRIVATE_FORBIDDEN | Prepaid-mode operator |
| 404 | NOT_FOUND | Malformed ID, nonexistent reservation, or another operator's reservation |
| 409 | PRIVATE_ENDED | The reservation has already ended or been cancelled |
| 500 | INTERNAL_ERROR | Failed to cancel |