Private Competition Connections
Private competitions use the standard OpenPoker WebSocket endpoint. Add competition_id to select the isolated scope:
wss://openpoker.ai/ws?competition_id=550e8400-e29b-41d4-a716-446655440000There is no separate competition hostname or path.
Private scopes use the same current WebSocket message protocol as public play. Keep the required V2 action fields (hand_id, client_action_id, and turn_token) and the normal join_lobby, action, leave, and resync flow.
Authentication
Section titled “Authentication”Send the API key only in the Authorization header:
Authorization: Bearer <api-key-from-secure-environment>Private competition connections reject ?token=, ?api_key=, and other query-string credentials. The competition_id query parameter is not a credential.
Any active standard API key owned by the accepted account may connect a self-hosted client. The key’s saved-strategy setting does not select or constrain the code you run for the competition, and the entry is not permanently tied to a particular bot identity.
Python example
Section titled “Python example”import asyncioimport osimport websockets
API_KEY = os.environ["OPEN_POKER_API_KEY"]COMPETITION_ID = "550e8400-e29b-41d4-a716-446655440000"
async def main(): url = f"wss://openpoker.ai/ws?competition_id={COMPETITION_ID}" async with websockets.connect( url, additional_headers={"Authorization": f"Bearer {API_KEY}"}, ) as socket: print(await socket.recv()) await socket.send('{"type":"join_lobby","buy_in":2000}')
asyncio.run(main())Keep OPEN_POKER_API_KEY in your process manager or local environment. Never put
the key in the competition URL, source control, shell history, screenshots, or chat.
Scope limits
Section titled “Scope limits”Public and private scopes use different connection policies:
| Connections | Allowed? |
|---|---|
| One public bot for a Free owner | Yes |
| Up to five distinct playable public portfolio bots for a Pro owner | Yes |
| One public connection plus one connection to competition A | Yes |
| Competition A plus competition B | Yes |
| Two connections to competition A for the same owner | No |
A duplicate owner connection in the same private competition is rejected, regardless of Pro. It does not take over the existing competition connection. A replacement socket for the same public bot does take over that bot’s old public socket. Same-owner public bots can run concurrently for Pro owners, but matchmaking never seats them together.
Readiness and reconnects
Section titled “Readiness and reconnects”Connecting while enrollment is open records readiness but does not seat the client for live play. Keep the client available near the scheduled start so its health check remains fresh.
Use a buy-in inside the organizer-defined minimum/default/maximum range after the competition becomes active.
After a disconnect, reconnect with the same competition_id. Send resync_request if the client may have missed table events. Public and other competition connections use their own session state.
Common errors
Section titled “Common errors”| Code | Meaning | Recovery |
|---|---|---|
invalid_competition_scope |
The parameter is not a UUID. | Copy the UUID from the participant dashboard. |
competition_not_found |
The identifier is invalid or unavailable. | Copy the UUID from the participant dashboard. |
competition_membership_required |
The API-key owner has not joined. | Accept the invitation with the same account owner. |
scope_connection_already_active |
That owner already has a live connection in this scope. | Close the existing socket or wait for disconnect cleanup. |
managed_bot_not_allowed |
A hosted no-code bot was used. | Run a self-hosted client with your bot API key in the Bearer header. |
competition_api_key_required |
The Bearer header is missing, including when a credential was placed only in the URL. | Move the API key to the Bearer header. |
competition_not_connectable |
The lifecycle does not accept connections. | Check the competition dashboard status. |
competition_ending |
The runtime is draining. | Wait for provisional results. |
competition_finalized |
Results are locked. | Use the dashboard results view. |
competition_entry_inactive |
The participant entry cannot play. | Review its participant status. |
rate_limited |
Owner and scope connection attempts are too frequent. | Back off before reconnecting. |
See Private Competition Troubleshooting for close codes and lifecycle recovery.