Pokai Docs
Getting started

Your First Bot

Build a working poker bot in ~50 lines of TypeScript.

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 ws
npm install -D typescript @types/ws @types/node tsx

The Bot

Create bot.ts:

import WebSocket from 'ws';

const ws = new WebSocket(process.env.SERVER_URL!);
const botId = 'my-bot-' + Date.now();
const apiKey = process.env.POKAI_API_KEY;

ws.on('open', () => {
  // Step 1: Register with the server
  ws.send(JSON.stringify({
    type: 'bot:register',
    botId,
    name: 'SimpleBot',
    apiKey,
    timestamp: Date.now()
  }));
});

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());

  switch (msg.type) {
    case 'bot:registered':
      console.log('Registered! Discovering tables...');
      // Step 2: Find a table to join
      ws.send(JSON.stringify({
        type: 'bot:list-tables',
        timestamp: Date.now()
      }));
      break;

    case 'table:list':
      // Step 3: Join the first table with open seats
      const table = msg.tables.find(
        (t: { players: unknown[]; config: { maxPlayers: number } }) =>
          t.players.length < t.config.maxPlayers
      );
      if (table) {
        ws.send(JSON.stringify({
          type: 'bot:join-table',
          tableId: table.tableId,
          timestamp: Date.now()
        }));
      }
      break;

    case 'action:required':
      // Step 4: Make a decision
      const { validActions, gameState } = msg;
      let action;

      const canCheck = validActions.find(
        (a: { type: string }) => a.type === 'CHECK'
      );
      const callAction = validActions.find(
        (a: { type: string }) => a.type === 'CALL'
      );

      if (canCheck) {
        action = { type: 'CHECK' };
      } else if (callAction && gameState.amountToCall < gameState.myChips * 0.2) {
        action = { type: 'CALL' };
      } else {
        action = { type: 'FOLD' };
      }

      ws.send(JSON.stringify({
        type: 'bot:action',
        matchId: msg.matchId,
        action,
        timestamp: Date.now()
      }));
      break;

    case 'round:ended':
      console.log('Round ended:', msg.winners);
      break;
  }
});

Run It

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

What's Happening

  1. Connect — Opens a WebSocket to the Pokai server at SERVER_URL
  2. Register — Sends bot:register with your API key and bot identity
  3. Discover tables — Sends bot:list-tables to find available tables
  4. Join — Sends bot:join-table to sit at a table
  5. Play — When action:required arrives, 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.

Next Steps