{"openapi":"3.0.3","info":{"title":"Future football performance API","description":"Future football performance API provides prediction, player lookup, score database,\nrole-cluster, career trajectory, chart, and report endpoints for football analytics products.\n\n## Authentication\n\nSend your API key with either header on authenticated endpoints. Career trajectory endpoints can be used without a key for the free 300-call tier; valid paid API keys are unlimited for that project:\n\n```http\nAuthorization: Bearer YOUR_API_KEY\nX-API-Key: YOUR_API_KEY\n```\n\n## Typical workflow\n\n1. Use `GET /database/players/basic` to find a player id.\n2. Use `GET /database/ratings` or `GET /database/player-features` to inspect stored score and feature rows.\n3. Use `GET /database/career-trajectory/players` and `GET /database/career-trajectory/{canonical_player_id}` for basic-data career trajectory views. These support anonymous free access up to 300 calls, while paid API keys are unlimited.\n4. Use `POST /score/predict` for a single player feature kit or `POST /score/predict-batch` for bulk scoring.\n5. Use `GET /report/data` for a structured player report payload.\n6. Use `/player-charts/*` endpoints when you need ready-to-render PNG, SVG, WebP, or interactive HTML charts.\n\n## Errors\n\nErrors use the standard FastAPI shape:\n\n```json\n{ \"detail\": \"Human-readable error message\" }\n```\n\nValidation errors return `422` with a list of field-level details.","version":"1.0.0"},"servers":[{"url":"https://footballperformanceapi.site"}],"paths":{"/database/ratings":{"get":{"tags":["database"],"summary":"Get stored rating rows","operationId":"ratings_database_ratings_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"query","required":false,"schema":{"type":"integer","description":"Filter by player_id","title":"Player Id","nullable":true},"description":"Filter by player_id"},{"name":"full_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by full_name (exact match)","title":"Full Name","nullable":true},"description":"Filter by full_name (exact match)"},{"name":"position","in":"query","required":false,"schema":{"type":"string","description":"Filter by position (exact match)","title":"Position","nullable":true},"description":"Filter by position (exact match)"},{"name":"season","in":"query","required":false,"schema":{"type":"string","description":"Filter by season (exact match)","title":"Season","nullable":true},"description":"Filter by season (exact match)"},{"name":"league","in":"query","required":false,"schema":{"type":"string","description":"Filter by league (exact match)","title":"League","nullable":true},"description":"Filter by league (exact match)"},{"name":"team","in":"query","required":false,"schema":{"type":"string","description":"Filter by team (exact match)","title":"Team","nullable":true},"description":"Filter by team (exact match)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"description":"Max rows to return per table","default":200,"title":"Limit"},"description":"Max rows to return per table"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset per table","default":0,"title":"Offset"},"description":"Row offset per table"}],"responses":{"200":{"description":"Base and pro rating rows grouped by table.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"pro_rating.db","filters":{"player_id":12345,"season":"2024/2025"},"base_scores":{"count":1,"rows":[{"player_id":12345,"full_name":"Example Player","position":"Defender","season":"2024/2025","league":"Premier League","attack_score_score_pct":6.2,"defense_score_score_pct":7.8,"rating_display_score_pct":7.1}]},"pro_scores":{"count":1,"rows":[{"player_id":12345,"full_name":"Example Player","position":"Defender","season":"2024/2025","league":"Premier League","Current Club":"Example FC","passing_score_score_pct":7.2,"progression_score_score_pct":7.5,"rating_display_score_pct":7.3}]}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Returns base and pro score rows from the ratings database. Filters are exact match unless noted."}},"/database/players/basic":{"get":{"tags":["database"],"summary":"Search basic player records","operationId":"get_players_basic_database_players_basic_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"query","required":false,"schema":{"type":"integer","description":"Filter by player_id","title":"Player Id","nullable":true},"description":"Filter by player_id"},{"name":"name","in":"query","required":false,"schema":{"type":"string","description":"Filter by name (contains match)","title":"Name","nullable":true},"description":"Filter by name (contains match)"},{"name":"position","in":"query","required":false,"schema":{"type":"string","description":"Filter by position (exact match)","title":"Position","nullable":true},"description":"Filter by position (exact match)"},{"name":"postiton","in":"query","required":false,"schema":{"type":"string","description":"Alias of position","title":"Postiton","nullable":true},"description":"Alias of position"},{"name":"league","in":"query","required":false,"schema":{"type":"string","description":"Filter by league (exact match)","title":"League","nullable":true},"description":"Filter by league (exact match)"},{"name":"season","in":"query","required":false,"schema":{"type":"string","description":"Filter by season (exact match)","title":"Season","nullable":true},"description":"Filter by season (exact match)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"description":"Max rows to return","default":200,"title":"Limit"},"description":"Max rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Matching player identity rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"pro_rating.db","table":["base_scores","pro_scores"],"filters":{"name":"messi","season":"2024/2025"},"count":1,"rows":[{"player_id":12345,"name":"Example Player","position":"Forward","league":"Premier League","season":"2024/2025"}]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Find player ids by name, position, league, season, or exact player id."}},"/database/player-features":{"get":{"tags":["database"],"summary":"Get engineered feature rows","operationId":"player_features_database_player_features_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"query","required":false,"schema":{"type":"integer","description":"Filter by player_id (exact match)","title":"Player Id","nullable":true},"description":"Filter by player_id (exact match)"},{"name":"name","in":"query","required":false,"schema":{"type":"string","description":"Filter by full_name (contains match)","title":"Name","nullable":true},"description":"Filter by full_name (contains match)"},{"name":"full_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by full_name (exact match)","title":"Full Name","nullable":true},"description":"Filter by full_name (exact match)"},{"name":"league","in":"query","required":false,"schema":{"type":"string","description":"Filter by league (exact match)","title":"League","nullable":true},"description":"Filter by league (exact match)"},{"name":"season","in":"query","required":false,"schema":{"type":"string","description":"Filter by season (exact match)","title":"Season","nullable":true},"description":"Filter by season (exact match)"},{"name":"position","in":"query","required":false,"schema":{"type":"string","description":"Filter by position (exact match)","title":"Position","nullable":true},"description":"Filter by position (exact match)"},{"name":"club","in":"query","required":false,"schema":{"type":"string","description":"Filter by Current Club/club (exact match)","title":"Club","nullable":true},"description":"Filter by Current Club/club (exact match)"},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"pro | base | all","default":"pro","title":"Source"},"description":"pro | base | all"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"description":"Max rows to return per table","default":200,"title":"Limit"},"description":"Max rows to return per table"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset per table","default":0,"title":"Offset"},"description":"Row offset per table"}],"responses":{"200":{"description":"Feature rows grouped by base/pro source.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_features.db","filters":{"player_id":12345,"source":"pro"},"limit":200,"offset":0,"pro":{"table":"player_features_pro","count":1,"rows":[{"player_id":12345,"full_name":"Example Player","position":"Defender","season":"2024/2025","league":"Premier League","minutes_played_overall":1980,"tackles_per_90_overall":3.09}]},"total_count":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Returns raw and engineered model feature rows from the player features database."}},"/database/role-cluster-results":{"get":{"tags":["database"],"summary":"Get player role-cluster assignments","operationId":"role_cluster_results_database_role_cluster_results_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"query","required":false,"schema":{"type":"integer","description":"Filter by player_id","title":"Player Id","nullable":true},"description":"Filter by player_id"},{"name":"player_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by player_name (exact match)","title":"Player Name","nullable":true},"description":"Filter by player_name (exact match)"},{"name":"season","in":"query","required":false,"schema":{"type":"string","description":"Filter by season (exact match)","title":"Season","nullable":true},"description":"Filter by season (exact match)"},{"name":"league","in":"query","required":false,"schema":{"type":"string","description":"Filter by league (exact match)","title":"League","nullable":true},"description":"Filter by league (exact match)"},{"name":"club","in":"query","required":false,"schema":{"type":"string","description":"Filter by club (exact match)","title":"Club","nullable":true},"description":"Filter by club (exact match)"},{"name":"position","in":"query","required":false,"schema":{"type":"string","description":"Filter by position (exact match)","title":"Position","nullable":true},"description":"Filter by position (exact match)"},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"Filter by source (exact match)","title":"Source","nullable":true},"description":"Filter by source (exact match)"},{"name":"cluster_id","in":"query","required":false,"schema":{"type":"integer","description":"Filter by cluster_id","title":"Cluster Id","nullable":true},"description":"Filter by cluster_id"},{"name":"cluster_group","in":"query","required":false,"schema":{"type":"string","description":"Filter by cluster_group","title":"Cluster Group","nullable":true},"description":"Filter by cluster_group"},{"name":"cluster_local","in":"query","required":false,"schema":{"type":"string","description":"Filter by cluster_local","title":"Cluster Local","nullable":true},"description":"Filter by cluster_local"},{"name":"cluster_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by cluster_name","title":"Cluster Name","nullable":true},"description":"Filter by cluster_name"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"description":"Max rows to return","default":200,"title":"Limit"},"description":"Max rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Role-cluster rows for players.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"rolecluster_results.db","table":"role_cluster_results","filters":{"player_id":12345},"count":1,"rows":[{"player_id":12345,"player_name":"Example Player","season":"2024/2025","league":"Premier League","cluster_id":4,"cluster_group":"Defenders","cluster_name":"Progressive Defender","top_traits":"[\"defense_score_z\", \"progression_score_z\"]"}]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Returns player-level role-cluster assignments and probability payloads."}},"/database/role-cluster-summary":{"get":{"tags":["database"],"summary":"Get role-cluster summaries","operationId":"role_cluster_summary_database_role_cluster_summary_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"cluster_id","in":"query","required":false,"schema":{"type":"integer","description":"Filter by cluster_id","title":"Cluster Id","nullable":true},"description":"Filter by cluster_id"},{"name":"cluster_group","in":"query","required":false,"schema":{"type":"string","description":"Filter by cluster_group","title":"Cluster Group","nullable":true},"description":"Filter by cluster_group"},{"name":"cluster_local","in":"query","required":false,"schema":{"type":"string","description":"Filter by cluster_local","title":"Cluster Local","nullable":true},"description":"Filter by cluster_local"},{"name":"cluster_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by cluster_name","title":"Cluster Name","nullable":true},"description":"Filter by cluster_name"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":5000,"minimum":1,"description":"Max rows to return","default":200,"title":"Limit"},"description":"Max rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Role-cluster summary rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"rolecluster_results.db","table":"role_cluster_summary","filters":{"cluster_group":"Defenders"},"count":1,"rows":[{"cluster_id":4,"cluster_group":"Defenders","cluster_name":"Progressive Defender","player_count":214,"mean_score_z":"{\"defense_score_z\":0.82,\"progression_score_z\":0.67}"}]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Returns cluster-level labels, groups, and aggregate score profiles."}},"/database/career-trajectory/players":{"get":{"tags":["database"],"summary":"Search career trajectory players","operationId":"career_trajectory_players_database_career_trajectory_players_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"query","required":false,"schema":{"type":"string","description":"Filter by canonical_player_id","title":"Canonical Player Id","nullable":true},"description":"Filter by canonical_player_id"},{"name":"name","in":"query","required":false,"schema":{"type":"string","description":"Case-insensitive partial player name search","title":"Name","nullable":true},"description":"Case-insensitive partial player name search"},{"name":"nationality","in":"query","required":false,"schema":{"type":"string","description":"Filter by nationality","title":"Nationality","nullable":true},"description":"Filter by nationality"},{"name":"career_timing_label_zh","in":"query","required":false,"schema":{"type":"string","description":"Filter by career timing label","title":"Career Timing Label Zh","nullable":true},"description":"Filter by career timing label"},{"name":"cluster_label_zh","in":"query","required":false,"schema":{"type":"string","description":"Filter by trajectory cluster label","title":"Cluster Label Zh","nullable":true},"description":"Filter by trajectory cluster label"},{"name":"career_momentum","in":"query","required":false,"schema":{"type":"string","description":"Filter by latest career momentum","title":"Career Momentum","nullable":true},"description":"Filter by latest career momentum"},{"name":"latest_trajectory_label","in":"query","required":false,"schema":{"type":"string","description":"Filter by latest season trajectory label","title":"Latest Trajectory Label","nullable":true},"description":"Filter by latest season trajectory label"},{"name":"model_eligible","in":"query","required":false,"schema":{"type":"integer","maximum":1,"minimum":0,"description":"1 keeps players eligible for model labels; 0 returns excluded samples","title":"Model Eligible","nullable":true},"description":"1 keeps players eligible for model labels; 0 returns excluded samples"},{"name":"min_seasons","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Minimum career season count","title":"Min Seasons","nullable":true},"description":"Minimum career season count"},{"name":"min_minutes","in":"query","required":false,"schema":{"type":"number","minimum":0,"description":"Minimum career minutes","title":"Min Minutes","nullable":true},"description":"Minimum career minutes"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max players to return","default":50,"title":"Limit"},"description":"Max players to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career summary search rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","table":"player_career_display_summary","filters":{"name":"mitrovic","min_seasons":5},"count":1,"rows":[{"canonical_player_id":"cp_002417bee788b8cc","full_name":"Example Player","latest_season":"2025/2026","career_seasons":14,"total_minutes":32884,"career_timing_label_zh":"晚熟上升","cluster_label_zh":"长生涯高分钟主力"}]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Search canonical player career summaries built from basic season data. Use this endpoint before loading a full career trajectory payload."}},"/database/career-trajectory/cluster-profiles":{"get":{"tags":["database"],"summary":"Get trajectory cluster profiles","operationId":"career_trajectory_cluster_profiles_database_career_trajectory_cluster_profiles_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"model_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by model name, for example kmeans or gmm","default":"kmeans","title":"Model Name","nullable":true},"description":"Filter by model name, for example kmeans or gmm"},{"name":"cluster_id","in":"query","required":false,"schema":{"type":"integer","description":"Filter by cluster_id","title":"Cluster Id","nullable":true},"description":"Filter by cluster_id"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max rows to return","default":50,"title":"Limit"},"description":"Max rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/model-evaluations":{"get":{"tags":["database"],"summary":"Get trajectory cluster model evaluation rows","operationId":"career_trajectory_model_evaluations_database_career_trajectory_model_evaluations_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"model_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by model name","title":"Model Name","nullable":true},"description":"Filter by model name"},{"name":"selected","in":"query","required":false,"schema":{"type":"integer","maximum":1,"minimum":0,"description":"Filter selected model rows","title":"Selected","nullable":true},"description":"Filter selected model rows"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max rows to return","default":50,"title":"Limit"},"description":"Max rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/league-tier-map":{"get":{"tags":["database"],"summary":"Get league tier mapping rows","operationId":"career_trajectory_league_tier_map_database_career_trajectory_league_tier_map_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"raw_league","in":"query","required":false,"schema":{"type":"string","description":"Filter by raw league name","title":"Raw League","nullable":true},"description":"Filter by raw league name"},{"name":"canonical_league","in":"query","required":false,"schema":{"type":"string","description":"Filter by canonical league name","title":"Canonical League","nullable":true},"description":"Filter by canonical league name"},{"name":"country_or_region","in":"query","required":false,"schema":{"type":"string","description":"Filter by country or region","title":"Country Or Region","nullable":true},"description":"Filter by country or region"},{"name":"needs_manual_review","in":"query","required":false,"schema":{"type":"integer","maximum":1,"minimum":0,"description":"Filter manual-review flags","title":"Needs Manual Review","nullable":true},"description":"Filter manual-review flags"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"description":"Max rows to return","default":200,"title":"Limit"},"description":"Max rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/data-quality":{"get":{"tags":["database"],"summary":"Get career trajectory data quality report","operationId":"career_trajectory_data_quality_database_career_trajectory_data_quality_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"metric_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by metric_name","title":"Metric Name","nullable":true},"description":"Filter by metric_name"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max rows to return","default":100,"title":"Limit"},"description":"Max rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/usage":{"get":{"tags":["database"],"summary":"Get career trajectory free-tier usage","description":"Returns the current career trajectory quota status without consuming a free call. Anonymous users receive the configured free tier; valid paid API keys return unlimited access.","operationId":"career_trajectory_usage_database_career_trajectory_usage_get","security":[{},{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Career trajectory quota status.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"feature":"career_trajectory","plan":"free","period":"lifetime:career_trajectory","limit":300,"used":8,"remaining":292,"unlimited":false,"auth_source":"anonymous_free"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/database/career-trajectory/{canonical_player_id}":{"get":{"tags":["database"],"summary":"Get full career trajectory payload","operationId":"career_trajectory_detail_database_career_trajectory__canonical_player_id__get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"include_timeline","in":"query","required":false,"schema":{"type":"boolean","description":"Include season timeline rows","default":true,"title":"Include Timeline"},"description":"Include season timeline rows"},{"name":"include_events","in":"query","required":false,"schema":{"type":"boolean","description":"Include breakout, decline, climb, spike, and peak event markers","default":true,"title":"Include Events"},"description":"Include breakout, decline, climb, spike, and peak event markers"},{"name":"include_phases","in":"query","required":false,"schema":{"type":"boolean","description":"Include contiguous career phase segments","default":true,"title":"Include Phases"},"description":"Include contiguous career phase segments"},{"name":"include_age_bands","in":"query","required":false,"schema":{"type":"boolean","description":"Include age-band playing-time and output summary","default":true,"title":"Include Age Bands"},"description":"Include age-band playing-time and output summary"},{"name":"include_transitions","in":"query","required":false,"schema":{"type":"boolean","description":"Include league-upgrade transition windows","default":true,"title":"Include Transitions"},"description":"Include league-upgrade transition windows"},{"name":"event_limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max event markers in the combined payload","default":100,"title":"Event Limit"},"description":"Max event markers in the combined payload"}],"responses":{"200":{"description":"Full player career trajectory payload.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","canonical_player_id":"cp_002417bee788b8cc","summary":{"full_name":"Example Player","career_timing_label_zh":"晚熟上升"},"timeline":{"count":2,"rows":[{"season":"2024/2025","season_age":29,"primary_league":"Super Liga","minutes_played_overall":2400,"goals_overall":12,"assists_overall":4,"trajectory_label":"stable","is_breakout_season":0}]}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Returns one player career summary plus season timeline, event markers, phase segments, age-band summaries, and league transition windows. Forecast tables are not exposed."}},"/database/career-trajectory/{canonical_player_id}/timeline":{"get":{"tags":["database"],"summary":"Get season-by-season trajectory rows","operationId":"career_trajectory_timeline_database_career_trajectory__canonical_player_id__timeline_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"season","in":"query","required":false,"schema":{"type":"string","description":"Filter by season","title":"Season","nullable":true},"description":"Filter by season"},{"name":"league","in":"query","required":false,"schema":{"type":"string","description":"Filter by league or primary_league","title":"League","nullable":true},"description":"Filter by league or primary_league"},{"name":"start_year","in":"query","required":false,"schema":{"type":"integer","description":"Minimum starting_year","title":"Start Year","nullable":true},"description":"Minimum starting_year"},{"name":"end_year","in":"query","required":false,"schema":{"type":"integer","description":"Maximum starting_year","title":"End Year","nullable":true},"description":"Maximum starting_year"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max timeline rows to return","default":200,"title":"Limit"},"description":"Max timeline rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/{canonical_player_id}/events":{"get":{"tags":["database"],"summary":"Get career event markers","operationId":"career_trajectory_events_database_career_trajectory__canonical_player_id__events_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"event_type","in":"query","required":false,"schema":{"type":"string","description":"Filter by event_type","title":"Event Type","nullable":true},"description":"Filter by event_type"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max event rows to return","default":100,"title":"Limit"},"description":"Max event rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/{canonical_player_id}/phases":{"get":{"tags":["database"],"summary":"Get grouped career phase segments","operationId":"career_trajectory_phases_database_career_trajectory__canonical_player_id__phases_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max phase rows to return","default":100,"title":"Limit"},"description":"Max phase rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/{canonical_player_id}/age-bands":{"get":{"tags":["database"],"summary":"Get age-band stability summary","operationId":"career_trajectory_age_bands_database_career_trajectory__canonical_player_id__age_bands_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Max age-band rows to return","default":20,"title":"Limit"},"description":"Max age-band rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/{canonical_player_id}/league-transitions":{"get":{"tags":["database"],"summary":"Get league transition windows","operationId":"career_trajectory_league_transitions_database_career_trajectory__canonical_player_id__league_transitions_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max transition rows to return","default":50,"title":"Limit"},"description":"Max transition rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/{canonical_player_id}/summary":{"get":{"tags":["database"],"summary":"Get base career summary row","operationId":"career_trajectory_summary_database_career_trajectory__canonical_player_id__summary_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/{canonical_player_id}/raw-timeline":{"get":{"tags":["database"],"summary":"Get full raw season trajectory rows","operationId":"career_trajectory_raw_timeline_database_career_trajectory__canonical_player_id__raw_timeline_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"season","in":"query","required":false,"schema":{"type":"string","description":"Filter by season","title":"Season","nullable":true},"description":"Filter by season"},{"name":"league","in":"query","required":false,"schema":{"type":"string","description":"Filter by league, primary_league, or raw_primary_league","title":"League","nullable":true},"description":"Filter by league, primary_league, or raw_primary_league"},{"name":"start_year","in":"query","required":false,"schema":{"type":"integer","description":"Minimum starting_year","title":"Start Year","nullable":true},"description":"Minimum starting_year"},{"name":"end_year","in":"query","required":false,"schema":{"type":"integer","description":"Maximum starting_year","title":"End Year","nullable":true},"description":"Maximum starting_year"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Max raw season rows to return","default":200,"title":"Limit"},"description":"Max raw season rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/{canonical_player_id}/clusters":{"get":{"tags":["database"],"summary":"Get player trajectory cluster assignments","operationId":"career_trajectory_player_clusters_database_career_trajectory__canonical_player_id__clusters_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"model_name","in":"query","required":false,"schema":{"type":"string","description":"Filter by model name, for example kmeans or gmm","title":"Model Name","nullable":true},"description":"Filter by model name, for example kmeans or gmm"},{"name":"trajectory_dimension","in":"query","required":false,"schema":{"type":"string","description":"Filter by trajectory_dimension","title":"Trajectory Dimension","nullable":true},"description":"Filter by trajectory_dimension"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Max cluster rows to return","default":20,"title":"Limit"},"description":"Max cluster rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/database/career-trajectory/{canonical_player_id}/identity":{"get":{"tags":["database"],"summary":"Get player identity merge rows","operationId":"career_trajectory_identity_database_career_trajectory__canonical_player_id__identity_get","security":[{},{"ApiKeyAuth":[]}],"parameters":[{"name":"canonical_player_id","in":"path","required":true,"schema":{"type":"string","title":"Canonical Player Id"}},{"name":"include_manual_review","in":"query","required":false,"schema":{"type":"integer","maximum":1,"minimum":0,"description":"Filter by needs_manual_review","title":"Include Manual Review","nullable":true},"description":"Filter by needs_manual_review"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Max identity rows to return","default":50,"title":"Limit"},"description":"Max identity rows to return"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Row offset","default":0,"title":"Offset"},"description":"Row offset"}],"responses":{"200":{"description":"Career trajectory rows.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"db":"player_career_trajectory.db","count":1,"rows":[]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Read-only career trajectory data generated from basic season data. Anonymous free access is limited to 300 calls; valid paid API keys are unlimited. No rating, skill, similar-player, vector, or forecast API is included."}},"/score/":{"get":{"tags":["score"],"summary":"Score service metadata","operationId":"root_score__get","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Score service metadata and example request.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"message":"Score service is running.","example_request":{"features":{"position":"defender","season":"2024/2025","league":"Premier League","player_name":"Example Player","club":"Example FC","minutes":1980,"goals":3,"assists":5,"shots":28,"shots_on_target":10,"passes_completed":1650,"passes_attempted":1900,"tackles":68,"tackles_won":45,"interceptions":52,"clearances":140,"blocks":35,"dribbles":42,"dribbles_successful":23,"aerials":90,"aerials_won":56,"fouls_committed":22,"fouls_drawn":18,"yellow_cards":4,"red_cards":0}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Returns a short service status message and a ready-to-copy single-player prediction request."}},"/score/predict":{"post":{"tags":["score"],"summary":"Predict one player","operationId":"predict_score_predict_post","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictRequest"}}}},"responses":{"200":{"description":"Predicted 0-10 scores and best role-cluster match.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"scores_0_10":{"attack_score":6.43,"shooting_quality_score":5.71,"assist_score":6.08,"creation_score":6.62,"passing_score":7.21,"progression_score":7.48,"dribble_score":5.94,"ball_security_score":7.02,"defense_score":7.76,"aerial_score":7.31,"discipline_score":6.58,"appearance_score":7.84,"rating_pred":7.18},"cluster":{"cluster_name":"Progressive Defender","cluster_id":4,"probabilities":{"Progressive Defender":0.62,"Ball-Playing Defender":0.25,"Defensive Stopper":0.13}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Scores a single player feature kit. `position`, `season`, and `league` are required. Missing optional numeric features are filled from model reference distributions.","x-codeSamples":[{"lang":"cURL","source":"curl -X POST 'https://footballperformanceapi.site/score/predict' \\\n  -H 'Authorization: Bearer YOUR_API_KEY' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"features\":{\"position\":\"defender\",\"season\":\"2024/2025\",\"league\":\"Premier League\",\"minutes\":1980,\"goals\":3,\"assists\":5,\"shots\":28,\"passes_completed\":1650,\"tackles\":68,\"interceptions\":52}}'"}]}},"/score/predict-batch":{"post":{"tags":["score"],"summary":"Predict multiple players","operationId":"predict_batch_score_predict_batch_post","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictBatchRequest"}}}},"responses":{"200":{"description":"Batch prediction results in request order.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"count":2,"items":[{"scores_0_10":{"attack_score":6.43,"shooting_quality_score":5.71,"assist_score":6.08,"creation_score":6.62,"passing_score":7.21,"progression_score":7.48,"dribble_score":5.94,"ball_security_score":7.02,"defense_score":7.76,"aerial_score":7.31,"discipline_score":6.58,"appearance_score":7.84,"rating_pred":7.18},"cluster":{"cluster_name":"Progressive Defender","cluster_id":4,"probabilities":{"Progressive Defender":0.62,"Ball-Playing Defender":0.25,"Defensive Stopper":0.13}}},{"scores_0_10":{"attack_score":7.22,"creation_score":7.81,"passing_score":8.04,"defense_score":6.33,"rating_pred":7.46},"cluster":{"cluster_name":"Creative Midfielder","cluster_id":9,"probabilities":{"Creative Midfielder":0.71,"Ball Progressor":0.18}}}]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Scores up to 500 player feature kits in one request. Each item uses the same feature shape as `POST /score/predict`."}},"/score/predict-base":{"post":{"tags":["score"],"summary":"Predict base scores","operationId":"predict_base_score_predict_base_post","security":[{"ApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PredictRequest"}}}},"responses":{"200":{"description":"Base model 0-10 scores and role-cluster match.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"scores_0_10":{"attack_score":6.18,"assist_score":5.91,"rating_pred":6.84,"foul_card_score":6.52,"goalkeeper_score":4.21,"appearance_score":7.49,"conceded_score":6.12},"cluster":{"cluster_name":"Defensive Contributor","cluster_id":3,"probabilities":{"Defensive Contributor":0.58,"Two-Way Defender":0.29}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Runs the base model family only and returns the base score set."}},"/charts/overview":{"get":{"tags":["model charts"],"summary":"Overview","operationId":"overview_charts_overview_get","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Model dataset overview chart. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/charts/positions":{"get":{"tags":["model charts"],"summary":"Positions","operationId":"positions_charts_positions_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Top N positions","default":20,"title":"Limit"},"description":"Top N positions"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Position distribution chart. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/charts/leagues":{"get":{"tags":["model charts"],"summary":"Leagues","operationId":"leagues_charts_leagues_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Top N leagues","default":20,"title":"Limit"},"description":"Top N leagues"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"League distribution chart. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/charts/models/base":{"get":{"tags":["model charts"],"summary":"Base Models","operationId":"base_models_charts_models_base_get","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Base model metadata chart. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/charts/models/pro":{"get":{"tags":["model charts"],"summary":"Pro Models","operationId":"pro_models_charts_models_pro_get","security":[{"ApiKeyAuth":[]}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Pro model metadata chart. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/charts/features":{"get":{"tags":["model charts"],"summary":"Feature Diff","operationId":"feature_diff_charts_features_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"top","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Top N features by usage difference","default":30,"title":"Top"},"description":"Top N features by usage difference"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Feature usage and model coverage chart. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/radar/{player_id}":{"get":{"tags":["player charts"],"summary":"Radar chart: player skill profile vs position average","operationId":"radar_player_charts_radar__player_id__get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"season","in":"query","required":false,"schema":{"type":"string","description":"e.g. 2024/2025","title":"Season","nullable":true},"description":"e.g. 2024/2025"},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"pro | base","default":"pro","title":"Source"},"description":"pro | base"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Radar chart comparing a player against position average. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/timeline/{player_id}":{"get":{"tags":["player charts"],"summary":"Season-by-season rating & skill timeline for a player","operationId":"timeline_player_charts_timeline__player_id__get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"pro | base","default":"pro","title":"Source"},"description":"pro | base"},{"name":"dims","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated score column names","default":"rating_display_score_pct,attack_score_score_pct,defense_score_score_pct,creation_score_score_pct","title":"Dims"},"description":"Comma-separated score column names"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Season-by-season score timeline for one player. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/compare":{"get":{"tags":["player charts"],"summary":"Overlay radar chart comparing 2–5 players","operationId":"compare_player_charts_compare_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_ids","in":"query","required":true,"schema":{"type":"string","description":"Comma-separated player IDs, e.g. 100,200,300","title":"Player Ids"},"description":"Comma-separated player IDs, e.g. 100,200,300"},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"pro | base","default":"pro","title":"Source"},"description":"pro | base"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Radar comparison for 2-5 players. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/top-players":{"get":{"tags":["player charts"],"summary":"Top N players by overall rating — filterable by position / league / season","operationId":"top_players_player_charts_top_players_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"n","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":5,"default":20,"title":"N"}},{"name":"position","in":"query","required":false,"schema":{"type":"string","title":"Position","nullable":true}},{"name":"league","in":"query","required":false,"schema":{"type":"string","title":"League","nullable":true}},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"pro | base","default":"pro","title":"Source"},"description":"pro | base"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Top player ranking chart by overall rating. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/score-distribution":{"get":{"tags":["player charts"],"summary":"Box-plot distribution of a score dimension across positions","operationId":"score_distribution_player_charts_score_distribution_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"dim","in":"query","required":false,"schema":{"type":"string","description":"Score column name","default":"rating_display_score_pct","title":"Dim"},"description":"Score column name"},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"pro | base","default":"pro","title":"Source"},"description":"pro | base"},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"minimum":100,"default":10000,"title":"Limit"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Score distribution box plot by position. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/cluster-heatmap":{"get":{"tags":["player charts"],"summary":"Heatmap of mean z-scores per role cluster","operationId":"cluster_heatmap_player_charts_cluster_heatmap_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"group","in":"query","required":false,"schema":{"type":"string","description":"Filter cluster_group, e.g. Forwards","title":"Group","nullable":true},"description":"Filter cluster_group, e.g. Forwards"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Role-cluster mean z-score heatmap. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/cluster-distribution":{"get":{"tags":["player charts"],"summary":"Bar chart of player counts per role cluster","operationId":"cluster_distribution_player_charts_cluster_distribution_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"Filter source: base | pro","title":"Source","nullable":true},"description":"Filter source: base | pro"},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Player counts per role cluster. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/cluster-profile/{player_id}":{"get":{"tags":["player charts"],"summary":"GMM cluster membership probabilities for a player","operationId":"cluster_profile_player_charts_cluster_profile__player_id__get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"base | pro","title":"Source","nullable":true},"description":"base | pro"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Cluster membership probability chart for one player. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/league-scores":{"get":{"tags":["player charts"],"summary":"Heatmap of average skill scores per league","operationId":"league_scores_player_charts_league_scores_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"pro | base","default":"pro","title":"Source"},"description":"pro | base"},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"top_leagues","in":"query","required":false,"schema":{"type":"integer","maximum":60,"minimum":5,"default":20,"title":"Top Leagues"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Average score heatmap by league. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/player-charts/score-scatter":{"get":{"tags":["player charts"],"summary":"Scatter plot: two score dimensions coloured by position or cluster","operationId":"score_scatter_player_charts_score_scatter_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"x_dim","in":"query","required":false,"schema":{"type":"string","description":"X-axis score column","default":"attack_score_score_pct","title":"X Dim"},"description":"X-axis score column"},{"name":"y_dim","in":"query","required":false,"schema":{"type":"string","description":"Y-axis score column","default":"defense_score_score_pct","title":"Y Dim"},"description":"Y-axis score column"},{"name":"color_by","in":"query","required":false,"schema":{"type":"string","description":"position | cluster_group | cluster_name","default":"position","title":"Color By"},"description":"position | cluster_group | cluster_name"},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"pro | base","default":"pro","title":"Source"},"description":"pro | base"},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"league","in":"query","required":false,"schema":{"type":"string","title":"League","nullable":true}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20000,"minimum":100,"default":5000,"title":"Limit"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"png | jpg | jpeg | webp | svg | html","default":"png","title":"Format"},"description":"png | jpg | jpeg | webp | svg | html"}],"responses":{"200":{"description":"Chart binary or interactive HTML response.","content":{"image/png":{"schema":{"type":"string","format":"binary"}},"image/jpeg":{"schema":{"type":"string","format":"binary"}},"image/webp":{"schema":{"type":"string","format":"binary"}},"image/svg+xml":{"schema":{"type":"string"}},"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Scatter plot for two score dimensions. Use the `format` query parameter where available to request `png`, `jpg`, `jpeg`, `webp`, `svg`, or interactive `html`."}},"/report/data":{"get":{"tags":["report"],"summary":"Get structured player report","operationId":"player_report_data_report_data_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"query","required":false,"schema":{"type":"integer","title":"Player Id","nullable":true}},{"name":"name","in":"query","required":false,"schema":{"type":"string","title":"Name","nullable":true}},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"league","in":"query","required":false,"schema":{"type":"string","title":"League","nullable":true}},{"name":"team","in":"query","required":false,"schema":{"type":"string","title":"Team","nullable":true}}],"responses":{"200":{"description":"Player report data.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"player":{"id":12345,"name":"Example Player","position":"Defender","team":"Example FC","league":"Premier League","season":"2024/2025","minutes_played":1980},"scores":{"overall":7.31,"tier":"Starter-level output","attack":6.2,"creation":6.6,"defense":7.8,"appearance":7.9},"stats":{"goals":3,"assists":5,"goals_per90":0.14,"assists_per90":0.23},"role":{"label":"Progressive Defender","cluster_id":4,"confidence":0.62,"traits":["defense_score_z","progression_score_z"]},"meta":{"updated_at":"2026-04-23","model":"pro_scores","label_source":"database"},"features":[{"name":"minutes_played_overall","value":1980,"unit":"minutes","group":"Base · Production","visibility":"Visible"}]}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Returns the JSON payload used by the hosted player report page."}},"/report":{"get":{"tags":["report"],"summary":"Render player report page","operationId":"player_report_report_get","security":[{"ApiKeyAuth":[]}],"parameters":[{"name":"player_id","in":"query","required":false,"schema":{"type":"integer","title":"Player Id","nullable":true}},{"name":"name","in":"query","required":false,"schema":{"type":"string","title":"Name","nullable":true}},{"name":"season","in":"query","required":false,"schema":{"type":"string","title":"Season","nullable":true}},{"name":"league","in":"query","required":false,"schema":{"type":"string","title":"League","nullable":true}},{"name":"team","in":"query","required":false,"schema":{"type":"string","title":"Team","nullable":true}}],"responses":{"200":{"description":"Rendered player report HTML.","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"description":"Returns a hosted HTML player report for the requested player."}},"/health":{"get":{"tags":["system"],"summary":"Health check","operationId":"health_check_health_get","responses":{"200":{"description":"Service is reachable.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true},"example":{"status":"ok"}}}}},"description":"Returns service availability. This endpoint does not require a request body."}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"PredictBatchRequest":{"properties":{"items":{"items":{"$ref":"#/components/schemas/PredictRequest"},"type":"array","maxItems":500,"minItems":1,"title":"Items"}},"type":"object","required":["items"],"title":"PredictBatchRequest","example":{"items":[{"features":{"aerials":90,"aerials_won":56,"assists":5,"blocks":35,"clearances":140,"club":"Example FC","dribbles":42,"dribbles_successful":23,"fouls_committed":22,"fouls_drawn":18,"goals":3,"interceptions":52,"league":"Premier League","minutes":1980,"passes_attempted":1900,"passes_completed":1650,"player_name":"Example Player","position":"defender","red_cards":0,"season":"2024/2025","shots":28,"shots_on_target":10,"tackles":68,"tackles_won":45,"yellow_cards":4}},{"features":{"assists":8,"club":"Example FC","goals":5,"interceptions":33,"league":"Premier League","minutes":1710,"passes_attempted":1650,"passes_completed":1420,"player_name":"Example Midfielder","position":"midfielder","red_cards":0,"season":"2024/2025","shots":31,"shots_on_target":12,"tackles":54,"yellow_cards":3}}]}},"PredictRequest":{"properties":{"features":{"additionalProperties":true,"type":"object","title":"Features"}},"type":"object","required":["features"],"title":"PredictRequest","example":{"features":{"aerials":90,"aerials_won":56,"assists":5,"blocks":35,"clearances":140,"club":"Example FC","dribbles":42,"dribbles_successful":23,"fouls_committed":22,"fouls_drawn":18,"goals":3,"interceptions":52,"league":"Premier League","minutes":1980,"passes_attempted":1900,"passes_completed":1650,"player_name":"Example Player","position":"defender","red_cards":0,"season":"2024/2025","shots":28,"shots_on_target":10,"tackles":68,"tackles_won":45,"yellow_cards":4}}},"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"}},"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Your customer API key."}}},"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"score","description":"Run football performance prediction models from submitted feature kits."},{"name":"database","description":"Lookup players, stored ratings, engineered features, role clusters, and basic-data career trajectory datasets."},{"name":"player charts","description":"Generate player-facing analytics charts as images, SVG, WebP, or interactive HTML."},{"name":"model charts","description":"Generate model and dataset overview charts."},{"name":"report","description":"Fetch structured player report data or render the hosted player report page."},{"name":"system","description":"Service health endpoint."}]}