{"openapi":"3.0.3","info":{"title":"pokerai.bet API (GTO strategy + Poker engine)","version":"1.0","description":"GTO strategy API for preflop / flop / turn / river. Returns each action's mixed frequency (no recommended action — you choose by frequency). Preflop and flop tap a library of presolved GTO solutions, served instantly (millisecond). The solver endpoint computes in real time (flop ~70s, turn/river faster). Card/board inputs use a no-separator string (\"2c2h2s\", \"AdKd\"); board is returned as an array ([\"2c\",\"2h\",\"2s\"]). Range strings are comma-separated `hand:weight` (class notation AA/AKs/AKo; weight 0..1, default 1).\n\n⚠ Note: the \"Test Request\" button below sends a real request with your key and consumes your real monthly quota. New here? Read the guide first: https://pokerai.bet/docs\n"},"servers":[{"url":"https://pokerai.bet"}],"security":[{"BearerApiKey":[]},{"XApiKey":[]}],"tags":[{"name":"Lookup","description":"Presolved GTO solutions, served instantly (millisecond) — preflop + the full flop decision tree. Charges 1 presolved quota each."},{"name":"Solver","description":"Real-time solver (flop ~70s, turn/river faster). schedule -> tree -> node."},{"name":"Range","description":"Update ranges along an action line (range conversion / flop projected range)."}],"paths":{"/v1/gto/preflop":{"post":{"tags":["Lookup"],"operationId":"preflopStrategy","summary":"Preflop strategy (presolved)","description":"Charges 1 presolved quota. The situation (RFI/Limp/Raise/3-Bet/4-Bet/5-Bet) is derived from the actions.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreflopRequest"},"example":{"hole_cards":"AhKh","positions":{"hero":"MP"},"preflop_version":"6max","preflop_actions":[{"position":"SB","action":"small blind","amount":0.5},{"position":"BB","action":"big blind","amount":1},{"position":"UTG","action":"raise","amount":3}]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PreflopResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/QuotaExceeded"}}}},"/v1/gto/preflop/range":{"post":{"tags":["Lookup"],"operationId":"preflopRange","summary":"Whole preflop range for a spot (presolved)","description":"The full 13×13 preflop range for a position + action line in one call — 169 hand types →\nfold/call/raise frequencies. No `hole_cards` (the spot comes from positions +\npreflop_actions). Charges 1 presolved quota (one call, not 169). For a range grid.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["table_size","positions","preflop_actions"],"properties":{"table_size":{"type":"string","example":"6max"},"preflop_version":{"type":"string","enum":["6max","6max_RC_100bb_200NL","6max_RC_100bb_100NL","6max_RC_40bb"],"description":"optional; which 6max preflop chart set to use (same as /v1/gto/preflop). Omit for the default."},"positions":{"type":"object","properties":{"hero":{"type":"string","example":"BTN"}}},"preflop_actions":{"type":"array","items":{"type":"object"},"description":"full action sequence from SB/BB, same as /v1/gto/preflop"}}},"example":{"table_size":"6max","preflop_version":"6max","positions":{"hero":"BTN"},"preflop_actions":[{"position":"SB","action":"small blind","amount":0.5},{"position":"BB","action":"big blind","amount":1}]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"range":{"type":"object","description":"hand type (AA / AKs / AKo) -> {fold, call, raise}; 169 entries, each summing to ~1","additionalProperties":{"type":"object","properties":{"fold":{"type":"number"},"call":{"type":"number"},"raise":{"type":"number"}}}},"quota":{"type":"object","properties":{"used":{"type":"integer"},"limit":{"type":"integer"}}}}},"example":{"range":{"AA":{"fold":0,"call":0,"raise":1},"AKs":{"fold":0,"call":0,"raise":1},"72o":{"fold":1,"call":0,"raise":0}},"quota":{"used":7,"limit":100}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NoSolution"},"429":{"$ref":"#/components/responses/QuotaExceeded"}}}},"/v1/gto/preflop/versions":{"get":{"tags":["Lookup"],"operationId":"preflopVersions","summary":"List installed preflop strategy versions (free)","description":"The selectable preflop_version values for /v1/gto/preflop and /v1/gto/preflop/range, with a human label for each and which one is the default (used when preflop_version is omitted). Free (no quota). Use this instead of hardcoding the list — new versions appear here automatically.\n","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"versions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"pass this as preflop_version"},"label":{"type":"string"},"default":{"type":"boolean","description":"present and true on the default version"}}}},"default":{"type":"string","description":"the id used when preflop_version is omitted"}}},"example":{"versions":[{"id":"6max","label":"6 max 100bb Deepsolver","default":true},{"id":"6max_RC_100bb_200NL","label":"6 max 100bb GG 200NL 3b/f 2.2x - 2.5x"},{"id":"6max_RC_100bb_100NL","label":"6 max 100bb GG 100NL 3b/f"},{"id":"6max_RC_40bb","label":"6 max 40bb GG 100NL"}],"default":"6max"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/gto/flop/tree":{"post":{"tags":["Lookup"],"operationId":"flopTree","summary":"Flop decision tree (presolved)","description":"Charges 1 presolved quota. Returns starting ranges + all decision nodes (each with a token for /v1/gto/flop/node).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlopTreeRequest"},"examples":{"SRP":{"summary":"Single-raised pot — positions: hero, raiser, caller","value":{"board":"2c2h2s","pot_type":"SRP","positions":{"hero":"UTG","raiser":"UTG","caller":"BTN"}}},"3BET":{"summary":"3-bet pot — positions: hero, raiser (opener), three_bettor","value":{"board":"2c2h2s","pot_type":"3BET","positions":{"hero":"CO","raiser":"CO","three_bettor":"BTN"}}},"4BET":{"summary":"4-bet pot — positions: hero, raiser (opener who 4-bet), three_bettor (3-bettor who called)","value":{"board":"2c2h2s","pot_type":"4BET","positions":{"hero":"CO","raiser":"CO","three_bettor":"BTN"}}},"LIMP":{"summary":"Limped pot — positions: hero, limper (hero or limper must be BB)","value":{"board":"2c2h2s","pot_type":"LIMP","positions":{"hero":"BB","limper":"BTN"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlopTreeResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NoSolution"},"429":{"$ref":"#/components/responses/QuotaExceeded"}}}},"/v1/gto/flop/node":{"post":{"tags":["Lookup"],"operationId":"flopNode","summary":"Flop node strategy (presolved) — one decision-tree node","description":"Per-node strategy for the flop decision tree (free, token-gated). Pass a `node` token minted by POST /v1/gto/flop/tree. With hole_cards → that hand's mixed strategy at the node; omit hole_cards → the node's whole-range strategy.\n\nThis is how you get EVERY hero flop decision — hero in position, hero facing a bet, or a later action: fetch the tree, pick a node where is_hero is true (e.g. root/CHECK/BET_13 = hero faces a bet after checking → fold/call/raise), and pass its token here. The root node (root) is hero's first decision (OOP check/bet).\n\nThe flop tree is single-street; for turn/river decisions use the solver line (/v1/gto/solver/*).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlopNodeRequest"},"example":{"node":"eyJ...<token from /v1/gto/flop/tree>","hole_cards":"AdKd"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NodeStrategyResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NoSolution"}}}},"/v1/gto/solver":{"post":{"tags":["Solver"],"operationId":"solverSchedule","summary":"Schedule a real-time solve (flop/turn/river)","description":"board length sets the street (3=flop, 4=turn, 5=river). Charges 1 solve quota on a fresh trigger; a cached solve returns status=queryable with no solve_quota field (not charged); all solver hosts busy returns 429 status=busy.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolverScheduleRequest"},"example":{"board":"2c2h2s9d","oop_range":"AA,KK,QQ,AKs","ip_range":"JJ,TT,AQs,KQs","pot":20,"effective_stack":90,"hero":"OOP","bet_sizes":{"turn":[67],"river":[75]},"raise_sizes":{"turn":[80],"river":[125]},"donk_sizes":{"turn":[55],"river":[90]},"raise_limit":3}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolverScheduleResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"description":"solve quota exceeded, or all solver hosts busy (status=busy)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/gto/solver/tree":{"post":{"tags":["Solver"],"operationId":"solverTree","summary":"Poll the solve tree + node status (free)","description":"Poll until spot_status = queryable. To advance a multi-street solve to the dealt runout, pass\nthe dealt cards: `turn_card` (e.g. a flop solve → a specific turn), and/or `river_card`.\nA river spot from a *flop* solve needs BOTH `turn_card` and `river_card` to be unique;\na turn solve needs only `river_card`. Omit both to get the solve's own street.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["solve"],"properties":{"solve":{"type":"string","description":"handle from /v1/gto/solver"},"turn_card":{"type":"string","description":"optional; for a flop solve, the dealt turn card (e.g. \"Td\") — returns nodes under that turn."},"river_card":{"type":"string","description":"optional; the dealt river card (e.g. \"Qh\"). From a flop solve, pair with turn_card to disambiguate."}}},"example":{"solve":"eyJ0Ijoic2x2X3h4eXoi...(handle from /v1/gto/solver)","turn_card":"Td","river_card":"Qh"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolverTreeResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/gto/solver/node":{"post":{"tags":["Solver"],"operationId":"solverNode","summary":"Node strategy from a solve (free)","description":"hero node → hero strategy; villain node (or omit hole_cards) → whole-range strategy.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["node"],"properties":{"node":{"type":"string","description":"node token from /v1/gto/solver/tree"},"hole_cards":{"$ref":"#/components/schemas/HoleCards"}}},"example":{"node":"eyJ0Ijoic2x2X3h4eXoi...(token from /v1/gto/solver/tree)","hole_cards":"AhKh"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/NodeStrategyResponse"},{"type":"object","properties":{"node_status":{"type":"string","enum":["available","computing","queryable","expired","error"],"description":"expired = solve reclaimed/replaced, reschedule; error = solver per-node strategy_error (with message); computing = still solving."},"message":{"type":"string","description":"present on node_status = error"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/gto/solver/release":{"post":{"tags":["Solver"],"operationId":"solverRelease","summary":"Release a solve's pool port early (free, optional)","description":"Signal you are done querying this solve so its solver port returns to the pool immediately\ninstead of lingering the cache TTL (which can 429-busy the next request when the pool is small).\nOptional — skipping it just falls back to the TTL. Call it only AFTER your last\n/v1/gto/solver/tree and /v1/gto/solver/node for this solve: once released the port may be\nreused, and further queries on this handle return node_status = expired. Idempotent; does not\nrestart the solver.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["solve"],"properties":{"solve":{"type":"string","description":"handle from /v1/gto/solver"}}},"example":{"solve":"eyJ0Ijoic2x2X3h4eXoi...(handle from /v1/gto/solver)"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"released":{"type":"boolean","description":"true if a live port claim was dropped; false if the solve had already expired (no-op)"}}},"example":{"released":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/gto/range":{"post":{"tags":["Range"],"operationId":"rangeConvert","summary":"Range conversion — update ranges along an action line","description":"Thin proxy to the solver's /api/range. You assemble all inputs including solver_results (the decision tree). Charges 1 presolved quota. Output ranges feed the next street's solve.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RangeRequest"},"example":{"range_oop":"AA,KK,QQ,JJ,AKs","range_ip":"TT,99,AQs,KQs,JTs","board":"2c2h2s","node_id":"root/CHECK/BET 8.000000","solver_results":{"node_type":"action_node","player":1,"strategy":{"actions":["CHECK","BET 8.000000"],"strategy":{"AsAh":[0.6,0.4]}},"childrens":{"CHECK":{"node_type":"action_node","player":0,"strategy":{"actions":["CHECK","BET 8.000000"],"strategy":{"KsKh":[0.5,0.5]}},"childrens":{"BET 8.000000":{"node_type":"action_node","player":1,"strategy":{"actions":["FOLD","CALL","RAISE 18.000000"],"strategy":{"QsQh":[0.2,0.5,0.3]}},"childrens":{}}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RangeResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/QuotaExceeded"},"502":{"$ref":"#/components/responses/Upstream"}}}},"/v1/gto/flop/projected-range":{"post":{"tags":["Range"],"operationId":"projectedRange","summary":"Projected range — flop range update along an action line (presolved quota)","description":"Projects the flop ranges forward along an action line for the given board / pot_type / positions. Charges 1 presolved quota. Returns the same range-update output as /v1/gto/range.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectedRangeRequest"},"example":{"board":"2c2h2s","pot_type":"SRP","positions":{"hero":"UTG","raiser":"UTG","caller":"BTN"},"node_id":"root/BET_4","normalize":true,"bluff_discount_ratio":0.8,"bluff_combos_ratio":0.5,"hero_position":"oop","hero_hand":"AsKs","partner_hands":["Ac9c"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectedRangeResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NoSolution"},"429":{"$ref":"#/components/responses/QuotaExceeded"}}}},"/v1/gto/evs":{"post":{"tags":["Range"],"operationId":"queryEvs","summary":"Node EVs — per-hand, per-action expected values of a completed solve (free)","description":"Per-hand, per-action expected values at one node of a completed solve. Give the solve handle (from /v1/gto/solver) + a node_id (from /v1/gto/solver/tree); optional hand filters to one hand. Free (already charged via /v1/gto/solver). Poll /v1/gto/solver/tree until queryable first.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvsRequest"},"example":{"solve":"eyJ0Ijoic2x2X3h4eXoi...(handle from /v1/gto/solver)","node_id":"root"}}}},"responses":{"200":{"description":"node EVs; or { spot_status: computing } if not converged yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"solve handle invalid or not yours"},"410":{"description":"solve expired (TTL); reschedule via /v1/gto/solver"}}}},"/v1/gto/turn/projected-range":{"post":{"tags":["Range"],"operationId":"turnProjectedRange","summary":"Projected range — turn→river range update along a turn action line (free)","description":"The turn→river analog of /v1/gto/flop/projected-range, for a real-time turn solve. Narrows the entering-turn ranges (the ranges the solve was scheduled with, read from the solve's own config) along a turn action line — including the street-closing CALL/CHECK — to the entering-river ranges. Free (the solve was already charged via /v1/gto/solver), like /v1/gto/solver/tree. Returns the same range-update output as /v1/gto/range. Poll /v1/gto/solver/tree until spot_status = queryable first.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnProjectedRangeRequest"},"example":{"solve":"eyJ0Ijoic2x2X3h4eXoi...(handle from /v1/gto/solver)","node_id":"root/CHECK/BET 6.000000/CALL","normalize":true}}}},"responses":{"200":{"description":"narrowed entering-river ranges; or { spot_status: computing } if the solve has not converged yet (keep polling /v1/gto/solver/tree).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RangeResponse"},{"type":"object","properties":{"spot_status":{"type":"string","enum":["computing"]}}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"410":{"description":"solve expired (TTL) — reschedule via /v1/gto/solver","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"$ref":"#/components/responses/Upstream"}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Health Get"}}}}}}},"/v1/pokerkit/texture":{"post":{"tags":["Semantic"],"summary":"Texture","operationId":"texture_v1_pokerkit_texture_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/nuts":{"post":{"tags":["Semantic"],"summary":"Nuts","operationId":"nuts_v1_pokerkit_nuts_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/category-combos":{"post":{"tags":["Semantic"],"summary":"Category Combos","operationId":"category_combos_v1_pokerkit_category_combos_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/board-report":{"post":{"tags":["Semantic"],"summary":"Board Report","operationId":"board_report_v1_pokerkit_board_report_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BoardRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/hand-tier":{"post":{"tags":["Semantic"],"summary":"Hand Tier","operationId":"hand_tier_v1_pokerkit_hand_tier_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/draws":{"post":{"tags":["Semantic"],"summary":"Draws","operationId":"draws_v1_pokerkit_draws_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/outs":{"post":{"tags":["Semantic"],"summary":"Outs","operationId":"outs_v1_pokerkit_outs_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/blockers":{"post":{"tags":["Semantic"],"summary":"Blockers","operationId":"blockers_v1_pokerkit_blockers_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/hand-report":{"post":{"tags":["Semantic"],"summary":"Hand Report","operationId":"hand_report_v1_pokerkit_hand_report_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/range/expand":{"post":{"tags":["Ranges"],"summary":"Range Expand","operationId":"range_expand_v1_pokerkit_range_expand_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RangeExpandRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/range/value":{"post":{"tags":["Ranges"],"summary":"Range Value","operationId":"range_value_v1_pokerkit_range_value_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValueRangeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/range/nut-advantage":{"post":{"tags":["Ranges"],"summary":"Range Nut Advantage","operationId":"range_nut_advantage_v1_pokerkit_range_nut_advantage_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NutAdvantageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/cards/normalize":{"post":{"tags":["Cards"],"summary":"Cards Normalize","operationId":"cards_normalize_v1_pokerkit_cards_normalize_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/eval/hand":{"post":{"tags":["Core"],"summary":"Eval Hand","operationId":"eval_hand_v1_pokerkit_eval_hand_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvalHandRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/eval/compare":{"post":{"tags":["Core"],"summary":"Eval Compare","operationId":"eval_compare_v1_pokerkit_eval_compare_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvalCompareRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/equity":{"post":{"tags":["Core"],"summary":"Equity","operationId":"equity_v1_pokerkit_equity_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquityRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/hand-strength":{"post":{"tags":["Core"],"summary":"Hand Strength","operationId":"hand_strength_v1_pokerkit_hand_strength_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandStrengthRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/icm":{"post":{"tags":["Core"],"summary":"Icm","operationId":"icm_v1_pokerkit_icm_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IcmRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/range/equity-advantage":{"post":{"tags":["Core"],"summary":"Range Equity Advantage","operationId":"range_equity_advantage_v1_pokerkit_range_equity_advantage_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EquityAdvantageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/notation/parse":{"post":{"tags":["Core"],"summary":"Notation Parse","operationId":"notation_parse_v1_pokerkit_notation_parse_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotationParseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/games/state":{"post":{"tags":["Games"],"summary":"Games State","operationId":"games_state_v1_pokerkit_games_state_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameStateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/games/step":{"post":{"tags":["Games"],"summary":"Games Step","operationId":"games_step_v1_pokerkit_games_step_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameStepRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/notation/replay":{"post":{"tags":["Games"],"summary":"Notation Replay","operationId":"notation_replay_v1_pokerkit_notation_replay_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Authorization"}},{"name":"x-api-key","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReplayRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/combined-openapi.json":{"get":{"tags":["Meta"],"summary":"Combined Openapi","description":"GTO spec + this service's auto spec merged into one document (paths are disjoint;\npokerkit schemas are prefixed only on a name collision). Always reflects current code.","operationId":"combined_openapi_v1_pokerkit_combined_openapi_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/pokerkit/meta":{"get":{"tags":["Meta"],"summary":"Meta","operationId":"meta_v1_pokerkit_meta_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Meta V1 Pokerkit Meta Get"}}}}}}}},"components":{"securitySchemes":{"BearerApiKey":{"type":"http","scheme":"bearer","description":"Authorization: Bearer gto_..."},"XApiKey":{"type":"apiKey","in":"header","name":"X-API-Key"}},"responses":{"BadRequest":{"description":"invalid input or missing field","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"missing or invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NoSolution":{"description":"no GTO data for this spot/board","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"QuotaExceeded":{"description":"monthly quota exceeded (resets on the 1st)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Upstream":{"description":"backend temporarily unavailable, retry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UpstreamUnavailable":{"description":"solver unreachable after the service's own retries (transport error / 5xx) — retryable; error: upstream_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"token invalid or not yours","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","example":"missing_api_key"},"message":{"type":"string"}}},"Position":{"type":"string","enum":["SB","BB","UTG","MP","CO","BTN"]},"HoleCards":{"type":"string","description":"two cards, no separator, e.g. \"AdKd\". Rank AKQJT98765432, suit c d h s.","pattern":"^[2-9TJQKA][cdhs][2-9TJQKA][cdhs]$","example":"AdKd"},"BoardInput":{"type":"string","description":"community cards as a no-separator string: 3=flop \"2c2h2s\", 4=turn, 5=river.","example":"2c2h2s"},"BoardOutput":{"type":"array","items":{"type":"string"},"description":"community cards returned as an array","example":["2c","2h","2s"]},"RangeString":{"type":"string","description":"comma-separated hand:weight. class notation AA/AKs/AKo (high rank first); weight 0..1, default 1.","example":"AA:1,KK,AKs:0.5,72o:0.1"},"Quota":{"type":"object","properties":{"used":{"type":"integer"},"limit":{"type":"integer"}}},"StrategyItem":{"type":"object","properties":{"action":{"type":"string","description":"check / call / fold / raise / bet"},"frequency":{"type":"number","format":"float","description":"0..1 probability"},"sizing_pot":{"type":"number","description":"pot-relative sizing, standard % pot convention: a bet = bet ÷ pot; a raise = (raise − amount-to-call) ÷ pot-after-call. e.g. 0.5 / 0.8 / 1. bet/raise only"},"amount_bb":{"type":"number","description":"absolute bet/raise amount in BB (for bet/raise)"},"allin":{"type":"boolean","description":"present and true when the action is all-in"}},"required":["action","frequency"]},"PreflopRequest":{"type":"object","required":["hole_cards","positions","preflop_actions"],"properties":{"hole_cards":{"$ref":"#/components/schemas/HoleCards"},"positions":{"type":"object","required":["hero"],"properties":{"hero":{"$ref":"#/components/schemas/Position"}}},"table_size":{"type":"string","default":"6max"},"preflop_version":{"type":"string","enum":["6max","6max_RC_100bb_200NL","6max_RC_100bb_100NL","6max_RC_40bb"],"description":"optional; which 6max preflop chart set to use. Omit for the platform default (6max). Unknown value -> 400 unsupported_preflop_version."},"preflop_actions":{"type":"array","description":"Explicit, complete action sequence from the small blind up to the player right before hero (hero is NOT included; hero's position is positions.hero). Must start with small blind (0.5) then big blind (1). amount is the increment newly committed this action in BB (not the running total); pot = sum of all amounts. A raise's resulting total must exceed the current bet and meet the min-raise (= current bet + size of the last raise) unless allin:true; a call's total must exactly match the current bet unless allin:true. Exact amounts only make the pot/sizing_pot exact — GTO frequencies are situation-based (RFI/3bet/4bet + positions) and do not change with bet sizes. Violations return 400 invalid_actions.\n","items":{"type":"object","required":["position","action"],"properties":{"position":{"$ref":"#/components/schemas/Position"},"action":{"type":"string","enum":["small blind","big blind","raise","call","fold"]},"amount":{"type":"number","description":"increment newly committed this action in BB (required for non-fold actions); omitted/0 for fold"},"allin":{"type":"boolean","description":"optional; mark a short all-in (raise/call below the min-raise). when true, the min-raise check is skipped"}}}}}},"PreflopResponse":{"type":"object","properties":{"hole_cards":{"type":"string"},"situation":{"type":"string","enum":["RFI","Limp","Raise","3-Bet","4-Bet","5-Bet"],"description":"table state hero faces: RFI (folded to hero, open spot) / Limp (a limper is in, no raise) / Raise (1 raise) / 3-Bet / 4-Bet / 5-Bet"},"strategy":{"type":"array","items":{"$ref":"#/components/schemas/StrategyItem"}},"quota":{"$ref":"#/components/schemas/Quota"}}},"FlopPositions":{"type":"object","description":"required keys depend on pot_type — SRP: hero,raiser,caller; 3BET/4BET: hero,raiser,three_bettor (for 4BET, raiser = the opener who 4-bet, three_bettor = the 3-bettor who called; no four_bettor key); LIMP: hero,limper. hero must be one of the named seats.","properties":{"hero":{"$ref":"#/components/schemas/Position"},"raiser":{"$ref":"#/components/schemas/Position"},"caller":{"$ref":"#/components/schemas/Position"},"three_bettor":{"$ref":"#/components/schemas/Position"},"limper":{"$ref":"#/components/schemas/Position"}}},"FlopNodeRequest":{"type":"object","required":["node"],"properties":{"node":{"type":"string","description":"node token from /v1/gto/flop/tree (the `token` field of a node)"},"hole_cards":{"$ref":"#/components/schemas/HoleCards"}}},"FlopTreeRequest":{"type":"object","required":["board","pot_type","positions"],"properties":{"board":{"$ref":"#/components/schemas/BoardInput"},"pot_type":{"type":"string","enum":["SRP","3BET","4BET","LIMP"]},"positions":{"$ref":"#/components/schemas/FlopPositions"},"flop_version":{"type":"string","enum":["6max","6max_RC_100bb_200NL","6max_RC_100bb_100NL","6max_RC_40bb"],"description":"optional; which flop dataset (one solved per preflop version). Omit for the default (6max). If the chosen version has no data for the spot the service degrades gracefully to 6max. Unknown value -> 400 unsupported_flop_version. Independent of preflop_version. The node tokens carry this version, so /v1/gto/flop/node stays on the same dataset."}}},"FlopTreeResponse":{"type":"object","properties":{"board":{"$ref":"#/components/schemas/BoardOutput"},"pot_type":{"type":"string"},"pot":{"type":"number"},"effective_stack":{"type":"number"},"oop_range":{"$ref":"#/components/schemas/RangeString"},"ip_range":{"$ref":"#/components/schemas/RangeString"},"node_count":{"type":"integer"},"nodes":{"type":"array","items":{"type":"object","properties":{"node":{"type":"string","example":"root/CHECK/BET_8"},"is_hero":{"type":"boolean"},"token":{"type":"string"}}}},"quota":{"$ref":"#/components/schemas/Quota"}}},"NodeStrategyResponse":{"type":"object","description":"hero node has `strategy`; villain node (or no hole_cards) has `actions` + `range_strategy`.","properties":{"node":{"type":"string"},"is_hero":{"type":"boolean"},"hole_cards":{"type":"string"},"strategy":{"type":"array","items":{"$ref":"#/components/schemas/StrategyItem"}},"actions":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string"},"amount_bb":{"type":"number"},"sizing_pot":{"type":"number"},"allin":{"type":"boolean"}}}},"range_strategy":{"type":"object","additionalProperties":{"type":"array","items":{"type":"number"}},"description":"combo (e.g. \"AhKh\") -> frequencies aligned to actions"},"range_hand_count":{"type":"integer"}}},"SolverScheduleRequest":{"type":"object","required":["board","oop_range","ip_range","pot","effective_stack","hero"],"properties":{"board":{"$ref":"#/components/schemas/BoardInput"},"oop_range":{"$ref":"#/components/schemas/RangeString"},"ip_range":{"$ref":"#/components/schemas/RangeString"},"pot":{"type":"number"},"effective_stack":{"type":"number"},"hero":{"type":"string","enum":["OOP","IP"]},"bet_sizes":{"type":"object","description":"optional per-street opening bet sizes in pot %; flop defaults to 50%","properties":{"flop":{"type":"array","items":{"type":"integer"}},"turn":{"type":"array","items":{"type":"integer"}},"river":{"type":"array","items":{"type":"integer"}}}},"raise_sizes":{"type":"object","description":"optional per-street raise sizes in pot %; omitted streets reuse bet_sizes/defaults","properties":{"flop":{"type":"array","items":{"type":"integer"}},"turn":{"type":"array","items":{"type":"integer"}},"river":{"type":"array","items":{"type":"integer"}}}},"donk_sizes":{"type":"object","description":"optional OOP donk-lead sizes in pot %; turn defaults to 67%, river defaults to 100%","properties":{"turn":{"type":"array","items":{"type":"integer"}},"river":{"type":"array","items":{"type":"integer"}}}},"raise_limit":{"type":"integer","minimum":1,"maximum":4,"description":"optional tree-wide raise cap; defaults to 3 for flop/turn solves and 4 for river-only solves"}}},"SolverScheduleResponse":{"type":"object","properties":{"status":{"type":"string","enum":["computing","queryable","busy"]},"solve":{"type":"string","description":"handle for /tree and /node"},"solve_quota":{"allOf":[{"$ref":"#/components/schemas/Quota"}],"description":"present only when a new solve was triggered (charged)"}}},"SolverTreeResponse":{"type":"object","properties":{"street":{"type":"string","enum":["flop","turn","river"]},"pot":{"type":"number"},"effective_stack":{"type":"number"},"spot_status":{"type":"string","enum":["available","computing","queryable","expired","no_nodes"],"description":"no_nodes = solve converged but the queried round/runout has no decision nodes in the tree (terminal — stop polling)."},"node_count":{"type":"integer"},"nodes":{"type":"array","items":{"type":"object","properties":{"node":{"type":"string"},"is_hero":{"type":"boolean"},"status":{"type":"string"},"token":{"type":"string"}}}}}},"RangeRequest":{"type":"object","required":["range_oop","range_ip","solver_results","node_id"],"properties":{"range_oop":{"$ref":"#/components/schemas/RangeString"},"range_ip":{"$ref":"#/components/schemas/RangeString"},"solver_results":{"type":"object","description":"the decision tree (you assemble it)"},"node_id":{"type":"string","example":"root/CHECK/BET 8.000000"},"board":{"$ref":"#/components/schemas/BoardInput"},"normalize":{"type":"boolean","default":true},"explain":{"type":"boolean","default":false},"track_hands":{"type":"array","items":{"type":"string"}},"bluff_discount_ratio":{"type":"number","minimum":0,"maximum":1},"hero_position":{"type":"string","enum":["oop","ip"],"description":"optional card blocking: which player is Hero. Pair with hero_hand."},"hero_hand":{"type":"string","example":"AsKs","description":"optional card blocking: remove every combo containing one of Hero's cards from the ranges (range-vs-hand analysis). Echoed back in the response. Applies to /v1/gto/range only, not the projected-range wrappers."}}},"RangeResponse":{"type":"object","properties":{"range_oop_new":{"$ref":"#/components/schemas/RangeString"},"range_ip_new":{"$ref":"#/components/schemas/RangeString"},"range_oop_new_raw":{"type":"string"},"range_ip_new_raw":{"type":"string"},"range_oop_new_raw_before_normalization":{"type":"string"},"range_ip_new_raw_before_normalization":{"type":"string"},"hand_ranks_oop":{"type":"string","description":"OOP combos by made-hand strength: 'combo:rank,...' (lower rank = stronger), sorted by rank ascending. Equal-rank tie order is NOT guaranteed stable across endpoints/runs — do not depend on it."},"hand_ranks_ip":{"type":"string","description":"IP analog of hand_ranks_oop."},"hand_bottom_ranks_oop":{"type":"string","description":"The weakest bluff_combos_ratio fraction of hand_ranks_oop (bluff candidates), same format."},"hand_bottom_ranks_ip":{"type":"string","description":"IP analog of hand_bottom_ranks_oop."},"node_id":{"type":"string"},"board":{"$ref":"#/components/schemas/BoardOutput"},"path_length":{"type":"integer"},"bluff_discount_ratio":{"type":"number"},"bluff_combos_ratio":{"type":"number"},"quota":{"$ref":"#/components/schemas/Quota"}}},"ProjectedRangeRequest":{"type":"object","required":["board","pot_type","positions"],"properties":{"board":{"$ref":"#/components/schemas/BoardInput"},"pot_type":{"type":"string","enum":["SRP","3BET","4BET","LIMP"]},"positions":{"$ref":"#/components/schemas/FlopPositions"},"node_id":{"type":"string","default":"root","example":"root/BET_4"},"normalize":{"type":"boolean","default":true},"bluff_discount_ratio":{"type":"number","default":0.8,"minimum":0,"maximum":1},"hero_position":{"type":"string","enum":["oop","ip"],"description":"optional card blocking, pair with hero_hand."},"hero_hand":{"type":"string","example":"AsKs","description":"optional card blocking: remove every combo containing one of Hero's cards from the villain's updated range (the range_*_new_raw outputs). Hero's own hand is also ensured present in Hero's own range. Echoed back."},"bluff_combos_ratio":{"type":"number","minimum":0,"maximum":1,"description":"optional; fraction of the range treated as bluffs (bottom-of-range). Omit to use the server turn/river default. Echoed back."},"partner_hands":{"type":"array","items":{"type":"string"},"example":["Ac9c"],"description":"optional; 4-char combos whose cards are removed from the villain's updated range (range_*_new_raw). Requires hero_position. Input only (not echoed). flop/projected-range only."},"flop_version":{"type":"string","enum":["6max","6max_RC_100bb_200NL","6max_RC_100bb_100NL","6max_RC_40bb"],"description":"optional; which flop dataset (one solved per preflop version). Omit for the default (6max). If the chosen version has no data for the spot the service degrades gracefully to 6max. Unknown value -> 400 unsupported_flop_version. Independent of preflop_version."}}},"ProjectedRangeResponse":{"description":"Same fields as RangeResponse, plus pot_type echoed from the request (17 fields total).","allOf":[{"$ref":"#/components/schemas/RangeResponse"},{"type":"object","properties":{"pot_type":{"type":"string"}}}]},"TurnProjectedRangeRequest":{"type":"object","required":["solve","node_id"],"properties":{"solve":{"type":"string","description":"handle from /v1/gto/solver (a turn solve)"},"node_id":{"type":"string","description":"a turn action line; may end in the street-closing CALL/CHECK. Solver node format with spaces, e.g. \"root/CHECK/BET 6.000000/CALL\"."},"normalize":{"type":"boolean","default":true},"bluff_discount_ratio":{"type":"number","minimum":0,"maximum":1},"hero_position":{"type":"string","enum":["oop","ip"],"description":"optional card blocking, pair with hero_hand."},"hero_hand":{"type":"string","example":"AsKs","description":"optional card blocking: remove every combo containing one of Hero's cards from the villain's updated range."},"partner_hands":{"type":"array","items":{"type":"string"},"example":["Ac9c"],"description":"optional; 4-char combos whose cards are removed from the villain's updated range. Requires hero_position. Input only."}}},"EvsRequest":{"type":"object","required":["solve","node_id"],"properties":{"solve":{"type":"string","description":"handle from /v1/gto/solver"},"node_id":{"type":"string","example":"root","description":"a node from /v1/gto/solver/tree (solver notation, e.g. \"root/CHECK/BET 6.000000\")"},"hand":{"type":"string","example":"AsKh","description":"optional; filter to one hand's EVs (else all hands)"}}},"EvsResponse":{"type":"object","description":"Per-hand, per-action EVs at the node; each hand's EV array aligns with actions.","properties":{"node_id":{"type":"string"},"task_id":{"type":"string"},"player":{"type":"integer"},"round":{"type":"string","example":"FLOP"},"actions":{"type":"array","items":{"type":"string"},"example":["CHECK","BET 4.000000","BET 97.000000"]},"evs":{"type":"object","additionalProperties":{"type":"array","items":{"type":"number"}},"description":"hand -> per-action EV array (bb); a single array when hand is given","example":{"2c2d":[-0.826359,-0.792223,-1.643411]}}}},"BoardRequest":{"properties":{"board":{"type":"string","title":"Board","description":"3/4/5 board cards, e.g. 'AsKsQs'","examples":["AsKsQs"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hand Type","examples":["StandardHighHand"]},"dead":{"type":"string","title":"Dead","description":"optional dead/removed cards","default":""}},"type":"object","required":["board"],"title":"BoardRequest"},"CardsRequest":{"properties":{"cards":{"type":"string","title":"Cards","description":"cards to normalize/validate","examples":["AsKsQs"]}},"type":"object","required":["cards"],"title":"CardsRequest"},"EquityAdvantageRequest":{"properties":{"hero":{"items":{"type":"string"},"type":"array","title":"Hero","examples":[["AA","KK","AKs"]]},"villain":{"items":{"type":"string"},"type":"array","title":"Villain","examples":[["QQ","JJ","AQs"]]},"board":{"type":"string","title":"Board","examples":["AsKsQs"]},"sample_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sample Count"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed"},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hand Type"}},"type":"object","required":["hero","villain","board"],"title":"EquityAdvantageRequest"},"EquityRequest":{"properties":{"ranges":{"items":{"items":{"type":"string"},"type":"array"},"type":"array","title":"Ranges","description":"per-player ranges (notation)","examples":[[["AA","KK"],["QQ","JJ"]]]},"board":{"type":"string","title":"Board","default":"","examples":["AhKhQh"]},"sample_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sample Count","description":"Monte-Carlo samples (capped); default applies if unset"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed","description":"seed for reproducible sampling"}},"type":"object","required":["ranges"],"title":"EquityRequest"},"EvalCompareRequest":{"properties":{"holdings":{"items":{"type":"string"},"type":"array","title":"Holdings","description":"2+ holdings to rank","examples":[["AcAd","KcKd","JhTh"]]},"board":{"type":"string","title":"Board","default":"","examples":["AhKhQh"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hand Type"}},"type":"object","required":["holdings"],"title":"EvalCompareRequest"},"EvalHandRequest":{"properties":{"hole":{"type":"string","title":"Hole","examples":["AcAd"]},"board":{"type":"string","title":"Board","default":"","examples":["AhKhQh"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hand Type"}},"type":"object","required":["hole"],"title":"EvalHandRequest"},"GameStateRequest":{"properties":{"variant":{"type":"string","title":"Variant","description":"variant code, e.g. NT (NL hold'em); see /meta","examples":["NT"]},"starting_stacks":{"items":{"type":"integer"},"type":"array","title":"Starting Stacks","examples":[[200,200]]},"antes":{"items":{"type":"integer"},"type":"array","title":"Antes","examples":[[0,0]]},"blinds_or_straddles":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Blinds Or Straddles","examples":[[1,2]]},"bring_in":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bring In"},"small_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Small Bet"},"big_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Big Bet"},"min_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Bet","description":"required for no-limit/pot-limit, e.g. 2"},"ante_trimming_status":{"type":"boolean","title":"Ante Trimming Status","default":false},"automations":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Automations","description":"Automation names; omit for pokerkit defaults"},"actions":{"items":{"type":"string"},"type":"array","title":"Actions","examples":[["d dh p1 AhKh","d dh p2 QsQd","p2 cbr 6"]]},"viewer":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Viewer","description":"reserved (hidden-info tier); v1 is full-information"}},"type":"object","required":["variant","starting_stacks","antes"],"title":"GameStateRequest"},"GameStepRequest":{"properties":{"variant":{"type":"string","title":"Variant","description":"variant code, e.g. NT (NL hold'em); see /meta","examples":["NT"]},"starting_stacks":{"items":{"type":"integer"},"type":"array","title":"Starting Stacks","examples":[[200,200]]},"antes":{"items":{"type":"integer"},"type":"array","title":"Antes","examples":[[0,0]]},"blinds_or_straddles":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Blinds Or Straddles","examples":[[1,2]]},"bring_in":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bring In"},"small_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Small Bet"},"big_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Big Bet"},"min_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Bet","description":"required for no-limit/pot-limit, e.g. 2"},"ante_trimming_status":{"type":"boolean","title":"Ante Trimming Status","default":false},"automations":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Automations","description":"Automation names; omit for pokerkit defaults"},"actions":{"items":{"type":"string"},"type":"array","title":"Actions","examples":[["d dh p1 AhKh","d dh p2 QsQd","p2 cbr 6"]]},"viewer":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Viewer","description":"reserved (hidden-info tier); v1 is full-information"},"next_action":{"type":"string","title":"Next Action","description":"the player/deal action to apply","examples":["p1 cc"]},"expected_action_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Action Count","description":"optimistic-concurrency token = len(actions) you are extending; 409 on mismatch"}},"type":"object","required":["variant","starting_stacks","antes","next_action"],"title":"GameStepRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HandRequest":{"properties":{"hole":{"type":"string","title":"Hole","description":"2 hole cards, e.g. 'JhTh'","examples":["JhTh"]},"board":{"type":"string","title":"Board","examples":["AsKsQs"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hand Type"},"dead":{"type":"string","title":"Dead","default":""}},"type":"object","required":["hole","board"],"title":"HandRequest"},"HandStrengthRequest":{"properties":{"hole_range":{"items":{"type":"string"},"type":"array","title":"Hole Range","description":"hero range/hand (notation)","examples":[["AhKh"]]},"board":{"type":"string","title":"Board","default":"","examples":["AhKhQh"]},"player_count":{"type":"integer","minimum":2.0,"title":"Player Count","default":2},"sample_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Sample Count"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seed"}},"type":"object","required":["hole_range"],"title":"HandStrengthRequest"},"IcmRequest":{"properties":{"payouts":{"items":{"type":"number"},"type":"array","title":"Payouts","examples":[[50,30,20]]},"chips":{"items":{"type":"number"},"type":"array","title":"Chips","examples":[[5000,3000,2000]]}},"type":"object","required":["payouts","chips"],"title":"IcmRequest"},"NotationParseRequest":{"properties":{"text":{"type":"string","title":"Text","description":"a pokerkit .phh hand-history string"}},"type":"object","required":["text"],"title":"NotationParseRequest"},"NutAdvantageRequest":{"properties":{"hero":{"items":{"type":"string"},"type":"array","title":"Hero","description":"hero range (notation)","examples":[["AA","KK","AKs"]]},"villain":{"items":{"type":"string"},"type":"array","title":"Villain","description":"villain range (notation)","examples":[["QQ","JJ","AQs"]]},"board":{"type":"string","title":"Board","examples":["AsKsQs"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hand Type"}},"type":"object","required":["hero","villain","board"],"title":"NutAdvantageRequest"},"RangeExpandRequest":{"properties":{"notation":{"items":{"type":"string"},"type":"array","title":"Notation","description":"range notation tokens","examples":[["AA","KQs","QQ+"]]}},"type":"object","required":["notation"],"title":"RangeExpandRequest"},"ReplayRequest":{"properties":{"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Text","description":"a .phh string; OR supply the config+actions fields below"},"variant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variant"},"starting_stacks":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Starting Stacks"},"antes":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Antes"},"blinds_or_straddles":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Blinds Or Straddles"},"bring_in":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bring In"},"small_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Small Bet"},"big_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Big Bet"},"min_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Bet"},"ante_trimming_status":{"type":"boolean","title":"Ante Trimming Status","default":false},"automations":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Automations"},"actions":{"items":{"type":"string"},"type":"array","title":"Actions"},"index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Index","description":"return only the snapshot at this step index"}},"type":"object","title":"ReplayRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"ValueRangeRequest":{"properties":{"board":{"type":"string","title":"Board","examples":["AsKsQs"]},"aggression":{"type":"string","title":"Aggression","default":"SINGLE_BET","examples":["NO_BET","SINGLE_BET","RAISED"]},"floor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Floor","description":"optional category floor, e.g. 'TWO_PAIR' (overrides aggression default)"},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hand Type"},"dead":{"type":"string","title":"Dead","default":""}},"type":"object","required":["board"],"title":"ValueRangeRequest"}}}}