{"openapi":"3.1.0","info":{"title":"Chessvia Analysis API","description":"Chess analysis API for developers and partners.\n\n## Endpoints\n\n- `POST /analyze_position` — Position evaluation with strategic coaching\n- `POST /analyze_game` — Full game analysis with move-by-move breakdown\n\n## Authentication\n\nAll endpoints require Bearer token authentication:\n```\nAuthorization: Bearer YOUR_API_KEY\n```\n\n## Getting started\n\n1. Sign in at [api.chessvia.ai/portal](/portal) with your Google account.\n2. Buy a credit pack on the [pricing page](/pricing). Starts at $5 / 100 credits.\n3. Make your first request with the example below.\n\nFor high-volume integrations, SLA, DPA, or a custom contract: [talk to us](mailto:rohan@chessvia.ai).\n\n## Quick example\n\n```bash\ncurl -X POST https://api.chessvia.ai/analyze_position \\\n  -H \"Authorization: Bearer YOUR_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"position\": \"rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3\"}'\n```\n","contact":{"name":"Chessvia Support","email":"support@chessvia.ai"},"license":{"name":"Proprietary","url":"https://chessvia.ai/terms-of-service"},"version":"2.0"},"paths":{"/analyze_position":{"post":{"tags":["Analysis"],"summary":"Analyze a chess position","description":"Analyze a chess position with Stockfish + coaching response.\n\n**Main use cases:**\n- Live game analysis - Get best move suggestions during games\n- Board evaluation - Show position assessment to users\n- Q&A bot - Answer user questions about positions\n\n**What you get:**\n- Stockfish evaluation in centipawns\n- Best move recommendation\n- Categorical position assessment (equal, slight advantage, winning, etc.)\n- Natural language coaching response\n\n**Response fields:** response, fen, best_move, best_move_uci, evaluation, assessment\n\n**Example request:**\n```json\n{\n  \"position\": \"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1\",\n  \"question\": \"What should I play?\",\n  \"skill_level\": \"intermediate\"\n}\n```","operationId":"analyze_position_endpoint_analyze_position_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzePositionRequest"}}},"required":true},"responses":{"200":{"description":"Position analysis with coaching. Evaluation is integer centipawns (White's perspective); forced mate uses the ±10000 sentinel.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PositionAnalysisResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/analyze_game":{"post":{"tags":["Analysis"],"summary":"Analyze a complete chess game","description":"Analyze a complete chess game from PGN.\n\n**What you get:**\n- Move-by-move evaluation with error classification (blunder/mistake/inaccuracy)\n- Per-side phase summaries (opening/middlegame/endgame for White AND Black)\n- Mistakes separated by side with best move alternatives\n- Expandable overview bullet points and a 4-category study plan\n  (opening/tactics/strategy/endgame)\n- Turning points with phase context\n- Natural language game narrative\n\n**Per-move data** (for eval charts, board overlays, move arrows):\nevaluation_before, best_move_uci, fen_before, fen_after, coaching_text.","operationId":"analyze_game_endpoint_analyze_game_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeGameEndpointRequest"}}},"required":true},"responses":{"200":{"description":"Structured game review. Per-move evaluations are pawn-unit floats (White's perspective) and are null on terminal plies — distinct from /analyze_position's integer centipawns.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GameAnalysisResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}}},"components":{"schemas":{"AccuracySide":{"properties":{"accuracy":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Accuracy","description":"Accuracy percentage (0-100) for the side."}},"type":"object","title":"AccuracySide","description":"Overall accuracy score for one side."},"AnalyzeGameEndpointRequest":{"properties":{"pgn":{"type":"string","title":"Pgn","description":"Full PGN game text with moves","example":"[Event \"Test\"]\n[Result \"1-0\"]\n\n1. e4 e5 2. Nf3 Nc6 3. Bb5 1-0"},"question":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question","description":"User's question about the game. Partner-tier contracts only — ignored on standard API keys.","example":"What were my biggest mistakes?"},"personality":{"type":"string","title":"Personality","description":"Coaching personality: 'Coach', 'Grandmaster Chessy', 'Hustler Chessy', 'Roasty Chessy'","default":"Grandmaster Chessy"},"player_color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Player Color","description":"Focus analysis on this player: 'white' or 'black'","example":"black"},"user_stats":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"User Stats","description":"User context (rating, recent performance) for personalized coaching"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Coaching model override. Partner-tier contracts only — ignored on standard API keys."},"classify_intent":{"type":"boolean","title":"Classify Intent","description":"Classify user's question intent for better response generation","default":true},"include_all_moves":{"type":"boolean","title":"Include All Moves","description":"Include all moves (true) or just errors (false)","default":true},"detect_motifs":{"type":"boolean","title":"Detect Motifs","description":"Detect tactical motifs (forks, pins, hanging pieces)","default":true},"output_format":{"type":"string","enum":["structured","narrative","both"],"title":"Output Format","description":"Response format: 'structured' (JSON), 'narrative' (text), or 'both'","default":"both"},"detail_level":{"type":"string","enum":["brief","standard","detailed"],"title":"Detail Level","description":"Verbosity level of response","default":"standard"},"coaching_style":{"type":"string","enum":["encouraging","direct","socratic"],"title":"Coaching Style","description":"Coaching tone","default":"direct"},"skill_level":{"type":"string","enum":["beginner","intermediate","advanced"],"title":"Skill Level","description":"Player skill level for tailored explanations","default":"intermediate"},"include_variations":{"type":"boolean","title":"Include Variations","description":"Include move variations in response","default":true},"max_moves_analyzed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Moves Analyzed","description":"Limit number of moves analyzed (null = all moves)","example":20},"language":{"type":"string","title":"Language","description":"Response language code (ISO 639-1)","default":"en"},"player_rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Player Rating","description":"Player rating (e.g. 1200) for rating-adjusted explanations"},"include_debug":{"type":"boolean","title":"Include Debug","description":"Internal use — ignored on customer API keys","default":false},"reasoning_effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort","description":"Reasoning effort for LLM coaching. 'none' disables reasoning entirely (fastest). Default: 'minimal'.","default":"minimal","example":"low"},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens","description":"Max output tokens for LLM coaching response. Clamped to 256-4000.","example":500},"position_analysis_scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position Analysis Scope","description":"Which moves get deep positional analysis: 'key' (errors + big eval swings, default), 'none' (skip), or 'all' (every move — partner-tier contracts only).","default":"key","example":"key"},"per_move_coaching":{"type":"boolean","title":"Per Move Coaching","description":"Generate LLM coaching commentary per analyzed move. Each move gets a 1-3 sentence coaching comment. Runs in parallel with narrative generation (~3% overhead).","default":true}},"type":"object","required":["pgn"],"title":"AnalyzeGameEndpointRequest"},"AnalyzePositionRequest":{"properties":{"position":{"type":"string","title":"Position","description":"Position in FEN notation or PGN moves","example":"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1"},"question":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question","description":"User's question about the position","example":"What should I play here?"},"personality":{"type":"string","title":"Personality","description":"Coaching personality: 'Coach', 'Grandmaster Chessy', 'Hustler Chessy', 'Roasty Chessy'","default":"Grandmaster Chessy"},"last_move":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Move","description":"Last move played in SAN notation (for tactical context)","example":"Nf3"},"user_stats":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"User Stats","description":"User context (rating, recent performance) for personalized coaching"},"history":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"History","description":"Optional prior conversation turns [{role:'user'|'assistant', content}] for follow-up coherence. Fully lenient (List[Any]) — non-dict / wrong-role / empty entries are filtered at runtime, never rejected at validation. Ignored when absent — no change to existing single-turn behavior."},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Coaching model override. Partner-tier contracts only — ignored on standard API keys."},"classify_intent":{"type":"boolean","title":"Classify Intent","description":"Classify user's question intent for better response generation","default":true},"output_format":{"type":"string","enum":["structured","narrative","both"],"title":"Output Format","description":"Response format: 'structured' (JSON), 'narrative' (text), or 'both'","default":"both"},"detail_level":{"type":"string","enum":["brief","standard","detailed"],"title":"Detail Level","description":"Verbosity level of response","default":"standard"},"coaching_style":{"type":"string","enum":["encouraging","direct","socratic"],"title":"Coaching Style","description":"Coaching tone","default":"direct"},"skill_level":{"type":"string","enum":["beginner","intermediate","advanced"],"title":"Skill Level","description":"Player skill level for tailored explanations","default":"intermediate"},"include_variations":{"type":"boolean","title":"Include Variations","description":"Include move variations in response","default":true},"include_stockfish":{"type":"boolean","title":"Include Stockfish","description":"Run Stockfish engine analysis","default":true},"language":{"type":"string","title":"Language","description":"Response language code (ISO 639-1)","default":"en"},"player_rating":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Player Rating","description":"Player rating (e.g. 1200) for rating-adjusted explanations"},"include_debug":{"type":"boolean","title":"Include Debug","description":"Internal use — ignored on customer API keys","default":false},"reasoning_effort":{"anyOf":[{"type":"string","enum":["none","minimal","low","medium","high"]},{"type":"null"}],"title":"Reasoning Effort","description":"Reasoning effort for LLM coaching. 'none' disables reasoning entirely (fastest). Default: 'minimal'.","default":"minimal","example":"low"},"max_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Tokens","description":"Max output tokens for LLM coaching response. Clamped to 256-4000 — values below 256 truncate coaching mid-sentence because the model's internal reasoning consumes part of the budget.","example":300}},"type":"object","required":["position"],"title":"AnalyzePositionRequest"},"GameAccuracyContext":{"properties":{"white":{"anyOf":[{"$ref":"#/components/schemas/AccuracySide"},{"type":"null"}],"description":"White's accuracy."},"black":{"anyOf":[{"$ref":"#/components/schemas/AccuracySide"},{"type":"null"}],"description":"Black's accuracy."}},"type":"object","title":"GameAccuracyContext","description":"Per-side accuracy scores for the game."},"GameAnalysisResponse":{"properties":{"overview":{"anyOf":[{"$ref":"#/components/schemas/GameOverview"},{"type":"null"}],"description":"High-level game summary and per-phase prose."},"turning_points":{"items":{"$ref":"#/components/schemas/GameTurningPoint"},"type":"array","title":"Turning Points","description":"Moments where the balance shifted."},"white_mistakes":{"items":{"$ref":"#/components/schemas/GameMistake"},"type":"array","title":"White Mistakes","description":"White's errors with recommended alternatives."},"black_mistakes":{"items":{"$ref":"#/components/schemas/GameMistake"},"type":"array","title":"Black Mistakes","description":"Black's errors with recommended alternatives."},"errors":{"items":{"$ref":"#/components/schemas/GameMistake"},"type":"array","title":"Errors","description":"Combined error list across both sides."},"white_best_move":{"anyOf":[{"$ref":"#/components/schemas/GameBestMove"},{"type":"null"}],"description":"White's single strongest move, or null."},"black_best_move":{"anyOf":[{"$ref":"#/components/schemas/GameBestMove"},{"type":"null"}],"description":"Black's single strongest move, or null."},"study_plan":{"anyOf":[{"$ref":"#/components/schemas/GameStudyPlan"},{"type":"null"}],"description":"Four-part training plan tailored to one player."},"response":{"type":"string","title":"Response","description":"Full natural-language narrative of the game."},"tactical_themes":{"anyOf":[{"$ref":"#/components/schemas/GameTacticalThemes"},{"type":"null"}],"description":"Tactical motif tally across the game."},"momentum":{"anyOf":[{"$ref":"#/components/schemas/GameMomentum"},{"type":"null"}],"description":"Win-probability trajectory and momentum events."},"opening_deviation":{"anyOf":[{"$ref":"#/components/schemas/GameOpeningDeviation"},{"type":"null"}],"description":"Where each side left opening theory."},"accuracy_context":{"anyOf":[{"$ref":"#/components/schemas/GameAccuracyContext"},{"type":"null"}],"description":"Per-side accuracy scores."},"critical_lines":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Critical Lines","description":"Key forcing lines worth studying, when detected."},"piece_activity":{"anyOf":[{"$ref":"#/components/schemas/GamePieceActivity"},{"type":"null"}],"description":"Standout best/worst pieces per side."},"game_summary":{"anyOf":[{"$ref":"#/components/schemas/GameSummary"},{"type":"null"}],"description":"Basic game metadata and accuracy stats."},"moves":{"items":{"$ref":"#/components/schemas/GameMove"},"type":"array","title":"Moves","description":"Per-move review list for eval charts, board overlays, and move arrows."},"phases":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Phases","description":"Per-phase summaries, when the analysis pipeline produces them."},"narrative":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Narrative","description":"Legacy narrative field emitted by some analysis paths; prefer overview.narrative_text."}},"type":"object","required":["response"],"title":"GameAnalysisResponse","description":"Success response for ``POST /analyze_game``.\n\nA structured game review: a natural-language narrative plus per-side\nmistakes, turning points, a study plan, tactical-theme tallies, a\nwin-probability curve, and a simplified per-move list for charts and\nboard overlays.\n\nNote on evaluations: per-move evaluations here are pawn-unit floats and\nare null on terminal plies — unlike ``/analyze_position``'s integer\ncentipawns with the ±10000 mate sentinel."},"GameBestMove":{"properties":{"ply":{"type":"integer","title":"Ply","description":"Half-move number (1-based) of the move."},"move":{"type":"string","title":"Move","description":"The move played, in Standard Algebraic Notation."},"swing_pp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Swing Pp","description":"Win-probability gained by the move, in percentage points."},"why":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Why","description":"Why the move was strong."},"move_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Move Category","description":"Move quality label."}},"type":"object","required":["ply","move"],"title":"GameBestMove","description":"The single strongest move a side found in the game."},"GameMistake":{"properties":{"ply":{"type":"integer","title":"Ply","description":"Half-move number (1-based) of the error."},"move":{"type":"string","title":"Move","description":"The move played, in Standard Algebraic Notation."},"swing_pp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Swing Pp","description":"Win-probability lost by the move, in percentage points."},"why":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Why","description":"Explanation of what went wrong and the idea behind the better move."},"move_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Move Category","description":"Error severity label (e.g. 'inaccuracy', 'mistake', 'blunder')."},"better_move":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Better Move","description":"The recommended move, in Standard Algebraic Notation."}},"type":"object","required":["ply","move"],"title":"GameMistake","description":"An error made by one side, with the recommended alternative."},"GameMomentum":{"properties":{"momentum_events":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Momentum Events","description":"Notable swings in momentum during the game."},"wp_curve":{"items":{"$ref":"#/components/schemas/WinProbabilityPoint"},"type":"array","title":"Wp Curve","description":"Per-ply win-probability curve for charting the game's flow."}},"type":"object","title":"GameMomentum","description":"Win-probability trajectory and notable momentum shifts."},"GameMove":{"properties":{"move_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Move Number","description":"Full-move number (1-based)."},"ply":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ply","description":"Half-move number (1-based)."},"move":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Move","description":"The move in Standard Algebraic Notation."},"color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Color","description":"Side to move: 'white' or 'black'."},"classification":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Classification","description":"Move quality label (e.g. 'book', 'good', 'excellent', 'inaccuracy', 'mistake', 'blunder')."},"evaluation_before":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Evaluation Before","description":"Evaluation in pawns before the move (White's perspective). Null on terminal plies."},"evaluation_after":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Evaluation After","description":"Evaluation in pawns after the move (White's perspective). Null on terminal plies (e.g. the mating move)."},"best_move":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Best Move","description":"Recommended move in Standard Algebraic Notation, when a better move existed."},"best_move_uci":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Best Move Uci","description":"Recommended move in UCI coordinate notation, when available."},"fen_before":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fen Before","description":"Position before the move, in Forsyth-Edwards Notation."},"fen_after":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fen After","description":"Position after the move, in Forsyth-Edwards Notation."},"review_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Review Text","description":"Short factual annotation of the move."},"coaching_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Coaching Text","description":"Deeper coaching prose for the move. Populated on notable moves; null otherwise."},"game_phase":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Game Phase","description":"Game phase: 'opening', 'middlegame', or 'endgame'."},"best_move_explanation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Best Move Explanation","description":"Explanation of the recommended move, when available."},"expected_points_before":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Expected Points Before","description":"Expected points (0-1) before the move, when available."},"expected_points_after":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Expected Points After","description":"Expected points (0-1) after the move, when available."},"expected_points_lost":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Expected Points Lost","description":"Expected points lost by the move, when available."}},"type":"object","title":"GameMove","description":"One half-move, with the data needed to render a review UI.\n\nPer-move evaluations are pawn-unit floats (e.g. 0.41), from White's\nperspective — distinct from ``/analyze_position``'s integer centipawns.\n``evaluation_before`` / ``evaluation_after`` are null on terminal plies\n(checkmate/stalemate), where no continuation evaluation exists."},"GameOpeningDeviation":{"properties":{"white_deviation":{"anyOf":[{"$ref":"#/components/schemas/OpeningDeviationSide"},{"type":"null"}],"description":"White's first opening deviation, or null if none."},"black_deviation":{"anyOf":[{"$ref":"#/components/schemas/OpeningDeviationSide"},{"type":"null"}],"description":"Black's first opening deviation, or null if none."},"opening_violations":{"items":{"type":"string"},"type":"array","title":"Opening Violations","description":"Human-readable opening-principle violations detected."}},"type":"object","title":"GameOpeningDeviation","description":"Where each side departed from opening theory."},"GameOverview":{"properties":{"result":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result","description":"Game result: 'white', 'black', or 'draw'."},"opening_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Opening Name","description":"Named opening/variation identified for the game."},"summary_sentence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary Sentence","description":"One-sentence summary of how the game was decided."},"overview_bullets":{"items":{"type":"string"},"type":"array","title":"Overview Bullets","description":"Expandable bullet points walking through the key moments."},"white_opening":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"White Opening","description":"Prose on White's opening play. May be empty when the game did not reach the phase."},"black_opening":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Black Opening","description":"Prose on Black's opening play. May be empty."},"white_middlegame":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"White Middlegame","description":"Prose on White's middlegame play. May be empty."},"black_middlegame":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Black Middlegame","description":"Prose on Black's middlegame play. May be empty."},"white_endgame":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"White Endgame","description":"Prose on White's endgame play. May be empty."},"black_endgame":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Black Endgame","description":"Prose on Black's endgame play. May be empty."},"narrative_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Narrative Text","description":"Full natural-language narrative of the game (same content as the top-level 'response')."}},"type":"object","title":"GameOverview","description":"High-level game summary: result, opening, and per-phase prose."},"GamePieceActivity":{"properties":{"star_piece":{"anyOf":[{"$ref":"#/components/schemas/PieceBySide"},{"type":"null"}],"description":"Each side's best-performing piece."},"worst_piece":{"anyOf":[{"$ref":"#/components/schemas/PieceBySide"},{"type":"null"}],"description":"Each side's worst-performing piece."}},"type":"object","title":"GamePieceActivity","description":"Standout pieces of the game, per side."},"GameStudyPlan":{"properties":{"for_color":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"For Color","description":"Which side the plan is written for: 'white' or 'black'."},"strengths":{"items":{"type":"string"},"type":"array","title":"Strengths","description":"What the player did well."},"weaknesses":{"items":{"type":"string"},"type":"array","title":"Weaknesses","description":"Areas to work on."},"opening_work":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Opening Work","description":"Opening-phase study recommendation."},"tactics_work":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tactics Work","description":"Tactics study recommendation."},"strategic_work":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Strategic Work","description":"Strategy/planning study recommendation."},"endgame_work":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Endgame Work","description":"Endgame study recommendation."}},"type":"object","title":"GameStudyPlan","description":"A four-part training plan tailored to one player's game."},"GameSummary":{"properties":{"result":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Result","description":"Result string in PGN form (e.g. '1-0', '0-1', '1/2-1/2')."},"opening":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Opening","description":"Named opening."},"eco":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Eco","description":"ECO opening code, when identified. May be null even with a named opening."},"total_moves":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Moves","description":"Total half-moves (plies) in the game."},"white_accuracy":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"White Accuracy","description":"White accuracy percentage (0-100)."},"black_accuracy":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Black Accuracy","description":"Black accuracy percentage (0-100)."}},"type":"object","title":"GameSummary","description":"Basic game metadata and accuracy stats."},"GameTacticalThemes":{"properties":{"themes":{"additionalProperties":{"$ref":"#/components/schemas/ThemeCount"},"type":"object","title":"Themes","description":"Map of theme name (e.g. 'pin', 'fork', 'skewer') to its per-side counts."},"total_motifs":{"type":"integer","title":"Total Motifs","description":"Total tactical motifs detected in the game.","default":0}},"type":"object","title":"GameTacticalThemes","description":"Tactical motif tally across the whole game."},"GameTurningPoint":{"properties":{"ply":{"type":"integer","title":"Ply","description":"Half-move number (1-based) at which the shift occurred."},"move":{"type":"string","title":"Move","description":"The move played, in Standard Algebraic Notation."},"phase":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phase","description":"Game phase: 'opening', 'middlegame', or 'endgame'."},"swing_pp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Swing Pp","description":"Size of the win-probability swing, in percentage points."},"explanation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explanation","description":"Why this move mattered."},"move_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Move Category","description":"Move quality label (e.g. 'mistake', 'good', 'excellent', 'blunder', 'inaccuracy', 'book')."}},"type":"object","required":["ply","move"],"title":"GameTurningPoint","description":"A moment where the game's balance shifted."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"OpeningDeviationSide":{"properties":{"ply":{"type":"integer","title":"Ply","description":"Half-move number (1-based) of the deviation."},"move":{"type":"string","title":"Move","description":"The move played, in Standard Algebraic Notation."},"engine_preferred":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Engine Preferred","description":"The recommended move at that point, in Standard Algebraic Notation."}},"type":"object","required":["ply","move"],"title":"OpeningDeviationSide","description":"The first ply at which a side left the recommended opening line."},"PieceBySide":{"properties":{"white":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"White","description":"Piece name for White (e.g. 'Queen')."},"black":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Black","description":"Piece name for Black."}},"type":"object","title":"PieceBySide","description":"A named piece for each side."},"PositionAnalysisResponse":{"properties":{"response":{"type":"string","title":"Response","description":"Natural-language coaching for the position: the best plan and why it works."},"fen":{"type":"string","title":"Fen","description":"The analysed position in Forsyth-Edwards Notation (echoed from the request)."},"best_move":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Best Move","description":"Best move in Standard Algebraic Notation (e.g. 'Nxe5'). Null when the position is terminal (checkmate/stalemate)."},"best_move_uci":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Best Move Uci","description":"Best move in UCI coordinate notation (e.g. 'f3e5'), for drawing arrows on a board. Null on terminal positions."},"evaluation":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Evaluation","description":"Position evaluation in centipawns from White's perspective (positive favours White). A forced mate returns the sentinel +10000 or -10000 (no numeric mate distance). Null on terminal positions."},"assessment":{"type":"string","title":"Assessment","description":"Categorical read of the evaluation: one of equal, slight_white, slight_black, winning_white, winning_black, decisive_white, decisive_black, or unknown."}},"type":"object","required":["response","fen","assessment"],"title":"PositionAnalysisResponse","description":"Success response for ``POST /analyze_position``.\n\nA compact, six-field shape: coaching prose plus the machine-readable\nfields needed to draw a best-move arrow and an evaluation bar.\n\nEvaluation convention: ``evaluation`` is an integer in centipawns from\nWhite's point of view (positive favours White). A forced mate is reported\nwith the sentinel ``+10000`` / ``-10000`` rather than a numeric distance;\nthe mate distance, when known, is stated in ``response``. (On\n``/analyze_game`` the per-move evaluations are pawn-unit floats instead —\nsee ``GameMove.evaluation_before``.)","example":{"assessment":"slight_white","best_move":"Nxe5","best_move_uci":"f3e5","evaluation":41,"fen":"rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3","response":"The position is roughly equal. Capturing with Nxe5 challenges Black immediately while keeping development on track."}},"ThemeCount":{"properties":{"white":{"type":"integer","title":"White","description":"Times the theme appeared for White.","default":0},"black":{"type":"integer","title":"Black","description":"Times the theme appeared for Black.","default":0},"missed":{"type":"integer","title":"Missed","description":"Times the theme was available but not played.","default":0}},"type":"object","title":"ThemeCount","description":"How often a tactical theme appeared for each side, plus missed chances."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WinProbabilityPoint":{"properties":{"ply":{"type":"integer","title":"Ply","description":"Half-move number (1-based)."},"wp_white":{"type":"number","title":"Wp White","description":"White's win probability at this ply, as a percentage (0-100)."}},"type":"object","required":["ply","wp_white"],"title":"WinProbabilityPoint","description":"One point on the win-probability curve."}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}},"tags":[{"name":"Analysis","description":"Chess analysis endpoints"}]}