Short Deck Strategy Endpoint
This page documents how to query the strategy API for Short Deck (6+ Hold'em) through the POST /lookup endpoint. It is self-contained: it covers every request and response field, with a full request and response example.
Endpoint
Endpoint: POST /lookup
All requests require an authorization token in the Authorization header:
curl --location '<glue-URL>/lookup' \
--header 'Content-Type: application/json' \
--header 'Authorization: <Auth-TOKEN>' \
--data '{ ... }'The actual <glue-URL> for your environment (dev / stg / prod) and the <Auth-TOKEN> are provided separately.
Possible HTTP error statuses: 400 (bad request), 401 (missing Authorization header), 403 (invalid token), 422 (validation error), 502 (upstream error). Note that some engine-level failures are reported inside an HTTP 200 body via the error / error_code response fields — clients should always check them (see Response Fields).
Game Rules
Short Deck rules the engine plays by:
- 36-card deck — ranks 2, 3, 4 and 5 are removed; requests containing them (hole or board) are invalid.
- Modified hand ranking — flush beats full house.
- 2 to 6 players.
- Ante = 1 big blind, always — the engine forces this regardless of the request value, so send
anteequal tobig_blindfor consistency. - Blind structures: regular SB/BB layouts are supported, as well as the common button-blind structure (single blind posted by the button plus antes from everyone) — for the latter send
sb_seat: -1,bb_seat: -1and the button indealer_seat.
The variant is selected with hand.game_type: "shortdeck" (lowercase, one word — this is the only accepted spelling). hand.game_mode_code is "normal".
Card Notation
Cards use the same two-character notation as NLHE: uppercase rank (A K Q J T 9 8 7 6) followed by lowercase suit (c d h s). A hand is the concatenation of its cards with no separators — the hero's hole_cards is always 2 cards / 4 characters, e.g. "Jc9s". Board cards are sent as entries of the action list (see the Action object below), also concatenated: "9h8cAh" for the flop, "Kc" for a turn or river.
A hole-card string that is not exactly 2 cards is rejected with error E106. Only the hero — the player the strategy is requested for — carries hole_cards; every other player must omit the field.
Request Format
{
"request_id": "unique-request-id",
"hand": { <Hand-object> },
"protocol_ver": "v2"
}Request Fields
Top Level
| Field | Type | Required | Description |
|---|---|---|---|
request_id | string | No | Caller-chosen identifier, echoed back inside the response's request echo. Use it to correlate requests; use hand.gameuuid to track whole hands (a hand spans multiple requests). |
hand | Hand-object | Yes | The full game state — players, blinds, seats and the action history. See the Hand object below. |
protocol_ver | string | Yes | Protocol version. Use "v2" for Short Deck. |
Hand Object
"hand": {
"gameuuid": "<hand-unique-identifier>",
"game_type": "shortdeck",
"game_mode_code": "normal",
"players": [ <Player-object> ],
"actions": { "entries": [ <Action-object> ] },
"big_blind": <big-blind-size>,
"small_blind": <small-blind-size>,
"ante": <same-value-as-big-blind>,
"dealer_seat": <dealer-player-seat>,
"sb_seat": <small-blind-player-seat-or-minus-1>,
"bb_seat": <big-blind-player-seat-or-minus-1>,
"straddle_seat": <straddle-seat-or-minus-1>
}| Field | Type | Required | Description |
|---|---|---|---|
gameuuid | string | Yes | Unique hand identifier for tracking. Any value is accepted. |
game_type | string | Yes | Must be "shortdeck". |
game_mode_code | string | Yes | Always "normal" for Short Deck. |
players | Player-objects | Yes | List of player objects — see below. |
actions | Action-objects | Yes | Chronological list of everything that happened in the hand so far, including board cards — see below. |
big_blind | integer | Yes | Big blind value in actual chips. |
small_blind | integer | No | Small blind in chips. When absent it is derived from the big blind. |
ante | integer | Yes | Ante per player in chips. The engine always plays Short Deck with ante = 1 big blind — send ante equal to big_blind. |
dealer_seat | integer | Yes | Dealer (button) seat. |
sb_seat | integer | Yes | Small blind seat. For a button-blind structure (no positional blinds): send -1. |
bb_seat | integer | Yes | Big blind seat. Same -1 convention as sb_seat. |
straddle_seat | integer | Yes | Straddle seat for 3-blind games; -1 when there is no straddle. |
rake_ratio_pct | double | No | Rake percentage. Explicit 0 means rake-free; absent applies the server default. |
rake_cap_bb | double | No | Rake cap in big blinds. Explicit 0 means uncapped. |
roomid | string | No | Caller room/table identifier, passed through. |
Player Object
"players": [
{
"seat_no": <player-seat-number>,
"stack": <chip-amount>,
"hole_cards": "<two-cards-or-field-removed>"
}
]| Field | Type | Required | Description |
|---|---|---|---|
seat_no | integer | Yes | The player's seat number. Must match the seat indexes used in the hand fields (sb_seat, bb_seat, dealer_seat, straddle_seat) and in action entries. |
stack | integer | Yes | The player's chip count at the start of the hand, before blinds and antes. |
hole_cards | string | Yes (hero only) | The hero's 2 hole cards in card notation, ranks 6 and above only (e.g. "Jc9s"). Exactly one player must carry this field; remove it for all other players. |
uid | string | No | Caller player identifier, passed through. |
Action Object
"actions": {
"entries": [
{ "action": "call", "seat_no": 1 },
{ "action": "check", "seat_no": 3 },
{ "action": "9h8cAh" },
{ "action": "raise", "amount": 198, "seat_no": 1 }
]
}entries is a single flat chronological list mixing player actions and board deals:
| Field | Type | Required | Description |
|---|---|---|---|
action | string | Yes | Either an action verb — fold, check, call, bet, raise, allin — or, for a board deal, the dealt cards concatenated (e.g. "9h8cAh" for the flop, "Kc" for turn/river). Board cards must also respect the 36-card deck. |
seat_no | integer | Yes for player actions | Seat of the acting player. Removed on board-deal entries — that is how the two entry kinds are distinguished. |
amount | integer | For bet/raise/allin | Chips added by the player in this action on the current street. |
The street is implied by the position of the board-deal entries — there is no explicit street field. An empty list ("entries": []) means it is preflop and the first player is to act. Blinds, antes and straddles are not listed as entries; they are derived from the hand fields.
Response Format
The response has exactly the same shape for Short Deck as for NLHE:
{
"request": { <echo-of-the-request> },
"strategy": {
"actions": [ <StrategyAction> ],
"decision_action_seq": { <ActionList> },
"suggested_action": { <ActionDetails> }
},
"supportScore": <0-to-1>,
"solution_information": { <Solution-information-object> },
"strategy_profile": null,
"warnings": [],
"flags": []
}Response Fields
Top Level
| Field | Type | Description |
|---|---|---|
request | object | Echo of the request. |
strategy | Strategy-object | The strategy solution at the decision point. |
supportScore | double | Model confidence that it covers this spot, 0 to 1. 0.5 is the neutral default. |
solution_information | object | Diagnostics, including situation_key — how the engine classified the spot (game_type, street, flop, players_bin, bb_depth). |
strategy_profile | object | null — strategy profiles are not applied to Short Deck. |
warnings | string[] | Human-readable warnings. |
flags | string[] | Machine-readable processing flags. |
error / error_code | string | Present on engine soft failures even with HTTP 200 — e.g. "error_code": "E500" with an explanatory error text. Always check these before consuming strategy. |
Strategy Object
| Field | Type | Description |
|---|---|---|
actions | StrategyAction[] | All candidate actions for the hero with their probabilities and EVs. |
decision_action_seq | Action-objects | The action line of the decision point (echo of the request's entries, normalized). |
suggested_action | ActionDetails | The single action the engine recommends taking — the sampled/most likely action of the strategy. |
Strategy Action Object
| Field | Type | Description |
|---|---|---|
action | ActionDetails | The concrete action: action verb (fold, check, call, bet, raise, allin), amount — the raise-to / bet chip amount (null for fold/check/call), pot_size — the bet as a ratio of the pot if called, and seat_no of the hero. |
action_name | string | Compact action code: f, c, x, b<pct>, r<pct>, allin<pct> where the number is the pot percentage — "b75" is a bet of 75% pot, "allin150" an all-in at 150% pot. |
action_seq | Action-objects | The full action line ending in this candidate action (the request's entries plus this action appended). |
hand_strategy | float | Probability the strategy assigns to this action for the hero hand, 0 to 1. |
hand_ev | float | Expected value of taking this action, in big blinds. |
Request Example
4-handed Short Deck cash game, 100-chip big blind, 100-chip ante. Preflop went limped (SB folded, BB and BTN saw the flop). On the 9h8cAh flop the hero (seat 1, big blind, holding Jc9s) bet and got called. The turn Kc just came — the hero is first to act:
curl --location '<glue-URL>/lookup' \
--header 'Content-Type: application/json' \
--header 'Authorization: <Auth-TOKEN>' \
--data '{
"request_id": "shortdeck-turn-demo",
"hand": {
"gameuuid": "shortdeck_4p_game",
"game_type": "shortdeck",
"game_mode_code": "normal",
"players": [
{ "seat_no": 0, "stack": 2000 },
{ "seat_no": 1, "stack": 4800, "hole_cards": "Jc9s" },
{ "seat_no": 2, "stack": 2600 },
{ "seat_no": 3, "stack": 7600 }
],
"big_blind": 100,
"ante": 100,
"dealer_seat": 3,
"sb_seat": 0,
"bb_seat": 1,
"straddle_seat": -1,
"actions": {
"entries": [
{ "action": "fold", "seat_no": 0 },
{ "action": "call", "seat_no": 1 },
{ "action": "fold", "seat_no": 2 },
{ "action": "check", "seat_no": 3 },
{ "action": "9h8cAh" },
{ "action": "raise", "amount": 198, "seat_no": 1 },
{ "action": "call", "seat_no": 3 },
{ "action": "Kc" }
]
}
},
"protocol_ver": "v2"
}'Reading the request: the hero is the only player with hole_cards ("Jc9s" — two cards, both rank 6+). The action entries tell the whole story in order — four preflop actions, the flop deal "9h8cAh" (an entry with no seat_no), the flop bet and call, then the turn card "Kc". Nothing after the last board card means the hero is next to act. The ante equals the big_blind, per the Short Deck rule.
Response Example
{
"request": { ... },
"strategy": {
"actions": [
{
"action": { "action": "fold", "amount": null, "pot_size": null, "seat_no": 1 },
"action_name": "f",
"action_seq": { ... },
"hand_strategy": 0.0,
"hand_ev": -3.9800000190734863
},
{
"action": { "action": "check", "amount": null, "pot_size": null, "seat_no": 1 },
"action_name": "x",
"action_seq": {
"entries": [
{ "action": "fold", "seat_no": 0 },
{ "action": "call", "seat_no": 1 },
{ "action": "fold", "seat_no": 2 },
{ "action": "check", "seat_no": 3 },
{ "action": "9h8cAh" },
{ "action": "raise", "amount": 198, "seat_no": 1 },
{ "action": "call", "seat_no": 3 },
{ "action": "Kc" },
{ "action": "check", "seat_no": 1 }
]
},
"hand_strategy": 0.8718456242506326,
"hand_ev": 7.172830581665039
},
{
"action": { "action": "bet", "amount": 350, "pot_size": 0.35140562057495117, "seat_no": 1 },
"action_name": "b35",
"action_seq": { ... },
"hand_strategy": 0.0009188470164877678,
"hand_ev": 7.172830581665039
},
{
"action": { "action": "bet", "amount": 500, "pot_size": 0.5020080208778381, "seat_no": 1 },
"action_name": "b50",
"action_seq": { ... },
"hand_strategy": 0.00640601162634791,
"hand_ev": 7.172830581665039
},
{
"action": { "action": "bet", "amount": 750, "pot_size": 0.7530120611190795, "seat_no": 1 },
"action_name": "b75",
"action_seq": { ... },
"hand_strategy": 0.05969334610453702,
"hand_ev": 7.172830581665039
},
{
"action": { "action": "bet", "amount": 1000, "pot_size": 1.0040160417556765, "seat_no": 1 },
"action_name": "b100",
"action_seq": { ... },
"hand_strategy": 0.060299268394497625,
"hand_ev": 7.172830581665039
},
{
"action": { "action": "bet", "amount": 1500, "pot_size": 1.5060241222381592, "seat_no": 1 },
"action_name": "b151",
"action_seq": { ... },
"hand_strategy": 0.0008369026074969687,
"hand_ev": 7.172830581665039
}
],
"decision_action_seq": { "entries": [ ...same-entries-as-the-request... ] },
"suggested_action": {
"action": "check",
"amount": null,
"pot_size": null,
"seat_no": 1
}
},
"supportScore": 0.6659996509552002,
"solution_information": {
"situation_key": {
"game_type": "shortdeck",
"street": "turn",
"flop": "9h8cAh",
"players_bin": "4",
"bb_depth": 50.0
}
},
"strategy_profile": null,
"warnings": [],
"flags": []
}({ ... } marks elided parts: the full request echo, the repeated action_seq objects, and the diagnostic members of solution_information.)
How to read it: the suggested_action is a check. The strategy.actions array explains why — checking carries 87.2% of the probability mass (hand_strategy: 0.8718), with the rest split mainly between a 75%-pot bet of 750 chips ("b75", 6.0%) and a pot-sized bet of 1000 chips ("b100", 6.0%); the remaining sizes carry negligible probability. Folding has probability 0 and a clearly negative EV of −3.98 bb, while the played actions share the spot EV of +7.17 bb. solution_information.situation_key confirms how the engine classified the spot: game_type: "shortdeck", turn, 4 players, 50 bb deep.
Limitations
- 2 to 6 players.
- Ante is forced to 1 big blind by the engine regardless of the request value.
- Cards 2–5 are invalid (36-card deck) — in hole cards and on the board.
- Hero
hole_cardsmust be exactly 2 cards; mismatches fail withE106. - Short Deck is served as a cash game only —
game_mode_codeis always"normal". - Soft failures can arrive with HTTP 200 — check
error/error_codein the response body. - Use
protocol_ver: "v2"for Short Deck requests.