Protocol v2 strategy_grid Query Formats
This document explains how to query /strategy_grid for Squid, Short Deck,
Bombpot, MTT, and PLO spots. It is focused on request fields, response fields,
and JSON examples.
The examples use chips, not BB, for stacks and action amounts. With
big_blind: 100, a 100 BB stack is 10000.
Output examples are representative snippets. Live strategy probabilities, EVs, bucket ids, and model metadata will depend on the loaded model and spot.
Endpoint
POST <gto-glue-environment-URL>/strategy_grid
Content-Type: application/jsonFor Holdem-like v2 formats, send protocol_ver: "v2". PLO is selected before
the v2 Holdem route by hand.game_type being plo4, plo5, or plo6; keep
protocol_ver: "v2" for consistency.
Common Input Fields
All formats use a strategy-act-style top-level request with a required hand
object.
| Field | Type | Notes |
|---|---|---|
protocol_ver | string | Use "v2" for the v2 strategy-grid route. |
strategy_min_threshold | number | Optional. Drops tiny action probabilities and renormalizes. The UI commonly sends 0.05. |
hand.game_type | string | "nlhe", "shortdeck", "plo4", "plo5", or "plo6". |
hand.game_mode_code | string | "normal", "squid", "bomb", or "spin". |
hand.big_blind | integer | Big blind in chips. |
hand.small_blind | integer | Small blind in chips. Defaults to big_blind / 2 if omitted. |
hand.ante | integer | Per-player ante in chips. For pure Bombpot, this is the bomb deposit. For Short Deck, the backend forces ante to 1 BB. |
hand.dealer_seat | integer | Button seat, 0-indexed. The UI uses last seat for 3+ players and seat 0 for heads-up. |
hand.sb_seat | integer | Small blind seat, usually 0; use -1 for dead-SB MTT spots. |
hand.bb_seat | integer | Big blind seat, usually 1. |
hand.straddle_seat | integer | Straddle seat, usually 2 for 3-blind cash, otherwise -1. |
hand.players[] | array | One item per table seat: { "seat_no": 0, "stack": 10000 }. Omit hole_cards for range-viewer grid requests. |
hand.rake_ratio_pct | number | Optional cash rake percentage, e.g. 3. Use 0 for MTT if desired. |
hand.rake_cap_bb | number | Optional rake cap in BB, e.g. 3. |
hand.actions.entries[] | array | Action and board history so far. Empty means first decision. |
Action entries use this shape:
{
"hand": {
"actions": {
"entries": [
{ "seat_no": 2, "action": "fold" },
{ "seat_no": 3, "action": "call" },
{ "seat_no": 4, "action": "raise", "amount": 300, "raise_to": 300 },
{ "action": "Ah7d2c" },
{ "action": "Ks" }
]
}
}
}Player actions use action: "fold", "call", "check", "raise", "bet",
or "allin". amount is raise-by/bet-by in chips. The v2 frontend also sends
raise_to, the cumulative raise-to in chips; the backend preserves it and
prefers it when present.
Board cards are deal entries: put the card string in action and omit
seat_no and amount. Flop uses six characters such as "Ah7d2c";
turn/river use two characters such as "Ks".
Common Holdem-like Output Fields
Squid, Short Deck, Bombpot, and MTT use the v2 Holdem response shape.
| Field | Type | Notes |
|---|---|---|
hands[] | array | The 169 grid cells. Each item has handName, strategy, reach, ev, actions, and combos. |
hands[].handName | string | Matrix label such as "AA", "AKs", or "AKo". This replaces v1 top-level combo. |
hands[].strategy | number[] | Strategy vector in action-slot order. |
hands[].reach | number | Average reach for that grid cell. |
hands[].ev | number | Aggregated EV for that grid cell. |
hands[].actions[] | array | Aggregated action rows: { "actionName", "probability", "ev" }. |
hands[].combos[] | array | Concrete two-card combos in that cell. Each combo still uses combo, e.g. "AsAh". |
overallStrategy | number[] | Overall range strategy in action-slot order. |
overallReach | number | Average overall reach. |
gridWeightType | string | "uniform" by default, or "reach" when requested. |
actionLabels[] | array | Legal action labels. Each label includes slot, name, rawAction, amount, amountBb, and raiseByBb. |
currentPlayer | integer | Seat number for the acting player, or -1 if terminal. |
numBoardCards | integer | Number of board cards currently dealt. |
pendingDeal | string | "", "flop", "turn", or "river" when more board cards are required. |
numCombos | integer | Number of concrete NLHE combos evaluated. |
tableState | object | Pot, board, player stacks/commitments, acting context, and equity arrays. |
actionHistory[] | array | Backend-rendered action history for UI replay. |
stateRender | string | Debug render of the engine state. |
obsDebug | object | Debug fields for action mask, action sizes, game tags, raw board, and obs dim. |
model | string | Selected model name. |
modelMd5 | string | Selected model checksum. |
computeTimeMs | integer | Total service-side compute time. |
inferenceTimeMs | integer | Model inference time for v2 Holdem. |
supportScore | number | Optional support score when provided by the model output. |
MTT fills tableState.icmEquityBb and tableState.bountyBb. Squid fills
tableState.squidEquityBb.
Squid
Squid is a Holdem-like v2 request with hand.game_mode_code: "squid" and a
top-level squid object. Use hand.game_type: "nlhe" for regular Squid and
"shortdeck" for Short Deck Squid.
Squid Input Fields
| Field | Type | Notes |
|---|---|---|
hand.game_type | string | "nlhe" or "shortdeck". |
hand.game_mode_code | string | Must be "squid". |
squid.squid_value_in_bb | number | Squid value in BB. Legacy alias val_v is still normalized, but use this canonical name. |
squid.mode | string | "classic", "blood_battle", or "double". |
squid.players[] | array | Per-seat squid counts: { "seat_no": 0, "squid_count": 1 }. |
squid.total_squids | integer | Total squid markers this round. Classic is commonly num_players - 1; blood/double commonly num_players + 4. |
squid.remaining_squids | integer | Markers not yet awarded. |
squid.super_squid_count | integer | Optional blood/double super-squid count. |
squid.super_squid_remaining | integer | Optional remaining super squids. |
squid.is_super_squid_hand | boolean | Optional marker that this hand has a super squid at stake. |
squid.double_thresholds | integer[] | Optional threshold/multiplier pairs, e.g. [3, 2, 5, 4]. |
Squid Request Example
{
"protocol_ver": "v2",
"strategy_min_threshold": 0.05,
"hand": {
"game_type": "nlhe",
"game_mode_code": "squid",
"big_blind": 100,
"small_blind": 50,
"ante": 0,
"dealer_seat": 5,
"sb_seat": 0,
"bb_seat": 1,
"straddle_seat": -1,
"players": [
{ "seat_no": 0, "stack": 10000 },
{ "seat_no": 1, "stack": 10000 },
{ "seat_no": 2, "stack": 10000 },
{ "seat_no": 3, "stack": 10000 },
{ "seat_no": 4, "stack": 10000 },
{ "seat_no": 5, "stack": 10000 }
],
"rake_ratio_pct": 0,
"rake_cap_bb": 0,
"actions": { "entries": [] }
},
"squid": {
"squid_value_in_bb": 5,
"mode": "classic",
"players": [
{ "seat_no": 0, "squid_count": 0 },
{ "seat_no": 1, "squid_count": 1 },
{ "seat_no": 2, "squid_count": 0 },
{ "seat_no": 3, "squid_count": 2 },
{ "seat_no": 4, "squid_count": 0 },
{ "seat_no": 5, "squid_count": 0 }
],
"total_squids": 5,
"remaining_squids": 2
}
}Squid Output Example
{
"hands": [
{
"handName": "AA",
"strategy": [0.0, 0.18, 0.0, 0.82, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
"reach": 1.0,
"ev": 14.25,
"actions": [
{ "actionName": "call", "probability": 0.18, "ev": 11.2 },
{ "actionName": "raise3.0", "probability": 0.82, "ev": 15.1 }
],
"combos": [
{
"combo": "AsAh",
"reach": 1.0,
"actions": [
{ "actionName": "call", "probability": 0.12, "ev": 10.9 },
{ "actionName": "raise3.0", "probability": 0.88, "ev": 15.4 }
]
}
]
}
],
"overallStrategy": [0.11, 0.31, 0.0, 0.58, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
"overallReach": 1.0,
"gridWeightType": "uniform",
"actionLabels": [
{ "index": 0, "slot": 0, "name": "fold", "rawAction": -1, "amount": null, "amountBb": 0.0, "raiseByBb": 0.0 },
{ "index": 1, "slot": 1, "name": "call 1.0 BB", "rawAction": 0, "amount": 100, "amountBb": 1.0, "raiseByBb": 0.0 },
{ "index": 2, "slot": 3, "name": "raise 3.0 BB", "rawAction": 300, "amount": 300, "amountBb": 3.0, "raiseByBb": 2.0 }
],
"currentPlayer": 2,
"numBoardCards": 0,
"pendingDeal": "",
"tableState": {
"street": "preflop",
"pot": 150,
"chipsPerBb": 100,
"board": [],
"actingPlayer": 2,
"squidEquityBb": [0.0, 5.2, 0.0, 10.1, 0.0, 0.0]
},
"model": "example-model.onnx",
"modelMd5": "example-md5",
"computeTimeMs": 18,
"inferenceTimeMs": 7
}Short Deck
Short Deck is selected by hand.game_type: "shortdeck". Use
hand.game_mode_code: "normal" for regular Short Deck. The backend forces
ante = big_blind for all Short Deck variants, matching the v1 behavior; send
that value explicitly for readability.
Short Deck Input Fields
| Field | Type | Notes |
|---|---|---|
hand.game_type | string | Must be "shortdeck". |
hand.game_mode_code | string | "normal" for regular Short Deck. Use "squid" or "bomb" only for combined variants. |
hand.ante | integer | Backend treats this as 1 BB regardless of request value. Send big_blind. |
hand.players[] | array | Two to six players are typical for Short Deck configs. |
hand.actions.entries[] | array | Same action/deal entry format as NLHE. |
Short Deck Request Example
{
"protocol_ver": "v2",
"strategy_min_threshold": 0.05,
"hand": {
"game_type": "shortdeck",
"game_mode_code": "normal",
"big_blind": 100,
"small_blind": 50,
"ante": 100,
"dealer_seat": 5,
"sb_seat": 0,
"bb_seat": 1,
"straddle_seat": -1,
"players": [
{ "seat_no": 0, "stack": 10000 },
{ "seat_no": 1, "stack": 10000 },
{ "seat_no": 2, "stack": 10000 },
{ "seat_no": 3, "stack": 10000 },
{ "seat_no": 4, "stack": 10000 },
{ "seat_no": 5, "stack": 10000 }
],
"rake_ratio_pct": 3,
"rake_cap_bb": 3,
"actions": { "entries": [] }
}
}Short Deck Output Example
{
"hands": [
{
"handName": "AKs",
"strategy": [0.08, 0.52, 0.0, 0.40, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
"reach": 1.0,
"ev": 5.2,
"actions": [
{ "actionName": "fold", "probability": 0.08, "ev": 0.0 },
{ "actionName": "call", "probability": 0.52, "ev": 4.7 },
{ "actionName": "raise4.0", "probability": 0.40, "ev": 6.1 }
],
"combos": [
{
"combo": "AsKs",
"reach": 1.0,
"actions": [
{ "actionName": "fold", "probability": 0.06, "ev": 0.0 },
{ "actionName": "call", "probability": 0.54, "ev": 4.8 },
{ "actionName": "raise4.0", "probability": 0.40, "ev": 6.2 }
]
}
]
}
],
"actionLabels": [
{ "index": 0, "slot": 0, "name": "fold", "rawAction": -1, "amount": null, "amountBb": 0.0, "raiseByBb": 0.0 },
{ "index": 1, "slot": 1, "name": "call 1.0 BB", "rawAction": 0, "amount": 100, "amountBb": 1.0, "raiseByBb": 0.0 },
{ "index": 2, "slot": 3, "name": "raise 4.0 BB", "rawAction": 400, "amount": 400, "amountBb": 4.0, "raiseByBb": 3.0 }
],
"currentPlayer": 0,
"numBoardCards": 0,
"pendingDeal": "",
"tableState": {
"street": "preflop",
"pot": 700,
"chipsPerBb": 100,
"board": [],
"actingPlayer": 0,
"players": [
{ "position": "SB", "stack": 9900, "startStack": 10000, "committed": 100, "folded": false, "allIn": false }
]
},
"model": "example-model.onnx",
"computeTimeMs": 15,
"inferenceTimeMs": 6
}Bombpot
Bombpot is selected by hand.game_mode_code: "bomb". Use
hand.game_type: "nlhe" for regular Bombpot and "shortdeck" for Short Deck
Bombpot.
For pure non-shortdeck Bombpot, hand.ante is the bomb deposit in chips. For
Short Deck Bombpot, the backend follows Short Deck behavior and forces the
effective ante to 1 BB, then uses a 2 BB bomb deposit internally to match v1.
Bombpot Input Fields
| Field | Type | Notes |
|---|---|---|
hand.game_type | string | "nlhe" or "shortdeck". |
hand.game_mode_code | string | Must be "bomb". |
hand.ante | integer | Bomb deposit in chips for regular Bombpot. |
hand.actions.entries[] | array | Include board card deal entries to query a board-specific spot. |
Bombpot Request Example
{
"protocol_ver": "v2",
"strategy_min_threshold": 0.05,
"hand": {
"game_type": "nlhe",
"game_mode_code": "bomb",
"big_blind": 100,
"small_blind": 50,
"ante": 500,
"dealer_seat": 5,
"sb_seat": 0,
"bb_seat": 1,
"straddle_seat": -1,
"players": [
{ "seat_no": 0, "stack": 10000 },
{ "seat_no": 1, "stack": 10000 },
{ "seat_no": 2, "stack": 10000 },
{ "seat_no": 3, "stack": 10000 },
{ "seat_no": 4, "stack": 10000 },
{ "seat_no": 5, "stack": 10000 }
],
"rake_ratio_pct": 3,
"rake_cap_bb": 3,
"actions": {
"entries": [
{ "action": "Ah7d2c" }
]
}
}
}Bombpot Output Example
{
"hands": [
{
"handName": "KQo",
"strategy": [0.34, 0.46, 0.0, 0.20, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
"reach": 1.0,
"ev": 2.15,
"actions": [
{ "actionName": "fold", "probability": 0.34, "ev": 0.0 },
{ "actionName": "call", "probability": 0.46, "ev": 1.7 },
{ "actionName": "bet5.0", "probability": 0.20, "ev": 3.9 }
],
"combos": [
{
"combo": "KhQc",
"reach": 1.0,
"actions": [
{ "actionName": "fold", "probability": 0.31, "ev": 0.0 },
{ "actionName": "call", "probability": 0.49, "ev": 1.8 },
{ "actionName": "bet5.0", "probability": 0.20, "ev": 4.0 }
]
}
]
}
],
"currentPlayer": 0,
"numBoardCards": 3,
"pendingDeal": "",
"tableState": {
"street": "flop",
"pot": 3150,
"chipsPerBb": 100,
"board": ["Ah", "7d", "2c"],
"actingPlayer": 0
},
"actionHistory": [
{ "isDeal": true, "label": "Flop: Ah 7d 2c" }
],
"modelMd5": "example-md5",
"computeTimeMs": 16,
"inferenceTimeMs": 7
}MTT
MTT is selected by a top-level mtt object with tournament data. Use
hand.game_type: "nlhe" and hand.game_mode_code: "normal" for regular MTT.
Use hand.game_type: "shortdeck" with the same mtt object for Short Deck
MTT.
MTT Input Fields
| Field | Type | Notes |
|---|---|---|
hand.game_type | string | "nlhe" or "shortdeck". |
hand.game_mode_code | string | Usually "normal". |
mtt.total_entries | integer | Total tournament entries, including rebuys. |
mtt.total_alive_players | integer | Players still alive. Defaults to total_entries if omitted. |
mtt.prize_pool | number | Total prize pool in dollars. |
mtt.initial_chips | number | Starting stack in chips. |
mtt.payout_structure_limit_top10[] | array | Top payout entries: { "position": 1, "prize_value": 2500 }. Legacy alias payout_structure is accepted and truncated to top 10. |
mtt.current_table_players_mttinfo[] | array | Per-seat tournament info: seat_no, stack, rank, optional head_bounty. Legacy alias players is accepted. |
mtt.bounty_structure | object | Required for bounty formats; use { "bounty_type": "normal" } for no bounty. |
mtt.prize_fee | number | Optional prize component of buy-in. |
mtt.bounty_fee | number | Optional bounty component of buy-in. |
mtt.registration_fee | number | Optional total buy-in. |
mtt.current_level | integer | Optional current tournament level. |
mtt.current_blind_level | integer | Optional blind level id. |
mtt.blind_structure[] | array | Optional levels with level, ante, small_blind, and big_blind. |
bounty_structure.bounty_type can be "normal",
"progressive_bounty_pko", "normal_knockout_ko", "mystery_bounty", or
"spin".
MTT Request Example
{
"protocol_ver": "v2",
"strategy_min_threshold": 0.05,
"hand": {
"game_type": "nlhe",
"game_mode_code": "normal",
"big_blind": 1000,
"small_blind": 500,
"ante": 100,
"dealer_seat": 5,
"sb_seat": 0,
"bb_seat": 1,
"straddle_seat": -1,
"players": [
{ "seat_no": 0, "stack": 42000 },
{ "seat_no": 1, "stack": 38000 },
{ "seat_no": 2, "stack": 61000 },
{ "seat_no": 3, "stack": 27000 },
{ "seat_no": 4, "stack": 51000 },
{ "seat_no": 5, "stack": 33000 }
],
"rake_ratio_pct": 0,
"rake_cap_bb": 0,
"actions": {
"entries": [
{ "seat_no": 2, "action": "raise", "amount": 2400, "raise_to": 2500 },
{ "seat_no": 3, "action": "fold" },
{ "seat_no": 4, "action": "call" }
]
}
},
"mtt": {
"total_entries": 100,
"total_alive_players": 54,
"prize_pool": 9000,
"initial_chips": 30000,
"payout_structure_limit_top10": [
{ "position": 1, "prize_value": 2500 },
{ "position": 2, "prize_value": 1600 },
{ "position": 3, "prize_value": 1100 },
{ "position": 4, "prize_value": 800 },
{ "position": 5, "prize_value": 600 }
],
"bounty_structure": {
"bounty_type": "normal",
"initial_bounty": 0,
"bounty_proportion": 0
},
"current_table_players_mttinfo": [
{ "seat_no": 0, "stack": 42000, "rank": 18 },
{ "seat_no": 1, "stack": 38000, "rank": 24 },
{ "seat_no": 2, "stack": 61000, "rank": 8 },
{ "seat_no": 3, "stack": 27000, "rank": 39 },
{ "seat_no": 4, "stack": 51000, "rank": 12 },
{ "seat_no": 5, "stack": 33000, "rank": 31 }
],
"prize_fee": 90,
"bounty_fee": 0,
"registration_fee": 100,
"current_level": 10,
"current_blind_level": 10,
"blind_structure": [
{ "level": 10, "ante": 100, "small_blind": 500, "big_blind": 1000 }
]
}
}MTT Output Example
{
"hands": [
{
"handName": "AQs",
"strategy": [0.22, 0.48, 0.0, 0.30, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
"reach": 0.77,
"ev": 6.4,
"actions": [
{ "actionName": "fold", "probability": 0.22, "ev": 0.0 },
{ "actionName": "call", "probability": 0.48, "ev": 5.8 },
{ "actionName": "raise7.5", "probability": 0.30, "ev": 7.9 }
],
"combos": [
{
"combo": "AsQs",
"reach": 0.8,
"actions": [
{ "actionName": "fold", "probability": 0.18, "ev": 0.0 },
{ "actionName": "call", "probability": 0.52, "ev": 5.7 },
{ "actionName": "raise7.5", "probability": 0.30, "ev": 8.1 }
]
}
]
}
],
"tableState": {
"street": "preflop",
"pot": 9500,
"chipsPerBb": 1000,
"board": [],
"actingPlayer": 5,
"icmEquityBb": [38.2, 34.7, 55.1, 24.3, 46.5, 30.2],
"bountyBb": []
},
"actionLabels": [
{ "index": 0, "slot": 0, "name": "fold", "rawAction": -1, "amount": null, "amountBb": 0.0, "raiseByBb": 0.0 },
{ "index": 1, "slot": 1, "name": "call 2.5 BB", "rawAction": 0, "amount": 2500, "amountBb": 2.5, "raiseByBb": 0.0 },
{ "index": 2, "slot": 3, "name": "raise 7.5 BB", "rawAction": 7500, "amount": 7500, "amountBb": 7.5, "raiseByBb": 5.0 }
],
"currentPlayer": 5,
"numBoardCards": 0,
"pendingDeal": "",
"model": "example-model.onnx",
"computeTimeMs": 20,
"inferenceTimeMs": 9
}PLO
PLO uses the PLO-specific bucket taxonomy pipeline, not the Holdem hands[]
grid. Select it with hand.game_type: "plo4", "plo5", or "plo6".
Do not expect the v2 Holdem hands[] array to contain strategy data for PLO.
PLO strategy is returned in ploStrategy, keyed by concrete PLO combo string.
PLO Input Fields
| Field | Type | Notes |
|---|---|---|
hand.game_type | string | "plo4", "plo5", or "plo6". Controls hole-card count. |
hand.game_mode_code | string | Usually "normal". |
hand.players[] | array | Omit hole_cards; the grid enumerates/samples PLO combos. |
hand.actions.entries[] | array | Same action/deal format. For normal PLO, only add board cards after a valid completed preflop sequence. |
postProcess.ploSampling.perGroup | integer | Current JSON route reads camelCase postProcess.ploSampling; default is 100. |
postProcess.ploSampling.groupParentId | string | Optional taxonomy parent to sample within. |
postProcess.ploSampling.fullId | string | Optional taxonomy group id to return in full, paged. |
postProcess.ploSampling.fullOffset | integer | Optional page offset for fullId; page size is capped internally. |
reach_query.target_seat_no | integer | Optional. Seat whose replayed range reach should be reported. Defaults to current player. |
reach_query.normalize | string | Optional. "conditional" or "absolute". |
reach_query.group_by | string | Optional. "bucket" or "combo"; current response builder returns bucketed data. |
reach_query.max_buckets | integer | Optional cap on returned reach buckets. |
reach_query.max_examples_per_bucket | integer | Optional cap on example combos per bucket. |
The proto schema names post-processing as post_process.plo_sampling, but the
current /strategy_grid PLO route reads the UI JSON spelling
postProcess.ploSampling. Use the camelCase spelling for PLO sampling on this
endpoint.
PLO Output Fields
| Field | Type | Notes |
|---|---|---|
taxonomyOnly | boolean | Present because the response includes taxonomy data. Check ploStrategy to see strategy results. |
ploBucketTree[] | array | Hierarchical taxonomy buckets. |
ploBucketMap | object | Concrete combo string to bucket id. |
ploMultiplicity | object | Combo string to suit-isomorphic multiplicity/weight. Sampling may scale this value. |
ploBucketCounts | object | True combo count per leaf bucket when sampling is used. |
sampledMode | boolean | Present when sampling was applied. |
fullTotalCount | integer | Present when fullId full-mode paging is used. |
holeCardCount | integer | 4, 5, or 6. |
hands[] | array | Empty for PLO; do not consume this for PLO strategy. |
ploStrategy | object | Strategy keyed by combo string. Each value has strategy, evs, ev, and optional reach. |
ploReach | object | Combo-level reach map when reach computation runs. |
reachResult | object | Bucketed reach summary when reach_query is sent. |
actionLabels[] | array | Legal action labels for interpreting the 11 strategy slots. |
tableState | object | Pot, board, acting player, players, and acting context. |
pendingDeal | string | "", "flop", "turn", or "river" when board cards are required. |
currentPlayer | integer | Acting seat, or -1 if terminal/pending. |
numBoardCards | integer | Count of board cards in the request/session. |
model | string | Selected PLO model. |
modelMd5 | string | Selected model checksum. |
computeTimeMs | integer | Total service-side compute time. |
PLO Request Example
{
"protocol_ver": "v2",
"strategy_min_threshold": 0.05,
"hand": {
"game_type": "plo4",
"game_mode_code": "normal",
"big_blind": 100,
"small_blind": 50,
"ante": 0,
"dealer_seat": 5,
"sb_seat": 0,
"bb_seat": 1,
"straddle_seat": -1,
"players": [
{ "seat_no": 0, "stack": 10000 },
{ "seat_no": 1, "stack": 10000 },
{ "seat_no": 2, "stack": 10000 },
{ "seat_no": 3, "stack": 10000 },
{ "seat_no": 4, "stack": 10000 },
{ "seat_no": 5, "stack": 10000 }
],
"rake_ratio_pct": 3,
"rake_cap_bb": 3,
"actions": { "entries": [] }
},
"postProcess": {
"ploSampling": {
"perGroup": 100
}
},
"reach_query": {
"target_seat_no": 2,
"normalize": "conditional",
"group_by": "bucket",
"max_buckets": 10,
"max_examples_per_bucket": 3
}
}PLO Output Example
{
"taxonomyOnly": true,
"holeCardCount": 4,
"sampledMode": true,
"ploBucketTree": [
{
"id": "made_hand",
"label": "Made hand",
"children": [
{ "id": "one_pair", "label": "One pair", "children": [] }
]
}
],
"ploBucketMap": {
"AsAhKdQc": "one_pair"
},
"ploMultiplicity": {
"AsAhKdQc": 124.0
},
"ploBucketCounts": {
"one_pair": 8420
},
"hands": [],
"ploStrategy": {
"AsAhKdQc": {
"strategy": [0.0, 0.42, 0.0, 0.58, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
"evs": [-1.0, 2.4, 0.0, 3.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
"ev": 2.806,
"reach": 1.0
}
},
"ploReach": {
"AsAhKdQc": 1.0
},
"reachResult": {
"normalization": "conditional",
"range_buckets": [
{
"bucket": "one_pair",
"mass": 1.0,
"examples": [
{ "hand": "AsAhKdQc", "reach_prob": 1.0, "multiplicity": 124.0 }
]
}
],
"covered_mass": 1.0
},
"actionLabels": [
{ "index": 0, "slot": 0, "name": "fold", "rawAction": -1, "amount": null, "amountBb": 0.0, "raiseByBb": 0.0 },
{ "index": 1, "slot": 1, "name": "call 1.0 BB", "rawAction": 0, "amount": 100, "amountBb": 1.0, "raiseByBb": 0.0 },
{ "index": 2, "slot": 3, "name": "raise 3.0 BB", "rawAction": 300, "amount": 300, "amountBb": 3.0, "raiseByBb": 2.0 }
],
"tableState": {
"street": "preflop",
"pot": 150,
"chipsPerBb": 100,
"board": [],
"actingPlayer": 2
},
"currentPlayer": 2,
"numBoardCards": 0,
"pendingDeal": "",
"model": "example-plo-model.onnx",
"modelMd5": "example-md5",
"computeTimeMs": 32
}