# Pokerai API > The first self-serve, solver-grade GTO (game-theory-optimal) strategy API for 6-max No-Limit > Texas Hold'em. It returns mixed-frequency strategy for every street: preflop and flop come from > millions of presolved solutions (5.8M+ strategy nodes across 66K isomorphic-board spots, served > in milliseconds); turn and river are solved on demand on a real-time solver pool. Every request > is stateless and self-contained — you send the spot, the API returns the strategy. It does NOT > store your hands, and it does NOT return a single "recommended" action — it returns the GTO > frequency of each action so you choose per your own randomization. Base URL: https://pokerai.bet Auth: `Authorization: Bearer ` (get a free key at https://pokerai.bet/login) Format: JSON request + JSON response, `Content-Type: application/json`. Quota: monthly, metered per key. Two independent counters — a **presolved** counter (preflop/flop lookups) and a **solve** counter (real-time turn/river solves). HTTP 402 `quota_exceeded` when a counter is exhausted. Free tier available. Tree-poll and node reads do not charge. Scope: 6-max NLHE, multiple stack depths (e.g. 100bb, 40bb). Action vocab: check, call, bet, raise, fold (bet = first bet into a pot, raise = raising a bet). Sizes are % of pot; all-in has no size. Acceptable use: training, coaching, hand review, study, and research. Real-time assistance (RTA) at real-money tables is prohibited. ## Canonical example — preflop strategy Request `POST https://pokerai.bet/v1/gto/preflop`: ```json { "hole_cards": "AhKh", "positions": { "hero": "MP" }, "preflop_actions": [ { "position": "UTG", "action": "raise", "amount": 3 } ] } ``` Response `200`: ```json { "hole_cards": "AhKh", "situation": "Raise", "strategy": [ { "action": "raise", "frequency": 1, "amount_bb": 9, "sizing_pot": 0.8 } ] } ``` (Hero MP holding AhKh facing a UTG open: raise 100% of the time, to 9bb.) --- # Full endpoint reference — real request/response pairs All examples below are real, captured I/O from the live API (tokens redacted). Large tree/range responses are truncated with a note. ## POST /v1/gto/preflop Preflop strategy for one hole-cards + action sequence. Charges 1 presolved quota. Request: ```json { "hole_cards": "AhKh", "positions": { "hero": "MP" }, "preflop_actions": [ { "position": "SB", "action": "small blind", "amount": 0.5 }, { "position": "BB", "action": "big blind", "amount": 1 }, { "position": "UTG", "action": "raise", "amount": 3 } ] } ``` Response: ```json { "hole_cards": "AhKh", "situation": "Raise", "strategy": [ { "action": "raise", "frequency": 1, "amount_bb": 9, "sizing_pot": 0.8 } ], "quota": { "used": 7, "limit": 100 } } ``` ## POST /v1/gto/preflop/range Whole 13x13 preflop range for a spot (one call). Charges 1 presolved quota. Request: a large object (full board + both ranges + solver_results). See https://pokerai.bet/reference for the exact shape. Response: ```json { "bluff_combos_ratio": 0.33, "bluff_discount_ratio": 1, "board": [ "2c", "2h", "2s" ], "hand_bottom_ranks_ip": "KsQh:2413,KsQd:2413,KsQc:2413,KhQs:2413,KhQh:2413,KhQd:2413,KdQs:2413,KdQh:2413,KcQc:2413,KcQd:2413,KcQh:2413,KcQs:2413,KdQd:2413,KdQc:2413,KdJd:2414,KsJs:2414,KhJh:2414,KcJc:2414,KsTs:2415,KcTc:2415,KdTd:2415,KhTh:2415,Kd9d:2416,Kc9c:2416,Kh9h:2416,Ks9s:2416,QdJd:2423,QhJh:2423,QsJs:2423,QcJc:2423,QcTc:2424,QdTd:2424,QhTh:2424,QsTs:2424,JsTs:2432,JhTh:2432,JdTd:2432,JcTc:2432,Ts9s:2440,Tc9c:2440,Td9d:2440,Th9h:2440,9s8s:2447,9c8c:2447,9d8d:2447,9h8h:2447,8c7c:2453,8d7d:2453,8h7h:2453,8s7s:2453,7s6s:2458,7h6h:2458,7d6d:2458,7c6c:2458,6s5s:2462,6h5h:2462,6d5d:2462,6c5c:2462,5s4s:2465,5h4h:2465,5d4d:2465,5c4c:2465", "hand_bottom_ranks_oop": "KcJh:2414,KcTs:2415,KsTs:2415,KsTh:2415,KsTd:2415,KsTc:2415,KcTc:2415,KcTd:2415,KhTs:2415,KhTh:2415,KdTc:2415,KdTd:2415,KdTh:2415,KdTs:2415,KhTd:2415,KhTc:2415,KcTh:2415,Kd9d:2416,Ks9s:2416,Kc9c:2416,Kh9h:2416,Kc8c:2417,Kh8h:2417,Kd8d:2417,Ks8s:2417,Kc7c:2418,Kh7h:2418,Kd7d:2418,Ks7s:2418,Kd6d:2419,Kh6h:2419,Kc6c:2419,Ks6s:2419,Kd5d:2420,Kh5h:2420,Kc5c:2420,Ks5s:2420,QcJs:2423,QsJs:2423,QsJh:2423,QsJd:2423,QsJc:2423,QhJs:2423,QhJh:2423,QhJd:2423,QhJc:2423,QdJs:2423,QdJh:2423,QdJd:2423,QdJc:2423,QcJc:2423,QcJd:2423,QcJh:2423,QcTc:2424,QsTs:2424,QhTh:2424,QdTd:2424,Qd9d:2425,Qc9c:2425,Qh9h:2425,Qs9s:2425,JhTh:2432,JsTs:2432,JcTc:2432,JdTd:2432,Jh9h:2433,Jd9d:2433,Jc9c:2433,Js9s:2433,Ts9s:2440,Th9h:2440,Td9d:2440,Tc9c:2440,Tc8c:2441,Ts8s:2441,Th8h:2441,Td8d:2441,9c8c:2447,9d8d:2447,9s8s:2447,9h8h:2447,8s7s: … (truncated — full shape at https://pokerai.bet/reference) ``` ## POST /v1/gto/flop/tree Presolved flop decision tree: starting ranges + all nodes (each with a token for /flop/node). Charges 1 presolved quota. Request: ```json { "board": "2c2h2s", "pot_type": "SRP", "positions": { "hero": "UTG", "raiser": "UTG", "caller": "BTN" } } ``` Response: ```json { "board": [ "2c", "2h", "2s" ], "pot_type": "SRP", "pot": 7.5, "effective_stack": 97, "oop_range": "AA:1,AKs:1,AQs:1,AJs:1,ATs:1,A9s:1,A8s:1,A7s:1,A6s:1,A5s:1,A4s:1,A3s:1,A2s:0.296,AKo:1,KK:1,KQs:1,KJs:1,KTs:1,K9s:1,K8s:1,K7s:0.49,K6s:1,K5s:0.246,AQo:1,KQo:1,QQ:1,QJs:1,QTs:1,Q9s:1,AJo:1,KJo:0.92,QJo:0.19,JJ:1,JTs:1,J9s:1,ATo:1,KTo:0.31,TT:1,T9s:1,T8s:0.246,99:1,98s:0.316,88:1,87s:0.286,77:1,76s:0.356,66:1,65s:0.33,55:0.47,54s:0.42,44:0.28,33:0.246,22:0.33", "ip_range": "AQs:0.05,AJs:0.86,ATs:0.436,A9s:0.356,A8s:0.36,A7s:0.196,A6s:0.1,A5s:0.296,A4s:0.38,A3s:0.29,AKo:0.126,KQs:0.67,KJs:0.48,KTs:0.58,K9s:0.18,AQo:0.69,KQo:0.196,QQ:0.146,QJs:0.106,QTs:0.34,JJ:0.506,JTs:0.57,TT:0.526,T9s:0.516,99:0.616,98s:0.206,88:0.6,87s:0.136,77:0.56,76s:0.296,66:0.56,65s:0.436,55:0.296,54s:0.566,44:0.186,33:0.166,22:0.226", "node_count": 36, "nodes": [ { "node": "root", "is_hero": true, "token": "eyJ…" }, { "node": "root/BET_4", "is_hero": false, "token": "eyJ…" }, { "node": "root/BET_8", "is_hero": false, "token": "eyJ…" }, { "node": "root/BET_97", "is_hero": false, "token": "eyJ…" }, { "node": "root/CHECK", "is_hero": false, "token": "eyJ…" }, { "node": "root/BET_4/RAISE_12", "is_hero": true, "token": "eyJ…" }, { "node": "root/BET_4/RAISE_20", "is_hero": true, "token": "eyJ…" }, { "node": "root/BET_4/RAISE_97", "is_hero": true, "token": "eyJ…" }, { … (truncated — full shape at https://pokerai.bet/reference) ``` ## POST /v1/gto/flop/node Strategy at one node of a presolved flop tree. Request: ```json { "node": "eyJ…", "hole_cards": "AdKd" } ``` Response: ```json { "hole_cards": "AdKd", "node": "root", "is_hero": true, "strategy": [ { "action": "check", "frequency": 0.7208 }, { "action": "bet", "amount_bb": 4, "sizing_pot": 0.5333, "frequency": 0.0533 }, { "action": "bet", "amount_bb": 8, "sizing_pot": 1.0667, "frequency": 0.2259 }, { "action": "bet", "amount_bb": 97, "sizing_pot": 12.9333, "allin": true, "frequency": 0 } ] } ``` ## POST /v1/gto/turn/projected-range Updated range after an action line into the turn. Charges 1 presolved quota. Request: ```json { "board": "2c2h2s", "pot_type": "SRP", "positions": { "hero": "UTG", "raiser": "UTG", "caller": "BTN" }, "node_id": "root/BET_4", "normalize": true, "bluff_discount_ratio": 0.8 } ``` Response: ```json { "board": [ "2c", "2h", "2s" ], "pot_type": "SRP", "node_id": "root/BET_4", "bluff_combos_ratio": 0.33, "bluff_discount_ratio": 1, "hand_bottom_ranks_ip": "KcQh:2413,KcQs:2413,KdQc:2413,KdQd:2413,KdQh:2413,KdQs:2413,KhQc:2413,KhQd:2413,KhQh:2413,KhQs:2413,KsQc:2413,KsQd:2413,KsQh:2413,KsQs:2413,KcJc:2414,KdJd:2414,KhJh:2414,KsJs:2414,KcTc:2415,KdTd:2415,KhTh:2415,KsTs:2415,Kc9c:2416,Kd9d:2416,Kh9h:2416,Ks9s:2416,QcJc:2423,QdJd:2423,QhJh:2423,QsJs:2423,QcTc:2424,QdTd:2424,QhTh:2424,QsTs:2424,JcTc:2432,JdTd:2432,JhTh:2432,JsTs:2432,Tc9c:2440,Td9d:2440,Th9h:2440,Ts9s:2440,9c8c:2447,9d8d:2447,9h8h:2447,9s8s:2447,8c7c:2453,8d7d:2453,8h7h:2453,8s7s:2453,7c6c:2458,7d6d:2458,7h6h:2458,7s6s:2458,6c5c:2462,6d5d:2462,6h5h:2462,6s5s:2462,5c4c:2465,5d4d:2465,5h4h:2465,5s4s:2465", "hand_bottom_ranks_oop": "KdQs:2413,KhQc:2413,KhQd:2413,KhQh:2413,KhQs:2413,KsQc:2413,KsQd:2413,KsQh:2413,KsQs:2413,KcJc:2414,KcJs:2414,KdJd:2414,KdJs:2414,KhJh:2414,KhJs:2414,KsJc:2414,KsJd:2414,KsJh:2414,KsJs:2414,KcTc:2415,KcTs:2415,KdTd:2415,KdTs:2415,KhTh:2415,KhTs:2415,KsTc:2415,KsTd:2415,KsTh:2415,KsTs:2415,Kc9c:2416,Kh9h:2416,Ks9s:2416,Ks8s:2417,QcJc:2423,QcJd:2423,QcJs:2423,QdJd:2423,QdJs:2423,QhJd:2423,QhJh:2423,QhJs:2423,QsJc:2423,QsJd:2423,QsJh:2423,QsJs:2423,QcTc:2424,QdTd:2424,QhTh:2424,QsTs:2424,Qs9s:2425,JcTc:2432,JdTd:2432,JhTh:2432,JsTs:2432,Jc9c:2433,Jd9d:2433,Jh9h:2433,Js9s:2433,Tc9c:2440,Td9d:2440,Th9h:2440,Ts9s:2440,Tc8c:2441,Td8d:2441,Th8h:2441,Ts8s:2441,9c8c:2447,9d8d:2447,9h8h:2447,9s8s:2447", "hand_ranks_ip": "QcQd:313,QcQh:313,QcQs:313,QdQh:313,QdQs:313, … (truncated — full shape at https://pokerai.bet/reference) ``` ## POST /v1/gto/solver Submit a turn/river spot for on-demand solving; returns a task state (available → computing → queryable). Charges solve quota. Request: ```json { "board": "2c2h2s9d", "oop_range": "AA,KK,QQ,AKs", "ip_range": "JJ,TT,AQs,KQs", "pot": 20, "effective_stack": 90, "hero": "OOP" } ``` Response: ```json { "status": "computing", "solve": "eyJ…", "solve_quota": { "used": 1, "limit": 100 } } ``` ## POST /v1/gto/solver/tree Decision tree of a solved spot (poll; does not charge). Request: ```json { "solve": "eyJ…" } ``` Response: ```json { "street": "turn", "spot_status": "queryable", "pot": 20, "effective_stack": 90, "node_count": 42, "nodes": [ { "node": "root", "is_hero": true, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 13.000000", "is_hero": false, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 13.000000/RAISE 28.000000", "is_hero": true, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 13.000000/RAISE 28.000000/RAISE 77.000000", "is_hero": false, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 13.000000/RAISE 44.000000", "is_hero": true, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 13.000000/RAISE 44.000000/RAISE 77.000000", "is_hero": false, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 13.000000/RAISE 90.000000", "is_hero": true, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 24.000000", "is_hero": false, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 24.000000/RAISE 46.000000", "is_hero": true, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 24.000000/RAISE 46.000000/RAISE 66.000000", "is_hero": false, "status": "queryable", "token": "eyJ…" }, { "node": "root/BET 24.000000/RAISE 90.000000", "is_hero": true, "status": … (truncated — full shape at https://pokerai.bet/reference) ``` ## POST /v1/gto/solver/node Strategy at one node of a solved spot (does not charge). Request: ```json { "node": "eyJ…", "hole_cards": "AhKh" } ``` Response: ```json { "hole_cards": "AhKh", "node": "root", "is_hero": true, "strategy": [ { "action": "check", "frequency": 0 }, { "action": "bet", "amount_bb": 7, "sizing_pot": 0.35, "frequency": 0.0002 }, { "action": "bet", "amount_bb": 13, "sizing_pot": 0.65, "frequency": 0.2085 }, { "action": "bet", "amount_bb": 24, "sizing_pot": 1.2, "frequency": 0.314 }, { "action": "bet", "amount_bb": 90, "sizing_pot": 4.5, "allin": true, "frequency": 0.4773 } ] } ``` ## POST /v1/gto/evs Per-hand, per-action expected values at one node of a solved spot (does not charge). Give the solve handle + node_id; optional `hand` filters to one hand (omit for all hands, where `evs` is a hand→array map). Request: ```json { "solve": "eyJ…", "node_id": "root", "hand": "2c2d" } ``` Response (each EV array aligns with `actions`): ```json { "node_id": "root", "task_id": "slv_srp_…", "player": 1, "round": "FLOP", "actions": ["CHECK", "BET 4.000000", "BET 97.000000"], "evs": [-0.826359, -0.792223, -1.643411] } ``` --- Canonical source: https://pokerai.bet/llms.txt · Docs: https://pokerai.bet/docs.en · OpenAPI: https://pokerai.bet/openapi.yaml