ドキュメント
API は稼働中
ドキュメント/概要
1つのキー · 4ストリート

1回のリクエストで戦略を取得。

1つのセルフサービス API で MelaSolver GPU を利用できます。ミリ秒単位の事前計算済みルックアップから始めるか、カスタムのフロップ、ターン、またはリバーのスポットをリアルタイムソルバープールに送信してください。

クイックスタートを実行 APIリファレンスを開く POST /v1/gto/preflop · 41ms · 200 OK

Postman コレクション

公開コレクションをダウンロードして Postman にインポートし、リクエストを送信する前にコレクションの apiKey 変数を API キーに設定してください。Authorization: Bearer {{apiKey}} と公開 https://pokerai.bet ベース URL を使用します。含まれる例は GTO プリフロップ戦略と PokerKit のボードテクスチャを扱います。

Postman コレクション ダウンロード可能なソースには実際のキー、Cookie、または非公開エンドポイントは含まれていません。完全な公開仕様については、APIリファレンスおよびOpenAPIスナップショットを参照してください。

パスを選択

どちらも同じ API キーと月間クォータを使用します。

事前計算済みの検索

高速

プリフロップと580万件超のフロップソリューション。タスクのポーリングなしで、ミリ秒単位で戦略を返します。

プリフロップから始める

リアルタイム解析

カスタム

カスタムのフロップ、ターン、リバーのツリー。1回送信し、タスクIDでポーリングしてから、計算済みの戦略を取得します。

ソルブを送信

最初の200レスポンス

インストール、認証、呼び出し。それ以外の準備は不要です。

01 / インストールSDKを選択
02 / 認証1つのキーをエクスポート
03 / リクエストPreflop APIを呼び出す
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 }
}

開発を続ける

長い1ページを探し回ることなく、最初の呼び出しから本番環境へ移行できます。

認証

すべてのリクエストにはAPI キーが必要です。60秒でキーを取得:

  1. コンソールを開き、メールアドレスを入力します → メールで認証コードを受け取ります(パスワードレスログイン、登録不要)。
  2. コードを入力してログインします → API キーを作成 → コピーします(表示は一度だけなので、安全に保管してください)。
  3. 環境変数として設定します: export POKERAI_API_KEY=gto_xxxxxxxx。これで以下のクイックスタートを実行できます。

以降は、すべてのリクエストのリクエストヘッダーで同じキー(先ほどコピーした gto_xxx — これが「Bearer トークン」です)を送信します。以下のどちらか一方を選択してください — キーは1つであり、2つではありません:

Authorization: Bearer gto_xxxxxxxx     # 標準(推奨。OpenAPI スキーム BearerApiKey と一致)
# または(完全に等価。どちらか一方を選択)
X-API-Key: gto_xxxxxxxx                 # 等価(OpenAPI スキーム XApiKey)。一部のゲートウェイ / SDK / 簡易テストに便利

クォータ

月次クォータは2種類あり、個別に計測され、毎月1日にリセットされます。現在の使用量はコンソールで確認できます:

  • 一般クォータ(無料、デフォルトで月1,000件): プリフロップ、プリフロップレンジ、フロップの意思決定ツリー取得、レンジ変換 /v1/gto/range、プロジェクテッドレンジ呼び出しは、それぞれ1件として課金されます。
  • 解析クォータ(無料、デフォルトで月25件): リアルタイムソルバー /v1/gto/solver は、新しい解析をトリガーするたびに1件として課金されます。キャッシュ済みの解析結果の再利用とツリー/ノードの取得は無料です(課金時はレスポンスに solve_quota フィールドがあり、非課金時はありません)。

エラーモデル

すべてのエラーは統一された JSON を返します: { "error": "<code>", "message": "<description>" }。いくつかの例外があります: 一部の 502 は message ではなく reason を使用します。すべてのソルバーがビジー状態の場合の 429 は { "status": "busy", "message": ... } のようになります。エンドポイント固有の errorは各エンドポイントの「想定されるエラー」テーブルにあります。共通のステータスコードは以下のとおりです:

HTTPエラー / 意味再試行?
400無効な入力またはフィールド不足(具体的な error については各エンドポイントのテーブルを参照)。いいえ、入力を修正してください
401missing_api_key / invalid_api_key: キーがないか無効です。いいえ、キーを確認してください
403invalid_node_token / invalid_solve: トークン/ハンドルが無効、またはあなたのものではありません。いいえ、先にツリーを再取得するか再スケジュールしてください
404no_solution: このスポットにはまだ GTO データがありません。いいえ、スポットを変更してください
429quota_exceeded(一般)/ solve_quota_exceeded(解析): 月次クォータを使い切りました。いいえ、1日にリセットされるのを待つか、クォータをアップグレードしてください
429status: busy: すべてのソルバーがビジー状態です(/v1/gto/solver のみ)。課金されませんはい、待機時間を増やして再試行してください
502no_resultreason: timeout / no_worker_available)/ auth_unavailable / solver_unreachable: バックエンドが一時的に利用できません。はい、待機時間を増やして2~3回再試行してください

エラーレスポンス本文の例

400(無効な入力):

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

401(キーがない)/ 404(データなし)/ 429(クォータを使い切り)— 単一フィールドまたは短いメッセージ:

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

502(バックエンドが一時的に利用不可、再試行可能):

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

再試行: 再試行する価値があるのは 429 busy と 502 だけです — 指数バックオフを使用します(約1秒から開始し、倍にして、最大2~3回)。それ以外(400/401/403/404/クォータ枯渇)は最終的なものであり、再試行しても無意味です。入力を修正する / キーを変更する / ツリーを再取得する、または毎月1日にクォータがリセットされるまで待ってください。秒あたりのレート制限はないため、Retry-After ヘッダーはありません。

クイックスタート

キーを取得したら(上記を参照)、POKERAI_API_KEY として保存し、この curl をコピーします — 最も簡単に成功する呼び出しです。ヒーローは UTG でオープンの機会(RFI)があり、プリフロップの事前解析済み解析結果はミリ秒単位で返されます。同じスタータースニペットはダッシュボードからもコピーできます。

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}]}'

実際のレスポンス(AKs を持つ UTG、オープン機会 → 3BB に100%オープン):

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

レイズに直面していますか? 相手のアクションを preflop_actions に追加するだけです({"position":"UTG","action":"raise","amount":3} を追加し、ヒーローを MP に変更すると → 3ベットスポットになり、situationRaise を返します)。各アクションのミックス頻度が返されます(推奨アクションはありませんfrequency に基づいて自分で選択してください)。以下のセクションは、事前解析済みの解析結果(プリフロップ / フロップ)、リアルタイムのソルバー計算レンジ変換の3部構成です。

クライアント SDK Python · TypeScript · MCP

HTTP を手書きしたくありませんか? 公式クライアントは OpenAPI 仕様から自動生成され、完全に型付けされているため、常に API に追従します。認証は API キー だけです。

Python pip

pip install pokerai-bet   # 配布名は pokerai-bet、pokerai としてインポート

同じクイックスタートのスポット(ヒーロー の UTG オープン)を型付きで:

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())

実際の出力(クイックスタートと同じスポット):

{"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 }]

パス、リクエスト本文、レスポンスフィールドはすべて型チェックされるため、エディタで API 全体を自動補完できます。型は仕様から openapi-typescript によって生成され、ランタイムは openapi-fetch です。

MCP(LLM エージェント向け) npm

Claude / Cursor などから Pokerai API をツールとして呼び出せます(@pokerai/mcp):

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

デフォルトでは事前解析済み検索ツールが5つです。"POKERAI_ENABLE_SOLVE": "1" を追加すると、リアルタイムのソルバーツールを有効化できます(解析クォータを消費します)。

概念

全体像となる考え方です。一度読むと、以下のエンドポイントごとのセクションをよりスムーズに理解できます。

戦略を取得する2つの方法

  • 事前解析済みの解析結果: プリフロップ/フロップは事前解析済みの GTO 解析結果を使用し、ミリ秒単位で返されるため、高速なレスポンスが必要なユースケースに適しています。
  • リアルタイムのソルバー計算: フロップ/ターン/リバーはソルバーによりライブで計算されます(フロップは約70秒、ターン/リバーはより高速です)。任意のカスタムレンジ/スポットに適しています。
  • レンジ変換: アクションラインに沿ってレンジを次のストリートに入るレンジへ更新し、それをソルバーに渡します。

推奨アクションは返されません

すべての戦略は各アクションのミックス頻度(0~1)を返し、あなたに代わってアクションを選びませんfrequency から自分で実装してください(最大確率を選ぶ、または頻度に従ってランダムにサンプリングします)。

ベットサイズ: amount_bb と sizing_pot

bet/raise には、2つのサイズフィールドがあります。amount_bb(絶対額、つまりレイズの BB 額)と、sizing_pot(ポットに対する値、標準的なポット比の表記)です:

  • bet(最初のベット) = bet ÷ pot。
  • raise(ベットに対して) = (レイズ後の額 − 現在のベット)÷ コール後のポット。

例: 3 のオープンに対して 9 へ 3bet。ポットは 4.5、コール後は 4.5+3=7.5、レイズの上乗せは 9−3=6 なので、sizing_pot = 6/7.5 = 0.8 です。オールインの場合は allin: true も含まれます。

tree → node(ツリーを取得 → ノードを取得)

フロップの意思決定ツリーとリアルタイムのソルバーはいずれも2ステップです。まずツリー全体を取得し(各意思決定ノードには token が含まれます)、次に ヒーロー ノードのトークンを使ってそのステップの戦略を取得します。

ツリーを取得   /flop/tree   または   /solver(+ /solver/tree をポーリング)
         └─→ nodes[]: 各ノードに is_hero + token が含まれます
               └─→ is_hero:true のノードを選択
ノードを取得   /flop/node  または   /solver/node    (本文にそのノードのトークンを含める)
               └─→ このステップのミックス戦略
  • フロップ: /flop/tree(1回消費)→ /flop/node(無料)。root ノード = ヒーロー の最初の意思決定です。
  • ソルバー: /solver のスケジュールで solve ハンドルが返されます(1回消費)→ /solver/tree のポーリング + /solver/node(どちらも無料)。レンジはスケジュール時に一度だけ指定され、再度渡しません。

ノードパス表記(ツリーのソースに応じて2つの規則があります): フロップの意思決定ツリーでは BET_8(アンダースコア、整数 BB)を使用し、ソルバーツリーでは BET 8.000000(空白、小数6桁)を使用します。node_id を渡す/移動する際は、そのツリー内(または solver_results 内)のラベルに1文字単位で一致させる必要があります。

ノード状態マシン(リアルタイム解析)

スケジュール後、/solver/treespot_status をポーリングします: available(未スケジュール)→ computing(解析中、ポーリングを継続)→ queryable(ノードを取得可能)→ expired(TTL によりキャッシュが回収済み。再スケジュールが必要)。問い合わせが完了したら、任意で /solver/release を呼び出してポートを直ちにプールへ返却できます(そうしない場合は TTL により回収されます)。リリース後、この solve ハンドルへの以後の問い合わせは expired を返します。

事前解析済みの解析結果 事前解析済み · ミリ秒

プリフロップとフロップでは事前解析済みの GTO 解析結果を利用し、即座に返されるため、高速な応答が必要な用途に適しています。有効スタックは 100BB に固定されています(事前解析済みであり、入力ではありません)。実際のソルバーでフロップをライブ解析するには、次の節を参照してください。

プリフロップ

POST https://pokerai.bet/v1/gto/preflop 一般枠を 1 消費

完全なパラメータ/レスポンススキーマとインタラクティブリファレンスで実際に試す → インタラクティブリファレンス.

「ポットが何ベットか」を判断する必要はありません。ヒーローより前のプリフロップアクションを順に指定すれば、サーバーがスポットを自動的に導出します(未オープン/レイズに直面/3ベット/4ベット…)。

注記 · リクエストボディ

フィールド説明
hole_cards文字列ヒーローの 2 枚のホールカード。例:"AdKd"
positions.hero文字列ヒーローのポジション。SB BB UTG MP CO BTN のいずれか(positions の下に配置)。
preflop_actions配列スモールブラインドから ヒーロー の直前のプレイヤーまでの完全で明示的なアクション列です(ヒーロー はこの列に含まれません。ヒーロー のポジションは positions.hero で指定し、この列は ヒーロー の直前のプレイヤーで終わります)。各項目は { position, action, amount, allin? } です。以下の表を参照してください。
preflop_version文字列任意。使用する6max プリフロップチャートセットです: 6max(デフォルト)/ 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb。プラットフォームのデフォルト(6max)を使用するには、このパラメータを省略します。不明な値の場合は 400 unsupported_preflop_version になります。同じスポットでもバージョンが異なれば頻度は異なります。

各 preflop_actions 項目のフィールド

フィールド説明
position文字列このアクションのポジション。SB BB UTG MP CO BTN のいずれかです。
action文字列使用可能な値は "small blind" / "big blind" / "raise" / "call" / "fold" です(ブラインドは2語からなる文字列であることに注意してください)。
amount数値このアクションで新たに投じる増分額です(BB 単位、累積合計ではありません)。例: スモールブラインドは 0.5、ビッグブラインドは 1、3 へのオープンレイズは amount が 3(0 から)、すでに 1 を投じたプレイヤーが 9 にリレイズする場合は amount が 8 です。fold ではこの値を省略します(0 として扱われます)。ポット = すべての amount の合計です。
allin真偽値任意。ショートスタックのオールイン(ベット/コール額が最小レイズ未満)を示します。true の場合、最小レイズのチェックは省略されます。

検証(違反時 → 400 invalid_actions: この列は small blind(0.5)、続いて big blind(1)で開始する必要があります。各 raise/call には正の amount が必要です。raise累積合計は現在のベットを超え、最小レイズ(= 現在のベット + 直前のレイズ額。したがってオープンは 2BB 以上、3 へのオープンに対する 3ベットは 5BB 以上)を満たす必要があります。ただし allin:true の場合を除きます。call の累積合計は現在のベットと正確に一致する必要があります。ただし allin:true の場合を除きます。

正確な額が影響するのはポット/sizing_pot のみで、頻度には影響しません: 正確な amount 値を指定しても、ポット/sizing_pot が正確になるだけです。GTO の頻度はスポット(RFI/3ベット/4ベット + ポジション)で決まり、ベットサイズでは変わりません

呼び出し例

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}]}'

デフォルト(6max)を使用するには preflop_version パラメータを省略してください。利用可能なバージョンは以下に一覧で示すほか、GET /v1/gto/preflop/versions でライブ取得できます。

レスポンス(200)

{"hole_cards": "AhKh", "situation": "Raise", "strategy": [{"action": "raise", "frequency": 1, "amount_bb": 9, "sizing_pot": 0.8}], "quota": {"used": 7, "limit": 100}}
フィールド説明
hole_cardsエコーされたハンド。
situationヒーロー の番になったときにテーブルが置かれている状態です: RFI(ポットに誰も参加しておらず、ヒーロー にオープンの機会がある)/ Limp(誰かがリンプし、レイズはない)/ Raise(1回のオープンレイズに直面している)/ 3-Bet / 4-Bet / 5-Bet。注: BB は常に Limp になります(BB がアクションする前に、必ず誰かがポットに参加しているためです)。
strategy[]各アクションのミックス戦略です。raise には amount_bb(レイズの絶対額、BB 単位)と sizing_potベットサイズを参照)が含まれます。プリフロップの amount_bb は ヒーロー より前のレイズ回数によって決まり、以下の表を参照してください。推奨アクションは返されませんfrequency に基づいて自分で選択してください。
quota今月の一般クォータ使用量(used / limit)です。

プリフロップの amount_bb(事前解析済みのフロップポットから導出される、レイズの額):

ヒーロー より前のレイズ回数スポットamount_bb
0オープン3
13ベット9
24ベット25
≥35ベット以上オールイン 100 (allin: true)

戦略バージョン preflop_version

同じ6maxでもチャートセットは異なります(同じスポットでも頻度が異なります)。デフォルトの 6max を使用する場合は省略してください。正式な一覧はディスカバリーエンドポイント GET /v1/gto/preflop/versions です(無料。id + label + default を返します):

id(preflop_version として渡す)説明
6max(デフォルト)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"}

想定されるエラー

HTTPエラー発生条件/修正方法
400invalid_hole_cardshole_cards が2枚のカードではありません(例:"AdKd")。
400unsupported_table_size / invalid_positions / invalid_actionsテーブルタイプ(現在は6maxのみ)、hero/ポジション、または preflop_actions が無効です。
400unsupported_preflop_versionpreflop_version が許可されたセット(6max / 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb)に含まれていません。
404no_solutionこのプリフロップのスポットには事前解析済みの解析結果がありません。スポットを変更してください。

ダウンロード: request.jsonresponse.json

全レンジ(13×13) 一般クォータを1消費

POST https://pokerai.bet/v1/gto/preflop/range · スポット(ポジション + アクションライン)の完全な13×13レンジを対象とし、全169ハンドタイプのfold/call/raiseを1回の呼び出しで返します。hole_cards は不要です(スポットは positions + preflop_actions で決まります)。一般クォータを1消費します(169回ではなく1回の呼び出し)。レンジグリッドの描画用です。

// リクエスト(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"}]}

// レスポンス
{ "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ハンド… },
  "quota": {"used": 7, "limit": 100} }

ハンド表記:ペア AA、スーテッド AKs、オフスート AKo(高いカードを先に表記)。各エントリのfold+call+raise≈1です。完全なスキーマ/ライブで試す → インタラクティブリファレンス

フロップの決定木

フロップ戦略は決定木です。まずツリーを取得して(すべての意思決定ノードと各ノードの token を取得)、システムが実際のベットに沿ってツリー上のパスをたどり、ヒーローのノードでそのステップの戦略を取得します。ソルバーと同じ2ステップです(treenode)。

1) 決定木を取得 一般クォータを1消費

POST https://pokerai.bet/v1/gto/flop/tree · 入力は board + pot_type + positionshole_cards は不要です。ツリーはハンドに依存しません)。

完全なパラメータ/レスポンススキーマとライブで試す → インタラクティブリファレンス

board3枚のフロップカード。例:"2c2h2s"
pot_type"SRP" はシングルレイズド、"3BET" は3ベット、"4BET" は4ベット、"LIMP" はリンプです。
positions各ロールのポジション(SB BB UTG MP CO BTN)。必要な値は pot_type ごとに以下のとおりです。
flop_version任意。使用するフロップデータセット(プリフロップバージョンごとに1つ解析済み):6max(デフォルト)/ 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb。デフォルト(6max)を使用する場合は省略してください。そのバージョンにスポットのデータがない場合は、適切にフォールバックして 6max を使用します。不明な値の場合は 400 unsupported_flop_version になります。preflop_version とは独立しています。ノードトークンにはこのバージョンが含まれるため、/v1/gto/flop/node は同じデータセットに留まります。
pot_type必要なポジションヒーローの値
SRPhero, raiser, callerraiser または caller
3BET / 4BEThero, raiser, three_bettorraiser または three_bettor
LIMPhero, limperヒーロー または limper のいずれかは BB である必要があります
// リクエスト(hole_cards なし)
{"board": "2c2h2s", "pot_type": "SRP", "positions": {"hero": "UTG", "raiser": "UTG", "caller": "BTN"}}

// レスポンス(全36ノード、最初の5件を表示)
{"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}}
フィールド説明
oop_range / ip_rangeこのスポットの開始レンジ(重み付きコンボ文字列)であり、レンジ変換の開始重みとして使用されます。
nodes[]すべての意思決定ノード: node(アクションパス、例: "root/CHECK/BET_8")、is_hero(ヒーローの意思決定ポイントかどうか)、token(そのノードの戦略を取得するための認証情報。ステップ 2 に渡し、アカウントとスポットに紐付くため偽造できません)。
pot / effective_stack / node_countポット、有効スタック(BB)、および意思決定ノードの総数。
quota今月の一般クォータ使用量(used / limit)。

2) ノードの戦略を取得 無料

POST https://pokerai.bet/v1/gto/flop/node · node(ステップ 1 のいずれかのノードのトークン)を指定します。hole_cards を指定した場合 → そのハンドの混合戦略、hole_cards を指定しない場合 → レンジ全体の戦略。

完全なパラメータ/レスポンススキーマとライブ試行 → インタラクティブリファレンス.

ヒーローのすべての意思決定はここで行います: ヒーローの最初のアクション = root ノード(OOP が先にアクションし、チェック/ベット)。ヒーローが IP の場合、ベットに直面している場合、または 2 回目にアクションする場合は、対応する is_hero:true ノードを選びます(例: root/CHECK/BET_8 = 自分がチェックし、今ベットに直面している → フォールド/コール/レイズ)。フロップツリーは単一ストリートです。ストリートをまたぐ場合(ターン/リバー)は /v1/gto/solver/* を使用してください。

// リクエスト(ヒーローノード、hole_cards あり) -> ヒーローの戦略
{"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}]}

// リクエスト(hole_cards なし) -> レンジ全体の戦略
{"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 ハンド"}, "range_hand_count": 188}
フィールド説明
is_heroこのノードがヒーローの意思決定かどうか。
strategy[]ヒーローノード(hole_cards あり): このハンドのミックス戦略。actioncheck / bet / call / raise / foldbet = 最初のベット、raise = ベットに対するレイズ)。bet/raise には amount_bbsizing_potベットサイズを参照)が含まれ、オールインには allin: true も含まれます。frequency は 0~1 の確率です。推奨アクションは返されませんfrequency に基づいて自分で選択してください。
actions[] + range_strategy相手ノード(または hole_cards なし): レンジ全体の戦略で、各ハンドの頻度は actions の順序に対応します。range_hand_count も含まれます。"レンジ変換"用の solver_results の組み立てに使用できます。

ノード ID 内の BET_8 / RAISE_20 は絶対ベット額(BB)です。

想定されるエラー

HTTPエラー発生条件/修正方法
4001) invalid_board / invalid_positions; 2) missing_node / invalid_hole_cards1) board が 3 枚のカードではない、または hero/positions が無効です。2) node がない、または hole_cards が 2 枚のカードではありません。
403invalid_node_token(ステップ 2)node トークンが無効、またはあなたのものではありません。まず /v1/gto/flop/tree を呼び出してツリーを取得してください。
404no_solutionこのスポット/ボードには事前解析済みの解析結果がありません。

ダウンロード: tree_request.jsontree_response.jsonnode_request.jsonnode_response.json

ソルバー(リアルタイム) ソルバー

POST https://pokerai.bet/v1/gto/solver ファミリー。リアルタイムで計算する純粋なポストフロップソルバーで、専用の解析クォータを使用します。入力から解析することが本質です:board + oop/ip レンジ + pot + 残りのスタック + ヒーローは誰か。履歴は不要なので、どのスポットからでも開始できます。3ステップ:スケジュール → ツリーをポーリング → ノードの戦略を取得

完全なパラメータ/レスポンススキーマとライブ試行 → インタラクティブリファレンス/solver/tree/solver/node を含む)。

board の長さでストリートが決まります:3=フロップ / 4=ターン / 5=リバー。⚠ フロップから開始するリアルタイム解析には時間がかかります(計測された SRP フロップでは約 70 秒)。また、高速な応答が必要な用途には適しません。高速なフロップ結果が必要な場合は、上記の「事前解析済みの解析結果」を使用してください(ミリ秒単位で即座に返されます)。ターン/リバーはより高速です(数秒から数十秒)。

呼び出し例(3ステップ:1)スケジュール → 2)ツリーをポーリング → 3)ノードを取得)

# 1) スケジュール(board 3/4/5 = フロップ/ターン/リバー、フロップは約70秒)
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) spot_status=queryable になるまでツリーをポーリング、3) ノードを取得
curl -s https://pokerai.bet/v1/gto/solver/tree -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" -d '{"solve":"eyJ...<前の手順のsolve>"}'

1)解析をスケジュール 解析1回分を消費

board3=フロップ / 4=ターン / 5=リバー、例: "2c2h2s9d"(ターン)。
oop_range / ip_range必須。このストリートに入る2人のプレイヤーのレンジ。加重コンボ文字列。例: "AsKs:1,QQ:0.75,..."
pot / effective_stack必須。このストリートに入る際のポットと残りの実効スタック(BB)。これらがベットサイズを決定するため、実際の値である必要があります。
hero必須: "OOP" または "IP"
bet_sizes任意: ストリートごとの初回ベットサイズを上書きします。例: {"flop":[33,75],"turn":[67],"river":[75]}(ポット比)。flop を省略した場合はデフォルトで50%になります。
raise_sizes任意: ストリートごとのレイズサイズを上書きします。例: {"flop":[50],"turn":[80],"river":[125]}(ポット比)。省略したストリートでは bet_sizes またはデフォルト値を再利用します。
donk_sizes任意: OOP のドンクリードサイズを上書きします。例: {"turn":[55],"river":[90]}(ポット比)。デフォルトはターン67%、リバー100%です。
raise_limit任意: ツリー全体のレイズ上限(1~4)。フロップ/ターン解析ではデフォルトで3、リバーのみの解析では4です。
// リクエスト(フロップ、カスタムのベット/レイズ/ドンクサイズあり)
{"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}

// レスポンス(初回トリガー、解析1回分を消費)
{"status": "computing", "solve": "eyJ0Ijoic2x2XzJmMjk2MWU3Y2Y0ODU3OGUiLCJ1IjoiYjk4Y2Y5NzAtZTVjMS00Njk5LTg4ODQtOGQzYzcwMGIyNGJlIiwidHMiOjE3ODIxMjkxMTUyMDJ9.rtmeNcZoBNWJRhkAGkTSSR58ZafpAh35mi510bgPU6c", "solve_quota": {"used": 1, "limit": 100}}
フィールド/ケース説明
solve解析ハンドル。後続の /tree/node で使用します。レンジはこの手順で一度だけ指定します。
status = computing新しい解析が開始され、解析クォータを1回消費しますsolve_quota を参照)。
status = queryableこのスポットにはキャッシュ済みの解析結果がすでにあり、消費されませんsolve_quota フィールドなし)。直接 /tree をポーリングしてください。
429 status = busyすべてのソルバーが使用中です。消費されません。後でもう一度試してください。

キャッシュヒット(再消費なし): 同じスポット(同じ ボード/レンジ/ポット/スタック/ヒーロー/bet_sizes/raise_sizes/donk_sizes/raise_limit)を再スケジュールしても、解析クォータはもう消費されません。レスポンスに solve_quota フィールドがない場合は未消費を意味します。返された solve ハンドルを使用して /tree をポーリングしてください。例: リクエスト / レスポンス

2)意思決定ツリーとノード状態を取得 無料

POST https://pokerai.bet/v1/gto/solver/tree · solve ハンドルを渡し、spot_status = queryable になるまでポーリングします。後のストリートに進むには、配られたカードを渡します: turn_card(フロップ解析 → 特定のターン)および/または river_cardフロップ解析からのリバースポットには turn_card + river_card の両方が必要です(リバーだけでは一意になりません)。ターン解析には river_card のみが必要です。解析自体のストリートでは両方を省略してください。

// (2)このストリート(フロップ)のツリーを取得
{"solve": "eyJ…"}
{"street": "flop", "spot_status": "queryable", "pot": 7.5, "effective_stack": 97, "solve_seconds": 25.84, "node_count": 14, "nodes": [{"node": "root", "is_hero": true, "status": "queryable", "token": "eyJ…"}, {"node": "root/BET 4.000000", "is_hero": false, "status": "queryable", "token": "eyJ…"}, {"node": "root/BET 4.000000/RAISE 12.000000", "is_hero": true, "status": "queryable", "token": "eyJ…"}, …]}

// ターンツリー(フロップ解析 + turn_card)
{"solve": "eyJ…", "turn_card": "9d"}
{"street": "turn", "spot_status": "queryable", "pot": 7.5, "effective_stack": 97, "solve_seconds": 25.84, "node_count": 104, "nodes": [{"node": "root/BET 4.000000/CALL/9d", "is_hero": false, "status": "queryable", "token": "eyJ…"}, {"node": "root/BET 4.000000/CALL/9d/BET 10.000000", "is_hero": true, "status": "queryable", "token": "eyJ…"}, {"node": "root/BET 4.000000/CALL/9d/BET 10.000000/RAISE 34.000000", "is_hero": false, "status": "queryable", "token": "eyJ…"}, …]}

// リバーツリー(フロップ解析 + turn_card + river_card)
{"solve": "eyJ…", "turn_card": "9d", "river_card": "Qh"}
{"street": "river", "spot_status": "queryable", "pot": 7.5, "effective_stack": 97, "solve_seconds": 25.84, "node_count": 308, "nodes": [{"node": "root/BET 4.000000/CALL/9d/BET 10.000000/CALL/Qh", "is_hero": true, "status": "queryable", "token": "eyJ…"}, {"node": "root/BET 4.000000/CALL/9d/BET 10.000000/CALL/Qh/BET 27.000000", "is_hero": false, "status": "queryable", "token": "eyJ…"}, {"node": "root/BET 4.000000/CALL/9d/BET 10.000000/CALL/Qh/BET 27.000000/RAISE 83.000000", "is_hero": true, "status": "queryable", "token": "eyJ…"}, …]}
フィールド説明
spot_status解析状態: available(未スケジュール) / computing(解析中。ポーリングを継続) / queryable(取得可能) / expired(キャッシュが回収済み。手順1で再スケジュール) / no_nodes(解析は収束しましたが、問い合わせたランアウト/ストリートにはツリー内の意思決定ノードがありません。終端のため、ポーリングを停止してください)。
nodes[]各意思決定ノード: node(アクションパス)、is_herostatustoken(そのノードの戦略を取得する認証情報。手順3に渡します)。リバーのランアウトはチャンスノードで、リバーカードで移動します。
street / pot / effective_stack / node_countストリート、ポット、実効スタック、および意思決定ノードの総数。
solve_secondsこのリアルタイム解析の、スケジュールから収束までの実時間(秒)。queryable の場合にのみ返され、同じ解析のすべてのランアウトでこの値が共有されます。

完全なパラメータ/レスポンススキーマとライブ試行 → インタラクティブリファレンス.

3)ノードの戦略を取得 無料

POST https://pokerai.bet/v1/gto/solver/node · node トークンを渡します。ヒーローノードはヒーローの戦略を返します。相手ノード(または hole_cards なし)はレンジ戦略を返します。

{"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}]}
フィールド説明
is_heroこのノードがヒーローの意思決定かどうか。
strategy[]ヒーローノード: このハンドのヒーローのミックス戦略(action / amount_bb / sizing_potベットサイズを参照) / frequency)。オールイン時はallin: trueが追加されます。
actions[] + range_strategy相手ノード(またはhole_cardsなし): range_strategyでは各ハンドの頻度がactionsの順序に対応します。range_hand_countも含まれます。

完全なパラメータ/レスポンススキーマとライブ試行 → インタラクティブリファレンス.

完了したら、任意で /v1/gto/solver/release を呼び出してポートを直ちに解放できます(そうしない場合、システムが TTL により自動的に回収します)。キャッシュが回収された、または新しい解析結果に置き換えられた場合、この手順は { "node_status": "expired" } を返します。手順1で再スケジュールしてください。ノードごとの解析エラーでは { "node_status": "error", "message": … } が返されます(終端です。ポーリングを停止してください)。完全な /solver/release のパラメータ/レスポンススキーマ → インタラクティブリファレンス.

想定されるエラー

HTTPエラー発生条件/修正方法
400invalid_board / missing_range / invalid_pot / invalid_effective_stack / invalid_hero(スケジュール時)board、OOP/IP レンジ、pot、残りスタック、ヒーロー、またはその他の解析入力が無効です。
400missing_solve / missing_node(ツリー/ノードの取得時)solve ハンドルまたは node トークンがありません。
403invalid_solve / invalid_node_tokenハンドル/トークンが無効、またはあなたのものではありません — 再スケジュールするか、ツリーを再取得してください。
429status: busyすべてのソルバーがビジー状態です。課金されません。待機時間を増やして再試行してください。
502solve_failed解析の開始に失敗しました。後で再試行してください。
503upstream_unavailable(ツリー/ノード)サービス自身の再試行後もソルバーに到達できません(トランスポートエラー / 5xx)— 再試行可能です。

ダウンロード(ターン、board=4): schedule_reqschedule_restree_reqtree_resnode_reqnode_res

ダウンロード(フロップ、board=3): schedule_reqschedule_restree_reqtree_resnode_reqnode_res

ダウンロード(リバー、board=5): schedule_reqschedule_restree_reqtree_resnode_reqnode_res

エンドツーエンドのポーリング例(Python)

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

# 1) スケジュール(解析クォータを1消費。キャッシュヒット時は無料)
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) 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)                       # 解析中 -> 待機時間を延ばして再試行

# 3) ヒーローのルートノード戦略を取得
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"])

レンジ変換 レンジ

POST https://pokerai.bet/v1/gto/range 一般クォータを1消費

完全なパラメータ/レスポンススキーマとライブ試行 → インタラクティブリファレンス.

アクションラインに沿って OOP/IP レンジを更新します。主に次のストリートに進むレンジを取得するために使用し(フロップ→ターン / ターン→リバー)、その後 /v1/gto/solver に渡します。正規化とブラフ割引を含むレンジ更新の計算はすべてソルバーで行われ、ソルバーの解析結果と一貫しています。

これはパススループロキシです。solver_results(決定木)を含め、すべての入力を自分で組み立てます。決定木には、自身の解析結果、またはこのプラットフォームのフロップ決定木から組み立てたものを使用できます。開始レンジは /v1/gto/flop/tree を呼び出し、その後、各ノードで hole_cardsなしに /v1/gto/flop/node を呼び出して、{node_type,player,strategy,childrens} としてネストされた完全な range_strategy を取得します。末尾のスクリプトを参照してください。

リクエスト本文

{
  "range_oop": "AQs:1,AJs:0.48,...",            // 必須、開始時のOOPレンジ
  "range_ip":  "AA:1,AKs:1,...",                 // 必須、開始時のIPレンジ
  "solver_results": { /* 必須: 決定木 */ },
  "node_id": "root/CHECK",          // 必須、アクションライン
  "board": "2c2h2s",                             // 任意、区切りなしの文字列(他のエンドポイントと同じ)
  "normalize": true,                             // 任意、デフォルトはtrue
  "explain": false,                              // 任意、ハンドごとの変更説明
  "track_hands": ["AA"],                         // 任意、これらのハンドのみ追跡
  "bluff_discount_ratio": 0.8,                   // 任意、ブラフ割引
  "hero_position": "oop",                        // 任意、"oop" / "ip" — ヒーローがどちらのプレイヤーか(カードブロッキング用)
  "hero_hand": "AsKs"                            // 任意、レンジからヒーローのカードを含むコンボを削除(ブロッカー)。レスポンスにも返されます
}

カードブロッキング(任意): hero_position"oop"/"ip")+ hero_hand を設定すると、レンジからヒーローのカードのいずれか1枚を含むすべてのコンボを除外します。レンジ対ハンド分析に便利です。両方ともレスポンスに返されます。(この組み合わせは投影レンジのラッパーでも尊重されます。/v1/gto/flop/projected-range はさらに partner_hands をサポートします。)

呼び出し例

# solver_results は大きいため、ファイルに入れて -d @ を使用します
curl -s https://pokerai.bet/v1/gto/range -H "Authorization: Bearer $POKERAI_API_KEY" \
  -H "Content-Type: application/json" -d @range_request.json

レスポンス(200、実際のレスポンス、長い文字列は切り詰め)

{"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}}
フィールド説明
range_oop_new / range_ip_new正規化後に更新されたレンジ(クラス表記)。ソルバーに渡す次のストリートの oop_range / ip_range として直接使用します
range_oop_new_raw / range_ip_new_rawブラフ割引後で正規化前の中間値(コンボ表記)。必要に応じて使用してください。
range_oop_new_raw_before_normalization / range_ip_new_raw_before_normalizationアクションラインに沿ってのみ絞り込んだ、生の値です。ブラフ割引も正規化も行いません。
hand_ranks_oop / hand_ranks_ipハンド強度の順位(combo:rank。値が小さいほど強い)。
hand_bottom_ranks_oop / hand_bottom_ranks_ipレンジ下限の順位。
node_id / board / path_lengthレスポンスに返されるアクションライン、ボード、アクションラインのステップ数。
bluff_discount_ratio / bluff_combos_ratio今回実際に使用されたブラフ割引パラメータ。
quota今月の一般クォータ使用量(used / limit)。

考えられるエラー

HTTPエラー発生条件 / 修正方法
400missing_fieldrange_oop / range_ip / solver_results / node_id のいずれかが不足しています。
400bad_requestソルバー側で拒否されました(例: node_id が、指定した決定木内のどこにもつながっていない)。

ダウンロード: request.json(約1MB、決定木を含む)response.jsonassemble_solver_results.py(エンドツーエンドスクリプト)

フロップ投影レンジ 投影レンジ

POST https://pokerai.bet/v1/gto/flop/projected-range 一般クォータを1消費

完全なパラメータ / レスポンススキーマとライブ試行 → インタラクティブリファレンス

フロップのアクションラインに沿ってOOP/IPレンジを絞り込み、ターンに入る開始レンジを直接取得します。完全なスポット(board/pot_type/positions)と1つのアクションライン(node_id)を指定すると、プラットフォームがサーバー上で決定木を自動的に組み立て、レンジ更新を完了します。レンジ変換と同じフィールドに加え、レスポンスに返される pot_type を返します。

これは /v1/gto/range便利なラッパーです。solver_results を組み立てるために /v1/gto/flop/tree とノードごとの /v1/gto/flop/node を呼び出す手作業を省けます。フロップのアクションラインにのみ適用されます(決定木はこのプラットフォームの事前解析済みフロップ結果から組み立てられます)。ターン→リバーなど、自身で決定木を用意する必要がある場合は、引き続き /v1/gto/range を使用してください。

リクエスト本文

{
  "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"]
}
フィールド説明
board必須。フロップ(区切りなしの文字列、他のエンドポイントと同じ)。例: "2c2h2s"
pot_type必須。ポットタイプ。例: "SRP"
positions必須。{ hero, raiser, caller }(フロップと同じ)。3ベット/リンプスポットでは three_bettor / limper を持つ場合があります。
node_id任意。デフォルトは "root"/v1/gto/flop/tree が返すapi表記(BB単位の絶対ベット額)を使用するフロップのアクションラインです。例: "root/BET_4""root/CHECK/BET_8/CALL"
normalize任意。デフォルトは true。更新後のレンジを正規化するかどうか。
bluff_discount_ratio / bluff_combos_ratio任意。各値は [0,1] 内です(範囲外 → 400)。bluff_discount_ratio はレンジ下位のブラフコンボに重み付けし、bluff_combos_ratio はブラフとして扱うレンジの割合です。省略時はサーバーのターン/リバーのデフォルト値を使用します。両方ともエコーバックされます。
hero_position / hero_hand任意のカードブロッキング。hero_position"oop"/"ip")+ hero_hand(例:"AsKs")を設定すると、ヒーローのカードのいずれかを含むすべてのコンボを相手の更新後レンジ(range_*_new_raw)から除外し、ヒーロー自身のハンドが ヒーロー自身のレンジに存在することを保証します。両方ともエコーバックされます。影響を受けるのは range_*_new_raw のみです。hand_ranks / hand_bottom_ranks はボードでのみフィルタリングされます。
partner_hands任意の4文字コンボ配列(例:["Ac9c"])。hero_position が必要です。それらのカードのいずれかを含むすべてのコンボを相手の range_*_new_raw から除外します。既知のデッドカード(フォールド済みハンド、公開カード)をモデル化します。入力専用(エコーバックなし)。/v1/gto/turn/projected-range でもサポートされます。
flop_version任意。使用するフロップデータセット(各プリフロップバージョンごとに1つ解析済み):6max(デフォルト)/ 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb。デフォルト(6max)を使用するには flop_version パラメータを省略します。そのバージョンにそのスポットのデータがない場合は、適切に 6max へフォールバックします。不明な値 -> 400 unsupported_flop_versionpreflop_version とは独立しています。

呼び出し例

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

レスポンス(200、全フィールドを記載、長い文字列は切り詰め)

{"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}}
フィールド説明
range_oop_new / range_ip_new正規化された更新後レンジ(クラス表記)。ソルバーに渡す次のストリートの oop_range / ip_range として直接使用します
range_oop_new_raw / range_ip_new_rawブラフ割引後で正規化前の中間値(コンボ表記)。必要に応じて使用します。
range_oop_new_raw_before_normalization / range_ip_new_raw_before_normalizationブラフ割引も正規化も行わず、アクションラインに沿ってのみ絞り込んだ生の値。
hand_ranks_oop / hand_ranks_ipハンド強度ランキング(combo:rank、値が小さいほど強い)。
hand_bottom_ranks_oop / hand_bottom_ranks_ipレンジ下位のランキング。
node_id / board / pot_type / path_lengthエコーバックされたアクションライン、ボード、ポットタイプ、およびアクションラインのステップ数。
bluff_discount_ratio / bluff_combos_ratio今回実際に使用したブラフ割引パラメータ。
quota今月の一般クォータ使用量(used / limit)。

想定されるエラー

HTTPエラー発生条件 / 修正方法
400invalid_board / invalid_positionsboard が3枚のカードでない、または positions.hero が無効です。
404no_solution(およびサーバー errorType(例:no_ranges / no_root_node))このスポットに事前解析済みのフロップツリーがない、または node_id のアクションラインがどこにも到達しません。

ダウンロード:request.jsonresponse.json

ターンの投影レンジ(ターン→リバー) 投影レンジ

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

完全なパラメータ/レスポンススキーマとライブ試行 → インタラクティブリファレンス

フロップ投影レンジのターン→リバー版であり、リアルタイムのターン解析 用です。ストリートを終了する コール/チェックを含むターンのアクションラインに沿ってレンジを絞り込み、リバーに入る開始レンジを直接取得します。ターン突入時の OOP/IP レンジは解析自体の設定から読み取られます/v1/gto/solver 経由でスケジュール時に指定したレンジ)。そのため、渡すのは解析ハンドル solve と1つの node_id だけです。無料です(解析はすでに /v1/gto/solver 経由で課金済み)。/v1/gto/solver/tree と同様で、レンジ変換と同じフィールドを返します。

まず /v1/gto/solver/treespot_status = queryable になるまでポーリングしてください。ターン→リバーでは solver_results を手動で組み立てる必要はありません(プラットフォームが解析から読み取り、組み立てます)。

リクエストボディ

{
  "solve": "eyJ…",
  "node_id": "root/CHECK/BET 6.000000/CALL",
  "normalize": true,
  "bluff_discount_ratio": 0.8,
  "hero_position": "oop",
  "hero_hand": "AsKs"
}
フィールド説明
solve必須。/v1/gto/solver が返す解析ハンドル(ターン解析)。
node_id必須。ターンのアクションライン。ストリートを終了する コール/チェック で終えることができます。ソルバーのノード表記(スペースあり)、例:"root/CHECK/BET 6.000000/CALL"/v1/gto/solver/tree のノードから)。
normalize任意。デフォルトは true。更新後のレンジを正規化するかどうか。
bluff_discount_ratio任意。ブラフ割引(0..1)。
hero_position / hero_hand任意のカードブロッキング:hero_position"oop"/"ip")+ hero_hand(例:"AsKs")により、ヒーローのカードのいずれかを含むすべてのコンボを相手の更新後レンジから除外します。
partner_hands任意の 4 文字コンボ配列(例: ["Ac9c"])。hero_position が必要です。それらのカードのいずれかを含むすべてのコンボを、相手の range_*_new_raw から除外します。入力専用。

呼び出し例

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

レスポンス(200、全フィールドを掲載、長い文字列は切り詰め)

{"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,…"}
フィールド説明
range_oop_new / range_ip_new正規化されたリバー開始時レンジ(クラス表記)。リバー解析の oop_range / ip_range として直接使用されます
range_*_raw / range_*_raw_before_normalization未正規化 / ディスカウント前の中間値(コンボ表記)。
hand_ranks_* / hand_bottom_ranks_*ハンド強度ランキング / レンジ下位ランキング(combo:rank、小さいほど強い)。
node_id / board / path_lengthエコーバックされたアクションライン、ボード(4 枚のカード)、およびアクションラインのステップ数。
bluff_discount_ratio / bluff_combos_ratio今回実際に使用されたブラフのディスカウントパラメータ。

注: 無料のため、レスポンスに quota フィールドはなく、pot_type もありません(これはフロップ専用です)。

考えられるエラー / 状態

HTTPエラー / 状態発生条件 / 修正方法
200{ "spot_status": "computing" }解析がまだ収束していません — クエリ可能になるまで /v1/gto/solver/tree をポーリングし続けてください。
400missing_solve / missing_node_idsolve ハンドルまたは node_id がありません。
410expired解析が期限切れ(TTL)です — /v1/gto/solver 経由で再スケジュールしてください。
502no_solution など上流の解析エラー。

ダウンロード: request.jsonresponse.json

ノード EV ソルバー

POST https://pokerai.bet/v1/gto/evs 無料

完全なパラメータ / レスポンススキーマ、ライブで試す → インタラクティブリファレンス

完了した解析の 1 ノードにおける、ハンドごと・アクションごとの期待値solve ハンドル(/v1/gto/solver から)+ node_id/v1/gto/solver/tree から)を指定します。任意の hand で 1 ハンドに絞り込めます。無料(解析はすでに課金済みです)。最初に spot_status = queryable になるまで /v1/gto/solver/tree をポーリングしてください。

リクエスト本文

{
  "solve": "eyJ0Ijoic2x2X3h4eXoi...(/v1/gto/solver からのハンドル)",
  "node_id": "root",
  "hand": "2c2d"
}
フィールド説明
solve必須。/v1/gto/solver からの解析ハンドル。
node_id必須。/v1/gto/solver/tree のノード(ソルバー表記。例: "root""root/CHECK/BET 6.000000")。
hand任意。1 ハンドの EV に絞り込みます(例: "2c2d")。すべてのハンドでは省略してください。

レスポンス(200、各ハンドの EV 配列は 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": […], …}}
フィールド説明
actions順番どおりのノードアクション。各ハンドの EV 配列はこれに対応します。
evsハンドごと → 各アクションの EV(bb)の配列。hand 指定時、evs はそのハンド用の単一配列です。
player / round / node_id / task_idどのプレイヤーがアクションするか、ストリート、およびエコーバックされたノード / 解析 ID。

注: 無料のため quota フィールドはありません。解析がまだ収束していない場合は { "spot_status": "computing" } を返します(/v1/gto/solver/tree をポーリング)。

ハンドをプレイ(全フロー)

エンドポイントをつなげる例: 1 回の SRP ハンド(UTG がオープン、BTN がコール)、ヒーロー = UTG。以下の curl では認証ヘッダーを省略しています(クイックスタートと同じ)。

1) プリフロップ — オープンすべきか

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 } ] }

SB + BB のポストのみ(レイズなし)= ヒーローが最初にアクションします(オープンスポット)。オープン頻度とサイズを返します。

2) フロップ — フロップ戦略

フロップは 2c2h2s。フロップは意思決定ツリーで、2 ステップです。まずツリーを取得し、次にヒーローのノード token を使って戦略を取得します。

// 1) ツリーを取得(hole_cards は不要)
POST /v1/gto/flop/tree
{ "board": "2c2h2s", "pot_type": "SRP",
  "positions": { "hero": "UTG", "raiser": "UTG", "caller": "BTN" } }
// → nodes[] 内の root(is_hero:true)には token が含まれます

// 2) root の token を使ってヒーローの戦略を取得
POST /v1/gto/flop/node
{ "node": "<root の token>", "hole_cards": "AdKd" }

ヒーローの最初の意思決定 = root。ベットに直面する / 2 回目にアクションする場合 → 対応する is_hero:true ノードを選択します。フロップ意思決定ツリーを参照してください。

3) ターン — リアルタイム解析、フロップから導出したレンジ

ターン(例: 9d)にはリアルタイム解析が必要で、ターン開始時の両プレイヤーのレンジが必要です。フロップ意思決定ツリー + レンジ変換で取得します:

  1. 開始時の oop_range / ip_range と意思決定ノード用の /v1/gto/flop/tree
  2. フロップのアクションライン(例: root/CHECK/BET_8/CALL)に沿って、各ノードで /v1/gto/flop/node を呼び出し(hole_cards なし)、range_strategy を取得して solver_results を組み立てます — assemble_solver_results.py スクリプトはレンジ変換セクションを参照してください。
  3. /v1/gto/range はそのアクションラインに沿って更新します → range_oop_new / range_ip_newターンに入るレンジです。
  4. それらをソルバーに渡し(4 枚のカードを持つボード)、queryable になるまでツリーをポーリングしてから、ノードを取得します:
    POST /v1/gto/solver
    { "board": "2c2h2s9d", "oop_range": "<OOP ターンに入るレンジ>", "ip_range": "<IP ターンに入るレンジ>",
      "pot": <ターンのポット>, "effective_stack": <ターンの有効スタック>, "hero": "OOP" }

すでに独自のレンジ/スポットがありますか?ステップ 3 で oop_range / ip_range を直接指定し、導出をスキップします。

4) リバー — リアルタイム解決

リバー(5 枚のカードを持つ board)はターンと同じです。単独で解決(リバーに入るレンジを直接指定)するか、レンジ変換を使ってターンのアクションラインをもう一度更新し、リバーに入るレンジを取得してからソルバーに渡せます。

ポーカーエンジン/セマンティクス API

pokerkit-plus(pokerkit 0.7.3 のスーパーセット)をラップしています: ボード/ハンドのセマンティクス、レンジとエクイティ、eval/equity/ICM/表記法、ゲームシミュレーション。同じ API キーとクォータを再利用します — 低コストのエンドポイントは一般バケットに、モンテカルロエンドポイントはsolveバケットに課金されます。ベースパスは /v1/pokerkit/*、カード入力は区切りなしの文字列(AsKsQs)、列挙型は {name,value} を返します。エンドポイントごとの完全なパラメータ/スキーマとライブ試行インタラクティブリファレンス;機械可読の仕様 → /openapi.en.json(GTO + pokerkit の統合スナップショット)。

ボード/ハンドのセマンティクス general を 1 消費

ボード(Hero 非依存): /texture(ウェットネス/接続性/利用可能なドロー)、/nuts(ナッツ + 引き分けコンボ)、/category-combos/board-report(texture+nuts)。Hero: /hand-tier(メイドハンドのティア)、/draws/outs/blockers/hand-report(1 回の呼び出しで texture+tier+draws+outs)。

リクエストフィールド(このグループで共通)

フィールド説明
board必須。区切りなしのコミュニティカード 3/4/5 枚、例: "AsKsQs"
holeHero エンドポイント(hand-tier / draws / outs / blockers / hand-report)では必須。ホールカード 2 枚、例: "JhTh"。ボードエンドポイント(texture / nuts / category-combos / board-report)では省略します。
hand_type任意。デフォルトは StandardHighHand(v1 のみ;他のタイプは 400 を返します)。
dead任意。デッド/除外されたカード(このグループのすべてのエンドポイントで受け付けます)。

テクスチャ general を 1 消費

POST https://pokerai.bet/v1/pokerkit/texture — ボード構造: ウェットネス/接続性/ランク帯/ドローの有無/スート形状。完全なパラメータ/ライブで試す →

{"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}}

ナッツ general を 1 消費

POST https://pokerai.bet/v1/pokerkit/nuts — 作成可能な最強ハンド + 引き分けとなるすべての 2 枚コンボ(is_royal / board_is_nuts を含む)。完全なパラメータ/ライブで試す →

{"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"}}}

カテゴリコンボ general を 1 消費

POST https://pokerai.bet/v1/pokerkit/category-combos — メイドカテゴリ別にグループ化した、すべての有効な 2 枚コンボ。完全なパラメータ/ライブで試す →

{"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"]}], …}}}

ボードレポート general を 1 消費

POST https://pokerai.bet/v1/pokerkit/board-report — 1 回の呼び出しで texture + nuts(ボードの概要)。完全なパラメータ/ライブで試す →

{"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"}}}}

ハンドティア general を 1 消費

POST https://pokerai.bet/v1/pokerkit/hand-tier — Hero のメイドハンドティア(ワンペア/ツーペア/トリップス/キッカーのティア、is_nut)。完全なパラメータ/ライブで試す →

{"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"}}}

ドロー general を 1 消費

POST https://pokerai.bet/v1/pokerkit/draws — Hero のドロー(ストレート/フラッシュドロー、ナッツランク)。完全なパラメータ/ライブで試す →

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

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

アウト general を 1 消費

POST https://pokerai.bet/v1/pokerkit/outs — メイドカテゴリを改善する Hero のアウトをグループ化し、数を示します。完全なパラメータ/ライブで試す →

{"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}}

ブロッカー 一般クレジットを 1 消費

POST https://pokerai.bet/v1/pokerkit/blockers — ヒーローがブロックするナッツコンボ数(ブロッカーカード/割合)。完全なパラメータ/ライブで試す →

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

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

ハンドレポート 一般クレジットを 1 消費

POST https://pokerai.bet/v1/pokerkit/hand-report — 1 回の呼び出しで texture + tier + draws + outs(ヒーローの概要、主力機能)。完全なパラメータ/ライブで試す →

{"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}}}

レンジ/エクイティ 一般クレジットを 1 消費

/range/expand(表記法 → 具体的なコンボ)、/range/value(メイドカテゴリの下限によるバリューレンジ;aggression ∈ NO_BET/SINGLE_BET/RAISED)、/range/nut-advantage(サンプリングなしの正確なナッツシェア)。

リクエストフィールド(このグループで共通)

フィールド説明
notation(expand)レンジ表記の配列、例: ["AA","KQs","QQ+"]
hero / villain(nut-advantage)それぞれ 1 つのレンジ表記配列。
boardコミュニティカード(value / nut-advantage では必須。expand では不要)。
aggression(value) NO_BET / SINGLE_BET / RAISED でカテゴリの下限を設定します。明示的に設定するには floor を使用します。

レンジの展開 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/range/expand — レンジ表記を具体的な 2 枚カードのコンボに展開します。完全なパラメータ / インタラクティブに試す →

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

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

バリューレンジ 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/range/value — 完成ハンドカテゴリの下限(aggression)に基づいてバリューレンジを構築します。完全なパラメータ / インタラクティブに試す →

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

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

レンジのナッツ優位性 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/range/nut-advantage — コンボ数による正確なナッツシェアの分割(サンプリングなし、決定論的)。完全なパラメータ / インタラクティブに試す →

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

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

ハンド評価・エクイティ・ICM・表記

一般クレジット 1 を消費 /eval/hand/eval/compare(ランク + 引き分け)、/icm(決定論的)、/notation/parse(.phh → 構造化)。解析クレジット 1 を消費 モンテカルロ: /equity/hand-strength/range/equity-advantagesample_count(上限あり)と seed(再現可能、10k で約 2 秒)を使用。

リクエストフィールド(このグループで共通)

モンテカルロのエンドポイント(equity / hand-strength / range/equity-advantage)は 解析 バケットを消費し、その他は 一般 バケットを消費します。

フィールド説明
hole / holdings / board評価入力: 単一の hole + board(eval/hand)、または複数ハンドの holdings(2 つ以上)+ board(eval/compare)。
ranges / hole_range / hero / villainレンジ表記(equity / hand-strength / range/equity-advantage)。
sample_count / seedモンテカルロ: サンプル数(上限あり。上限を超えると上限値に丸められます)/ RNG シード(再現可能)。
payouts / chips(icm) 賞金配分構造 / プレイヤーごとのチップ。
text(notation/parse) .phh のハンド履歴文字列。

ハンド評価 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/eval/hand — hole + board を完成ハンドとして評価します(5 枚のカード + カテゴリラベル)。完全なパラメータ / インタラクティブに試す →

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

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

ハンド比較 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/eval/compare — ボード上の 2 つ以上の holdings を順位付けします(引き分けを含む)。完全なパラメータ / インタラクティブに試す →

{"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"}}]}

エクイティ 解析クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/equity — ボード上の複数レンジのエクイティ(モンテカルロ)。完全なパラメータ / インタラクティブに試す →

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

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

ハンド強度 解析クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/hand-strength — N 人のプレイヤーに対する ヒーローの勝率(モンテカルロ)。完全なパラメータ / インタラクティブに試す →

{"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 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/icm — チップ / 賞金配分からの ICM エクイティ分割(決定論的)。完全なパラメータ / インタラクティブに試す →

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

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

レンジのエクイティ優位性 解析クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/range/equity-advantage — 2 つのレンジ間のエクイティシェア分割(モンテカルロ)。完全なパラメータ / インタラクティブに試す →

{"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}}

表記の解析 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/notation/parse — .phh のハンド履歴を構造化された設定に解析します(バリアント / ブラインド / スタック / アクション…)。完全なパラメータ / インタラクティブに試す →

{"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}}

ゲームシミュレーション 一般クレジット 1 を消費

完全情報・ステートレスのリプレイ: クライアントがアクションリストを保持し、サーバーは pokerkit で状態を再構築します(サーバー状態はゼロ)。/games/state(現在スポットのスナップショット)、/games/stepnext_action を適用。expected_action_count はオプティミスティック並行性トークンで、不一致 → 409)、/notation/replay(設定または .phh テキスト → ステップごとのスナップショット)、/cards/normalize(カード文字列を検証 / 正規化)。

リクエストフィールド(このグループで共通)

フィールド説明
variant必須。バリアントコード。例: "NT"(ノーリミット・ホールデム)。完全な一覧は /v1/pokerkit/meta
antes / starting_stacks必須。プレイヤーごとのアンティ / 開始スタック(整数配列)。
blinds_or_straddles / min_betブラインド / ストラドル。ノーリミット / ポットリミットでは min_bet が必須です(フィックスドリミット / スタッドでは small_bet / big_bet / bring_in を使用)。
actionsこれまでのアクションリスト(pokerkit 表記: d dh p1 AhKh はホールカードを配る、p2 cbr 6 は 6 へのレイズ、p1 cc はチェック / コール、p1 f はフォールド)。
next_action / expected_action_count(step)適用するアクション / 並行性トークン(= 拡張するリストの長さ。不一致 → 409)。
text / index(replay)代わりに .phh テキストを指定します。index はそのステップだけを返します。cards/normalizecards(カード文字列)のみを受け取ります。

ゲーム状態 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/games/state — アクションリスト → 現在スポットのスナップショット(すべてのホールカードを表示)。完全なパラメータ / インタラクティブに試す →

{"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"]}}

ゲームステップ 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/games/step — next_action を適用 → 新しいスナップショット(並行性トークン。不一致時は 409)。完全なパラメータ / ライブで試す →

{"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"]}}

表記のリプレイ 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/notation/replay — 設定または .phh → ステップごとのスナップショット(単一ステップ用の任意の index)。完全なパラメータ / ライブで試す →

{"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}}

カードの正規化 一般クレジット 1 を消費

POST https://pokerai.bet/v1/pokerkit/cards/normalize — カード文字列を検証 / 正規化して標準の 2 文字カードにします。完全なパラメータ / ライブで試す →

{"cards": "Ah Ks Qs"}

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

さらに GET /v1/pokerkit/meta(バージョン / バリアントコード / ハンドタイプ / 列挙値の語彙)。すべてのエンドポイントの完全なパラメータスキーマとライブ試行 → インタラクティブリファレンス(上部から両方の API を参照)。

すべてのサンプルダウンロード

各エンドポイントの 完全な リクエスト/レスポンスの概要(実データ、フィールドの省略なし)は、上記の各セクションの「ダウンロード」、または以下にあります。 プリフロップ · フロップツリー · フロップノード · ソルバー · レンジ · 投影レンジ · 投影レンジのレスポンス · 組み立てスクリプト

バージョニングと変更履歴

バージョニングポリシー

  • パス内の /v1メジャーバージョンです。破壊的変更(フィールドの削除/変更、セマンティクスの変更)は新しいメジャーバージョン /v2 に移行し、/v1 は引き続き利用できます。
  • 後方互換性のある追加(新しいエンドポイント、新しい任意フィールド、新しいレスポンスフィールド)は、個別の通知なしに直接 /v1 に追加されます。"未知のフィールドを無視"して解析し、レスポンスフィールドを厳格な許可リストで検証しないでください
  • フィールドの非推奨化は事前に以下の変更履歴で示され、移行期間を経た後にのみ削除されます。

変更履歴

日付変更
2026-07-22/v1/gto/solver は、bet_sizes に加えて独立した raise_sizesdonk_sizesraise_limit フィールドを受け付けるようになりました。
2026-07-12POST /v1/gto/solver/release を追加 — solve のプールポートを早期に解放し、キャッシュ TTL の満了を待たずに直ちにプールへ戻します(任意、無料。その solve に対する最後の /solver/tree / /solver/node の後に呼び出してください)。
2026-07-04/v1/gto/evs を追加(完了した solve のハンドごと・アクションごとのノード EV)。/v1/gto/turn/projected-rangepartner_hands もサポートするようになりました。
2026-07-04/v1/gto/flop/projected-range がリクエストの bluff_discount_ratio / bluff_combos_ratio を尊重し、ヒーロー自身のハンドを Hero のレンジに追加し、partner_hands を追加しました(パートナーのデッドカードを villain のレンジからブロック)。
2026-06-22ポーカーエンジン / セマンティクス API /v1/pokerkit/* を追加(ボード/ハンドのセマンティクス、レンジ/エクイティ、eval/equity/ICM/表記、ゲームシミュレーション。同じキーとクォータ)。以下を参照してください。
2026-06-22/v1/gto/preflop/range を追加(13×13 のプリフロップレンジ全体、1 回の呼び出しで 169 ハンド)。
2026-06-18フロップを分割: 単一クエリの /v1/gto/flop を削除し、/v1/gto/flop/tree(ツリー取得)+ /v1/gto/flop/node(ノード取得、無料)に置き換え、ソルバーの tree/node に合わせました。
2026-06-17/v1/gto/flop/projected-range を追加(/v1/gto/range 上の便利なラッパー: フロップスポット全体 + アクションラインを指定すると、サーバーが決定ツリーを自動で組み立て、ターンレンジを直接返します)。
2026-06-17ボード / ハンド形式を統一: 入力は区切りなしの文字列で、レスポンスの board は常に配列として返されます。
2026-06-17OpenAPI 3.0 仕様を追加。レンジ表記 / 概念 / フルフローのチュートリアルドキュメントを追加。
2026-06-17/v1/gto/solverリアルタイムのフロップソルビング(board=3)をサポートするようになりました。bet_sizes.flop でフロップのベットサイズをカスタマイズできます。
2026-06-17修正: フロップクエリのレイズ amount_bb が誤って 0 でした(現在は正しい絶対 BB を返します)。
2026-06-17レンジ変換 /v1/gto/range を追加。/flop/tree は開始時の oop_range / ip_range を公開し、/flop/solver/nodehole_cards が渡されない場合に完全なレンジ戦略を返します。
2026-06-16ターン/リバー向けのリアルタイムソルバー /v1/gto/solver ファミリー(個別の solve クォータ)を追加し、フロップの意思決定ツリー /v1/gto/flop/treeを追加しました。
2026-06-15すべてのレスポンスから recommendation フィールドを削除しました。frequency に基づいてご自身でアクションを選択してください。

pokerai.bet · GTO API v1