Documentation
API opérationnelle
Documentation/Aperçu
Une clé · quatre tours

Obtenez une stratégie en une requête.

Utilisez MelaSolver GPU via une API en libre-service. Commencez par une consultation présolue en quelques millisecondes, ou soumettez une situation personnalisée de flop, de turn ou de river au pool de solveurs en temps réel.

Collection Postman

Téléchargez la collection publique, importez-la dans Postman et définissez la variable apiKey de la collection avec votre clé API avant d'envoyer une requête. Elle utilise Authorization: Bearer {{apiKey}} et l'URL de base publique https://pokerai.bet ; les exemples inclus couvrent la stratégie GTO préflop et la texture du tableau PokerKit.

Collection PostmanLa source téléchargeable ne contient aucune véritable clé, aucun Cookie ni aucun point de terminaison privé. Pour le contrat public complet, consultez la Référence de l’API et l’instantané OpenAPI.

Choisissez votre parcours

Les deux utilisent la même clé API et le même quota mensuel.

Recherche présolue

RAPIDE

Solutions préflop et de flop (plus de 5,8 M). Une stratégie est renvoyée en quelques millisecondes, sans interrogation de tâche.

Commencez par le préflop

Résolution en temps réel

PERSONNALISÉ

Arbres personnalisés pour le flop, le turn et la river. Soumettez une fois, interrogez par ID de tâche, puis récupérez la stratégie résolue.

Soumettre une résolution

Première réponse 200

Installez, authentifiez-vous, appelez. Rien d'autre à provisionner.

01 / InstallerChoisir un SDK
02 / S’authentifierExporter une clé
03 / RequêteInterroger le préflop
request.sh
curl -s https://pokerai.bet/v1/gto/preflop \
  -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"hole_cards":"AhKh","positions":{"hero":"UTG"},"preflop_actions":[{"position":"SB","action":"small blind","amount":0.5},{"position":"BB","action":"big blind","amount":1}]}'
response.json41ms · 200 OK
{
  "hole_cards": "AhKh",
  "situation": "RFI",
  "strategy": [
    { "action": "raise", "frequency": 1, "amount_bb": 3, "sizing_pot": 0.8 }
  ],
  "quota": { "used": 6, "limit": 100 }
}

Continuer à développer

Passez du premier appel à la production sans avoir à parcourir une longue page.

Authentification

Chaque requête doit contenir une clé API. Obtenez une clé en 60 secondes:

  1. Ouvrez la console, saisissez votre e-mail → recevez un code de vérification par e-mail (connexion sans mot de passe, aucune inscription nécessaire).
  2. Saisissez le code pour vous connecter → créez une clé API → copiez-la (affichée une seule fois, conservez-la en lieu sûr).
  3. Définissez-la comme variable d’environnement : export POKERAI_API_KEY=gto_xxxxxxxx, puis vous pourrez exécuter le démarrage rapide ci-dessous.

Ensuite, envoyez la même clé (le gto_xxx que vous venez de copier — c’est le « jeton Bearer ») dans un en-tête de requête à chaque requête. Choisissez l’une des deux formes ci-dessous — il s’agit d’une seule clé, pas de deux:

Authorization: Bearer gto_xxxxxxxx     # standard (recommandé ; correspond au schéma OpenAPI BearerApiKey)
# ou (entièrement équivalent, choisissez-en un)
X-API-Key: gto_xxxxxxxx                 # équivalent (schéma OpenAPI XApiKey) ; pratique pour certaines passerelles / SDK / tests rapides

Quota

Deux types de quota mensuel, comptabilisés séparément et réinitialisés le 1er de chaque mois ; l’utilisation actuelle se trouve dans la console:

  • Quota général (offre gratuite par défaut : 1 000/mois) : les appels préflop, de range préflop, de récupération de l’arbre de décision du flop, de conversion de range /v1/gto/range et de range projetée coûtent chacun 1.
  • Quota de résolution (offre gratuite par défaut : 25/mois) : le solveur en temps réel /v1/gto/solver coûte 1 chaque fois qu’il déclenche une nouvelle résolution ; la réutilisation d’une résolution mise en cache et la récupération de l’arbre/du nœud sont gratuites (la réponse comporte un champ solve_quota lorsqu’elle est facturée et n’en comporte pas lorsqu’elle ne l’est pas).

Modèle d’erreurs

Toutes les erreurs renvoient un JSON uniforme : { "error": "<code>", "message": "<description>" }. Quelques variantes : certaines réponses 502 utilisent reason au lieu de message ; le 429 lorsque tous les solveurs sont occupés ressemble à { "status": "busy", "message": ... }. Les valeurs error propres à chaque point de terminaison figurent dans le tableau « Erreurs possibles » de chaque point de terminaison ; les codes d’état communs sont ci-dessous :

HTTPerror / significationréessayer ?
400Entrée non valide ou champ manquant (consultez le tableau de chaque point de terminaison pour la valeur error spécifique).Non, corrigez l’entrée
401missing_api_key / invalid_api_key: clé API manquante ou non valide.Non, vérifiez la clé API
403invalid_node_token / invalid_solve : jeton/identifiant non valide ou ne vous appartenant pas.Non, récupérez à nouveau l’arbre / replanifiez d’abord
404no_solution: aucune donnée GTO pour cette situation pour le moment.Non, modifiez la situation
429quota_exceeded (général) / solve_quota_exceeded (résolution) : quota mensuel épuisé.Non, réinitialisation le 1er ou augmentez votre quota
429status: busy : tous les solveurs sont occupés (uniquement /v1/gto/solver), non facturé.Oui, attendez davantage et réessayez
502no_result (reason : timeout / no_worker_available) / auth_unavailable / solver_unreachable : service principal temporairement indisponible.Oui, augmentez le délai puis réessayez 2 à 3 fois

Exemples de corps de réponse d’erreur

400 (entrée non valide) :

{
  "error": "invalid_board",
  "message": "board must be 3 cards, e.g. \"2c2h2s\""
}

401 (clé API manquante) / 404 (aucune donnée) / 429 (quota épuisé) — champ unique ou message court :

{ "error": "missing_api_key" }
{ "error": "no_solution", "message": "no GTO data for this spot/board" }
{ "error": "quota_exceeded" }

502 (service principal temporairement indisponible, nouvelle tentative possible) :

{
  "error": "no_result",
  "reason": "timeout"
}

Nouvelle tentative : seuls 429 busy et 502 méritent une nouvelle tentative — utilisez un backoff exponentiel (commencez à ~1 s, doublez, au plus 2–3 fois). Les autres (400/401/403/404/quota épuisé) sont définitifs et réessayer ne sert à rien : corrigez l’entrée / changez la clé API / récupérez à nouveau l’arbre, ou attendez la réinitialisation du quota le 1er du mois. Il n’y a pas de limite de débit par seconde, donc aucun en-tête Retry-After.

Démarrage rapide

Une fois votre clé API obtenue (voir ci-dessus), enregistrez-la sous POKERAI_API_KEY et copiez ce curl — l’appel réussi le plus simple : le Héros a une occasion d’ouvrir en UTG (RFI), et la solution préflop présolue est renvoyée en quelques millisecondes. Vous pouvez également copier le même extrait de départ depuis le tableau de bord.

curl -s https://pokerai.bet/v1/gto/preflop \
  -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"hole_cards":"AhKh","positions":{"hero":"UTG"},"preflop_actions":[{"position":"SB","action":"small blind","amount":0.5},{"position":"BB","action":"big blind","amount":1}]}'

Réponse réelle (UTG avec AKs, occasion d’ouvrir → ouvre 100 % à 3BB) :

{
  "hole_cards": "AhKh",
  "situation": "RFI",
  "strategy": [
    { "action": "raise", "frequency": 1, "amount_bb": 3, "sizing_pot": 0.8 }
  ],
  "quota": { "used": 6, "limit": 100 }
}

Face à une relance ? Ajoutez simplement l’action de l’adversaire à preflop_actions (ajoutez {"position":"UTG","action":"raise","amount":3} et remplacez le Héros par MP → cela devient une situation de 3bet, et situation renvoie Raise). La fréquence mixte de chaque action est renvoyée (aucune action recommandée ; choisissez vous-même selon frequency). Les sections ci-dessous sont organisées en trois parties : Solutions présolues (préflop / flop), calcul du solveur en temps réel et conversion de plage.

SDK clients Python · TypeScript · MCP

Vous ne voulez pas écrire HTTP à la main ? Les clients officiels sont générés automatiquement depuis la spécification OpenAPI et entièrement typés ; ils suivent donc toujours l’API. L’authentification se limite à votre clé API.

Python pip

pip install pokerai-bet   # nom de distribution pokerai-bet, importé sous pokerai

La même situation de démarrage rapide (ouverture UTG du Héros), typée :

from pokerai import AuthenticatedClient
from pokerai.api.lookup import preflop_strategy
from pokerai.models import (
    PreflopRequest, PreflopRequestPositions, PreflopRequestPreflopActionsItem,
)
from pokerai.models.preflop_request_preflop_actions_item_action import (
    PreflopRequestPreflopActionsItemAction as Act,
)
from pokerai.models.position import Position

client = AuthenticatedClient(base_url="https://pokerai.bet", token="gto_...")

resp = preflop_strategy.sync(client=client, body=PreflopRequest(
    hole_cards="AhKh",
    positions=PreflopRequestPositions(hero=Position.UTG),
    preflop_actions=[
        PreflopRequestPreflopActionsItem(position=Position.SB, action=Act.SMALL_BLIND, amount=0.5),
        PreflopRequestPreflopActionsItem(position=Position.BB, action=Act.BIG_BLIND, amount=1.0),
    ],
))
print(resp.to_dict())

Sortie réelle (même situation que dans le démarrage rapide) :

{"hole_cards": "AhKh", "situation": "RFI",
 "strategy": [{"action": "raise", "frequency": 1, "sizing_pot": 0.8, "amount_bb": 3}],
 "quota": {"used": 2702, "limit": 100000}}

TypeScript / JavaScript npm

npm install @pokerai/client
import { createPokeraiClient } from "@pokerai/client";

const client = createPokeraiClient({ apiKey: "gto_..." });

const { data, error } = await client.POST("/v1/gto/preflop", {
  body: {
    hole_cards: "AhKh",
    positions: { hero: "UTG" },
    preflop_actions: [
      { position: "SB", action: "small blind", amount: 0.5 },
      { position: "BB", action: "big blind", amount: 1 },
    ],
  },
});
if (error) throw new Error(JSON.stringify(error));
console.log(data.situation, data.strategy);
// "RFI" [{ action: "raise", frequency: 1, amount_bb: 3, sizing_pot: 0.8 }]

Les chemins, corps de requête et champs de réponse sont tous vérifiés par les types — votre éditeur complète automatiquement toute l’API. Les types sont générés depuis la spécification par openapi-typescript ; le runtime est openapi-fetch.

MCP (pour les agents LLM) npm

Laissez Claude / Cursor et consorts appeler l’API Pokerai comme outils (@pokerai/mcp) :

// mcp.json
{ "mcpServers": { "pokerai": {
  "command": "npx", "args": ["-y", "@pokerai/mcp"],
  "env": { "POKERAI_API_KEY": "gto_..." }
}}}

5 outils de consultation présolue par défaut ; ajoutez "POKERAI_ENABLE_SOLVE": "1" pour activer les outils de solveur en temps réel (consomme le quota de résolutions).

Concepts

Le modèle mental général — lisez-le une fois et les sections par point de terminaison ci-dessous seront plus faciles à suivre.

Deux façons d’obtenir une stratégie

  • Solutions présolues : le préflop / flop s’appuie sur des solutions GTO présolues, renvoyées en quelques millisecondes, adaptées aux cas d’utilisation nécessitant une réponse rapide.
  • Calcul du solveur en temps réel : flop / turn / river sont calculés en direct par le solveur (le flop prend environ 70 secondes ; turn/river sont plus rapides), adaptés à toute plage/situation personnalisée.
  • Conversion de plage : mettez à jour une plage le long d’une ligne d’actions pour obtenir la plage qui arrive au tour suivant, puis transmettez-la au solveur.

Aucune action recommandée n’est renvoyée

Chaque stratégie renvoie la fréquence mixte (0–1) de chaque action et ne choisit pas l’action à votre place — vous l’implémentez vous-même à partir de frequency (prenez la probabilité maximale ou échantillonnez aléatoirement selon la fréquence).

Taille des mises : amount_bb et sizing_pot

Chaque bet/raise comporte deux champs de taille : amount_bb (le montant absolu, c’est-à-dire le montant en BB jusqu’auquel vous relancez) et sizing_pot (la valeur relative au pot, selon la convention standard du % du pot) :

  • bet (première mise) = mise ÷ pot.
  • raise (face à une mise) = (montant de relance − mise actuelle) ÷ pot après le call.

Exemple : 3bet à 9 face à une ouverture de 3 — le pot est de 4,5 ; après le call, 4,5+3=7,5 ; la relance dépasse de 9−3=6, donc sizing_pot = 6/7,5 = 0.8. En cas d’all-in, il comporte aussi allin: true.

arbre → nœud (récupérer l’arbre → récupérer le nœud)

L’arbre de décision du flop comme le solveur en temps réel fonctionnent en deux étapes : récupérez d’abord l’arbre entier (chaque nœud de décision comporte un token), puis utilisez le token du nœud du Héros pour récupérer la stratégie de cette étape.

récupérer l’arbre   /flop/tree   ou   /solver (+ vérifier à répétition /solver/tree)
         └─→ nodes[] : chaque nœud comporte is_hero + token
               └─→ choisir le nœud avec is_hero:true
récupérer le nœud   /flop/node  ou   /solver/node    (le corps comporte le token de ce nœud)
               └─→ la stratégie mixte de cette étape
  • flop : /flop/tree (facture 1) → /flop/node (gratuit). Le nœud root = la première décision du Héros.
  • solver : la planification de /solver renvoie un identifiant solve (facture 1) → vérifications répétées de /solver/tree + /solver/node (tous deux gratuits). La plage n’est fournie qu’une seule fois lors de la planification, elle n’est pas transmise à nouveau.

Notation du chemin de nœud (deux conventions, selon la source de l’arbre) : l’arbre de décision du flop utilise BET_8 (underscore, BB entier) ; l’arbre du solveur utilise BET 8.000000 (espace, 6 décimales). Lors de la transmission de node_id / de la navigation, il doit correspondre aux libellés de cet arbre (ou de solver_results) caractère par caractère.

Machine à états du nœud (résolution en temps réel)

Après la planification, vérifiez de façon répétée le spot_status de /solver/tree : available (non planifié) → computing (résolution en cours, continuez à vérifier) → queryable (les nœuds peuvent être récupérés) → expired (cache libéré par le TTL, doit être replanifié). Une fois vos requêtes terminées, vous pouvez éventuellement appeler /solver/release afin de rendre immédiatement le port au pool (sinon, il est récupéré par le TTL) ; après cette libération, les requêtes ultérieures sur cet identifiant solve renvoient expired.

Solutions pré-résolues pré-résolues · millisecondes

Préflop et flop utilisent des solutions GTO pré-résolues, servies instantanément, adaptées aux cas d’utilisation nécessitant une réponse rapide. Le tapis effectif est fixé à 100BB (pré-résolu, pas une entrée). Pour calculer le flop en direct avec le véritable solveur, consultez la section suivante.

Préflop

POST https://pokerai.bet/v1/gto/preflop consomme 1 unité du quota général

Schéma complet des paramètres et de la réponse, et essai en direct → référence interactive.

Vous n’avez pas besoin de déterminer « combien de mises contient le pot » : fournissez dans l’ordre les actions préflop précédant le Héros, et le serveur détermine automatiquement la situation (pot non ouvert / face à une relance / 3bet / 4bet…).

Remarques · corps de la requête

champtypedescription
hole_cardschaîneLes 2 cartes privatives du Héros, par ex. "AdKd".
positions.herochaîneLa position du Héros, parmi SB BB UTG MP CO BTN (placée sous positions).
preflop_actionstableauLa séquence complète et explicite d’actions, de la petite blind jusqu’au joueur juste avant le Héros (le Héros n’est pas dans la séquence ; sa position est fournie par positions.hero, et la séquence s’arrête au joueur qui le précède). Chaque élément est { position, action, amount, allin? }, voir le tableau ci-dessous.
preflop_versionchaîneFacultatif. Quel jeu de grilles de stratégie préflop 6max utiliser : 6max (par défaut) / 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb. Omettez-le pour la valeur par défaut de la plateforme (6max) ; une valeur inconnue -> 400 unsupported_preflop_version. Des versions différentes donnent des fréquences différentes pour une même situation.

Champs de chaque élément preflop_actions

champtypedescription
positionchaîneLa position de cette action, parmi SB BB UTG MP CO BTN.
actionchaîne"small blind" / "big blind" / "raise" / "call" / "fold" (les blinds sont des chaînes de deux mots).
amountnombreLe montant incrémental nouvellement investi par cette action (BB, et non le total cumulé). Exemples : petite blind 0.5 ; grosse blind 1 ; une relance d’ouverture à 3 → amount 3 (depuis 0) ; un joueur ayant déjà investi 1 et relançant à 9 → amount 8. fold l’omet (compte pour 0). Pot = somme de tous les amount.
allinbooléenFacultatif. Indique un all-in d’un joueur à petit tapis (montant de mise/suivi inférieur à la relance minimale) ; lorsque true, la vérification de relance minimale est ignorée.

Validation (violation → 400 invalid_actions) : la séquence doit commencer par small blind (0.5), puis big blind (1) ; chaque raise/call nécessite un amount positif ; pour un raise, le total cumulé doit dépasser la mise actuelle et respecter la relance minimale (= mise actuelle + taille de la relance précédente ; ainsi, une ouverture ≥ 2BB, et un 3bet sur une ouverture à 3 doit être ≥ 5BB) — sauf allin:true ; le total cumulé d’un call doit être exactement égal à la mise actuelle — sauf allin:true.

Les montants exacts n’affectent que le pot / sizing_pot, pas les fréquences : fournir des valeurs amount exactes ne rend exacts que le pot / sizing_pot ; les fréquences GTO sont déterminées par la situation (RFI / 3bet / 4bet + position) et ne changent pas avec la taille de la mise.

Exemple d’appel

curl -s https://pokerai.bet/v1/gto/preflop \
  -H "Authorization: Bearer $POKERAI_API_KEY" -H "Content-Type: application/json" \
  -d '{"hole_cards":"AhKh","positions":{"hero":"MP"},"preflop_version":"6max_RC_100bb_200NL",
       "preflop_actions":[{"position":"SB","action":"small blind","amount":0.5},
                          {"position":"BB","action":"big blind","amount":1},
                          {"position":"UTG","action":"raise","amount":3}]}'

Omettez preflop_version pour la valeur par défaut (6max). Les versions disponibles sont listées ci-dessous, ou interrogez-les en direct avec GET /v1/gto/preflop/versions.

Réponse (200)

{"hole_cards": "AhKh", "situation": "Raise", "strategy": [{"action": "raise", "frequency": 1, "amount_bb": 9, "sizing_pot": 0.8}], "quota": {"used": 7, "limit": 100}}
champdescription
hole_cardsLa main renvoyée telle quelle.
situationL’état auquel la table fait face lorsque vient le tour du Héros : RFI (personne dans le pot, le Héros a une opportunité d’ouverture) / Limp (quelqu’un a limpé, aucune relance) / Raise (face à une relance d’ouverture) / 3-Bet / 4-Bet / 5-Bet. Remarque : BB se retrouve toujours sur Limp (quelqu’un doit être entré dans le pot avant son action).
strategy[]La stratégie mixte de chaque action. raise contient amount_bb (le montant absolu jusqu’auquel la relance est portée à, en BB) et sizing_pot (voir taille de mise). Au préflop, amount_bb est défini par le nombre de relances avant le Héros ; voir le tableau ci-dessous. Aucune action recommandée n’est renvoyée ; choisissez vous-même selon frequency.
quotaUtilisation du quota général de ce mois (used / limit).

amount_bb préflop (dérivé du pot de flop pré-résolu, relance portée à) :

nombre de relances avant le Hérossituationamount_bb
0ouverture3
13bet9
24bet25
≥35bet+à tapis 100 (allin: true)

Versions de stratégie preflop_version

Même 6max, différents ensembles de grilles de stratégie (les fréquences diffèrent pour la même situation) ; omettez pour la valeur par défaut 6max. La liste faisant autorité est le point de terminaison de découverte GET /v1/gto/preflop/versions (gratuit ; renvoie id + label + default) :

id (à transmettre comme preflop_version)descriptif
6max (par défaut)6 max 100bb Deepsolver
6max_RC_100bb_200NL6 max 100bb GG 200NL 3b/f 2.2x - 2.5x
6max_RC_100bb_100NL6 max 100bb GG 100NL 3b/f
6max_RC_40bb6 max 40bb GG 100NL
curl -s https://pokerai.bet/v1/gto/preflop/versions -H "Authorization: Bearer $POKERAI_API_KEY"
// {"versions": [{"id": "6max", "label": "6 max 100bb Deepsolver", "default": true}, …], "default": "6max"}

Erreurs possibles

HTTPerrordéclencheur / comment corriger
400invalid_hole_cardshole_cards ne contient pas 2 cartes (p. ex. "AdKd").
400unsupported_table_size / invalid_positions / invalid_actionsLe type de table (actuellement uniquement 6max), hero/les positions ou preflop_actions est invalide.
400unsupported_preflop_versionpreflop_version ne fait pas partie de l’ensemble autorisé (6max / 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb).
404no_solutionAucune solution pré-résolue pour cette situation préflop ; modifiez la situation.

Télécharger : requête.jsonréponse.json

Range complète (13×13) consomme 1 quota général

POST https://pokerai.bet/v1/gto/preflop/range · la range complète 13×13 pour une situation (position + ligne d’actions), qui renvoie se coucher / payer / relancer pour les 169 types de mains en un appel. Pas de hole_cards (la situation provient de positions + preflop_actions). Consomme 1 quota général (un appel, pas 169). Pour afficher une grille de stratégie de ranges.

// Requête (sans hole_cards)
{"table_size": "6max", "positions": {"hero": "BTN"}, "preflop_actions": [{"position": "SB", "action": "small blind", "amount": 0.5}, {"position": "BB", "action": "big blind", "amount": 1}, {"position": "UTG", "action": "fold"}, {"position": "MP", "action": "fold"}, {"position": "CO", "action": "fold"}]}

// Réponse
{ "range": {"22": {"fold": 0.69, "call": 0, "raise": 0.31}, "33": {"fold": 0, "call": 0, "raise": 1}, "ATs": {"fold": 0, "call": 0, "raise": 1}, "AKs": {"fold": 0, "call": 0, "raise": 1}, "AKo": {"fold": 0, "call": 0, "raise": 1}, "KQs": {"fold": 0, "call": 0, "raise": 1}, "72o": {"fold": 1, "call": 0, "raise": 0}, "JJ": {"fold": 0, "call": 0, "raise": 1} , …169 mains au total… },
  "quota": {"used": 7, "limit": 100} }

Notation des mains : paire AA, assorties AKs, dépareillées AKo (carte haute en premier) ; pour chaque entrée, fold+call+raise≈1. Schéma complet / essai en direct → référence interactive.

Arbre de décision au flop

La stratégie au flop est un arbre de décision : récupérez d’abord l’arbre (qui contient tous les nœuds de décision + le token de chaque nœud), votre système parcourt le chemin dans l’arbre selon les mises réelles et, au nœud du Héros, récupère la stratégie de cette étape. Deux étapes, comme pour le solveur (treenode).

1) Récupérer l’arbre de décision consomme 1 quota général

POST https://pokerai.bet/v1/gto/flop/tree · saisie de board + pot_type + positions (aucun hole_cards nécessaire, l’arbre est indépendant de la main).

Schéma complet des paramètres / de la réponse et essai en direct → référence interactive.

boardLes 3 cartes du flop, p. ex. "2c2h2s".
pot_type"SRP" relancé une fois / "3BET" / "4BET" / "LIMP" limpé.
positionsLa position de chaque rôle (SB BB UTG MP CO BTN), requise selon pot_type comme indiqué ci-dessous.
flop_versionFacultatif. Quel jeu de données de flop utiliser (un résolu par version préflop) : 6max (par défaut) / 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb. Omettez pour la valeur par défaut (6max) ; si cette version ne dispose pas de données pour la situation, elle revient gracieusement à 6max ; une valeur inconnue -> 400 unsupported_flop_version. Indépendant de preflop_version. Les jetons de nœud portent cette version, donc /v1/gto/flop/node reste sur le même jeu de données.
pot_typepositions requisesvaleur du Héros
SRPhero, raiser, callerraiser ou caller
3BET / 4BEThero, raiser, three_bettorraiser ou three_bettor
LIMPhero, limperle Héros ou le limper doit être BB
// Requête (sans hole_cards)
{"board": "2c2h2s", "pot_type": "SRP", "positions": {"hero": "UTG", "raiser": "UTG", "caller": "BTN"}}

// Réponse (36 nœuds au total ; 5 premiers affichés)
{"board": ["2c", "2h", "2s"], "pot_type": "SRP", "pot": 7.5, "effective_stack": 97, "oop_range": "AA:1,AKs:1,AQs:1,AJs:1,ATs:1,A9s:1,A8s:1,A7s:1,A6s:1,A5s:1,…", "ip_range": "AQs:0.05,AJs:0.86,ATs:0.436,A9s:0.356,A8s:0.36,A7s:0.196,…", "node_count": 36, "nodes": [{"node": "root", "is_hero": true, "token": "eyJ…"}, {"node": "root/BET_4", "is_hero": false, "token": "eyJ…"}, {"node": "root/BET_8", "is_hero": false, "token": "eyJ…"}, {"node": "root/BET_97", "is_hero": false, "token": "eyJ…"}, {"node": "root/CHECK", "is_hero": false, "token": "eyJ…"}, …], "quota": {"used": 7, "limit": 100}}
champdescriptif
oop_range / ip_rangeLa range de départ de cette situation (chaîne de combos pondérés), utilisée comme pondérations initiales pour la conversion de range.
nodes[]Tous les nœuds de décision : node (chemin d’action, par ex. "root/CHECK/BET_8"), is_hero (indique s’il s’agit d’un point de décision du Héros), token (l’identifiant permettant de récupérer la stratégie de ce nœud, transmis à l’étape 2 ; lié au compte + à la situation, il ne peut pas être forgé).
pot / effective_stack / node_countPot, tapis effectif (BB) et nombre total de nœuds de décision.
quotaUtilisation du quota général de ce mois-ci (used / limit).

2) Récupérer la stratégie d’un nœud gratuit

POST https://pokerai.bet/v1/gto/flop/node · accepte node (le jeton d’un nœud de l’étape 1). Avec hole_cards → la stratégie mixte pour cette main ; sans hole_cards → la stratégie de range complète.

Schéma complet des paramètres / réponses, et essai en direct → référence interactive.

Toutes les décisions du Héros passent par ici : première action du Héros = le nœud root (OOP agit en premier, check/bet) ; lorsque le Héros est IP, fait face à une mise ou agit une deuxième fois, choisissez le nœud is_hero:true correspondant (par ex. root/CHECK/BET_8 = j’ai checké et je fais maintenant face à une mise → se coucher / payer / relancer). L’arbre du flop est à une seule phase de jeu ; pour plusieurs phases de jeu (turn/river), utilisez /v1/gto/solver/*.

// Requête (nœud Héros, avec hole_cards) -> stratégie du Héros
{"node": "eyJ…", "hole_cards": "AdKd"}
{"hole_cards": "AdKd", "node": "root", "is_hero": true, "strategy": [{"action": "check", "frequency": 0.7208}, {"action": "bet", "amount_bb": 4, "sizing_pot": 0.5333, "frequency": 0.0533}, {"action": "bet", "amount_bb": 8, "sizing_pot": 1.0667, "frequency": 0.2259}, {"action": "bet", "amount_bb": 97, "sizing_pot": 12.9333, "allin": true, "frequency": 0}]}

// Requête (sans hole_cards) -> stratégie de range complète
{"node": "eyJ…"}
{"node": "root/BET_4", "is_hero": false, "actions": [{"action": "call"}, {"action": "raise", "amount_bb": 12, "sizing_pot": 0.5161}, {"action": "raise", "amount_bb": 20, "sizing_pot": 1.0323}, {"action": "raise", "amount_bb": 97, "sizing_pot": 6, "allin": true}, {"action": "fold"}], "range_strategy": {"3d3c": [0.93067, 4e-05, 0.06922, 1e-05, 7e-05], "3h3c": [0.92172, 6e-05, 0.07812, 1e-05, 0.0001], "3h3d": [0.94334, 4e-05, 0.05655, 1e-05, 7e-05], "…": "188 mains au total"}, "range_hand_count": 188}
champdescription
is_heroIndique si ce nœud correspond à une décision du Héros.
strategy[]Nœud Héros (avec hole_cards) : la stratégie mixte pour cette main. actioncheck / bet / call / raise / fold (bet = première mise, raise = relance face à une mise); bet/raise comportent amount_bb et sizing_pot (voir taille de mise), et le tapis comporte aussi allin: true; frequency est une probabilité de 0 à 1. Aucune action recommandée n’est renvoyée; choisissez vous-même selon frequency.
actions[] + range_strategyNœud adverse (ou sans hole_cards) : la stratégie de range complète, avec les fréquences de chaque main alignées sur actions ; inclut range_hand_count. Peut servir à assembler solver_results pour la « conversion de range ».

Les BET_8 / RAISE_20 dans un identifiant de nœud correspondent au montant absolu de la mise (BB).

Erreurs possibles

HTTPerrordéclencheur / correction
4001) invalid_board / invalid_positions; 2) missing_node / invalid_hole_cards1) le board ne comporte pas 3 cartes, ou hero/les positions sont invalides ; 2) node est absent ou hole_cards ne comporte pas 2 cartes.
403invalid_node_token(étape 2) le jeton node est invalide ou ne vous appartient pas — appelez d’abord /v1/gto/flop/tree pour récupérer l’arbre.
404no_solutionAucune solution précalculée pour cette situation / ce board.

Télécharger : tree_request.jsontree_response.jsonnode_request.jsonnode_response.json

Solveur (en temps réel) solveur

POST https://pokerai.bet/v1/gto/solver fait partie d’une famille de points de terminaison. Solveur postflop pur, calculé en temps réel, qui utilise un quota de résolution distinct. Le principe est de passer des données d’entrée à la résolution : board + ranges OOP/IP + pot + tapis restant + qui est le Héros, sans historique nécessaire, vous pouvez donc partir de n’importe quelle situation. Trois étapes : planifier → interroger l’arbre jusqu’à ce qu’il soit consultable → récupérer la stratégie d’un nœud.

Schéma complet des paramètres / réponses, et essai en direct → référence interactive (inclut /solver/tree, /solver/node).

la longueur de board définit la street : 3=flop / 4=turn / 5=river. ⚠ Une résolution en temps réel à partir du flop prend du temps (flop SRP mesuré ~70 secondes) et ne convient pas aux cas d’usage nécessitant une réponse rapide — pour un flop rapide, utilisez les « solutions précalculées » ci-dessus (servies instantanément en millisecondes) ; turn / river sont plus rapides (de quelques secondes à quelques dizaines de secondes).

Exemple d’appel (trois étapes : 1) planifier → 2) interroger l’arbre jusqu’à ce qu’il soit consultable → 3) récupérer un nœud)

# 1) planifier (board 3/4/5 = flop/turn/river ; flop ~70 secondes)
curl -s https://pokerai.bet/v1/gto/solver -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"board":"2c2h2s","oop_range":"AA,KK,QQ,AKs","ip_range":"JJ,TT,AQs,KQs","pot":7.5,"effective_stack":97,"hero":"OOP","bet_sizes":{"flop":[33,75],"turn":[67],"river":[75]},"raise_sizes":{"flop":[50],"turn":[80],"river":[125]},"donk_sizes":{"turn":[55],"river":[90]},"raise_limit":3}'
# 2) interroger l’arbre jusqu’à ce que spot_status=queryable ; 3) récupérer le nœud
curl -s https://pokerai.bet/v1/gto/solver/tree -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" -d '{"solve":"eyJ..."}'

1) Planifier une résolution consomme 1 résolution

board3=flop / 4=turn / 5=river, p. ex. "2c2h2s9d" (turn).
oop_range / ip_rangeObligatoire. Les ranges pondérées des deux joueurs arrivant sur cette street, sous forme de chaînes de combos, par ex. "AsKs:1,QQ:0.75,...".
pot / effective_stackObligatoire. Le pot et le stack effectif restant (BB) à l’entrée de cette street ; ils déterminent les tailles de mise et doivent être réels.
heroObligatoire: "OOP" ou "IP".
bet_sizesFacultatif : remplacer les tailles de mise d’ouverture par street, par ex. {"flop":[33,75],"turn":[67],"river":[75]} (% du pot) ; si flop est omis, la valeur par défaut est 50 %.
raise_sizesFacultatif : remplacer les tailles de relance par street, par ex. {"flop":[50],"turn":[80],"river":[125]} (% du pot) ; les streets omises réutilisent bet_sizes ou les valeurs par défaut.
donk_sizesFacultatif : remplacer les tailles de donk-lead OOP, par ex. {"turn":[55],"river":[90]} (% du pot) ; les valeurs par défaut sont 67 % à la turn et 100 % à la river.
raise_limitFacultatif : plafond de relances pour tout l’arbre, de 1 à 4 ; la valeur par défaut est 3 pour les résolutions flop/turn et 4 pour les résolutions river uniquement.
// Requête (flop, avec tailles de mise / relance / donk personnalisées)
{"board": "2c2h2s", "oop_range": "AA,KK,QQ,AKs", "ip_range": "JJ,TT,AQs,KQs", "pot": 7.5, "effective_stack": 97, "hero": "OOP", "bet_sizes": {"flop": [33,7      solve_secondsDurée réelle de cette résolution en temps réel, de la planification à la convergence (secondes). Renvoyée uniquement lorsque queryable ; tous les runouts de la même résolution partagent cette valeur.
    
    

Schéma complet des paramètres et de la réponse, et essai en direct → référence interactive.

3) Récupérer la stratégie d’un nœud gratuit

POST https://pokerai.bet/v1/gto/solver/node · utilise le jeton node. Un nœud Héros renvoie la stratégie du Héros ; un nœud adverse (ou sans hole_cards) renvoie la stratégie de range.

{"node": "eyJ…", "hole_cards": "AhKh"}
{"hole_cards": "AhKh", "node": "root", "is_hero": true, "strategy": [{"action": "check", "frequency": 0}, {"action": "bet", "amount_bb": 4, "sizing_pot": 0.5333, "frequency": 0.2666}, {"action": "bet", "amount_bb": 97, "sizing_pot": 12.9333, "allin": true, "frequency": 0.7334}]}
champdescription
is_heroIndique si ce nœud correspond à la décision du Héros.
strategy[]Nœud Héros : stratégie mixte du Héros pour cette main (action / amount_bb / sizing_pot (voir taille de mise) / frequency), avec allin: true ajouté en cas de tapis.
actions[] + range_strategyNœud adverse (ou sans hole_cards) : dans range_strategy, les fréquences de chaque main suivent l’ordre de actions ; inclut aussi range_hand_count.

Schéma complet des paramètres et de la réponse, et essai en direct → référence interactive.

Lorsque vous avez terminé, vous pouvez éventuellement appeler /v1/gto/solver/release pour libérer le port immédiatement (sinon, le système le récupère automatiquement selon le TTL). Lorsque le cache a été récupéré ou remplacé par une résolution plus récente, cette étape renvoie { "node_status": "expired" } ; reprogrammez simplement à l’étape 1. Une erreur de résolution par nœud renvoie { "node_status": "error", "message": … } (terminale — arrêtez les vérifications répétées). Schéma complet des paramètres et de la réponse de /solver/releaseréférence interactive.

Erreurs possibles

HTTPerreurdéclencheur / correction
400invalid_board / missing_range / invalid_pot / invalid_effective_stack / invalid_hero(planification) le tableau, la range oop/ip, le pot, le tapis restant, le Héros ou une autre entrée de résolution est invalide.
400missing_solve / missing_node(récupération de l’arbre/du nœud) l’identifiant solve ou le jeton node est manquant.
403invalid_solve / invalid_node_tokenIdentifiant/jeton invalide ou ne vous appartenant pas — reprogrammez / récupérez de nouveau l’arbre.
429status: busyTous les solveurs sont occupés, sans facturation ; attendez puis réessayez.
502solve_failedLe déclenchement de la résolution a échoué ; réessayez plus tard.
503upstream_unavailable(arbre/nœud) le solveur est inaccessible après les nouvelles tentatives effectuées par le service lui-même (erreur de transport / 5xx) — nouvelle tentative possible.

Télécharger (turn, board=4) : requête de planificationréponse de planificationrequête d’arbreréponse d’arbrerequête de nœudréponse de nœud

Télécharger (flop, board=3) : requête de planificationréponse de planificationrequête d’arbreréponse d’arbrerequête de nœudréponse de nœud

Télécharger (river, board=5) : requête de planificationréponse de planificationrequête d’arbreréponse d’arbrerequête de nœudréponse de nœud

Exemple de vérifications répétées de bout en bout (Python)

import requests, time
H = {"Authorization": "Bearer $POKERAI_API_KEY"}
BASE = "https://pokerai.bet/v1/gto"

# 1) planifier (consomme 1 quota de résolution ; gratuit si le résultat est trouvé dans le cache)
solve = requests.post(f"{BASE}/solver", headers=H, json={
    "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}).json()["solve"]

# 2) interroger l’arbre de façon répétée jusqu’à ce qu’il soit queryable
while True:
    tree = requests.post(f"{BASE}/solver/tree", headers=H, json={"solve": solve}).json()
    if tree["spot_status"] == "queryable": break
    time.sleep(2)                       # calcul en cours -> attendre puis réessayer

# 3) récupérer la stratégie du nœud racine du Héros
root = next(n for n in tree["nodes"] if n["node"] == "root")
strat = requests.post(f"{BASE}/solver/node", headers=H,
                      json={"node": root["token"], "hole_cards": "AhKh"}).json()
print(strat["strategy"])

Conversion de range range

POST https://pokerai.bet/v1/gto/range consomme 1 quota général

Schéma complet des paramètres et de la réponse, et essai en direct → référence interactive.

Mettre à jour les ranges OOP/IP le long d’une ligne d’actions. Principalement utilisé pour obtenir la range qui arrive à la street suivante (flop→turn / turn→river), puis la transmettre à /v1/gto/solver. Tous les calculs de mise à jour de range (y compris normalize et la réduction des bluffs) sont effectués par le solveur et sont cohérents avec ses résultats.

de> ajouté en cas de tapis. actions[] + range_strategyNœud adverse (ou sans hole_cards) : dans range_strategy les fréquences de chaque main correspondent à l’ordre de actions ; inclut également range_hand_count.

Schéma complet des paramètres et de la réponse, et essai en direct → référence interactive.

Une fois terminé, vous pouvez, si vous le souhaitez, appeler /v1/gto/solver/release pour libérer immédiatement le port (sinon le système le récupère automatiquement via TTL). Lorsque le cache a été récupéré ou remplacé par une résolution plus récente, cette étape renvoie { "node_status": "expired" } ; il suffit de replanifier à l’étape 1. Une erreur de résolution par nœud renvoie { "node_status": "error", "message": … } (terminal — arrêtez l’interrogation). Schéma complet des paramètres et de la réponse de /solver/releaseréférence interactive.

Erreurs possibles

HTTPerreurdéclencheur / correction
400invalid_board / missing_range / invalid_pot / invalid_effective_stack / invalid_hero(planification) le board, la range oop/ip, le pot, le stack restant, Héros ou une autre entrée de résolution est invalide.
400missing_solve / missing_node(récupération arbre/nœud) l’identifiant solve ou le jeton node est manquant.
403invalid_solve / invalid_node_tokenL’identifiant/jeton est invalide ou ne vous appartient pas — replanifiez / récupérez à nouveau l’arbre.
429status: busyTous les solveurs sont occupés, non facturé, attendez avant d’effectuer de nouvelles tentatives.
502solve_failedLe déclenchement de la résolution a échoué ; effectuez de nouvelles tentatives plus tard.
503upstream_unavailable(arbre/nœud) le solveur est inaccessible après les nouvelles tentatives effectuées par le service lui-même (erreur de transport / 5xx) — autorise de nouvelles tentatives.

Télécharger (turn, board=4) : requête de planificationréponse de planificationrequête d’arbreréponse d’arbrerequête de nœudréponse de nœud

Télécharger (flop, board=3) : requête de planificationréponse de planificationrequête d’arbreréponse d’arbrerequête de nœudréponse de nœud

Télécharger (river, board=5) : requête de planificationréponse de planificationrequête d’arbreréponse d’arbrerequête de nœudréponse de nœud

Exemple complet d’interrogations répétées jusqu’à disponibilité (Python)

import requests, time
H = {"Authorization": "Bearer $POKERAI_API_KEY"}
BASE = "https://pokerai.bet/v1/gto"

# 1) planifier (consomme un quota de résolution ; gratuit si le résultat est trouvé dans le cache)
solve = requests.post(f"{BASE}/solver", headers=H, json={
    "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}).json()["solve"]

# 2) interroger l’arbre jusqu’à ce qu’il soit queryable
while True:
    tree = requests.post(f"{BASE}/solver/tree", headers=H, json={"solve": solve}).json()
    if tree["spot_status"] == "queryable": break
    time.sleep(2)                       # calcul en cours -> attendez avant d’effectuer de nouvelles tentatives

# 3) récupérer la stratégie du nœud racine du Héros
root = next(n for n in tree["nodes"] if n["node"] == "root")
strat = requests.post(f"{BASE}/solver/node", headers=H,
                      json={"node": root["token"], "hole_cards": "AhKh"}).json()
print(strat["strategy"])

Conversion de range range

POST https://pokerai.bet/v1/gto/range décompte 1 quota général

Schéma complet des paramètres et de la réponse, et essai en direct → référence interactive.

Met à jour les ranges OOP/IP le long d’une ligne d’action. Principalement utilisé pour obtenir la range qui arrive à la street suivante (flop→turn / turn→river), puis la fournir à /v1/gto/solver. Tous les calculs de mise à jour de range (y compris la normalisation et la décote des bluffs) sont effectués par le solveur et sont cohérents avec ses résultats.

Il s’agit d’un proxy de transit : vous assemblez vous-même toutes les entrées, y compris solver_results (l’arbre de décision). L’arbre de décision peut provenir de vos propres résolutions ou être assemblé à partir de l’arbre de décision du flop de cette plateforme : appelez /v1/gto/flop/tree pour la plage de départ, puis, pour chaque nœud, appelez /v1/gto/flop/node sans hole_cards afin de récupérer le range_strategy complet, imbriqué sous la forme {node_type,player,strategy,childrens}. Consultez le script à la fin.

Corps de la requête

{
  "range_oop": "AQs:1,AJs:0.48,...",            // requis, plage OOP de départ
  "range_ip":  "AA:1,AKs:1,...",                 // requis, plage IP de départ
  "solver_results": { /* requis : l’arbre de décision */ },
  "node_id": "root/CHECK",          // requis, la ligne d’actions
  "board": "2c2h2s",                             // facultatif, chaîne sans séparateur (comme les autres endpoints)
  "normalize": true,                             // facultatif, true par défaut
  "explain": false,                              // facultatif, explication des changements par main
  "track_hands": ["AA"],                         // facultatif, suivre uniquement ces mains
  "bluff_discount_ratio": 0.8,                   // facultatif, réduction des bluffs
  "hero_position": "oop",                        // facultatif, "oop" / "ip" — quel joueur est le Héros (pour le blocage des cartes)
  "hero_hand": "AsKs"                            // facultatif, supprimer les combos contenant les cartes du Héros (bloqueurs) ; renvoyé tel quel
}

Blocage des cartes (facultatif) : définissez hero_position ("oop"/"ip") + hero_hand pour supprimer des plages chaque combo contenant l’une des cartes du Héros — utile pour l’analyse plage contre main. Les deux sont renvoyés tels quels dans la réponse. (Cette paire est également prise en charge par les wrappers de plage projetée ; /v1/gto/flop/projected-range prend en outre en charge partner_hands.)

Exemple d’appel

# solver_results est volumineux, placez-le dans un fichier et utilisez -d @
curl -s https://pokerai.bet/v1/gto/range -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" -d @range_request.json

Réponse (200, réponse réelle, chaînes longues tronquées)

{"bluff_combos_ratio": 0.33, "bluff_discount_ratio": 1, "board": ["2c", "2h", "2s"], "hand_bottom_ranks_ip": "KsQh:2413,KsQd:2413,KsQc:2413,KhQs:2413,…", "hand_bottom_ranks_oop": "KcJh:2414,KcTs:2415,KsTs:2415,KsTh:2415,…", "hand_ranks_ip": "QcQh:313,QdQh:313,QdQs:313,QhQs:313,QcQs:313,…", "hand_ranks_oop": "Ad2d:155,AdAc:311,AhAc:311,AhAd:311,AsAc:311,…", "node_id": "root/CHECK", "path_length": 1, "range_ip_new": "33:0.193023,44:0.216279,54s:0.65814,…", "range_ip_new_raw": "3c3d:0.193023,3c3h:0.193023,3c3s:0.193023,…", "range_ip_new_raw_before_normalization": "3c3d:0.166,3c3h:0.166,3c3s:0.166,3d3h:0.166,…", "range_oop_new": "33:0.245724,44:0.272975,54s:0.420008,…", "range_oop_new_raw": "3d3c:0.245857,3h3c:0.245847,3h3d:0.24586,…", "range_oop_new_raw_before_normalization": "3d3c:0.245843,3h3c:0.245833,3h3d:0.245845,…", "quota": {"used": 7, "limit": 100}}
champdescription
range_oop_new / range_ip_newLa plage mise à jour normalisée (notation par classes), utilisée directement comme oop_range / ip_range de la street suivante fournie au solveur.
range_oop_new_raw / range_ip_new_rawLa valeur intermédiaire après réduction des bluffs, non normalisée (notation par combos) ; à utiliser selon les besoins.
range_oop_new_raw_before_normalization / range_ip_new_raw_before_normalizationLa valeur brute réduite uniquement le long de la ligne d’actions, sans réduction des bluffs ni normalisation.
hand_ranks_oop / hand_ranks_ipClassement de la force des mains (combo:rank, une valeur plus petite est plus forte).
hand_bottom_ranks_oop / hand_bottom_ranks_ipClassement du bas de plage.
node_id / board / path_lengthLa ligne d’actions, le board et le nombre d’étapes de la ligne d’actions renvoyés tels quels.
bluff_discount_ratio / bluff_combos_ratioLes paramètres de réduction des bluffs effectivement utilisés cette fois-ci.
quotaL’utilisation du quota général de ce mois-ci (used / limit).

Erreurs possibles

HTTPerreurdéclencheur / comment corriger
400missing_fieldIl manque l’un des champs range_oop / range_ip / solver_results / node_id.
400bad_requestLe côté solveur l’a rejeté (par ex., le node_id ne mène nulle part dans l’arbre de décision que vous avez fourni).

Télécharger : request.json (~1MB, inclut l’arbre de décision)response.jsonassemble_solver_results.py (script de bout en bout)

Plage projetée du flop projected-range

POST https://pokerai.bet/v1/gto/flop/projected-range coûte 1 quota général

Schéma complet des paramètres / de la réponse, et essai en direct → référence interactive.

Réduisez les plages OOP/IP le long d’une ligne d’actions du flop pour obtenir directement la plage de départ qui entre au tournant. Fournissez la situation complète (board/pot_type/positions) et une ligne d’actions (node_id), et la plateforme assemble automatiquement l’arbre de décision côté serveur et termine la mise à jour de plage, en renvoyant les mêmes champs que la conversion de plage, plus un pot_type renvoyé tel quel.

Il s’agit d’un wrapper pratique de /v1/gto/range : il vous évite les étapes manuelles consistant à appeler /v1/gto/flop/tree + /v1/gto/flop/node par nœud pour assembler solver_results. Il s’applique uniquement aux lignes d’actions du flop (l’arbre de décision est assemblé à partir des résultats pré-résolus du flop de cette plateforme) ; pour tournant→rivière, etc., où vous devez fournir votre propre arbre de décision, utilisez toujours /v1/gto/range.

Corps de la requête

{
  "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"]
}
champdescription
boardObligatoire. Le flop (chaîne sans séparateur, comme pour les autres endpoints), par ex. "2c2h2s".
pot_typeObligatoire. Le type de pot, par ex. "SRP".
positionsObligatoire. { hero, raiser, caller } (comme pour le flop) ; les situations de 3bet/limp peuvent contenir three_bettor / limper.
node_idFacultatif, valeur par défaut "root". La ligne d’actions du flop, utilisant la notation API renvoyée par /v1/gto/flop/tree (montant de mise absolu en BB), par ex. "root/BET_4", "root/CHECK/BET_8/CALL".
normalizeFacultatif, valeur par défaut true. Indique s’il faut normaliser la plage mise à jour.
bluff_discount_ratio / bluff_combos_ratioFacultatifs, chacun dans [0,1] (hors plage → 400). bluff_discount_ratio pondère les combos de bluff en bas de plage ; bluff_combos_ratio est la fraction de la plage traitée comme des bluffs. Omettez-les pour utiliser les valeurs par défaut du serveur pour le tournant/la rivière. Les deux sont renvoyés tels quels.
hero_position / hero_handBlocage de cartes facultatif. Définissez hero_position ("oop"/"ip") + hero_hand (par ex. "AsKs") : supprime de la plage mise à jour du vilain (range_*_new_raw) chaque combo contenant une des cartes de Hero, et garantit que la propre main de Hero est présente dans sa propre plage. Les deux sont renvoyés tels quels. Seul range_*_new_raw est affecté — hand_ranks / hand_bottom_ranks sont filtrés uniquement par le board.
partner_handsTableau facultatif de combos de 4 caractères (par ex. ["Ac9c"]), nécessite hero_position. Supprime chaque combo contenant une de ces cartes de la plage du vilain range_*_new_raw — modélisez les cartes mortes connues (mains couchées, cartes exposées). Entrée uniquement (non renvoyée). Aussi pris en charge par /v1/gto/turn/projected-range.
flop_versionFacultatif. Quel jeu de données du flop (un résolu par version préflop) : 6max (par défaut) / 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb. Omettez-le pour la valeur par défaut (6max) ; si cette version ne comporte pas de données pour la situation, elle se replie proprement sur 6max ; une valeur inconnue -> 400 unsupported_flop_version. Indépendant de preflop_version.

Exemple d’appel

curl -s https://pokerai.bet/v1/gto/flop/projected-range -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" -d @projected_range_request.json

Réponse (200, tous les champs sont listés, les longues chaînes sont tronquées)

{"board": ["2c", "2h", "2s"], "pot_type": "SRP", "node_id": "root/BET_4", "bluff_combos_ratio": 0.5, "bluff_discount_ratio": 0.8, "hero_position": "oop", "hero_hand": "AsKs", "hand_bottom_ranks_ip": "AhTh:2405,AsTs:2405,Ac9c:2406,Ad9d:2406,…", "hand_bottom_ranks_oop": "AhJs:2404,AsJc:2404,AsJd:2404,AsJh:2404,…", "hand_ranks_ip": "QcQd:313,QcQh:313,QcQs:313,QdQh:313,…", "hand_ranks_oop": "Ad2d:155,AdAc:311,AdAh:311,AdAs:311,…", "path_length": 1, "range_ip_new": "33:0.193023,44:0.216279,54s:0.65814,55:0.344186,…", "range_ip_new_raw": "3c3d:0.193023,3c3h:0.193023,3c3s:0.193023,3d3h:0.193023,…", "range_ip_new_raw_before_normalization": "3c3d:0.166,3c3h:0.166,3c3s:0.166,3d3h:0.166,…", "range_oop_new": "44:0.0120032,55:0.0422217,66:0.181192,77:0.327323,…", "range_oop_new_raw": "4s4c:0.0666554,4s4h:0.0666554,5d5c:0.005,5d5h:0.005,…", "range_oop_new_raw_before_normalization": "4s4c:0.011816,4s4h:0.011816,5s5c:0.0392591,5s5h:0.0392591,…", "quota": {"used": 7, "limit": 100}}
champdescription
range_oop_new / range_ip_newLa plage mise à jour normalisée (notation de classe), utilisée directement comme oop_range / ip_range de la rue suivante fournie au solveur.
range_oop_new_raw / range_ip_new_rawLa valeur intermédiaire après décote des bluffs, non normalisée (notation de combo) ; utilisez-la selon vos besoins.
range_oop_new_raw_before_normalization / range_ip_new_raw_before_normalizationLa valeur brute réduite uniquement le long de la ligne d’actions, sans décote des bluffs ni normalisation.
hand_ranks_oop / hand_ranks_ipClassement de force des mains (combo:rank, une valeur plus petite est plus forte).
hand_bottom_ranks_oop / hand_bottom_ranks_ipClassement du bas de la plage.
node_id / board / pot_type / path_lengthLa ligne d’actions, le board, le type de pot et le nombre d’étapes de la ligne d’actions renvoyés tels quels.
bluff_discount_ratio / bluff_combos_ratioLes paramètres de décote des bluffs effectivement utilisés cette fois.
quotaL’utilisation du quota général de ce mois (used / limit).

Erreurs possibles

HTTPerreurdéclencheur / correctif
400invalid_board / invalid_positionsLe board ne comporte pas 3 cartes, ou positions.hero n’est pas valide.
404no_solution (et un errorType serveur tel que no_ranges / no_root_node)Aucun arbre de flop pré-résolu pour cette situation, ou la ligne d’actions node_id ne mène nulle part.

Télécharger : request.jsonresponse.json

Plage projetée du tournant (tournant→rivière) projected-range

POST https://pokerai.bet/v1/gto/turn/projected-range gratuit

Schéma complet des paramètres / de la réponse, et essai en direct → référence interactive.

La version tournant→rivière de la plage projetée du flop, pour une résolution du tournant en temps réel. Réduisez les plages le long d’une ligne d’actions du tournant (y compris le CALL/CHECK qui clôt la rue) pour obtenir directement la plage de départ qui entre à la rivière. Les plages OOP/IP à l’entrée du tournant sont lues depuis la propre configuration de la résolution (les plages avec lesquelles elle a été planifiée via /v1/gto/solver), vous ne transmettez donc que l’identifiant de résolution solve + un node_id. Gratuit (la résolution a déjà été facturée via /v1/gto/solver), comme /v1/gto/solver/tree ; renvoie les mêmes champs que la conversion de plage.

Interrogez d’abord /v1/gto/solver/tree jusqu’à spot_status = queryable. Pour tournant→rivière, vous n’assemblez pas solver_results manuellement (la plateforme le lit depuis la résolution et l’assemble).

Corps de la requête

{
  "solve": "eyJ…",
  "node_id": "root/CHECK/BET 6.000000/CALL",
  "normalize": true,
  "bluff_discount_ratio": 0.8,
  "hero_position": "oop",
  "hero_hand": "AsKs"
}
champdescription
solveObligatoire. L’identifiant de résolution renvoyé par /v1/gto/solver (une résolution du tournant).
node_idObligatoire. Une ligne d’actions du tournant, peut se terminer par le CALL/CHECK qui clôt la rue. Notation de nœud du solveur (avec espaces), par ex. "root/CHECK/BET 6.000000/CALL" (depuis les nœuds de /v1/gto/solver/tree).
normalizeFacultatif, valeur par défaut true. Indique s’il faut normaliser la plage mise à jour.
bluff_discount_ratioFacultatif. Décote des bluffs (0..1).
hero_position / hero_handBlocage de cartes facultatif : hero_position ("oop"/"ip") + hero_hand (par ex. "AsKs") supprime de la plage mise à jour du vilain chaque combo contenant une des cartes de Hero.
partner_handsTableau facultatif de combos de 4 caractères (par ex. ["Ac9c"]), nécessite hero_position. Supprime chaque combo contenant une de ces cartes de la plage du vilain range_*_new_raw. Entrée uniquement.

Exemple d’appel

curl -s https://pokerai.bet/v1/gto/turn/projected-range -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" -d @turn_projected_range_request.json

Réponse (200, tous les champs sont listés, les longues chaînes sont tronquées)

{"bluff_combos_ratio": 0.33, "bluff_discount_ratio": 1, "board": ["8d", "4h", "8s", "Qc"], "hand_bottom_ranks_ip": "TcTs:2943,TdTh:2943,TdTs:2943,9h9s:3020,…", "hand_bottom_ranks_oop": "AhKd:4646,AhKc:4646,AcKh:4646,JsTs:4746,…", "hand_ranks_ip": "Ac8c:2007,Ah8h:2007,KcKs:2645,KhKs:2645,…", "hand_ranks_oop": "8c8h:85,Ah8h:2007,Ac8c:2007,9c8c:2029,…", "node_id": "root/CHECK/BET 6.000000/CALL", "path_length": 3, "range_ip_new": "99:0.603064,A8s:0.5,AKs:0.70197,AQs:0.453337,…", "range_ip_new_raw": "9c9d:0.71487,9c9h:0.394271,9c9s:0.71487,…", "range_ip_new_raw_before_normalization": "9c9d:0.714699,9c9h:0.394176,9c9s:0.714699,…", "range_oop_new": "88:0.131148,98s:0.0902494,A8s:0.0344418,…", "range_oop_new_raw": "8c8h:0.777777,9c8c:0.185048,9h8h:0.17177,…", "range_oop_new_raw_before_normalization": "8c8h:0.418968,9c8c:0.0996806,9h8h:0.0925282,…"}
champdescription
range_oop_new / range_ip_newLa plage normalisée entrant à la rivière (notation de classe), utilisée directement comme oop_range / ip_range de la résolution de la rivière.
range_*_raw / range_*_raw_before_normalizationLes valeurs intermédiaires non normalisées / avant décote (notation de combo).
hand_ranks_* / hand_bottom_ranks_*Classement de force des mains / classement du bas de la plage (combo:rank, plus petit est plus fort).
node_id / board / path_lengthLa ligne d’actions, le board (4 cartes) et le nombre d’étapes de la ligne d’actions renvoyés tels quels.
bluff_discount_ratio / bluff_combos_ratioLes paramètres de décote des bluffs effectivement utilisés cette fois.

Remarque : gratuit, la réponse ne comporte donc aucun champ quota ; et aucun pot_type (réservé au flop).

Erreurs / états possibles

HTTPerreur / étatdéclencheur / correctif
200{ "spot_status": "computing" }La résolution n’a pas encore convergé — continuez à interroger /v1/gto/solver/tree jusqu’à ce qu’elle soit interrogeable.
400missing_solve / missing_node_idL’identifiant de résolution solve ou node_id est manquant.
410expiredLa résolution a expiré (TTL) — replanifiez-la via /v1/gto/solver.
502no_solution etc.Erreur de résolution en amont.

Télécharger : request.jsonresponse.json

EV des nœuds solver

POST https://pokerai.bet/v1/gto/evs gratuit

Schéma complet des paramètres / réponses, essayez-le en direct → référence interactive.

Les valeurs espérées par main et par action à un nœud d’une résolution terminée. Fournissez l’identifiant de résolution solve (depuis /v1/gto/solver) + un node_id (depuis /v1/gto/solver/tree) ; le paramètre facultatif hand filtre sur une main. Gratuit (la résolution a déjà été facturée). Interrogez d’abord /v1/gto/solver/tree jusqu’à spot_status = queryable.

Corps de la requête

{
  "solve": "eyJ0Ijoic2x2X3h4eXoi...(identifiant de résolution de /v1/gto/solver)",
  "node_id": "root",
  "hand": "2c2d"
}
champdescription
solveObligatoire. L’identifiant de résolution provenant de /v1/gto/solver.
node_idObligatoire. Un nœud de /v1/gto/solver/tree (notation du solveur, par ex. "root", "root/CHECK/BET 6.000000").
handFacultatif. Filtre sur les EV d’une main (par ex. "2c2d") ; omettez-le pour toutes les mains.

Réponse (200, le tableau d’EV de chaque main est aligné sur actions)

{"node_id": "root", "task_id": "slv_srp_…", "player": 1, "round": "FLOP", "actions": ["CHECK", "BET 4.000000", "BET 97.000000"], "evs": {"2c2d": [-0.826359, -0.792223, -1.643411], "2c2h": […], …}}
champdescription
actionsLes actions du nœud dans l’ordre ; le tableau d’EV de chaque main s’y aligne.
evsPar main → tableau des EV de chaque action (bb). Lorsque hand est fourni, evs est un tableau unique pour cette main.
player / round / node_id / task_idLe joueur qui agit, la street et le nœud / identifiant de résolution renvoyés tels quels.

Remarque : gratuit, donc aucun champ quota. Renvoie { "spot_status": "computing" } si la résolution n’a pas convergé (interrogez /v1/gto/solver/tree).

Jouer une main (flux complet)

Enchaînons les endpoints : une main SRP (UTG ouvre, BTN paie), Hero = UTG. Les commandes curl ci-dessous omettent l’en-tête d’authentification (comme dans Démarrage rapide).

1) Préflop — devons-nous ouvrir

POST /v1/gto/preflop
{ "hole_cards": "AdKd", "positions": { "hero": "UTG" },
  "preflop_actions": [ { "position": "SB", "action": "small blind", "amount": 0.5 }, { "position": "BB", "action": "big blind", "amount": 1 } ] }

Uniquement les blindes SB + BB (sans relance) = Hero est le premier à agir (une situation d’ouverture). Renvoie la fréquence d’ouverture et le sizing.

2) Flop — stratégie au flop

Flop 2c2h2s. Le flop est un arbre de décision, en deux étapes : récupérez d’abord l’arbre, puis utilisez le token du nœud de Hero pour récupérer la stratégie.

// 1) récupérer l’arbre (aucun hole_cards nécessaire)
POST /v1/gto/flop/tree
{ "board": "2c2h2s", "pot_type": "SRP",
  "positions": { "hero": "UTG", "raiser": "UTG", "caller": "BTN" } }
// → dans nodes[], root (is_hero:true) porte un token

// 2) utiliser le token de root pour récupérer la stratégie de Hero
POST /v1/gto/flop/node
{ "node": "<token de root>", "hole_cards": "AdKd" }

La première décision de Hero = root ; face à une mise / lorsqu’il agit une deuxième fois → choisissez le nœud is_hero:true correspondant. Voir Arbre de décision du flop.

3) Turn — résolution en temps réel, éventail dérivé du flop

Le turn (p. ex. 9d) nécessite une résolution en temps réel, qui requiert les éventails des deux joueurs entrant au turn. Obtenez-les avec l’arbre de décision du flop + la conversion d’éventail :

  1. /v1/gto/flop/tree pour les oop_range / ip_range initiaux et les nœuds de décision.
  2. Le long d’une ligne d’action au flop (p. ex. root/CHECK/BET_8/CALL), appelez /v1/gto/flop/node pour chaque nœud (sans hole_cards) afin de récupérer range_strategy et de constituer solver_results — consultez le script assemble_solver_results.py dans la section conversion d’éventail.
  3. /v1/gto/range met à jour les éventails le long de cette ligne → range_oop_new / range_ip_new sont les éventails entrant au turn.
  4. Envoyez-les au solveur (board avec 4 cartes), interrogez l’arbre jusqu’à queryable, puis récupérez le nœud :
    POST /v1/gto/solver
    { "board": "2c2h2s9d", "oop_range": "<éventail OOP entrant au turn>", "ip_range": "<éventail IP entrant au turn>",
      "pot": <pot du turn>, "effective_stack": <stack effectif du turn>, "hero": "OOP" }

Vous avez déjà votre propre éventail/spot ? À l’étape 3, fournissez directement oop_range / ip_range et ignorez la dérivation.

4) River — résolution en temps réel

La river (board avec 5 cartes) fonctionne comme le turn : vous pouvez la résoudre de façon autonome (fournissez directement l’éventail entrant à la river), ou utilisez la conversion d’éventail pour mettre à jour une nouvelle fois la ligne d’action du turn afin d’obtenir l’éventail entrant à la river, puis envoyez-le au solveur.

Moteur de poker / API sémantique

Encapsule pokerkit-plus (un sur-ensemble de pokerkit 0.7.3) : sémantique du board/de la main, éventails & équité, évaluation/équité/ICM/notation et simulation de partie. Réutilise la même clé API & le même quota — les endpoints peu coûteux consomment le quota general, ceux de Monte-Carlo le quota solve. Chemin de base /v1/pokerkit/* ; les entrées de cartes sont des chaînes sans séparateur (AsKsQs), les enums renvoient {name,value}. Paramètres/schéma complets par endpoint & essai en directréférence interactive ; spécification lisible par machine → /openapi.en.json (instantané combiné GTO + pokerkit).

Sémantique du board / de la main coûte 1 quota général

Board (indépendant de Hero) : /texture (humidité/connectivité/tirages disponibles), /nuts (nuts + combinaisons à égalité), /category-combos, /board-report (texture+nuts). Hero : /hand-tier (niveau de main constituée), /draws, /outs, /blockers, /hand-report (texture+niveau+tirages+outs en un appel).

Champs de requête (partagés dans ce groupe)

champdescription
boardObligatoire. 3/4/5 cartes communes, sans séparateur, par ex. "AsKsQs".
holeObligatoire pour les endpoints Hero (hand-tier / draws / outs / blockers / hand-report). 2 cartes privatives, par ex. "JhTh" ; les endpoints board (texture / nuts / category-combos / board-report) l’omettent.
hand_typeFacultatif, StandardHighHand par défaut (v1 uniquement ; les autres types renvoient 400).
deadFacultatif. Cartes mortes / retirées (acceptées par tous les endpoints de ce groupe).

Texture coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/texture — Structure du board : humidité/connectivité/plage de rang/disponibilité des tirages/forme des couleurs. Paramètres complets / essayer en direct →

{"board": "AsKsQs"}

{"result": {"cards": ["As", "Ks", "Qs"], "wetness": {"name": "WET", "value": "Wet"}, "connectivity": {"name": "HIGH", "value": "High"}, "rank_band": {"name": "HIGH", "value": "High"}, "straight_draw": {"name": "OPEN_ENDED", "value": "Open-ended"}, "flush_draw": {"name": "LIVE", "value": "Live"}, "are_two_tone": false, "are_monotone": true, "are_rainbow": false}}

Nuts coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/nuts — Main réalisable la plus forte + toutes les combinaisons de deux cartes à égalité (avec is_royal / board_is_nuts). Paramètres complets / essayer en direct →

{"board": "AsKsQs"}

{"result": {"hand": "TsJsKsQsAs", "combos": [{"cards": ["Ts", "Js"], "hand": "TsJsKsQsAs", "as_frozenset": ["Js", "Ts"]}], "candidate_count": 1176, "board_is_nuts": false, "is_royal": true, "label": {"name": "STRAIGHT_FLUSH", "value": "Straight flush"}}}

Combinaisons par catégorie coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/category-combos — Chaque combinaison de deux cartes encore possible, regroupée par catégorie constituée. Paramètres complets / essayer en direct →

{"board": "AsKsQs"}

{"result": {"by_category": {"HIGH_CARD": [{"cards": ["2c", "3c"], "hand": "2c3cKsQsAs", "as_frozenset": ["2c", "3c"]}, {"cards": ["2c", "3d"], "hand": "2c3dKsQsAs", "as_frozenset": ["2c", "3d"]}], …}}}

Rapport de board coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/board-report — texture + nuts en un appel (vue d’ensemble du board). Paramètres complets / essayer en direct →

{"board": "AsKsQs"}

{"result": {"texture": {"cards": ["As", "Ks", "Qs"], "wetness": {"name": "WET", "value": "Wet"}, "connectivity": {"name": "HIGH", "value": "High"}, "rank_band": {"name": "HIGH", "value": "High"}, "straight_draw": {"name": "OPEN_ENDED", "value": "Open-ended"}, "flush_draw": {"name": "LIVE", "value": "Live"}, "are_two_tone": false, "are_monotone": true, "are_rainbow": false}, "nuts": {"hand": "TsJsKsQsAs", "combos": [{"cards": ["Ts", "Js"], "hand": "TsJsKsQsAs", "as_frozenset": ["Js", "Ts"]}], "candidate_count": 1176, "board_is_nuts": false, "is_royal": true, "label": {"name": "STRAIGHT_FLUSH", "value": "Straight flush"}}}}

Niveau de main coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/hand-tier — Niveau de main constituée de Hero (paire / deux paires / brelan / niveaux de kicker, is_nut). Paramètres complets / essayer en direct →

{"hole": "JhTh", "board": "AsKsQs"}

{"result": {"category": {"name": "STRAIGHT", "value": "Straight"}, "is_nut": false, "pair_tier": null, "two_pair_tier": null, "three_of_a_kind_tier": null, "kicker_tier": null, "nut_rank": {"name": "NON_NUT", "value": "Non-nut"}}}

Tirages coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/draws — Tirages de Hero (tirage quinte / couleur, rang des nuts). Paramètres complets / essayer en direct →

{"hole": "Ah5h", "board": "Kh7h2c"}

{"result": {"straight_draw": null, "flush_draw": {"name": "LIVE", "value": "Live"}, "nut_rank": {"name": "NUT", "value": "Nut"}}}

Outs coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/outs — Outs de Hero qui améliorent la catégorie constituée, regroupés + décompte. Paramètres complets / essayer en direct →

{"hole": "Ah5h", "board": "Kh7h2c"}

{"result": {"by_category": {"ONE_PAIR": ["2d", "2s", "5c", "5d", "5s", "7c", "7d", "7s", "Kc", "Kd", "Ks", "Ac", "Ad", "As"], "FLUSH": ["2h", "3h", "4h", "6h", "8h", "9h", "Th", "Jh", "Qh"]}, "count": 23}}

Bloqueurs coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/blockers — nombre de combinaisons nuts bloquées par Hero (cartes bloqueuses / fraction). Paramètres complets / essayer en direct →

{"hole": "AhAd", "board": "AsKsQs"}

{"result": {"nut_combos_total": 1, "nut_combos_blocked": 0, "blocker_cards": [], "block_fraction": 0.0, "blocks_nuts": false}}

Rapport de main coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/hand-report — texture + niveau + tirages + outs en un appel (vue d’ensemble de Hero, produit phare). Paramètres complets / essayer en direct →

{"hole": "JhTh", "board": "AsKsQs"}

{"result": {"texture": {"cards": ["As", "Ks", "Qs"], "wetness": {"name": "WET", "value": "Wet"}, "connectivity": {"name": "HIGH", "value": "High"}, "rank_band": {"name": "HIGH", "value": "High"}, "straight_draw": {"name": "OPEN_ENDED", "value": "Open-ended"}, "flush_draw": {"name": "LIVE", "value": "Live"}, "are_two_tone": false, "are_monotone": true, "are_rainbow": false}, "tier": {"category": {"name": "STRAIGHT", "value": "Straight"}, "is_nut": false, "pair_tier": null, "two_pair_tier": null, "three_of_a_kind_tier": null, "kicker_tier": null, "nut_rank": {"name": "NON_NUT", "value": "Non-nut"}}, "draws": {"straight_draw": null, "flush_draw": null, "nut_rank": null}, "outs": {"by_category": {}, "count": 0}}}

Éventails / équité coûte 1 quota général

/range/expand (notation → combinaisons concrètes), /range/value (éventail de valeur selon le plancher de catégorie constituée ; aggression ∈ NO_BET/SINGLE_BET/RAISED), /range/nut-advantage (part exacte des nuts, sans échantillonnage).

Champs de requête (partagés dans ce groupe)

champdescription
notation(expand) tableau de notation d’éventail, par ex. ["AA","KQs","QQ+"].
hero / villain(nut-advantage) un tableau de notation d’éventail chacun.
boardCartes communes (obligatoires pour value / nut-advantage ; expand l’omet).
aggression(value) NO_BET / SINGLE_BET / RAISED définit le plancher de catégorie ; ou utilisez floor pour le définir explicitement.

Développer l’éventail coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/range/expand — Développez la notation d’éventail en combinaisons concrètes de deux cartes. Paramètres complets / essayer en direct →

{"notation": ["AA", "KQs"]}

{"result": [["Ac", "Ad"], ["Ac", "Ah"], ["Ac", "As"], ["Ad", "Ah"], ["Ad", "As"], ["Ah", "As"], ["Kc", "Qc"], ["Kd", "Qd"], ["Kh", "Qh"], ["Ks", "Qs"]]}

Valeur d’éventail coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/range/value — Construisez un éventail de valeur selon le plancher de catégorie constituée (agression). Paramètres complets / essayer en direct →

{"board": "AsKsQs", "aggression": "SINGLE_BET"}

{"result": [["2s", "3s"], ["2s", "4s"], ["2s", "5s"], ["2s", "6s"], ["2s", "7s"], ["2s", "8s"], …]}

Avantage nuts d’éventail coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/range/nut-advantage — Répartition exacte de la part des nuts selon le nombre de combinaisons (sans échantillonnage, déterministe). Paramètres complets / essayer en direct →

{"hero": ["AA", "KK"], "villain": ["QQ", "JJ"], "board": "AsKsQs"}

{"result": {"hero_share": 0.5, "villain_share": 0.5, "basis": {"name": "NUT_SHARE", "value": "Nut share"}}}

Évaluation · équité · ICM · notation

coûte 1 quota général /eval/hand, /eval/compare (classement + égalités), /icm (déterministe), /notation/parse (.phh → structuré). coûte 1 quota résolution Monte-Carlo : /equity, /hand-strength, /range/equity-advantage — avec sample_count (plafonné) et seed (reproductible, ~2 s à 10 k).

Champs de requête (partagés dans ce groupe)

Les points de terminaison Monte-Carlo (equity / hand-strength / range/equity-advantage) consomment le quota résolution ; les autres consomment le quota général.

champdescription
hole / holdings / boardEntrées d’évaluation : un seul hole + board (eval/hand), ou plusieurs mains holdings (2+) + board (eval/compare).
ranges / hole_range / hero / villainNotation de plage (equity / hand-strength / range/equity-advantage).
sample_count / seedMonte-Carlo : nombre d’échantillons (plafonné ; toute valeur supérieure est ramenée au plafond) / graine RNG (reproductible).
payouts / chips(icm) structure des gains / jetons par joueur.
text(notation/parse) une chaîne d’historique de main .phh.

Évaluer une main coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/eval/hand — Évaluez hole + board en main constituée (5 cartes + libellé de catégorie). Paramètres complets / essayer en direct →

{"hole": "JhTh", "board": "AsKsQs"}

{"result": {"hand": "JhThAsKsQs", "label": {"name": "STRAIGHT", "value": "Straight"}}}

Comparer des mains coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/eval/compare — Classez 2+ holdings sur un board (avec égalités). Paramètres complets / essayer en direct →

{"holdings": ["AcAd", "KsKh", "JhTh"], "board": "AsKsQs"}

{"result": [{"index": 2, "hole": "JhTh", "hand": "JhThAsKsQs", "rank": 1, "label": {"name": "STRAIGHT", "value": "Straight"}}, {"index": 0, "hole": "AcAd", "hand": "AcAdAsKsQs", "rank": 2, "label": {"name": "THREE_OF_A_KIND", "value": "Three of a kind"}}, {"index": 1, "hole": "KsKh", "hand": "KsKhAsKsQs", "rank": 3, "label": {"name": "THREE_OF_A_KIND", "value": "Three of a kind"}}]}

Équité coûte 1 quota résolution

POST https://pokerai.bet/v1/pokerkit/equity — Équité de plusieurs plages sur un board (Monte-Carlo). Paramètres complets / essayer en direct →

{"ranges": [["AA"], ["KK"]], "board": "", "sample_count": 2000, "seed": 7}

{"result": {"equities": [0.8235, 0.1765], "sample_count": 2000}}

Force de la main coûte 1 quota résolution

POST https://pokerai.bet/v1/pokerkit/hand-strength — Fraction de victoires de Hero contre N joueurs (Monte-Carlo). Paramètres complets / essayer en direct →

{"hole_range": ["AhKh"], "board": "Qh7c2d", "player_count": 3, "sample_count": 2000, "seed": 7}

{"result": {"hand_strength": 0.3945, "player_count": 3, "sample_count": 2000}}

ICM coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/icm — Répartition d’équité ICM à partir des jetons / gains (déterministe). Paramètres complets / essayer en direct →

{"payouts": [50, 30, 20], "chips": [5000, 3000, 2000]}

{"result": {"icm": [38.392857142857146, 32.75, 28.857142857142854]}}

Avantage d’équité de plage coûte 1 quota résolution

POST https://pokerai.bet/v1/pokerkit/range/equity-advantage — Répartition de la part d’équité entre deux plages (Monte-Carlo). Paramètres complets / essayer en direct →

{"hero": ["AA", "KK"], "villain": ["QQ", "JJ"], "board": "AsKsQs", "sample_count": 2000, "seed": 7}

{"result": {"hero_share": 0.80325, "villain_share": 0.19675, "basis": {"name": "EQUITY", "value": "Equity"}, "sample_count": 2000}}

Analyser la notation coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/notation/parse — Analysez un historique de main .phh en configuration structurée (variant / blinds / stacks / actions…). Paramètres complets / essayer en direct →

{"text": "variant = \"NT\"\nante_trimming_status = true\nantes = [0, 0]\nblinds_or_straddles = [1, 2]\nmin_bet = 2\nstarting_stacks = [200, 200]\nactions = [\"d dh p1 AhKh\", \"d dh p2 QsQd\", \"p1 cbr 6\", \"p2 cc\", \"d db Qh7c2d\"]\n"}

{"result": {"variant": "NT", "ante_trimming_status": true, "antes": [0, 0], "blinds_or_straddles": [1, 2], "bring_in": null, "small_bet": null, "big_bet": null, "min_bet": 2, "starting_stacks": [200, 200], "actions": ["d dh p1 AhKh", "d dh p2 QsQd", "p1 cbr 6", "p2 cc", "d db Qh7c2d"], "automations": [{"name": "ANTE_POSTING", "value": "Ante posting"}, …], "author": null, "event": null, "day": null, "month": null, "year": null, "hand": null, "currency": null}}

Simulation de partie coûte 1 quota général

Relecture sans état, à information complète : le client fournit la liste des actions, le serveur reconstruit l’état avec pokerkit (aucun état côté serveur). /games/state (instantané de la situation actuelle), /games/step (applique next_action ; expected_action_count est un jeton de concurrence optimiste, discordance → 409), /notation/replay (configuration ou texte .phh → instantanés par étape), /cards/normalize (valide/normalise une chaîne de cartes).

Champs de requête (partagés dans ce groupe)

champdescription
variantObligatoire. Code de variante, par ex. "NT" (hold’em sans limite) ; liste complète dans /v1/pokerkit/meta.
antes / starting_stacksObligatoires. Antes / tapis de départ par joueur (tableaux d’entiers).
blinds_or_straddles / min_betBlindes / straddles ; min_bet est obligatoire pour le no-limit / pot-limit (le fixed-limit / stud utilise small_bet / big_bet / bring_in).
actionsListe des actions effectuées jusqu’ici (notation pokerkit : d dh p1 AhKh distribue les cartes fermées, p2 cbr 6 relance à 6, p1 cc checke/suit, p1 f se couche).
next_action / expected_action_count(étape) action à appliquer / jeton de concurrence (= longueur de la liste que vous étendez ; discordance → 409).
text / index(relecture) un texte .phh à la place ; index renvoie uniquement cette étape. cards/normalize n’accepte que cards (une chaîne de cartes).

État de la partie coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/games/state — Liste d’actions → instantané de la situation actuelle (toutes les cartes fermées affichées). Paramètres complets / essayer en direct →

{"variant": "NT", "antes": [0, 0], "blinds_or_straddles": [1, 2], "min_bet": 2, "starting_stacks": [200, 200], "actions": ["d dh p1 AhKh", "d dh p2 QsQd", "p2 cbr 6"]}

{"result": {"snapshot": {"terminal": false, "street_index": 0, "actor_index": 0, "pot": 8, "bets": [2, 6], "stacks": [198, 194], "board": [], "hole_cards": [{"player": 0, "cards": ["Ah", "Kh"]}, {"player": 1, "cards": ["Qs", "Qd"]}], "legal_actions": [{"action": "fold"}, {"action": "check_or_call", "amount": 4}, {"action": "complete_bet_or_raise_to", "min": 10, "max": 200}]}, "actions": ["d dh p1 AhKh", "d dh p2 QsQd", "p2 cbr 6"]}}

Étape de la partie coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/games/step — Appliquer next_action → nouvel instantané (jeton de concurrence ; 409 en cas de discordance). Paramètres complets / essayer en direct →

{"variant": "NT", "antes": [0, 0], "blinds_or_straddles": [1, 2], "min_bet": 2, "starting_stacks": [200, 200], "actions": ["d dh p1 AhKh", "d dh p2 QsQd", "p2 cbr 6"], "next_action": "p1 cc", "expected_action_count": 3}

{"result": {"snapshot": {"terminal": false, "street_index": 1, "actor_index": null, "pot": 12, "bets": [0, 0], "stacks": [194, 194], "board": [], "hole_cards": [{"player": 0, "cards": ["Ah", "Kh"]}, {"player": 1, "cards": ["Qs", "Qd"]}], "legal_actions": [{"action": "deal_board"}]}, "actions": ["d dh p1 AhKh", "d dh p2 QsQd", "p2 cbr 6", "p1 cc"]}}

Relecture de notation coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/notation/replay — configuration ou .phh → instantanés par étape (index facultatif pour une seule étape). Paramètres complets / essayer en direct →

{"variant": "NT", "antes": [0, 0], "blinds_or_straddles": [1, 2], "min_bet": 2, "starting_stacks": [200, 200], "actions": ["d dh p1 AhKh", "d dh p2 QsQd", "p2 cbr 6", "p1 f"], "index": 2}

{"result": {"snapshot": {"terminal": false, "street_index": 0, "actor_index": 1, "pot": 3, "bets": [2, 1], "stacks": [198, 199], "board": [], "hole_cards": [{"player": 0, "cards": ["Ah", "Kh"]}, {"player": 1, "cards": ["Qs", "Qd"]}], "legal_actions": [{"action": "fold"}, {"action": "check_or_call", "amount": 1}, {"action": "complete_bet_or_raise_to", "min": 4, "max": 200}]}, "step_count": 5}}

Normaliser les cartes coûte 1 quota général

POST https://pokerai.bet/v1/pokerkit/cards/normalize — Valider / normaliser une chaîne de cartes en cartes standard à 2 caractères. Paramètres complets / essayer en direct →

{"cards": "Ah Ks Qs"}

{"result": ["Ah", "Ks", "Qs"]}

Également, GET /v1/pokerkit/meta (versions / codes de variantes / types de main / vocabulaires d’énumération). Schéma complet des paramètres et essai en direct pour chaque endpoint → référence interactive (parcourez les deux API depuis le haut).

Téléchargement de tous les exemples

Un récapitulatif de la requête/réponse complète de chaque endpoint (données réelles, aucun champ omis) se trouve dans le « Télécharger » de chaque section ci-dessus, ou : préflop · arbre du flop · nœud du flop · solveur · plage · plage projetée · réponse de plage projetée · script d’assemblage.

Gestion des versions & journal des modifications

Politique de versionnement

  • Le /v1 dans le chemin est la version majeure. Les changements incompatibles (suppression/modification de champs, modification de la sémantique) passent à une nouvelle version majeure /v2, et /v1 reste disponible.
  • Les ajouts rétrocompatibles (nouveaux endpoints, nouveaux champs facultatifs, nouveaux champs de réponse) sont ajoutés directement à /v1 sans avis distinct — veuillez analyser en « ignorant les champs inconnus » et ne validez pas strictement les champs de réponse au moyen d’une liste blanche.
  • La dépréciation d’un champ sera signalée à l’avance dans le journal des modifications ci-dessous, puis celui-ci ne sera supprimé qu’après une période de transition.

Journal des modifications

datemodification
2026-07-22/v1/gto/solver accepte désormais les champs indépendants raise_sizes, donk_sizes et raise_limit, en plus de bet_sizes.
2026-07-12Ajout de POST /v1/gto/solver/release — libère tôt le port du pool d’une résolution afin qu’il retourne immédiatement au pool au lieu d’attendre l’expiration du TTL du cache (facultatif, gratuit ; appelez-le après votre dernier /solver/tree / /solver/node pour cette résolution).
2026-07-04Ajout de /v1/gto/evs (EV de nœud par main et par action d’une résolution terminée) ; /v1/gto/turn/projected-range prend désormais aussi en charge partner_hands.
2026-07-04/v1/gto/flop/projected-range respecte désormais bluff_discount_ratio / bluff_combos_ratio de la requête, injecte la propre main de Hero dans la plage de Hero et ajoute partner_hands (bloque les cartes mortes du partenaire dans la plage du vilain).
2026-06-22Ajout de l’API de moteur de poker / sémantique /v1/pokerkit/* (sémantique du board/de la main, plages/équité, évaluation/équité/ICM/notation, simulation de partie ; même clé et même quota). Voir ci-dessous.
2026-06-22Ajout de /v1/gto/preflop/range (toute la plage préflop 13×13, 169 mains en un seul appel).
2026-06-18Scission du flop : suppression de la requête unique /v1/gto/flop, remplacée par /v1/gto/flop/tree (récupérer l’arbre) + /v1/gto/flop/node (récupérer le nœud, gratuit), aligné sur l’arbre/le nœud du solveur.
2026-06-17Ajout de /v1/gto/flop/projected-range (un wrapper pratique autour de /v1/gto/range : fournissez la situation complète du flop + la ligne d’actions, le serveur assemble automatiquement l’arbre de décision et renvoie directement la plage du tournant).
2026-06-17Format board / main unifié : l’entrée est une chaîne sans séparateur, le board de réponse est toujours renvoyé sous forme de tableau.
2026-06-17Ajout de la spécification OpenAPI 3.0 ; ajout de la documentation du tutoriel complet sur la notation des plages / les concepts / le flux.
2026-06-17/v1/gto/solver prend désormais en charge la résolution du flop en temps réel (board=3) ; bet_sizes.flop peut personnaliser les tailles de mise du flop.
2026-06-17Correction : amount_bb pour une relance de requête flop était incorrectement à 0 (renvoie désormais la BB absolue correcte).
2026-06-17Ajout de la conversion de plage /v1/gto/range ; /flop/tree expose les plages initiales oop_range / ip_range ; /flop et /solver/node renvoient la stratégie de plage complète lorsque hole_cards n’est pas fourni.
2026-06-16Ajout de la famille de solveur en temps réel pour le tournant / la rivière /v1/gto/solver (quota de résolution distinct) ; ajout de l’arbre de décision du flop /v1/gto/flop/tree.
2026-06-15Suppression du champ recommendation de toutes les réponses — veuillez choisir vous-même les actions en fonction de frequency.

pokerai.bet · GTO API v1