{
  "openapi": "3.1.1",
  "info": {
    "title": "Blackjack Basic Strategy Calculator API",
    "version": "1.0.0",
    "summary": "Blackjack basic strategy chart and expected values computed for your table rules.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://playcardsblackjackstrategy.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Blackjack basic strategy chart and expected values computed for your table rules.",
        "description": "Computes the blackjack basic strategy for the rules at your table — number of decks, dealer hits or stands on soft 17, double after split, late surrender, which totals may double, 3:2 or 6:5 — from the exact dealer probabilities of the shoe, not from a copied chart. Enter a hand and the dealer’s up card to see the expected value of hit, stand, double, split and surrender. Play money and learning only: basic strategy lowers the house edge but never beats it.\n\nMethodology:\n- The dealer’s final totals (17–21 or bust) are computed exactly by recursion over the shoe with your two cards and the up card removed, conditioned on the dealer not having blackjack (US peek rule: with an Ace or ten-value up card the dealer checks first, so you only lose your original bet to a blackjack).\n- Hit, stand and double are valued with your extra cards drawn from the shoe with removal; a split hand is valued as a hand starting from one card (doubling only with double after split, split Aces get one card each, no re-splitting). Each hard total is averaged over its two-card combinations weighted by probability (total-dependent strategy).\n- The house edge sums every starting hand and up card with its probability, pays 3:2 or 6:5 for a natural, and assumes this strategy with no insurance. It is an estimate: re-splitting and composition-dependent plays are not modelled, so published figures can differ by about 0.05 %.\n\nFor learning and play money. No strategy removes the casino’s edge; gambling with real money can be addictive.",
        "tags": [
          "apps"
        ],
        "x-mcp-tool": "playcards_blackjack_strategy",
        "x-owner-app": "playcards",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PlaycardsBlackjackStrategyInput"
              },
              "examples": {
                "example1": {
                  "summary": "6 decks, dealer stands on soft 17, double after split",
                  "value": {
                    "decks": "6",
                    "h17": false,
                    "das": true
                  }
                },
                "example2": {
                  "summary": "Soft 18 against a 3 (6 decks, H17)",
                  "value": {
                    "decks": "6",
                    "h17": true,
                    "hand": "A,7",
                    "dealer": "3"
                  }
                },
                "example3": {
                  "summary": "Pair of eights against a 10, single deck",
                  "value": {
                    "decks": "1",
                    "h17": false,
                    "das": false,
                    "hand": "8,8",
                    "dealer": "10"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PlaycardsBlackjackStrategyResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "PlaycardsBlackjackStrategyInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "decks": {
            "title": "Decks",
            "type": "string",
            "enum": [
              "1",
              "2",
              "4",
              "6",
              "8"
            ],
            "default": "6"
          },
          "h17": {
            "title": "Dealer hits soft 17",
            "type": "boolean",
            "default": false
          },
          "das": {
            "title": "Double after split allowed",
            "type": "boolean",
            "default": true
          },
          "surrender": {
            "title": "Late surrender allowed",
            "type": "boolean",
            "default": false
          },
          "doubleOn": {
            "title": "Double on",
            "type": "string",
            "enum": [
              "any",
              "9-11",
              "10-11"
            ],
            "default": "any"
          },
          "bjPays": {
            "title": "Blackjack pays",
            "type": "string",
            "enum": [
              "3:2",
              "6:5"
            ],
            "default": "3:2"
          },
          "hand": {
            "title": "Your two cards (optional)",
            "description": "Ranks 2–10, J, Q, K, A separated by a comma.",
            "type": "string",
            "maxLength": 9,
            "default": ""
          },
          "dealer": {
            "title": "Dealer up card (optional)",
            "type": "string",
            "enum": [
              "",
              "2",
              "3",
              "4",
              "5",
              "6",
              "7",
              "8",
              "9",
              "10",
              "A"
            ],
            "default": ""
          }
        },
        "required": []
      },
      "PlaycardsBlackjackStrategyResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rules",
              "houseEdgePercent",
              "hard",
              "soft",
              "pairs",
              "hand"
            ],
            "properties": {
              "rules": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "decks",
                  "h17",
                  "das",
                  "surrender",
                  "doubleOn",
                  "bjPays"
                ],
                "properties": {
                  "decks": {
                    "type": "integer"
                  },
                  "h17": {
                    "type": "boolean"
                  },
                  "das": {
                    "type": "boolean"
                  },
                  "surrender": {
                    "type": "boolean"
                  },
                  "doubleOn": {
                    "type": "string"
                  },
                  "bjPays": {
                    "type": "number"
                  }
                }
              },
              "houseEdgePercent": {
                "type": "number",
                "description": "Estimated house edge with this strategy (no re-splitting)."
              },
              "hard": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "soft": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "pairs": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "hand": {
                "type": [
                  "object",
                  "null"
                ],
                "additionalProperties": false,
                "required": [
                  "cards",
                  "dealer",
                  "best",
                  "evs"
                ],
                "properties": {
                  "cards": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "dealer": {
                    "type": "string"
                  },
                  "best": {
                    "type": "string"
                  },
                  "evs": {
                    "type": "object"
                  }
                }
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}