{"openapi":"3.0.3","info":{"title":"API pokerai.bet (stratégie GTO + moteur de poker)","version":"1.0","description":"API de stratégie GTO pour le préflop / flop / turn / river. Renvoie la fréquence mixte de chaque action (aucune action recommandée — choisissez selon la fréquence). Le préflop et le flop utilisent une bibliothèque de solutions GTO pré-calculées, servies instantanément (en quelques millisecondes). L’endpoint du solveur effectue le calcul en temps réel (flop ~70s, turn/river plus rapides). Les cartes et le board sont fournis sous forme de chaîne sans séparateur (\"2c2h2s\", \"AdKd\") ; le board est renvoyé sous forme de tableau ([\"2c\",\"2h\",\"2s\"]). Les ranges sont des chaînes `hand:weight` séparées par des virgules (notation de classe AA/AKs/AKo ; weight de 0 à 1, valeur par défaut : 1).\n\n⚠ Remarque : le bouton « Tester la requête » ci-dessous envoie une véritable requête avec votre clé et consomme votre quota mensuel réel. Vous débutez ? Consultez d’abord le guide : https://pokerai.bet/docs\n"},"servers":[{"url":"https://pokerai.bet"}],"security":[{"BearerApiKey":[]},{"XApiKey":[]}],"tags":[{"name":"Consultation","description":"Solutions GTO pré-calculées, servies instantanément (en quelques millisecondes) — préflop + arbre de décision complet du flop. Chacune consomme 1 unité de quota pré-calculé."},{"name":"Solveur","description":"Solveur en temps réel (flop ~70s, turn/river plus rapides). planification -> arbre -> nœud."},{"name":"Éventail de mains","description":"Mettre à jour les ranges le long d’une ligne d’actions (conversion de range / range projetée au flop)."}],"paths":{"/v1/gto/preflop":{"post":{"tags":["Consultation"],"operationId":"preflopStrategy","summary":"Stratégie préflop (pré-calculée)","description":"Consomme 1 unité de quota pré-calculé. La situation (RFI/Limp/Raise/3-Bet/4-Bet/5-Bet) est déduite des 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":["Consultation"],"operationId":"preflopRange","summary":"Range préflop complète pour une situation (pré-calculée)","description":"La range préflop complète de 13×13 pour une position + une ligne d’actions en un seul appel — 169 types de mains →\nfréquences de fold/call/raise. Pas de `hole_cards` (la situation est déterminée par positions +\npreflop_actions). Consomme 1 unité de quota pré-calculé (un appel, pas 169). Destiné à une grille de ranges.\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":"facultatif ; ensemble de tableaux préflop 6max à utiliser (identique à /v1/gto/preflop). Omettez-le pour utiliser la valeur par défaut."},"positions":{"type":"object","properties":{"hero":{"type":"string","example":"BTN"}}},"preflop_actions":{"type":"array","items":{"type":"object"},"description":"séquence d’actions complète depuis SB/BB, identique à /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":"type de main (AA / AKs / AKo) -> {fold, call, raise} ; 169 entrées, chacune totalisant environ 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":["Consultation"],"operationId":"preflopVersions","summary":"Répertorier les versions de stratégie préflop installées (gratuit)","description":"Valeurs de preflop_version disponibles pour /v1/gto/preflop et /v1/gto/preflop/range, avec un libellé lisible pour chacune et l’indication de la valeur par défaut (utilisée lorsque preflop_version est omis). Gratuit (aucun quota). Utilisez ceci au lieu de coder la liste en dur — les nouvelles versions apparaissent ici automatiquement.\n","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"versions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"transmettez cette valeur comme preflop_version"},"label":{"type":"string"},"default":{"type":"boolean","description":"présent et défini sur true pour la version par défaut"}}}},"default":{"type":"string","description":"l’id utilisé lorsque preflop_version est omis"}}},"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":["Consultation"],"operationId":"flopTree","summary":"Arbre de décision du flop (pré-calculé)","description":"Consomme 1 unité de quota pré-calculé. Renvoie les ranges initiales + tous les nœuds de décision (chacun avec un token pour /v1/gto/flop/node).","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FlopTreeRequest"},"examples":{"SRP":{"summary":"Pot relancé une fois — positions : hero, raiser, caller","value":{"board":"2c2h2s","pot_type":"SRP","positions":{"hero":"UTG","raiser":"UTG","caller":"BTN"}}},"3BET":{"summary":"Pot 3-bet — positions : hero, raiser (ouvreur), three_bettor","value":{"board":"2c2h2s","pot_type":"3BET","positions":{"hero":"CO","raiser":"CO","three_bettor":"BTN"}}},"4BET":{"summary":"Pot 4-bet — positions : hero, raiser (ouvreur ayant effectué le 4-bet), three_bettor (joueur ayant effectué le 3-bet puis suivi)","value":{"board":"2c2h2s","pot_type":"4BET","positions":{"hero":"CO","raiser":"CO","three_bettor":"BTN"}}},"LIMP":{"summary":"Pot limpé — positions : hero, limper (hero ou limper doit être 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":["Consultation"],"operationId":"flopNode","summary":"Stratégie d’un nœud du flop (pré-calculée) — un nœud de l’arbre de décision","description":"Stratégie par nœud pour l’arbre de décision du flop (gratuite, accès par token). Transmettez un token `node` émis par POST /v1/gto/flop/tree. Avec hole_cards → stratégie mixte de cette main au nœud ; sans hole_cards → stratégie de toute la range au nœud.\n\nVoici comment obtenir CHAQUE décision de hero au flop — hero en position, confronté à une mise ou lors d’une action ultérieure : récupérez l’arbre, choisissez un nœud où is_hero vaut true (par ex. root/CHECK/BET_13 = hero fait face à une mise après avoir checké → fold/call/raise), puis transmettez son token ici. Le nœud racine (root) correspond à la première décision de hero (check/bet OOP).\n\nL’arbre du flop ne couvre qu’un seul tour d’enchères ; pour les décisions au turn/river, utilisez le flux du solveur (/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":["Solveur"],"operationId":"solverSchedule","summary":"Planifier un calcul en temps réel (flop/turn/river)","description":"la longueur du board détermine la street (3=flop, 4=turn, 5=river). Consomme 1 unité de quota de calcul lors d’un nouveau déclenchement ; un calcul en cache renvoie status=queryable sans champ solve_quota (aucune facturation) ; si tous les hôtes du solveur sont occupés, la réponse est 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":"quota de calcul dépassé, ou tous les hôtes du solveur sont occupés (status=busy)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/gto/solver/tree":{"post":{"tags":["Solveur"],"operationId":"solverTree","summary":"Interroger l’arbre de calcul + l’état du nœud (gratuit)","description":"Interrogez jusqu’à ce que spot_status = queryable. Pour faire avancer un calcul multi-street jusqu’au runout distribué, transmettez\nles cartes distribuées : `turn_card` (par ex. un calcul au flop → un turn précis), et/ou `river_card`.\nUne situation à la river issue d’un calcul au *flop* nécessite À LA FOIS `turn_card` et `river_card` pour être unique ;\nun calcul au turn nécessite uniquement `river_card`. Omettez les deux pour obtenir la street propre au calcul.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["solve"],"properties":{"solve":{"type":"string","description":"identifiant provenant de /v1/gto/solver"},"turn_card":{"type":"string","description":"facultatif ; pour un calcul au flop, carte distribuée au turn (par ex. \"Td\") — renvoie les nœuds sous ce turn."},"river_card":{"type":"string","description":"facultatif ; carte distribuée à la river (par ex. \"Qh\"). Pour un calcul au flop, associez-la à turn_card afin de lever l’ambiguïté."}}},"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":["Solveur"],"operationId":"solverNode","summary":"Stratégie d’un nœud issue d’un calcul (gratuit)","description":"nœud de hero → stratégie de hero ; nœud de l’adversaire (ou hole_cards omis) → stratégie de toute la range.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["node"],"properties":{"node":{"type":"string","description":"token de nœud provenant de /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 = calcul récupéré/remplacé, à replanifier ; error = strategy_error du solveur pour le nœud (avec message) ; computing = calcul toujours en cours."},"message":{"type":"string","description":"présent lorsque node_status = error"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"503":{"$ref":"#/components/responses/UpstreamUnavailable"}}}},"/v1/gto/solver/release":{"post":{"tags":["Solveur"],"operationId":"solverRelease","summary":"Libérer plus tôt le port du pool d’un calcul (gratuit, facultatif)","description":"Indiquez que vous avez terminé d’interroger ce calcul afin que son port de solveur retourne immédiatement dans le pool\nau lieu de rester réservé pendant le TTL du cache (ce qui peut produire 429-busy à la requête suivante lorsque le pool est petit).\nFacultatif — si vous l’omettez, le TTL s’applique simplement. Appelez-le uniquement APRÈS votre dernière requête\n/v1/gto/solver/tree et /v1/gto/solver/node pour ce calcul : une fois libéré, le port peut être\nréutilisé et les requêtes ultérieures sur cet identifiant renvoient node_status = expired. Idempotent ; ne\nredémarre pas le solveur.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["solve"],"properties":{"solve":{"type":"string","description":"identifiant provenant de /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 si la réservation d’un port actif a été libérée ; false si le calcul avait déjà expiré (aucune opération)"}}},"example":{"released":true}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/v1/gto/range":{"post":{"tags":["Éventail de mains"],"operationId":"rangeConvert","summary":"Conversion de range — mettre à jour les ranges le long d’une ligne d’actions","description":"Proxy léger vers /api/range du solveur. Vous assemblez toutes les entrées, y compris solver_results (l’arbre de décision). Consomme 1 unité de quota pré-calculé. Les ranges produites alimentent le calcul de la street suivante.\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":["Éventail de mains"],"operationId":"projectedRange","summary":"Range projetée — mise à jour de la range au flop le long d’une ligne d’actions (quota pré-calculé)","description":"Projette les ranges du flop le long d’une ligne d’actions pour le board / pot_type / positions indiqué. Consomme 1 unité de quota pré-calculé. Renvoie le même résultat de mise à jour de range que /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":["Éventail de mains"],"operationId":"queryEvs","summary":"EV du nœud — espérances par main et par action d’un calcul terminé (gratuit)","description":"Espérances par main et par action à un nœud d’un calcul terminé. Fournissez l’identifiant du calcul (provenant de /v1/gto/solver) + un node_id (provenant de /v1/gto/solver/tree) ; le paramètre facultatif hand limite le résultat à une main. Gratuit (déjà facturé via /v1/gto/solver). Interrogez d’abord /v1/gto/solver/tree jusqu’à ce que le résultat soit queryable.\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":"EV du nœud ; ou { spot_status: computing } si le calcul n’a pas encore convergé.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"identifiant de calcul invalide ou ne vous appartenant pas"},"410":{"description":"calcul expiré (TTL) ; replanifiez-le via /v1/gto/solver"}}}},"/v1/gto/turn/projected-range":{"post":{"tags":["Éventail de mains"],"operationId":"turnProjectedRange","summary":"Range projetée — mise à jour turn→river le long d’une ligne d’actions au turn (gratuit)","description":"Équivalent turn→river de /v1/gto/flop/projected-range pour un calcul en temps réel au turn. Réduit les ranges à l’entrée du turn (celles avec lesquelles le calcul a été planifié, lues dans sa propre configuration) le long d’une ligne d’actions au turn — y compris le CALL/CHECK qui clôt la street — afin d’obtenir les ranges à l’entrée de la river. Gratuit (le calcul a déjà été facturé via /v1/gto/solver), comme /v1/gto/solver/tree. Renvoie le même résultat de mise à jour de range que /v1/gto/range. Interrogez d’abord /v1/gto/solver/tree jusqu’à spot_status = queryable.\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":"ranges réduites à l’entrée de la river ; ou { spot_status: computing } si le calcul n’a pas encore convergé (continuez à interroger /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":"calcul expiré (TTL) — replanifiez-le via /v1/gto/solver","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"$ref":"#/components/responses/Upstream"}}}},"/health":{"get":{"summary":"Santé","operationId":"health_health_get","responses":{"200":{"description":"Réponse réussie","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Réponse du contrôle de santé"}}}}}}},"/v1/pokerkit/texture":{"post":{"tags":["Sémantique"],"summary":"Synthèse de texture","operationId":"texture_v1_pokerkit_texture_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/nuts":{"post":{"tags":["Sémantique"],"summary":"Jeu max (nuts)","operationId":"nuts_v1_pokerkit_nuts_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/category-combos":{"post":{"tags":["Sémantique"],"summary":"Combinaisons par catégorie","operationId":"category_combos_v1_pokerkit_category_combos_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/board-report":{"post":{"tags":["Sémantique"],"summary":"Rapport du board","operationId":"board_report_v1_pokerkit_board_report_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/hand-tier":{"post":{"tags":["Sémantique"],"summary":"Niveau de la main","operationId":"hand_tier_v1_pokerkit_hand_tier_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/draws":{"post":{"tags":["Sémantique"],"summary":"Tirages","operationId":"draws_v1_pokerkit_draws_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/outs":{"post":{"tags":["Sémantique"],"summary":"Cartes améliorantes (outs)","operationId":"outs_v1_pokerkit_outs_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/blockers":{"post":{"tags":["Sémantique"],"summary":"Bloqueurs","operationId":"blockers_v1_pokerkit_blockers_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/hand-report":{"post":{"tags":["Sémantique"],"summary":"Rapport sur la main","operationId":"hand_report_v1_pokerkit_hand_report_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/range/expand":{"post":{"tags":["Éventails de mains"],"summary":"Développer une range","operationId":"range_expand_v1_pokerkit_range_expand_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/range/value":{"post":{"tags":["Éventails de mains"],"summary":"Valeur de la range","operationId":"range_value_v1_pokerkit_range_value_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/range/nut-advantage":{"post":{"tags":["Éventails de mains"],"summary":"Avantage de nuts de la range","operationId":"range_nut_advantage_v1_pokerkit_range_nut_advantage_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/cards/normalize":{"post":{"tags":["Cartes"],"summary":"Normaliser les cartes","operationId":"cards_normalize_v1_pokerkit_cards_normalize_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/eval/hand":{"post":{"tags":["Cœur"],"summary":"Évaluer une main","operationId":"eval_hand_v1_pokerkit_eval_hand_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/eval/compare":{"post":{"tags":["Cœur"],"summary":"Comparer les mains","operationId":"eval_compare_v1_pokerkit_eval_compare_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/equity":{"post":{"tags":["Cœur"],"summary":"Équité","operationId":"equity_v1_pokerkit_equity_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/hand-strength":{"post":{"tags":["Cœur"],"summary":"Force de la main","operationId":"hand_strength_v1_pokerkit_hand_strength_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/icm":{"post":{"tags":["Cœur"],"summary":"ICM","operationId":"icm_v1_pokerkit_icm_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/range/equity-advantage":{"post":{"tags":["Cœur"],"summary":"Avantage d’équité de la range","operationId":"range_equity_advantage_v1_pokerkit_range_equity_advantage_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/notation/parse":{"post":{"tags":["Cœur"],"summary":"Analyser la notation","operationId":"notation_parse_v1_pokerkit_notation_parse_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/games/state":{"post":{"tags":["Jeux"],"summary":"État de la partie","operationId":"games_state_v1_pokerkit_games_state_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/games/step":{"post":{"tags":["Jeux"],"summary":"Étape de la partie","operationId":"games_step_v1_pokerkit_games_step_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/notation/replay":{"post":{"tags":["Jeux"],"summary":"Rejouer une notation","operationId":"notation_replay_v1_pokerkit_notation_replay_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"type":"string","default":"","title":"Autorisation"}},{"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":"Réponse réussie","content":{"application/json":{"schema":{}}}},"422":{"description":"Erreur de validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/pokerkit/combined-openapi.json":{"get":{"tags":["Métadonnées"],"summary":"Spécification OpenAPI combinée","description":"Spécification GTO + spécification automatique de ce service fusionnées en un seul document (les paths sont distincts ;\nles schémas pokerkit ne sont préfixés qu’en cas de collision de noms). Reflète toujours le code actuel.","operationId":"combined_openapi_v1_pokerkit_combined_openapi_json_get","responses":{"200":{"description":"Réponse réussie","content":{"application/json":{"schema":{}}}}}}},"/v1/pokerkit/meta":{"get":{"tags":["Métadonnées"],"summary":"Métadonnées","operationId":"meta_v1_pokerkit_meta_get","responses":{"200":{"description":"Réponse réussie","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Réponse des métadonnées"}}}}}}}},"components":{"securitySchemes":{"BearerApiKey":{"type":"http","scheme":"bearer","description":"Authorization: Bearer gto_..."},"XApiKey":{"type":"apiKey","in":"header","name":"X-API-Key"}},"responses":{"BadRequest":{"description":"entrée invalide ou champ manquant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Unauthorized":{"description":"clé API manquante ou invalide","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NoSolution":{"description":"aucune donnée GTO pour cette situation/ce board","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"QuotaExceeded":{"description":"quota mensuel dépassé (réinitialisé le 1er du mois)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Upstream":{"description":"backend temporairement indisponible, réessayez","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"UpstreamUnavailable":{"description":"solveur inaccessible après les nouvelles tentatives du service (erreur de transport / 5xx) — nouvelle tentative possible ; error: upstream_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"Forbidden":{"description":"token invalide ou ne vous appartenant pas","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":"deux cartes, sans séparateur, par ex. \"AdKd\". Valeurs AKQJT98765432, couleurs c d h s.","pattern":"^[2-9TJQKA][cdhs][2-9TJQKA][cdhs]$","example":"AdKd"},"BoardInput":{"type":"string","description":"cartes communes sous forme de chaîne sans séparateur : 3=flop \"2c2h2s\", 4=turn, 5=river.","example":"2c2h2s"},"BoardOutput":{"type":"array","items":{"type":"string"},"description":"cartes communes renvoyées sous forme de tableau","example":["2c","2h","2s"]},"RangeString":{"type":"string","description":"hand:weight séparés par des virgules. Notation de classe AA/AKs/AKo (valeur la plus haute en premier) ; weight de 0 à 1, valeur par défaut : 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":"probabilité de 0 à 1"},"sizing_pot":{"type":"number","description":"taille relative au pot, convention standard en % du pot : une mise = bet ÷ pot ; une relance = (raise − amount-to-call) ÷ pot-after-call. Par ex. 0.5 / 0.8 / 1. Uniquement pour bet/raise"},"amount_bb":{"type":"number","description":"montant absolu de bet/raise en BB (pour bet/raise)"},"allin":{"type":"boolean","description":"présent et défini sur true lorsque l’action est 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":"facultatif ; ensemble de tableaux préflop 6max à utiliser. Omettez-le pour utiliser la valeur par défaut de la plateforme (6max). Valeur inconnue -> 400 unsupported_preflop_version."},"preflop_actions":{"type":"array","description":"Séquence d’actions explicite et complète depuis la petite blinde jusqu’au joueur précédant immédiatement hero (hero n’est PAS inclus ; sa position est positions.hero). Elle doit commencer par la petite blinde (0.5), puis la grosse blinde (1). amount est l’incrément nouvellement engagé par cette action en BB (et non le total cumulé) ; pot = somme de tous les amount. Le total résultant d’un raise doit dépasser la mise actuelle et respecter le min-raise (= mise actuelle + taille du dernier raise), sauf si allin:true ; le total d’un call doit être exactement égal à la mise actuelle, sauf si allin:true. Les montants exacts ne servent qu’à rendre pot/sizing_pot exacts — les fréquences GTO dépendent de la situation (RFI/3bet/4bet + positions) et ne changent pas avec les tailles de mise. Toute violation renvoie 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":"incrément nouvellement engagé par cette action en BB (obligatoire pour les actions autres que fold) ; omis/0 pour fold"},"allin":{"type":"boolean","description":"facultatif ; indique un all-in court (raise/call inférieur au min-raise). Lorsque la valeur est true, le contrôle du min-raise est ignoré"}}}}}},"PreflopResponse":{"type":"object","properties":{"hole_cards":{"type":"string"},"situation":{"type":"string","enum":["RFI","Limp","Raise","3-Bet","4-Bet","5-Bet"],"description":"état de la table auquel hero fait face : RFI (tous les joueurs ont fold jusqu’à hero, situation d’ouverture) / Limp (un limper est entré, aucune relance) / Raise (1 relance) / 3-Bet / 4-Bet / 5-Bet"},"strategy":{"type":"array","items":{"$ref":"#/components/schemas/StrategyItem"}},"quota":{"$ref":"#/components/schemas/Quota"}}},"FlopPositions":{"type":"object","description":"les clés obligatoires dépendent de pot_type — SRP: hero,raiser,caller ; 3BET/4BET: hero,raiser,three_bettor (pour 4BET, raiser = l’ouvreur ayant effectué le 4-bet, three_bettor = le joueur ayant effectué le 3-bet puis suivi ; aucune clé four_bettor) ; LIMP: hero,limper. hero doit correspondre à l’un des sièges nommés.","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":"token de nœud provenant de /v1/gto/flop/tree (champ `token` d’un nœud)"},"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":"facultatif ; jeu de données du flop à utiliser (un jeu résolu par version préflop). Omettez-le pour utiliser la valeur par défaut (6max). Si la version choisie ne contient aucune donnée pour la situation, le service revient proprement à 6max. Valeur inconnue -> 400 unsupported_flop_version. Indépendant de preflop_version. Les tokens de nœud transportent cette version ; /v1/gto/flop/node reste donc sur le même jeu de données."}}},"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":"le nœud de hero contient `strategy` ; le nœud de l’adversaire (ou sans hole_cards) contient `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 (par ex. \"AhKh\") -> fréquences alignées sur les 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":"tailles facultatives des mises d’ouverture par street, en % du pot ; 50 % par défaut au flop","properties":{"flop":{"type":"array","items":{"type":"integer"}},"turn":{"type":"array","items":{"type":"integer"}},"river":{"type":"array","items":{"type":"integer"}}}},"raise_sizes":{"type":"object","description":"tailles facultatives des relances par street, en % du pot ; les streets omises réutilisent bet_sizes/les valeurs par défaut","properties":{"flop":{"type":"array","items":{"type":"integer"}},"turn":{"type":"array","items":{"type":"integer"}},"river":{"type":"array","items":{"type":"integer"}}}},"donk_sizes":{"type":"object","description":"tailles facultatives des donk bets OOP en % du pot ; 67 % par défaut au turn et 100 % à la river","properties":{"turn":{"type":"array","items":{"type":"integer"}},"river":{"type":"array","items":{"type":"integer"}}}},"raise_limit":{"type":"integer","minimum":1,"maximum":4,"description":"limite facultative du nombre de relances dans tout l’arbre ; 3 par défaut pour les calculs flop/turn et 4 pour les calculs river uniquement"}}},"SolverScheduleResponse":{"type":"object","properties":{"status":{"type":"string","enum":["computing","queryable","busy"]},"solve":{"type":"string","description":"identifiant pour /tree et /node"},"solve_quota":{"allOf":[{"$ref":"#/components/schemas/Quota"}],"description":"présent uniquement lorsqu’un nouveau calcul a été déclenché (facturé)"}}},"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 = le calcul a convergé, mais le tour/runout interrogé ne contient aucun nœud de décision dans l’arbre (état terminal — arrêtez les interrogations)."},"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":"l’arbre de décision (que vous assemblez)"},"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":"blocage facultatif des cartes : indique quel joueur est Hero. À associer à hero_hand."},"hero_hand":{"type":"string","example":"AsKs","description":"blocage facultatif des cartes : retire des ranges tout combo contenant l’une des cartes de Hero (analyse range contre main). Renvoyé dans la réponse. S’applique uniquement à /v1/gto/range, pas aux wrappers de range projetée."}}},"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":"combos OOP par force de la main faite : 'combo:rank,...' (rank inférieur = main plus forte), triés par rank croissant. L’ordre de départage des rank égaux n’est PAS garanti stable entre les endpoints/exécutions — ne vous y fiez pas."},"hand_ranks_ip":{"type":"string","description":"équivalent IP de hand_ranks_oop."},"hand_bottom_ranks_oop":{"type":"string","description":"fraction bluff_combos_ratio la plus faible de hand_ranks_oop (candidats au bluff), au même format."},"hand_bottom_ranks_ip":{"type":"string","description":"équivalent IP de 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":"blocage facultatif des cartes, à associer à hero_hand."},"hero_hand":{"type":"string","example":"AsKs","description":"blocage facultatif des cartes : retire du range mis à jour de l’adversaire tout combo contenant l’une des cartes de Hero (sorties range_*_new_raw). La présence de la propre main de Hero dans son propre range est également garantie. Renvoyé dans la réponse."},"bluff_combos_ratio":{"type":"number","minimum":0,"maximum":1,"description":"facultatif ; fraction de la range traitée comme des bluffs (bas de range). Omettez-la pour utiliser la valeur turn/river par défaut du serveur. Renvoyée dans la réponse."},"partner_hands":{"type":"array","items":{"type":"string"},"example":["Ac9c"],"description":"facultatif ; combos de 4 caractères dont les cartes sont retirées du range mis à jour de l’adversaire (range_*_new_raw). Nécessite hero_position. Entrée uniquement (non renvoyée). Uniquement pour flop/projected-range."},"flop_version":{"type":"string","enum":["6max","6max_RC_100bb_200NL","6max_RC_100bb_100NL","6max_RC_40bb"],"description":"facultatif ; jeu de données du flop à utiliser (un jeu résolu par version préflop). Omettez-le pour utiliser la valeur par défaut (6max). Si la version choisie ne contient aucune donnée pour la situation, le service revient proprement à 6max. Valeur inconnue -> 400 unsupported_flop_version. Indépendant de preflop_version."}}},"ProjectedRangeResponse":{"description":"Mêmes champs que RangeResponse, avec en plus pot_type renvoyé depuis la requête (17 champs au 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":"identifiant provenant de /v1/gto/solver (un calcul au turn)"},"node_id":{"type":"string","description":"ligne d’actions au turn ; peut se terminer par le CALL/CHECK qui clôt la street. Format de nœud du solveur avec espaces, par ex. \"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":"blocage facultatif des cartes, à associer à hero_hand."},"hero_hand":{"type":"string","example":"AsKs","description":"blocage facultatif des cartes : retire du range mis à jour de l’adversaire tout combo contenant l’une des cartes de Hero."},"partner_hands":{"type":"array","items":{"type":"string"},"example":["Ac9c"],"description":"facultatif ; combos de 4 caractères dont les cartes sont retirées du range mis à jour de l’adversaire. Nécessite hero_position. Entrée uniquement."}}},"EvsRequest":{"type":"object","required":["solve","node_id"],"properties":{"solve":{"type":"string","description":"identifiant provenant de /v1/gto/solver"},"node_id":{"type":"string","example":"root","description":"nœud provenant de /v1/gto/solver/tree (notation du solveur, par ex. \"root/CHECK/BET 6.000000\")"},"hand":{"type":"string","example":"AsKh","description":"facultatif ; limite les EV à une seule main (sinon, toutes les mains)"}}},"EvsResponse":{"type":"object","description":"EV par main et par action au nœud ; le tableau d’EV de chaque main est aligné sur 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 -> tableau d’EV par action (bb) ; tableau unique lorsque hand est fourni","example":{"2c2d":[-0.826359,-0.792223,-1.643411]}}}},"BoardRequest":{"properties":{"board":{"type":"string","title":"Tableau","description":"3/4/5 cartes du board, par ex. 'AsKsQs'","examples":["AsKsQs"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type de main","examples":["StandardHighHand"]},"dead":{"type":"string","title":"Cartes mortes","description":"cartes mortes/retirées facultatives","default":""}},"type":"object","required":["board"],"title":"Requête de board"},"CardsRequest":{"properties":{"cards":{"type":"string","title":"Cartes","description":"cartes à normaliser/valider","examples":["AsKsQs"]}},"type":"object","required":["cards"],"title":"Requête de cartes"},"EquityAdvantageRequest":{"properties":{"hero":{"items":{"type":"string"},"type":"array","title":"Héros","examples":[["AA","KK","AKs"]]},"villain":{"items":{"type":"string"},"type":"array","title":"Adversaire","examples":[["QQ","JJ","AQs"]]},"board":{"type":"string","title":"Tableau","examples":["AsKsQs"]},"sample_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nombre d’échantillons"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Graine"},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type de main"}},"type":"object","required":["hero","villain","board"],"title":"Requête d’avantage d’équité"},"EquityRequest":{"properties":{"ranges":{"items":{"items":{"type":"string"},"type":"array"},"type":"array","title":"Éventails de mains","description":"ranges par joueur (notation)","examples":[[["AA","KK"],["QQ","JJ"]]]},"board":{"type":"string","title":"Tableau","default":"","examples":["AhKhQh"]},"sample_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nombre d’échantillons","description":"échantillons de Monte-Carlo (plafonnés) ; la valeur par défaut s’applique si le champ n’est pas défini"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Graine","description":"graine permettant un échantillonnage reproductible"}},"type":"object","required":["ranges"],"title":"Requête d’équité"},"EvalCompareRequest":{"properties":{"holdings":{"items":{"type":"string"},"type":"array","title":"Mains détenues","description":"au moins 2 mains à classer","examples":[["AcAd","KcKd","JhTh"]]},"board":{"type":"string","title":"Tableau","default":"","examples":["AhKhQh"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type de main"}},"type":"object","required":["holdings"],"title":"Requête de comparaison des mains"},"EvalHandRequest":{"properties":{"hole":{"type":"string","title":"Cartes fermées","examples":["AcAd"]},"board":{"type":"string","title":"Tableau","default":"","examples":["AhKhQh"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type de main"}},"type":"object","required":["hole"],"title":"Requête d’évaluation d’une main"},"GameStateRequest":{"properties":{"variant":{"type":"string","title":"Variante","description":"code de variante, par ex. NT (NL hold’em) ; voir /meta","examples":["NT"]},"starting_stacks":{"items":{"type":"integer"},"type":"array","title":"Tapis initiaux","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":"Blindes ou straddles","examples":[[1,2]]},"bring_in":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mise d’ouverture"},"small_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Petite mise"},"big_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Grosse mise"},"min_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mise minimale","description":"obligatoire en no-limit/pot-limit, par ex. 2"},"ante_trimming_status":{"type":"boolean","title":"État d’élagage des antes","default":false},"automations":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Automatisations","description":"noms des automatisations ; omettez-les pour utiliser les valeurs par défaut de pokerkit"},"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":"Observateur","description":"réservé (niveau à informations masquées) ; v1 fournit toutes les informations"}},"type":"object","required":["variant","starting_stacks","antes"],"title":"Requête d’état de la partie"},"GameStepRequest":{"properties":{"variant":{"type":"string","title":"Variante","description":"code de variante, par ex. NT (NL hold’em) ; voir /meta","examples":["NT"]},"starting_stacks":{"items":{"type":"integer"},"type":"array","title":"Tapis initiaux","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":"Blindes ou straddles","examples":[[1,2]]},"bring_in":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mise d’ouverture"},"small_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Petite mise"},"big_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Grosse mise"},"min_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mise minimale","description":"obligatoire en no-limit/pot-limit, par ex. 2"},"ante_trimming_status":{"type":"boolean","title":"État d’élagage des antes","default":false},"automations":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Automatisations","description":"noms des automatisations ; omettez-les pour utiliser les valeurs par défaut de pokerkit"},"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":"Observateur","description":"réservé (niveau à informations masquées) ; v1 fournit toutes les informations"},"next_action":{"type":"string","title":"Action suivante","description":"action du joueur/de distribution à appliquer","examples":["p1 cc"]},"expected_action_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nombre d’actions attendu","description":"token de concurrence optimiste = len(actions) que vous prolongez ; 409 en cas de divergence"}},"type":"object","required":["variant","starting_stacks","antes","next_action"],"title":"Requête d’étape de la partie"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Détail"}},"type":"object","title":"Erreur de validation HTTP"},"HandRequest":{"properties":{"hole":{"type":"string","title":"Cartes fermées","description":"2 cartes fermées, par ex. 'JhTh'","examples":["JhTh"]},"board":{"type":"string","title":"Tableau","examples":["AsKsQs"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type de main"},"dead":{"type":"string","title":"Cartes mortes","default":""}},"type":"object","required":["hole","board"],"title":"Requête de main"},"HandStrengthRequest":{"properties":{"hole_range":{"items":{"type":"string"},"type":"array","title":"Range de cartes fermées","description":"range/main de hero (notation)","examples":[["AhKh"]]},"board":{"type":"string","title":"Tableau","default":"","examples":["AhKhQh"]},"player_count":{"type":"integer","minimum":2.0,"title":"Nombre de joueurs","default":2},"sample_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nombre d’échantillons"},"seed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Graine"}},"type":"object","required":["hole_range"],"title":"Requête de force de la main"},"IcmRequest":{"properties":{"payouts":{"items":{"type":"number"},"type":"array","title":"Gains","examples":[[50,30,20]]},"chips":{"items":{"type":"number"},"type":"array","title":"Jetons","examples":[[5000,3000,2000]]}},"type":"object","required":["payouts","chips"],"title":"Requête ICM"},"NotationParseRequest":{"properties":{"text":{"type":"string","title":"Texte","description":"chaîne d’historique de main pokerkit au format .phh"}},"type":"object","required":["text"],"title":"Requête d’analyse de notation"},"NutAdvantageRequest":{"properties":{"hero":{"items":{"type":"string"},"type":"array","title":"Héros","description":"range de hero (notation)","examples":[["AA","KK","AKs"]]},"villain":{"items":{"type":"string"},"type":"array","title":"Adversaire","description":"range de l’adversaire (notation)","examples":[["QQ","JJ","AQs"]]},"board":{"type":"string","title":"Tableau","examples":["AsKsQs"]},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type de main"}},"type":"object","required":["hero","villain","board"],"title":"Requête d’avantage de nuts"},"RangeExpandRequest":{"properties":{"notation":{"items":{"type":"string"},"type":"array","title":"Notation","description":"tokens de notation de range","examples":[["AA","KQs","QQ+"]]}},"type":"object","required":["notation"],"title":"Requête de développement de range"},"ReplayRequest":{"properties":{"text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Texte","description":"chaîne .phh ; OU fournissez les champs config+actions ci-dessous"},"variant":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Variante"},"starting_stacks":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Tapis initiaux"},"antes":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Antes"},"blinds_or_straddles":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Blindes ou straddles"},"bring_in":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mise d’ouverture"},"small_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Petite mise"},"big_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Grosse mise"},"min_bet":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mise minimale"},"ante_trimming_status":{"type":"boolean","title":"État d’élagage des antes","default":false},"automations":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Automatisations"},"actions":{"items":{"type":"string"},"type":"array","title":"Actions"},"index":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Index","description":"renvoyer uniquement l’instantané à l’index de cette étape"}},"type":"object","title":"Requête de relecture"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Emplacement"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Type d’erreur"},"input":{"title":"Entrée"},"ctx":{"type":"object","title":"Contexte"}},"type":"object","required":["loc","msg","type"],"title":"Erreur de validation"},"ValueRangeRequest":{"properties":{"board":{"type":"string","title":"Tableau","examples":["AsKsQs"]},"aggression":{"type":"string","title":"Agressivité","default":"SINGLE_BET","examples":["NO_BET","SINGLE_BET","RAISED"]},"floor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Plancher","description":"plancher de catégorie facultatif, par ex. 'TWO_PAIR' (remplace la valeur par défaut dérivée de aggression)"},"hand_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Type de main"},"dead":{"type":"string","title":"Cartes mortes","default":""}},"type":"object","required":["board"],"title":"Requête de range de valeur"}}},"x-pokerai-public-provenance":{"sourceUrl":"https://pokerai.bet/v1/pokerkit/combined-openapi.json","generatedAt":"2026-07-22T12:05:56Z","snapshotVersion":"1.0"}}