事前計算済みの検索
高速プリフロップと580万件超のフロップソリューション。タスクのポーリングなしで、ミリ秒単位で戦略を返します。
プリフロップから始める1つのセルフサービス API で MelaSolver GPU を利用できます。ミリ秒単位の事前計算済みルックアップから始めるか、カスタムのフロップ、ターン、またはリバーのスポットをリアルタイムソルバープールに送信してください。
公開コレクションをダウンロードして Postman にインポートし、リクエストを送信する前にコレクションの apiKey 変数を API キーに設定してください。Authorization: Bearer {{apiKey}} と公開 https://pokerai.bet ベース URL を使用します。含まれる例は GTO プリフロップ戦略と PokerKit のボードテクスチャを扱います。
Postman コレクション ダウンロード可能なソースには実際のキー、Cookie、または非公開エンドポイントは含まれていません。完全な公開仕様については、APIリファレンスおよびOpenAPIスナップショットを参照してください。
どちらも同じ API キーと月間クォータを使用します。
プリフロップと580万件超のフロップソリューション。タスクのポーリングなしで、ミリ秒単位で戦略を返します。
プリフロップから始めるカスタムのフロップ、ターン、リバーのツリー。1回送信し、タスクIDでポーリングしてから、計算済みの戦略を取得します。
ソルブを送信インストール、認証、呼び出し。それ以外の準備は不要です。
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}]}'
{
"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秒でキーを取得:
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日にリセットされます。現在の使用量はコンソールで確認できます:
/v1/gto/range、プロジェクテッドレンジ呼び出しは、それぞれ1件として課金されます。/v1/gto/solver は、新しい解析をトリガーするたびに1件として課金されます。キャッシュ済みの解析結果の再利用とツリー/ノードの取得は無料です(課金時はレスポンスに solve_quota フィールドがあり、非課金時はありません)。すべてのエラーは統一された JSON を返します: { "error": "<code>", "message": "<description>" }。いくつかの例外があります: 一部の 502 は message ではなく reason を使用します。すべてのソルバーがビジー状態の場合の 429 は { "status": "busy", "message": ... } のようになります。エンドポイント固有の error 値は各エンドポイントの「想定されるエラー」テーブルにあります。共通のステータスコードは以下のとおりです:
| HTTP | エラー / 意味 | 再試行? |
|---|---|---|
| 400 | 無効な入力またはフィールド不足(具体的な error については各エンドポイントのテーブルを参照)。 | いいえ、入力を修正してください |
| 401 | missing_api_key / invalid_api_key: キーがないか無効です。 | いいえ、キーを確認してください |
| 403 | invalid_node_token / invalid_solve: トークン/ハンドルが無効、またはあなたのものではありません。 | いいえ、先にツリーを再取得するか再スケジュールしてください |
| 404 | no_solution: このスポットにはまだ GTO データがありません。 | いいえ、スポットを変更してください |
| 429 | quota_exceeded(一般)/ solve_quota_exceeded(解析): 月次クォータを使い切りました。 | いいえ、1日にリセットされるのを待つか、クォータをアップグレードしてください |
| 429 | status: busy: すべてのソルバーがビジー状態です(/v1/gto/solver のみ)。課金されません。 | はい、待機時間を増やして再試行してください |
| 502 | no_result(reason: 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ベットスポットになり、situation は Raise を返します)。各アクションのミックス頻度が返されます(推奨アクションはありません。frequency に基づいて自分で選択してください)。以下のセクションは、事前解析済みの解析結果(プリフロップ / フロップ)、リアルタイムのソルバー計算、レンジ変換の3部構成です。
HTTP を手書きしたくありませんか? 公式クライアントは OpenAPI 仕様から自動生成され、完全に型付けされているため、常に API に追従します。認証は API キー だけです。
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}}
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 です。
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" を追加すると、リアルタイムのソルバーツールを有効化できます(解析クォータを消費します)。
全体像となる考え方です。一度読むと、以下のエンドポイントごとのセクションをよりスムーズに理解できます。
すべての戦略は各アクションのミックス頻度(0~1)を返し、あなたに代わってアクションを選びません。frequency から自分で実装してください(最大確率を選ぶ、または頻度に従ってランダムにサンプリングします)。
各 bet/raise には、2つのサイズフィールドがあります。amount_bb(絶対額、つまりレイズ先の BB 額)と、sizing_pot(ポットに対する値、標準的なポット比の表記)です:
例: 3 のオープンに対して 9 へ 3bet。ポットは 4.5、コール後は 4.5+3=7.5、レイズの上乗せは 9−3=6 なので、sizing_pot = 6/7.5 = 0.8 です。オールインの場合は allin: true も含まれます。
フロップの意思決定ツリーとリアルタイムのソルバーはいずれも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/tree の spot_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 になります。同じスポットでもバージョンが異なれば頻度は異なります。 |
| フィールド | 型 | 説明 |
|---|---|---|
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 でライブ取得できます。
{"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 |
| 1 | 3ベット | 9 |
| 2 | 4ベット | 25 |
| ≥3 | 5ベット以上 | オールイン 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_200NL | 6 max 100bb GG 200NL 3b/f 2.2x - 2.5x |
6max_RC_100bb_100NL | 6 max 100bb GG 100NL 3b/f |
6max_RC_40bb | 6 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 | エラー | 発生条件/修正方法 |
|---|---|---|
| 400 | invalid_hole_cards | hole_cards が2枚のカードではありません(例:"AdKd")。 |
| 400 | unsupported_table_size / invalid_positions / invalid_actions | テーブルタイプ(現在は6maxのみ)、hero/ポジション、または preflop_actions が無効です。 |
| 400 | unsupported_preflop_version | preflop_version が許可されたセット(6max / 6max_RC_100bb_200NL / 6max_RC_100bb_100NL / 6max_RC_40bb)に含まれていません。 |
| 404 | no_solution | このプリフロップのスポットには事前解析済みの解析結果がありません。スポットを変更してください。 |
ダウンロード: request.jsonresponse.json
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ステップです(tree → node)。
POST https://pokerai.bet/v1/gto/flop/tree · 入力は board + pot_type + positions(hole_cards は不要です。ツリーはハンドに依存しません)。
完全なパラメータ/レスポンススキーマとライブで試す → インタラクティブリファレンス。
board | 3枚のフロップカード。例:"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 | 必要なポジション | ヒーローの値 |
|---|---|---|
SRP | hero, raiser, caller | raiser または caller |
3BET / 4BET | hero, raiser, three_bettor | raiser または three_bettor |
LIMP | hero, 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)。 |
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 あり): このハンドのミックス戦略。action ∈ check / bet / call / raise / fold(bet = 最初のベット、raise = ベットに対するレイズ)。bet/raise には amount_bb と sizing_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 | エラー | 発生条件/修正方法 |
|---|---|---|
| 400 | 1) invalid_board / invalid_positions; 2) missing_node / invalid_hole_cards | 1) board が 3 枚のカードではない、または hero/positions が無効です。2) node がない、または hole_cards が 2 枚のカードではありません。 |
| 403 | invalid_node_token | (ステップ 2)node トークンが無効、またはあなたのものではありません。まず /v1/gto/flop/tree を呼び出してツリーを取得してください。 |
| 404 | no_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 秒)。また、高速な応答が必要な用途には適しません。高速なフロップ結果が必要な場合は、上記の「事前解析済みの解析結果」を使用してください(ミリ秒単位で即座に返されます)。ターン/リバーはより高速です(数秒から数十秒)。
# 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>"}'
board | 3=フロップ / 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 をポーリングしてください。例: リクエスト / レスポンス。
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_hero、status、token(そのノードの戦略を取得する認証情報。手順3に渡します)。リバーのランアウトはチャンスノードで、リバーカードで移動します。 |
street / pot / effective_stack / node_count | ストリート、ポット、実効スタック、および意思決定ノードの総数。 |
solve_seconds | このリアルタイム解析の、スケジュールから収束までの実時間(秒)。queryable の場合にのみ返され、同じ解析のすべてのランアウトでこの値が共有されます。 |
完全なパラメータ/レスポンススキーマとライブ試行 → インタラクティブリファレンス.
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 | エラー | 発生条件/修正方法 |
|---|---|---|
| 400 | invalid_board / missing_range / invalid_pot / invalid_effective_stack / invalid_hero | (スケジュール時)board、OOP/IP レンジ、pot、残りスタック、ヒーロー、またはその他の解析入力が無効です。 |
| 400 | missing_solve / missing_node | (ツリー/ノードの取得時)solve ハンドルまたは node トークンがありません。 |
| 403 | invalid_solve / invalid_node_token | ハンドル/トークンが無効、またはあなたのものではありません — 再スケジュールするか、ツリーを再取得してください。 |
| 429 | status: busy | すべてのソルバーがビジー状態です。課金されません。待機時間を増やして再試行してください。 |
| 502 | solve_failed | 解析の開始に失敗しました。後で再試行してください。 |
| 503 | upstream_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
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
{"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 | エラー | 発生条件 / 修正方法 |
|---|---|---|
| 400 | missing_field | range_oop / range_ip / solver_results / node_id のいずれかが不足しています。 |
| 400 | bad_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_version。preflop_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
{"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 | エラー | 発生条件 / 修正方法 |
|---|---|---|
| 400 | invalid_board / invalid_positions | board が3枚のカードでない、または positions.hero が無効です。 |
| 404 | no_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/tree を spot_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
{"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 をポーリングし続けてください。 |
| 400 | missing_solve / missing_node_id | solve ハンドルまたは node_id がありません。 |
| 410 | expired | 解析が期限切れ(TTL)です — /v1/gto/solver 経由で再スケジュールしてください。 |
| 502 | no_solution など | 上流の解析エラー。 |
ダウンロード: request.jsonresponse.json
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")。すべてのハンドでは省略してください。 |
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 では認証ヘッダーを省略しています(クイックスタートと同じ)。
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 のポストのみ(レイズなし)= ヒーローが最初にアクションします(オープンスポット)。オープン頻度とサイズを返します。
フロップは 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 ノードを選択します。フロップ意思決定ツリーを参照してください。
ターン(例: 9d)にはリアルタイム解析が必要で、ターン開始時の両プレイヤーのレンジが必要です。フロップ意思決定ツリー + レンジ変換で取得します:
oop_range / ip_range と意思決定ノード用の /v1/gto/flop/tree。root/CHECK/BET_8/CALL)に沿って、各ノードで /v1/gto/flop/node を呼び出し(hole_cards なし)、range_strategy を取得して solver_results を組み立てます — assemble_solver_results.py スクリプトはレンジ変換セクションを参照してください。/v1/gto/range はそのアクションラインに沿って更新します → range_oop_new / range_ip_new はターンに入るレンジです。queryable になるまでツリーをポーリングしてから、ノードを取得します:
POST /v1/gto/solver
{ "board": "2c2h2s9d", "oop_range": "<OOP ターンに入るレンジ>", "ip_range": "<IP ターンに入るレンジ>",
"pot": <ターンのポット>, "effective_stack": <ターンの有効スタック>, "hero": "OOP" }
すでに独自のレンジ/スポットがありますか?ステップ 3 で oop_range / ip_range を直接指定し、導出をスキップします。
リバー(5 枚のカードを持つ board)はターンと同じです。単独で解決(リバーに入るレンジを直接指定)するか、レンジ変換を使ってターンのアクションラインをもう一度更新し、リバーに入るレンジを取得してからソルバーに渡せます。
pokerkit-plus(pokerkit 0.7.3 のスーパーセット)をラップしています: ボード/ハンドのセマンティクス、レンジとエクイティ、eval/equity/ICM/表記法、ゲームシミュレーション。同じ API キーとクォータを再利用します — 低コストのエンドポイントは一般バケットに、モンテカルロエンドポイントはsolveバケットに課金されます。ベースパスは /v1/pokerkit/*、カード入力は区切りなしの文字列(AsKsQs)、列挙型は {name,value} を返します。エンドポイントごとの完全なパラメータ/スキーマとライブ試行 → インタラクティブリファレンス;機械可読の仕様 → /openapi.en.json(GTO + pokerkit の統合スナップショット)。
ボード(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"。 |
hole | Hero エンドポイント(hand-tier / draws / outs / blockers / hand-report)では必須。ホールカード 2 枚、例: "JhTh"。ボードエンドポイント(texture / nuts / category-combos / board-report)では省略します。 |
hand_type | 任意。デフォルトは StandardHighHand(v1 のみ;他のタイプは 400 を返します)。 |
dead | 任意。デッド/除外されたカード(このグループのすべてのエンドポイントで受け付けます)。 |
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}}
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"}}}
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"]}], …}}}
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"}}}}
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"}}}
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"}}}
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}}
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}}
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}}}
/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 を使用します。 |
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"]]}
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"], …]}
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"}}}
一般クレジット 1 を消費 /eval/hand、/eval/compare(ランク + 引き分け)、/icm(決定論的)、/notation/parse(.phh → 構造化)。解析クレジット 1 を消費 モンテカルロ: /equity、/hand-strength、/range/equity-advantage — sample_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 のハンド履歴文字列。 |
POST https://pokerai.bet/v1/pokerkit/eval/hand — hole + board を完成ハンドとして評価します(5 枚のカード + カテゴリラベル)。完全なパラメータ / インタラクティブに試す →
{"hole": "JhTh", "board": "AsKsQs"}
{"result": {"hand": "JhThAsKsQs", "label": {"name": "STRAIGHT", "value": "Straight"}}}
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"}}]}
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}}
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}}
POST https://pokerai.bet/v1/pokerkit/icm — チップ / 賞金配分からの ICM エクイティ分割(決定論的)。完全なパラメータ / インタラクティブに試す →
{"payouts": [50, 30, 20], "chips": [5000, 3000, 2000]}
{"result": {"icm": [38.392857142857146, 32.75, 28.857142857142854]}}
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}}
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}}
完全情報・ステートレスのリプレイ: クライアントがアクションリストを保持し、サーバーは pokerkit で状態を再構築します(サーバー状態はゼロ)。/games/state(現在スポットのスナップショット)、/games/step(next_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/normalize は cards(カード文字列)のみを受け取ります。 |
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"]}}
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"]}}
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}}
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_sizes、donk_sizes、raise_limit フィールドを受け付けるようになりました。 |
| 2026-07-12 | POST /v1/gto/solver/release を追加 — solve のプールポートを早期に解放し、キャッシュ TTL の満了を待たずに直ちにプールへ戻します(任意、無料。その solve に対する最後の /solver/tree / /solver/node の後に呼び出してください)。 |
| 2026-07-04 | /v1/gto/evs を追加(完了した solve のハンドごと・アクションごとのノード EV)。/v1/gto/turn/projected-range が partner_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-17 | OpenAPI 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/node は hole_cards が渡されない場合に完全なレンジ戦略を返します。 |
| 2026-06-16 | ターン/リバー向けのリアルタイムソルバー /v1/gto/solver ファミリー(個別の solve クォータ)を追加し、フロップの意思決定ツリー /v1/gto/flop/treeを追加しました。 |
| 2026-06-15 | すべてのレスポンスから recommendation フィールドを削除しました。frequency に基づいてご自身でアクションを選択してください。 |
pokerai.bet · GTO API v1