Guandan Game API Reference
Complete API documentation for integrating with the Guandan (掼蛋) game AI service.
Overview
Guandan (掼蛋) is a popular Chinese card game played with two decks of cards (108 cards total, including 4 jokers). The game is played by 4 players in 2 teams. This API provides AI strategy recommendations for optimal play.
Authentication
All API requests require authentication using a Bearer token in the Authorization header.
Authorization: Bearer YOUR_API_KEY
Base URL
https://gtoglue.dev.aceguardian.io
Endpoint
Get Strategy Recommendation
Request AI strategy recommendation for the current game state.
Endpoint: POST /lookup?services=RL
Request Headers:
| Header | Value | Required |
|---|---|---|
Authorization | Bearer YOUR_API_KEY | Yes |
Content-Type | application/json | Yes |
Request Body
{
"hand": {
"action_history": [...],
"current_player_hand": [...],
"current_player_position": 0,
"current_rank_card": 0,
"game_mode_code": "gd-no-jf",
"gameuuid": "unique-game-id"
},
"request_id": "unique-request-id"
}
Request Fields
Top Level
| Field | Type | Required | Description |
|---|---|---|---|
hand | object | Yes | The game state object |
request_id | string | Yes | Unique identifier for this request |
Hand Object
| Field | Type | Required | Description |
|---|---|---|---|
action_history | array | Yes | List of actions taken in the current trick |
current_player_hand | array | Yes | Cards in the current player's hand (card IDs 0-53) |
current_player_position | integer | Yes | Current player's position (0-3) |
current_rank_card | integer | Yes | The rank card for this round (0-12, where 0=2, 1=3, ..., 12=A) |
game_mode_code | string | Yes | Game mode code. Currently only "gd-no-jf" (no progression) is supported |
gameuuid | string | No | Unique game identifier for tracking |
Card Encoding
Cards are represented as integers from 0 to 53:
| Card ID Range | Description |
|---|---|
| 0-3 | 2♣, 2♦, 2♥, 2♠ (Rank 2) |
| 4-7 | 3♣, 3♦, 3♥, 3♠ (Rank 3) |
| 8-11 | 4♣, 4♦, 4♥, 4♠ (Rank 4) |
| 12-15 | 5♣, 5♦, 5♥, 5♠ (Rank 5) |
| 16-19 | 6♣, 6♦, 6♥, 6♠ (Rank 6) |
| 20-23 | 7♣, 7♦, 7♥, 7♠ (Rank 7) |
| 24-27 | 8♣, 8♦, 8♥, 8♠ (Rank 8) |
| 28-31 | 9♣, 9♦, 9♥, 9♠ (Rank 9) |
| 32-35 | 10♣, 10♦, 10♥, 10♠ (Rank 10) |
| 36-39 | J♣, J♦, J♥, J♠ (Rank J) |
| 40-43 | Q♣, Q♦, Q♥, Q♠ (Rank Q) |
| 44-47 | K♣, K♦, K♥, K♠ (Rank K) |
| 48-51 | A♣, A♦, A♥, A♠ (Rank A) |
| 52 | Black Joker (小王) |
| 53 | Red Joker (大王) |
Encoding Formula:
Card ID = (Rank * 4) + Suit
Where:
- Rank: 0=2, 1=3, ..., 8=10, 9=J, 10=Q, 11=K, 12=A
- Suit: 0=Clubs(♣), 1=Diamonds(♦), 2=Hearts(♥), 3=Spades(♠)
Note: Since Guandan uses two decks, cards 0-53 represent the first deck. The second deck uses the same card IDs (cards may appear twice in a hand).
Response Rank Encoding
The fields real_rank and smallest_rank in the response use an extended rank encoding that includes Jokers:
| Value | Rank |
|---|---|
| 0-12 | 2, 3, ..., A (Matches Rank Card Encoding) |
| 13 | Black Joker (Small Joker) |
| 14 | Red Joker (Big Joker) |
Action History Format
Each action in the action_history array has the following structure:
{
"cards": [4, 5],
"player_id": 1,
"type": "PAIR"
}
| Field | Type | Description |
|---|---|---|
cards | array | Card IDs played in this action (empty for PASS) |
player_id | integer | Player who made this action (0-3) |
type | string | Action type (see Action Types below) |
Action Types
| Type | Description |
|---|---|
PASS | Player passes (plays no cards) |
SINGLE | Single card |
PAIR | Pair (two cards of same rank) |
TRIPLE | Three cards of same rank |
TRIPLE_WITH_PAIR | Three of a kind with a pair (full house) |
STRAIGHT | Consecutive single cards (min 5 cards) |
CONSECUTIVE_PAIRS | Consecutive pairs (min 3 pairs) |
PLATE | Two consecutive triples (6 cards) |
TUBE | Three or more consecutive triples |
BOMB | Four or more cards of same rank |
STRAIGHT_FLUSH | Consecutive cards of same suit (5+ cards) |
JOKER_BOMB | Four jokers (highest bomb) |
Response Format
Success Response
{
"request": {
"hand": { ... },
"request_id": "req-strict-01"
},
"request_id": "req-strict-01",
"result": {
"strategy": [
{
"action": "B",
"action_id": 14,
"cards": [52],
"player_id": 0,
"probability": 1.0,
"real_rank": [13, -1],
"smallest_rank": 13.0,
"type": "SINGLE",
"type_id": 0
}
]
},
"status": "success"
}
Response Fields
Top Level
| Field | Type | Description |
|---|---|---|
status | string | "success" or "error" |
request_id | string | Echo of the request ID |
request | object | Echo of the original request |
result | object | Strategy result (only present on success) |
Strategy Array
Each item in the strategy array represents a recommended action:
| Field | Type | Description |
|---|---|---|
action | string | Short action notation (e.g., "B" for Black Joker, "22" for pair of 2s, "23456" for straight) |
action_id | integer | Internal action ID (0-375) |
cards | array | Card IDs to play |
player_id | integer | Current player ID |
probability | float | Probability/weight of this action (0.0-1.0) |
real_rank | array | [primary_rank, secondary_rank]. primary_rank is the main rank (0-14). secondary_rank denotes the pair's rank in a Full House (Triple with Pair), otherwise -1. |
smallest_rank | float | Smallest card rank in the combination (0-14). Note: 13 is Black Joker, 14 is Red Joker. |
type | string | Action type name |
type_id | integer | Action type ID |
Error Response
{
"status": "error",
"error": {
"code": "INVALID_INPUT",
"message": "Invalid current_player_position: 5. Must be 0, 1, 2, or 3"
}
}
Complete Example
Request
curl --request POST \
--url 'https://gtoglue.dev.aceguardian.io/lookup?services=RL' \
--header 'Authorization: Bearer YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"hand": {
"action_history": [
{ "cards": [4], "player_id": 1, "type": "SINGLE" },
{ "cards": [8], "player_id": 2, "type": "SINGLE" },
{ "cards": [12], "player_id": 3, "type": "SINGLE" },
{ "cards": [], "player_id": 0, "type": "PASS" },
{ "cards": [44], "player_id": 1, "type": "SINGLE" },
{ "cards": [], "player_id": 2, "type": "PASS" },
{ "cards": [], "player_id": 3, "type": "PASS" }
],
"current_player_hand": [
0, 1, 2, 3,
5, 6, 7,
9, 10, 11,
13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23,
48, 49, 50, 51,
52, 53
],
"current_player_position": 0,
"current_rank_card": 0,
"game_mode_code": "gd-no-jf",
"gameuuid": "example-game-001"
},
"request_id": "req-example-01"
}'
Response
{
"request": {
"hand": {
"action_history": [
{ "cards": [4], "player_id": 1, "type": "SINGLE" },
{ "cards": [8], "player_id": 2, "type": "SINGLE" },
{ "cards": [12], "player_id": 3, "type": "SINGLE" },
{ "cards": [], "player_id": 0, "type": "PASS" },
{ "cards": [44], "player_id": 1, "type": "SINGLE" },
{ "cards": [], "player_id": 2, "type": "PASS" },
{ "cards": [], "player_id": 3, "type": "PASS" }
],
"current_player_hand": [0, 1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 48, 49, 50, 51, 52, 53],
"current_player_position": 0,
"current_rank_card": 0,
"game_mode_code": "gd-no-jf",
"gameuuid": "example-game-001"
},
"request_id": "req-example-01"
},
"request_id": "req-example-01",
"result": {
"strategy": [
{
"action": "B",
"action_id": 14,
"cards": [52],
"player_id": 0,
"probability": 1.0,
"real_rank": [13, -1],
"smallest_rank": 13.0,
"type": "SINGLE",
"type_id": 0
}
]
},
"status": "success"
}
Error Codes
| Error Code | Description |
|---|---|
INVALID_INPUT | Invalid input format or field values |
E501 | Input parsing error |
E500 | Internal server error |
NO_OUTPUT | Model returned no output |
PROCESSING_ERROR | Error processing model output |
Input Validation Rules
- current_player_position: Must be 0, 1, 2, or 3
- current_player_hand: All card IDs must be in range [0, 54)
- current_rank_card: Must be in range [0, 13)
- game_mode_code: Currently only
"gd-no-jf"is supported
Game Mode Codes
| Code | Description |
|---|---|
gd-no-jf | Standard Guandan without level progression (currently supported) |
gd-jf | Guandan with level progression (coming soon) |
Rate Limits
Please refer to your API subscription plan for rate limit details.
Notes
- The AI model analyzes the current game state and returns up to 10 recommended actions sorted by probability
- Actions with probability less than 1% are filtered out
- The
probabilityfield represents the AI's confidence in each action - When multiple actions are returned, they are all valid plays - choose based on your strategy preference