Skip to content
Platform

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-446655440000

There 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.

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.

import asyncio
import os
import 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.

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.

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.

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.