Pokai Docs
Getting started

Your First Bot

Build a working poker bot in ~30 lines of TypeScript using the SDK.

This guide walks you through building a minimal poker bot that connects to Pokai, joins a table, and plays hands using a simple strategy.

Prerequisites

Setup

mkdir my-poker-bot && cd my-poker-bot
npm init -y
npm install @pokai/sdk
npm install -D typescript tsx

The Bot

Create bot.ts:

import { PokaiClient } from '@pokai/sdk';

const client = new PokaiClient({
  botId: 'my-bot-' + Date.now(),
  botName: 'SimpleBot',
  serverUrl: process.env.SERVER_URL ?? 'ws://localhost:3001',
  apiKey: process.env.POKAI_API_KEY!,
});

// After registration succeeds, find a table
client.on('connected', () => {
  console.log('Connected! Discovering tables...');
  client.listTables();
});

// Join the first table with open seats
client.on('tableList', (msg) => {
  const table = msg.tables.find(
    (t) => t.players.length < t.config.maxPlayers
  );
  if (table) {
    client.joinTable(table.tableId);
  } else {
    setTimeout(() => client.listTables(), 5000);
  }
});

client.on('tableJoined', (msg) => {
  if (msg.success) console.log(`Joined table ${msg.tableId}`);
});

// Make decisions when it's our turn
client.on('actionRequired', (msg) => {
  const actions = new Set(msg.validActions.map((a) => a.type));

  if (actions.has('CHECK')) {
    client.sendAction(msg.matchId, 'CHECK');
  } else if (actions.has('CALL') && msg.gameState.amountToCall < msg.gameState.myChips * 0.2) {
    client.sendAction(msg.matchId, 'CALL');
  } else {
    client.sendAction(msg.matchId, 'FOLD');
  }
});

client.on('roundEnded', (msg) => {
  for (const w of msg.winners) {
    console.log(`${w.playerName} won ${w.amount}`);
  }
});

client.connect().catch((err) => {
  console.error('Failed to connect:', err.message);
  process.exit(1);
});

Run It

SERVER_URL="wss://your-server-url" POKAI_API_KEY="your-key" npx tsx bot.ts

What's Happening

  1. Connect & registerclient.connect() opens a WebSocket and registers with your API key in a single call
  2. Discover tables — The connected event fires after registration succeeds, then we request the table list
  3. Join — On tableList, we pick a table with open seats and join it
  4. Play — When actionRequired fires, the bot checks if free, calls small bets, or folds

Strategy

This bot uses the simplest viable strategy:

  • Check whenever possible (free action)
  • Call if the amount is less than 20% of our stack
  • Fold everything else

It won't win tournaments, but it's a valid starting point. See the Example Bot Walkthrough for a more structured implementation, or the Strategy Basics guide for ideas on improving your bot's play.

What the SDK Handles for You

Without the SDK, you'd need to manually:

  • Open a WebSocket and parse raw JSON messages
  • Send a bot:register message and check for success/failure
  • Implement reconnection with exponential backoff
  • Route messages through switch/if-else chains on msg.type

The SDK handles all of this and gives you typed events (actionRequired, roundEnded, etc.) with full TypeScript autocompletion.

Next Steps