{"openapi":"3.1.0","info":{"title":"NFL Analytics Platform","description":"AI-powered NFL analytics platform. Free tier provides basic rankings, schedules, and live scores. Pro tier ($20/month) unlocks projections, interactive tools, trend analysis, matchup breakdowns, DFS optimization, and ForgeStat-powered deep analysis.","version":"1.0.0"},"paths":{"/api/auth/register":{"post":{"tags":["auth"],"summary":"register new user","description":"create a new free-tier account and return tokens.","operationId":"register_api_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/login":{"post":{"tags":["auth"],"summary":"log in","description":"validate credentials and return tokens.","operationId":"login_api_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserLogin"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/refresh":{"post":{"tags":["auth"],"summary":"refresh access token","description":"exchange a valid refresh token for a new access + refresh pair.","operationId":"refresh_token_api_auth_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_refresh_token_api_auth_refresh_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/profile":{"get":{"tags":["auth"],"summary":"get current user profile","description":"fetch the authenticated user's full profile.","operationId":"profile_api_auth_profile_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dashboard":{"get":{"tags":["dashboard"],"summary":"aggregated dashboard data","description":"return trending players, alerts, top pickups for the dashboard.","operationId":"dashboard_api_dashboard_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2020,"default":2025,"title":"Season"}},{"name":"week","in":"query","required":false,"schema":{"type":"integer","maximum":18,"minimum":1,"default":1,"title":"Week"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Dashboard Api Dashboard Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/search":{"get":{"tags":["players"],"summary":"fuzzy player search","description":"fuzzy search for NFL players by name using pg_trgm trigram matching.\n\npublic endpoint — no auth required. supports partial name matches and\ntypo tolerance via postgresql trigram similarity.","operationId":"search_players_api_players_search_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"search query (player name)","title":"Q"},"description":"search query (player name)"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter by position (QB, RB, WR, TE, K, etc.)","title":"Position"},"description":"filter by position (QB, RB, WR, TE, K, etc.)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"max results to return","default":20,"title":"Limit"},"description":"max results to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Search Players Api Players Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/by-sleeper-id/{sleeper_id}":{"get":{"tags":["players"],"summary":"map a Sleeper player_id to our player record","description":"resolve a Sleeper player_id (e.g. ``\"6794\"``) to our internal player.\n\nused by the Start/Sit recommender to pre-fill rosters from a Sleeper\nleague. returns ``null`` if no mapping exists. public endpoint.","operationId":"get_player_by_sleeper_id_api_players_by_sleeper_id__sleeper_id__get","parameters":[{"name":"sleeper_id","in":"path","required":true,"schema":{"type":"string","title":"Sleeper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Response Get Player By Sleeper Id Api Players By Sleeper Id  Sleeper Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/top":{"get":{"tags":["players"],"summary":"top players by fantasy points","description":"return top players ranked by current-season fantasy points.\n\npublic endpoint — no auth required.","operationId":"top_players_api_players_top_get","parameters":[{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter by position","title":"Position"},"description":"filter by position"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"max results","default":20,"title":"Limit"},"description":"max results"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Top Players Api Players Top Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/compare":{"get":{"tags":["players"],"summary":"side-by-side player comparison (pro)","description":"side-by-side comparison of 2-5 players. pro tier required.","operationId":"compare_players_api_players_compare_get","parameters":[{"name":"player_ids","in":"query","required":true,"schema":{"type":"string","description":"comma-separated player IDs (2-5)","title":"Player Ids"},"description":"comma-separated player IDs (2-5)"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"weeks","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"comma-separated week numbers","title":"Weeks"},"description":"comma-separated week numbers"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerCompareResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/{player_id}":{"get":{"tags":["players"],"summary":"basic player info (public)","description":"return basic player profile. available on free tier.","operationId":"get_player_api_players__player_id__get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/{player_id}/stats":{"get":{"tags":["players"],"summary":"full stat history with filters (pro)","description":"full stat history with optional filters. pro tier required (demo mode bypasses).","operationId":"get_player_stats_api_players__player_id__stats_get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"season","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Season"}},{"name":"weeks","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"comma-separated week numbers","title":"Weeks"},"description":"comma-separated week numbers"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/{player_id}/consensus":{"get":{"tags":["players"],"summary":"multi-source consensus comparison + house rank rationale","description":"return per-player consensus rankings across the 6 named expert sources\n(FantasyPros, ESPN, CBS, Yahoo, NFL.com, NBC/Rotoworld), the 4 ADP markets\n(Sleeper, FantasyCalc, Underdog, KTC), our house rank/tier/value-tag,\ndecision drivers, and a one-paragraph rationale.\n\npublic endpoint — no auth required (the existing GET /{id} is also public).\nsources that don't carry the player return ``null`` for that key — we\nnever fabricate ranks. consensus stats (median/min/max) ignore the nulls.","operationId":"get_player_consensus_api_players__player_id__consensus_get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"ppr / half_ppr / standard / superflex","default":"ppr","title":"Scoring"},"description":"ppr / half_ppr / standard / superflex"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"redraft / dynasty / best_ball","default":"redraft","title":"Format"},"description":"redraft / dynasty / best_ball"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Player Consensus Api Players  Player Id  Consensus Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/{player_id}/distribution":{"get":{"tags":["players"],"summary":"full per-player point distribution (P10/P50/P90 + skewness + format advice)","description":"return the full distribution of weekly fantasy points for one player.\n\ndiamond #3 of the Bible: ship distributions, not point estimates. mainstream\nsites publish \"Mike Clay says 13.4 PPG\"; we publish P10/P25/P50/P75/P90,\nskewness, boom/bust rates, consistency tier, and four format-specific\nadvice cards (best ball, season-long must-win, DFS cash, DFS GPP).\n\npublic endpoint — no auth required. weekly_scores are pulled from\n``player_game_stats``; if the requested season has <8 games of data we\nfall back to the prior season and flag it in ``data_quality.fallback_note``.\nNEVER fabricates data — players with no live history return a\n``data_quality.status == \"no_data\"`` payload.","operationId":"get_player_distribution_endpoint_api_players__player_id__distribution_get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"PPR / HALF_PPR / STANDARD","default":"PPR","title":"Scoring"},"description":"PPR / HALF_PPR / STANDARD"},{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2018,"description":"season for the empirical distribution","default":2025,"title":"Season"},"description":"season for the empirical distribution"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Player Distribution Endpoint Api Players  Player Id  Distribution Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/players/{player_id}/news":{"get":{"tags":["players"],"summary":"external news headlines for a player (link-out only)","description":"return recent external news for a player (espn + rotowire feeds).\n\npublic endpoint. items link out to the source — we never republish full\narticle body. snippets are short (<=240 chars) previews from the\nsource-provided summary. empty list when no recent news matches the player.","operationId":"get_player_news_api_players__player_id__news_get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":25,"minimum":1,"description":"max news items","default":10,"title":"Limit"},"description":"max news items"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Player News Api Players  Player Id  News Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rankings/weekly/{position}":{"get":{"tags":["rankings"],"summary":"top 20 positional rankings (public)","description":"top 20 per position — free tier. returns name, rank, projected points.","operationId":"weekly_rankings_public_api_rankings_weekly__position__get","parameters":[{"name":"position","in":"path","required":true,"schema":{"type":"string","title":"Position"}},{"name":"week","in":"query","required":false,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","default":18,"title":"Week"},"description":"nfl week number"},{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2020,"default":2025,"title":"Season"}},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"scoring format: ppr, half_ppr, standard","default":"ppr","title":"Scoring"},"description":"scoring format: ppr, half_ppr, standard"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Weekly Rankings Public Api Rankings Weekly  Position  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rankings/weekly/{position}/full":{"get":{"tags":["rankings"],"summary":"full positional rankings with tiers (pro)","description":"full positional rankings with tier assignments, floor/ceiling, notes.","operationId":"weekly_rankings_full_api_rankings_weekly__position__full_get","parameters":[{"name":"position","in":"path","required":true,"schema":{"type":"string","title":"Position"}},{"name":"week","in":"query","required":false,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","default":18,"title":"Week"},"description":"nfl week number"},{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2020,"default":2025,"title":"Season"}},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"scoring format: ppr, half_ppr, standard","default":"ppr","title":"Scoring"},"description":"scoring format: ppr, half_ppr, standard"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Weekly Rankings Full Api Rankings Weekly  Position  Full Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rankings/weekly":{"get":{"tags":["rankings"],"summary":"overall weekly rankings across all positions (public)","description":"top 20 overall rankings across all positions — free tier.","operationId":"weekly_rankings_all_api_rankings_weekly_get","parameters":[{"name":"week","in":"query","required":false,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","default":18,"title":"Week"},"description":"nfl week number"},{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2020,"default":2025,"title":"Season"}},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"scoring format: ppr, half_ppr, standard","default":"ppr","title":"Scoring"},"description":"scoring format: ppr, half_ppr, standard"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Weekly Rankings All Api Rankings Weekly Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rankings":{"get":{"tags":["rankings"],"summary":"convenience alias — overall weekly rankings (public)","description":"convenience alias for /weekly — accepts optional position filter and limit.","operationId":"rankings_root_api_rankings_get","parameters":[{"name":"week","in":"query","required":false,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","default":18,"title":"Week"},"description":"nfl week number"},{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2020,"default":2025,"title":"Season"}},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"scoring format: ppr, half_ppr, standard","default":"ppr","title":"Scoring"},"description":"scoring format: ppr, half_ppr, standard"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter by position (QB, RB, WR, TE, K)","title":"Position"},"description":"filter by position (QB, RB, WR, TE, K)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"max number of rankings to return","default":20,"title":"Limit"},"description":"max number of rankings to return"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Rankings Root Api Rankings Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rankings/full":{"get":{"tags":["rankings"],"summary":"full rankings with tiers — all positions or filtered (pro)","description":"full rankings with tier assignments, floor/ceiling, notes — pro only.\n\nthis endpoint is called by the frontend rankingsApi.getFull() method.","operationId":"rankings_full_api_rankings_full_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2020,"default":2025,"title":"Season"}},{"name":"week","in":"query","required":false,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","default":18,"title":"Week"},"description":"nfl week number"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter by position (QB, RB, WR, TE, K)","title":"Position"},"description":"filter by position (QB, RB, WR, TE, K)"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"scoring format: ppr, half_ppr, standard","default":"ppr","title":"Scoring"},"description":"scoring format: ppr, half_ppr, standard"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Rankings Full Api Rankings Full Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projections/weekly/{player_id}":{"get":{"tags":["projections"],"summary":"detailed weekly projection (pro)","description":"detailed weekly projection with floor/ceiling. pro tier required.","operationId":"weekly_projection_api_projections_weekly__player_id__get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"week","in":"query","required":true,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","title":"Week"},"description":"nfl week number"},{"name":"season","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"defaults to current season","title":"Season"},"description":"defaults to current season"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"ppr | half_ppr | standard","default":"ppr","title":"Scoring"},"description":"ppr | half_ppr | standard"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeeklyProjection"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projections/season/{player_id}":{"get":{"tags":["projections"],"summary":"season-long projection (pro)","description":"season-long projection with risk assessment. pro tier required.","operationId":"season_projection_api_projections_season__player_id__get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"season","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"defaults to current season","title":"Season"},"description":"defaults to current season"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"ppr | half_ppr | standard","default":"ppr","title":"Scoring"},"description":"ppr | half_ppr | standard"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeasonProjection"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projections/position/{position}":{"get":{"tags":["projections"],"summary":"positional projections for the week (pro)","description":"all weekly projections for a position, ranked by projected points. pro tier required.","operationId":"positional_projections_api_projections_position__position__get","parameters":[{"name":"position","in":"path","required":true,"schema":{"type":"string","title":"Position"}},{"name":"week","in":"query","required":true,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","title":"Week"},"description":"nfl week number"},{"name":"season","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"defaults to current season","title":"Season"},"description":"defaults to current season"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"ppr | half_ppr | standard","default":"ppr","title":"Scoring"},"description":"ppr | half_ppr | standard"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WeeklyProjection"},"title":"Response Positional Projections Api Projections Position  Position  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projections":{"get":{"tags":["projections"],"summary":"season projections list (public)","description":"public projection listing — returns season-long or weekly projections.","operationId":"projections_list_api_projections_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2020,"default":2026,"title":"Season"}},{"name":"week","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":22,"minimum":1},{"type":"null"}],"description":"week number (omit for season-long)","title":"Week"},"description":"week number (omit for season-long)"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"ppr | half_ppr | standard","default":"ppr","title":"Scoring"},"description":"ppr | half_ppr | standard"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter by position (QB, RB, WR, TE, K)","title":"Position"},"description":"filter by position (QB, RB, WR, TE, K)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Projections List Api Projections Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/matchups":{"get":{"tags":["matchups"],"summary":"weekly matchups via query params (public)","description":"weekly matchups using query parameters. public endpoint.","operationId":"matchups_by_query_api_matchups_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year","default":2025,"title":"Season"},"description":"nfl season year"},{"name":"week","in":"query","required":true,"schema":{"type":"integer","description":"week number","title":"Week"},"description":"week number"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeeklyMatchups"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/matchups/weekly/{week}":{"get":{"tags":["matchups"],"summary":"all matchup previews for a week (pro)","description":"all matchup previews for a given week. pro tier required.","operationId":"weekly_matchups_api_matchups_weekly__week__get","parameters":[{"name":"week","in":"path","required":true,"schema":{"type":"integer","title":"Week"}},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (defaults to current)","title":"Season"},"description":"nfl season year (defaults to current)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeeklyMatchups"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/matchups/{game_id}":{"get":{"tags":["matchups"],"summary":"detailed matchup analysis (pro)","description":"deep-dive matchup analysis for a single game. pro tier required.","operationId":"matchup_detail_api_matchups__game_id__get","parameters":[{"name":"game_id","in":"path","required":true,"schema":{"type":"integer","title":"Game Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Matchup Detail Api Matchups  Game Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/trade-analyzer":{"post":{"tags":["tools"],"summary":"evaluate a fantasy trade — v2 (composite-v2 + projections + VBD + drivers). polymorphic body: pass {team_a_gives,team_b_gives} for the v2 shape, or legacy {team_gives,team_gets} for the older trade_service explanation+verdict response.","description":"polymorphic body — see summary.","operationId":"trade_analyzer_api_tools_trade_analyzer_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Trade Analyzer Api Tools Trade Analyzer Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/saved-trades":{"get":{"tags":["tools"],"summary":"list current user's saved trade scenarios","description":"return the authenticated user's saved trade scenarios.\n\nstub: no `saved_trades` table exists in the schema yet, so this always\nreturns an empty list for authenticated users. unauthenticated callers\nget a clean 401 from `get_current_user` instead of the previous 404.\nwhen the persistence layer is added, swap the empty list for a scoped\nSELECT keyed on `user.user_id`.","operationId":"list_saved_trades_api_tools_saved_trades_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response List Saved Trades Api Tools Saved Trades Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/trade-finder":{"get":{"tags":["tools"],"summary":"find 5 value-balanced trade-target packages for the players you're sending out. uses the same VBD primitives as the trade analyzer, filters every candidate to within ±10% of give-side total VBD, and ranks by score = 0.5*value_match + 0.3*positional_fit + 0.2*tier_upgrade. returns each trade with give[], receive[], drivers, fairness rating, and a trade-partner profile (why a real opponent might say yes).","description":"find up to 5 realistic trade packages for the give-side players.\n\nevery suggested trade is value-balanced (receive VBD within ±10% of\ngive VBD) — random unfair offers never make the list.","operationId":"trade_finder_api_tools_trade_finder_get","parameters":[{"name":"give","in":"query","required":true,"schema":{"type":"string","description":"comma-separated player IDs the user is GIVING UP","title":"Give"},"description":"comma-separated player IDs the user is GIVING UP"},{"name":"target_position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter receive side to one position: QB | RB | WR | TE","title":"Target Position"},"description":"filter receive side to one position: QB | RB | WR | TE"},{"name":"target_tier","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter receive-side tier: SMASH_START | SOLID | RISKY | SIT | STASH","title":"Target Tier"},"description":"filter receive-side tier: SMASH_START | SOLID | RISKY | SIT | STASH"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"PPR | HALF_PPR | STANDARD","default":"PPR","title":"Scoring"},"description":"PPR | HALF_PPR | STANDARD"},{"name":"fmt","in":"query","required":false,"schema":{"type":"string","description":"redraft | dynasty | best_ball","default":"redraft","title":"Fmt"},"description":"redraft | dynasty | best_ball"},{"name":"league_size","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":4,"default":12,"title":"League Size"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Trade Finder Api Tools Trade Finder Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/start-sit":{"post":{"tags":["tools"],"summary":"weekly Start/Sit recommender — combines wind+Vegas, slot matchups, predictive leaderboards, and consistency tiers into one verdict per player. accepts EITHER {player_ids:[...]} (new recommender) OR {roster:[{slot,player_id},...]} (legacy lineup optimizer).","description":"polymorphic body:\n\n* NEW shape: ``{\"player_ids\": [421, 2189, ...]}`` → returns the\n  Start/Sit recommender response (wind+Vegas+slot+leaderboards+\n  consistency synthesised into START / SIT / FLEX_OK / FADE).\n\n* LEGACY shape: ``{\"roster\": [{\"slot\":\"QB\",\"player_id\":\"....\"}], \"scoring\":\"...\", \"week\":...}``\n  → returns the legacy lineup optimizer response (used by the older\n  StartSitBuilder UI).","operationId":"start_sit_api_tools_start_sit_post","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year","default":2025,"title":"Season"},"description":"nfl season year"},{"name":"week","in":"query","required":true,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week (1-22)","title":"Week"},"description":"nfl week (1-22)"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"PPR | HALF_PPR | STANDARD","default":"PPR","title":"Scoring"},"description":"PPR | HALF_PPR | STANDARD"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Start Sit Api Tools Start Sit Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/waiver-ranker":{"get":{"tags":["tools"],"summary":"find trending waiver wire targets (pro/demo) — GET","description":"find trending waiver wire targets based on recent performance data (GET).","operationId":"waiver_ranker_get_api_tools_waiver_ranker_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year","default":2025,"title":"Season"},"description":"nfl season year"},{"name":"week","in":"query","required":false,"schema":{"type":"integer","description":"week number","default":18,"title":"Week"},"description":"week number"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter to QB, RB, WR, TE","title":"Position"},"description":"filter to QB, RB, WR, TE"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Waiver Ranker Get Api Tools Waiver Ranker Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["tools"],"summary":"find trending waiver wire targets (pro/demo) — POST","description":"find trending waiver wire targets based on recent performance data (POST).","operationId":"waiver_ranker_api_tools_waiver_ranker_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaiverTargetRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Waiver Ranker Api Tools Waiver Ranker Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dfs/salaries/{week}":{"get":{"tags":["tools"],"summary":"DFS salaries and values (pro)","description":"DFS player salaries with projected value for a given week.","operationId":"dfs_salaries_api_dfs_salaries__week__get","parameters":[{"name":"week","in":"path","required":true,"schema":{"type":"integer","title":"Week"}},{"name":"platform","in":"query","required":false,"schema":{"type":"string","description":"draftkings | fanduel","default":"draftkings","title":"Platform"},"description":"draftkings | fanduel"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DFSSalariesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dfs/optimize-full":{"post":{"tags":["tools"],"summary":"DFS lineup optimizer with salary data (pro)","description":"generate optimal DFS lineups under salary cap constraints (requires dfs_salaries data).","operationId":"dfs_optimize_full_api_dfs_optimize_full_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DFSOptimizeRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DFSOptimizeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dfs/optimize":{"post":{"tags":["tools"],"summary":"DFS lineup optimizer from stats averages (pro/demo)","description":"generate an optimal DFS lineup using player_game_stats averages as projections.","operationId":"dfs_optimize_api_dfs_optimize_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DFSSimpleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Dfs Optimize Api Dfs Optimize Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/redzone-carries":{"get":{"tags":["tools"],"summary":"inside-the-10 carry share leaderboard — surfaces who actually gets the goal-line work (73.7% of rushing TDs come from inside the 10)","description":"inside-the-10 / inside-the-5 / goal-to-go carry share + TD efficiency, per RB or QB.","operationId":"redzone_carries_api_tools_redzone_carries_get","parameters":[{"name":"position","in":"query","required":false,"schema":{"type":"string","description":"RB or QB","default":"RB","title":"Position"},"description":"RB or QB"},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (2024 or 2025)","default":2025,"title":"Season"},"description":"nfl season year (2024 or 2025)"},{"name":"min_carries","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":0,"description":"filter out players with fewer than this many i10 carries","default":5,"title":"Min Carries"},"description":"filter out players with fewer than this many i10 carries"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Redzone Carries Api Tools Redzone Carries Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/predictive-leaderboards":{"get":{"tags":["tools"],"summary":"predictive metrics leaderboards — surfaces YPRR / TPRR / target-share / air-yards-share / aDOT / YACO-over-baseline. open-source proxies; PFF/SIS/Fantasy Points have proprietary versions","description":"leaderboard payload for one metric/position/season. v1 proxies — see is_proxy.","operationId":"predictive_leaderboards_api_tools_predictive_leaderboards_get","parameters":[{"name":"metric","in":"query","required":false,"schema":{"type":"string","description":"yprr | tprr | target_share | air_yards_share | adot | yac_per_rec | first_read_proxy | yaco_over_baseline | ypc","default":"yprr","title":"Metric"},"description":"yprr | tprr | target_share | air_yards_share | adot | yac_per_rec | first_read_proxy | yaco_over_baseline | ypc"},{"name":"position","in":"query","required":false,"schema":{"type":"string","description":"WR | TE | RB","default":"WR","title":"Position"},"description":"WR | TE | RB"},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (2024 or 2025)","default":2024,"title":"Season"},"description":"nfl season year (2024 or 2025)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"max rows to return","default":50,"title":"Limit"},"description":"max rows to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Predictive Leaderboards Api Tools Predictive Leaderboards Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/predictive-leaderboards/metrics":{"get":{"tags":["tools"],"summary":"metadata for every metric exposed by predictive-leaderboards","description":"returns {metrics: [...]} for the frontend dropdown.","operationId":"predictive_leaderboards_metrics_api_tools_predictive_leaderboards_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Predictive Leaderboards Metrics Api Tools Predictive Leaderboards Metrics Get"}}}}}}},"/api/tools/dst-streaming":{"get":{"tags":["tools"],"summary":"weekly streaming defense leaderboard — composite of opp implied total + wind + opp YTD turnovers + def YTD sacks/INTs (analysis 258)","description":"top-N defenses to stream this week, ranked by composite streaming score.","operationId":"dst_streaming_api_tools_dst_streaming_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (2024 or 2025)","default":2024,"title":"Season"},"description":"nfl season year (2024 or 2025)"},{"name":"week","in":"query","required":false,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","default":14,"title":"Week"},"description":"nfl week number"},{"name":"top_n","in":"query","required":false,"schema":{"type":"integer","maximum":32,"minimum":1,"description":"how many defenses to return","default":20,"title":"Top N"},"description":"how many defenses to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Dst Streaming Api Tools Dst Streaming Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/streaming-kickers":{"get":{"tags":["tools"],"summary":"weekly streaming kicker leaderboard — composite of team implied total + opp red-zone FG-lean + wind + kicker FG% (analysis 260)","description":"top-N kickers to stream this week, ranked by composite streaming score.","operationId":"streaming_kickers_api_tools_streaming_kickers_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (2024 or 2025)","default":2024,"title":"Season"},"description":"nfl season year (2024 or 2025)"},{"name":"week","in":"query","required":false,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week number","default":14,"title":"Week"},"description":"nfl week number"},{"name":"top_n","in":"query","required":false,"schema":{"type":"integer","maximum":32,"minimum":1,"description":"how many kickers to return","default":10,"title":"Top N"},"description":"how many kickers to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Streaming Kickers Api Tools Streaming Kickers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/sos":{"get":{"tags":["tools"],"summary":"per-NFL-team strength of schedule by fantasy position. SOS = avg opponent FP-allowed-per-game vs the position across the schedule (analysis 261). 2026 schedule TBD until 2026-05-14; falls back to 2025 with a banner when not loaded.","description":"returns per-team SOS, defense rankings, and weekly heatmap rows.","operationId":"sos_by_position_api_tools_sos_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2026,"minimum":2024,"description":"nfl season year","default":2025,"title":"Season"},"description":"nfl season year"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"optional position filter (QB|RB|WR|TE)","title":"Position"},"description":"optional position filter (QB|RB|WR|TE)"},{"name":"team","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"optional team abbr filter (KC, BAL, ...)","title":"Team"},"description":"optional team abbr filter (KC, BAL, ...)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Sos By Position Api Tools Sos Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/trap-games":{"get":{"tags":["tools"],"summary":"trap-game leaderboard — surfaces team-weeks where an easy opponent is sandwiched between hard ones (lookahead/letdown), often on short rest. opponent strength comes from team_win_baselines (Sharp Football). schedule mechanics layered on top: short rest, divisional, road, standalone primetime. methodology selectable; defaults to scrimmagelab_v1_opp_aware.","description":"returns sortable trap-game rows + a full league-by-week grid.","operationId":"trap_games_api_tools_trap_games_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2024,"description":"nfl season year","default":2026,"title":"Season"},"description":"nfl season year"},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":500,"minimum":1},{"type":"null"}],"description":"optional row cap (applied AFTER filters and ordering)","title":"Limit"},"description":"optional row cap (applied AFTER filters and ordering)"},{"name":"week","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":22,"minimum":1},{"type":"null"}],"description":"optional single-week filter","title":"Week"},"description":"optional single-week filter"},{"name":"team","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"optional team abbr filter (KC, BAL, ...)","title":"Team"},"description":"optional team abbr filter (KC, BAL, ...)"},{"name":"min_score","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":200,"minimum":0},{"type":"null"}],"description":"optional minimum trap_score floor","title":"Min Score"},"description":"optional minimum trap_score floor"},{"name":"reasons","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"optional comma-separated reason filter. rows are kept if ANY of the listed reasons match. valid keys are returned in `reasons_available` so the UI can self-populate filter chips.","title":"Reasons"},"description":"optional comma-separated reason filter. rows are kept if ANY of the listed reasons match. valid keys are returned in `reasons_available` so the UI can self-populate filter chips."},{"name":"methodology_version","in":"query","required":false,"schema":{"type":"string","description":"which scoring methodology to surface. defaults to the textbook opponent-aware build. options: hometeam_textbook_v1 (default), scrimmagelab_v1_opp_aware (first opp-aware draft), hometeam_hermes_v1 (legacy schedule-only).","default":"hometeam_textbook_v1","title":"Methodology Version"},"description":"which scoring methodology to surface. defaults to the textbook opponent-aware build. options: hometeam_textbook_v1 (default), scrimmagelab_v1_opp_aware (first opp-aware draft), hometeam_hermes_v1 (legacy schedule-only)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Trap Games Api Tools Trap Games Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/bench-analyzer":{"post":{"tags":["tools"],"summary":"team-level distribution analyzer — given 10-15 player IDs, computes roster P10/P50/P90 (independence assumption), per-player variance contribution, and lean advice for best-ball / season-long","description":"compute team-level distribution from each player's empirical history.","operationId":"bench_analyzer_api_tools_bench_analyzer_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BenchAnalyzerRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Bench Analyzer Api Tools Bench Analyzer Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/dynasty-rookies":{"get":{"tags":["tools"],"summary":"2026 dynasty rookie tier sheet — draft capital + landing spot + athletic profile + college production blended into a single dynasty_score, then bucketed into 5 tiers","description":"tier-sheet of every rookie in the 2026 class.\n\ndrafted players are hydrated from wikipedia's actual draft results;\nskill-position rookies have college production fields populated from\neach player's wikipedia article when available.  unknown numeric\nfields stay null with college_data_status='unavailable'.","operationId":"dynasty_rookies_api_tools_dynasty_rookies_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"PPR | HALF | STANDARD | SUPERFLEX | TE_PREMIUM","default":"PPR","title":"Scoring"},"description":"PPR | HALF | STANDARD | SUPERFLEX | TE_PREMIUM"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"QB | RB | WR | TE — filter to one position; omit for all","title":"Position"},"description":"QB | RB | WR | TE — filter to one position; omit for all"},{"name":"tier","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter to a single tier (1-5); blank for all","title":"Tier"},"description":"filter to a single tier (1-5); blank for all"},{"name":"limit","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":600,"minimum":1},{"type":"null"}],"description":"cap the response after sorting/filtering","title":"Limit"},"description":"cap the response after sorting/filtering"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Dynasty Rookies Api Tools Dynasty Rookies Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/lineup-advisor":{"get":{"tags":["tools"],"summary":"wind + Vegas implied-total lineup advisor — bench borderline pass-game starters in low-total + high-wind games; start dome high-total skill players","description":"combine open-meteo wind + nflfastR closing total/spread to grade every game.\n\ndrivers per Bible Ch10: wind ≥ 20 mph + game total < 40 ⇒ STRONG FADE pass-game;\ndome + total ≥ 50 ⇒ STRONG START; high implied team total (≥ 27) ⇒ START.","operationId":"lineup_advisor_api_tools_lineup_advisor_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (2024 or 2025)","default":2025,"title":"Season"},"description":"nfl season year (2024 or 2025)"},{"name":"week","in":"query","required":true,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week (1-22)","title":"Week"},"description":"nfl week (1-22)"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"PPR | HALF | STANDARD","default":"PPR","title":"Scoring"},"description":"PPR | HALF | STANDARD"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Lineup Advisor Api Tools Lineup Advisor Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/slot-matchups":{"get":{"tags":["tools"],"summary":"slot WR vs slot defense matchup tool — bottom-10 slot defenses concede volume + efficiency to slot WRs (highest-leverage WR matchup signal)","description":"slot WR matchup leaderboard for one week.\n\nLIMITATION: team-level slot defense proxy. We do not have PFF per-CB\ncoverage data, so individual slot CBs are not graded. Slot targets are\nproxied by {receiver=WR, pass_location='middle', air_yards<15}.","operationId":"slot_matchups_api_tools_slot_matchups_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (2024 or 2025)","default":2024,"title":"Season"},"description":"nfl season year (2024 or 2025)"},{"name":"week","in":"query","required":true,"schema":{"type":"integer","maximum":22,"minimum":1,"description":"nfl week (1-22)","title":"Week"},"description":"nfl week (1-22)"},{"name":"min_targets","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":0,"description":"min targets in the game to surface a WR","default":3,"title":"Min Targets"},"description":"min targets in the game to surface a WR"},{"name":"min_slot_rate","in":"query","required":false,"schema":{"type":"number","maximum":1.0,"minimum":0.0,"description":"min season-long slot rate to count as a slot WR (lowered 2026-05-14 from 0.30 because proxy max-caps ~0.28)","default":0.15,"title":"Min Slot Rate"},"description":"min season-long slot rate to count as a slot WR (lowered 2026-05-14 from 0.30 because proxy max-caps ~0.28)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Slot Matchups Api Tools Slot Matchups Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/slot-defense-rankings":{"get":{"tags":["tools"],"summary":"32-team slot defense ranking (Bible Ch09 §18) — 1=toughest, 32=softest","description":"full 32-team slot defense ranking for a season.","operationId":"slot_defense_rankings_api_tools_slot_defense_rankings_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (2024 or 2025)","default":2024,"title":"Season"},"description":"nfl season year (2024 or 2025)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Slot Defense Rankings Api Tools Slot Defense Rankings Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/waiver-trend":{"get":{"tags":["tools"],"summary":"snap + route + target + carry share trend leaderboard — ranks by 4-game OLS slope (leading indicator of fantasy points). WAIVER GEMs = STRONG_UP outside top-150 by season fantasy_pts_ppr","description":"opportunity-trend leaderboard for one season.\n\nThe waiver wire is won by spotting opportunity changes BEFORE they convert\nto fantasy points. Snap, route, target, and carry share trending up are\nleading indicators. We rank by 4-game slope, not weekly raw values.","operationId":"waiver_trend_api_tools_waiver_trend_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (2024 or 2025)","default":2025,"title":"Season"},"description":"nfl season year (2024 or 2025)"},{"name":"min_weeks","in":"query","required":false,"schema":{"type":"integer","maximum":22,"minimum":2,"description":"min games of player-game data required","default":4,"title":"Min Weeks"},"description":"min games of player-game data required"},{"name":"min_trend","in":"query","required":false,"schema":{"type":"string","description":"UP | STRONG_UP | DOWN | STRONG_DOWN","default":"UP","title":"Min Trend"},"description":"UP | STRONG_UP | DOWN | STRONG_DOWN"},{"name":"exclude_top_n","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":0,"description":"drop players inside top-N by season fantasy_pts_ppr","default":150,"title":"Exclude Top N"},"description":"drop players inside top-N by season fantasy_pts_ppr"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"QB | RB | WR | TE — filter by position","title":"Position"},"description":"QB | RB | WR | TE — filter by position"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":200,"title":"Limit"}},{"name":"include_series","in":"query","required":false,"schema":{"type":"boolean","description":"include per-game series in payload (heavy)","default":false,"title":"Include Series"},"description":"include per-game series in payload (heavy)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Waiver Trend Api Tools Waiver Trend Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/mock-draft/start":{"post":{"tags":["tools"],"summary":"start a mock draft — sets up league config and runs AI picks until user is on the clock","description":"create a new mock draft. body keys: teams, scoring, format, slot, rounds.\nreturns the full draft state with the user on the clock for their first pick.\n\n``format`` accepts ``h2h`` (default), ``best_ball``, or the legacy\n``snake`` alias for h2h. Best-ball drafts default to 18 rounds and\nstrip K/DST from the pool (per Bible Ch14 §1).","operationId":"mock_draft_start_endpoint_api_tools_mock_draft_start_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockDraftStartRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Mock Draft Start Endpoint Api Tools Mock Draft Start Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/mock-draft/{draft_id}/state":{"get":{"tags":["tools"],"summary":"get current draft state — picks, on-the-clock, top-30 available players","description":"fetch the current state of an in-progress mock draft.","operationId":"mock_draft_state_endpoint_api_tools_mock_draft__draft_id__state_get","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"string","title":"Draft Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Mock Draft State Endpoint Api Tools Mock Draft  Draft Id  State Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/mock-draft/{draft_id}/pick":{"post":{"tags":["tools"],"summary":"record user pick, then auto-advance AI picks until user is back on the clock","description":"record the user's pick. the service then runs AI picks forward until\neither the user is on the clock again or the draft is complete.","operationId":"mock_draft_pick_endpoint_api_tools_mock_draft__draft_id__pick_post","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"string","title":"Draft Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockDraftPickRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Mock Draft Pick Endpoint Api Tools Mock Draft  Draft Id  Pick Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/mock-draft/{draft_id}/finish":{"post":{"tags":["tools"],"summary":"finalize draft and return grade + roster summary + comparable analog","description":"compute the user's draft grade, including:\n* letter grade (A+..F)\n* VBD vs league average\n* top 3 strengths + top 3 weaknesses with explanations\n* comparable real-life draft template (e.g. Hyper-RB, Zero-RB)\n* 12 team rosters with starter assignments\n* improvement suggestions for next year","operationId":"mock_draft_finish_endpoint_api_tools_mock_draft__draft_id__finish_post","parameters":[{"name":"draft_id","in":"path","required":true,"schema":{"type":"string","title":"Draft Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Mock Draft Finish Endpoint Api Tools Mock Draft  Draft Id  Finish Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/compare":{"get":{"tags":["tools"],"summary":"side-by-side player comparison for trade evaluation, draft-day decisions, or weekly start/sit. assembles composite rank + 6 expert + 4 ADP consensus + distribution P10/P50/P90 + 2026 projection + predictive leaderboard ranks + last-5 games + drivers, then computes per-axis A/B/TIE/N/A winners and an overall verdict (only when >= 3 axes have data on both sides).","description":"head-to-head comparison payload — see service for the per-axis logic.\n\nNEVER fabricates winners. when either side lacks data on an axis, that\naxis returns winner='N/A' and is excluded from the overall verdict.\ncross-position comparisons (RB vs WR) include a 'projection_vs_replacement'\naxis that normalizes raw points against each player's positional\nreplacement baseline so the verdict isn't biased toward WRs.\n\ndynasty mode (``format=dynasty``) pulls KTC values from expert_rankings\n(notes ktc_value=NNNN). NEVER fabricates dynasty values — when a player\nhas no KTC row we surface dynasty_value=null with source='unavailable'.","operationId":"player_compare_api_tools_compare_get","parameters":[{"name":"a","in":"query","required":true,"schema":{"type":"integer","description":"player_a_id","title":"A"},"description":"player_a_id"},{"name":"b","in":"query","required":true,"schema":{"type":"integer","description":"player_b_id","title":"B"},"description":"player_b_id"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"PPR | HALF_PPR | STANDARD","default":"PPR","title":"Scoring"},"description":"PPR | HALF_PPR | STANDARD"},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"season for the empirical distribution","default":2025,"title":"Season"},"description":"season for the empirical distribution"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"redraft (default — current-year value) or dynasty (KTC value + age cliff + draft capital re-weighted). dynasty mode adds three extra axes (dynasty_value, age_winner, draft_capital) and re-weights the verdict (dynasty_value 1.5x, age 1.2x, projection_vs_replacement 0.7x).","default":"redraft","title":"Format"},"description":"redraft (default — current-year value) or dynasty (KTC value + age cliff + draft capital re-weighted). dynasty mode adds three extra axes (dynasty_value, age_winner, draft_capital) and re-weights the verdict (dynasty_value 1.5x, age 1.2x, projection_vs_replacement 0.7x)."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Player Compare Api Tools Compare Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/latest":{"get":{"tags":["articles"],"summary":"last N articles (public)","description":"return the most recent published articles. free tier — excerpt only.","operationId":"latest_articles_api_articles_latest_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Latest Articles Api Articles Latest Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles":{"get":{"tags":["articles"],"summary":"full article archive with search/filter (pro)","description":"searchable article archive with pagination.\n\n`q` is the canonical search parameter; `search` is kept as an alias for\nbackwards-compat with existing /articles consumers. Both filter on\ntitle/excerpt/body via ILIKE (a tsvector index can drop in later without\nchanging this contract).","operationId":"list_articles_api_articles_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"full-text search across title/excerpt/body","title":"Q"},"description":"full-text search across title/excerpt/body"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"alias for ?q= (legacy parameter)","title":"Search"},"description":"alias for ?q= (legacy parameter)"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter by ArticleCategory.slug","title":"Category"},"description":"filter by ArticleCategory.slug"},{"name":"tag","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"exact tag match against the tags array","title":"Tag"},"description":"exact tag match against the tags array"},{"name":"type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ArticleType filter (e.g. STAT_DEEP_DIVE or stat-deep-dive)","title":"Type"},"description":"ArticleType filter (e.g. STAT_DEEP_DIVE or stat-deep-dive)"},{"name":"author","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"case-insensitive author/model match","title":"Author"},"description":"case-insensitive author/model match"},{"name":"published_after","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date — only articles published on/after this","title":"Published After"},"description":"ISO date — only articles published on/after this"},{"name":"published_before","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date — only articles published on/before this","title":"Published Before"},"description":"ISO date — only articles published on/before this"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"newest | relevance | popular","default":"newest","title":"Sort"},"description":"newest | relevance | popular"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Page Size"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response List Articles Api Articles Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/tags/popular":{"get":{"tags":["articles"],"summary":"most-used tags across published articles","description":"return the top tags (by frequency) for the filter chip row.","operationId":"popular_tags_api_articles_tags_popular_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Popular Tags Api Articles Tags Popular Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/by-team/{abbr}":{"get":{"tags":["articles"],"summary":"articles about a specific team","description":"return published articles linked to a team via article_teams junction or tags array.","operationId":"articles_by_team_api_articles_by_team__abbr__get","parameters":[{"name":"abbr","in":"path","required":true,"schema":{"type":"string","title":"Abbr"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Articles By Team Api Articles By Team  Abbr  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/by-player/{player_id}":{"get":{"tags":["articles"],"summary":"articles about a specific player","description":"return published articles linked to a player via article_players junction.","operationId":"articles_by_player_api_articles_by_player__player_id__get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Articles By Player Api Articles By Player  Player Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/{article_id}":{"get":{"tags":["articles"],"summary":"full article","description":"full article body. paywall handled by frontend in demo mode.","operationId":"get_article_api_articles__article_id__get","parameters":[{"name":"article_id","in":"path","required":true,"schema":{"type":"integer","title":"Article Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Article Api Articles  Article Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/{article_id}/related-entities":{"get":{"tags":["articles"],"summary":"players and teams mentioned in an article","description":"return player cards and team badges for entities linked in the article body.","operationId":"get_article_related_entities_api_articles__article_id__related_entities_get","parameters":[{"name":"article_id","in":"path","required":true,"schema":{"type":"integer","title":"Article Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Article Related Entities Api Articles  Article Id  Related Entities Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/{article_id}/assign-image":{"post":{"tags":["articles"],"summary":"match and assign an image_library image to an article (admin)","description":"run the 5-tier matching algorithm for a single article and persist\nthe result to articles.featured_image.","operationId":"assign_image_to_article_api_articles__article_id__assign_image_post","parameters":[{"name":"article_id","in":"path","required":true,"schema":{"type":"integer","title":"Article Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Assign Image To Article Api Articles  Article Id  Assign Image Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/assign-images/all":{"post":{"tags":["articles"],"summary":"batch-assign images from image_library to all articles (admin)","description":"run the matching algorithm for all published articles.\n\nensures no two articles get the same image.","operationId":"assign_images_all_api_articles_assign_images_all_post","parameters":[{"name":"only_missing","in":"query","required":false,"schema":{"type":"boolean","description":"only assign to articles without a featured_image","default":true,"title":"Only Missing"},"description":"only assign to articles without a featured_image"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Assign Images All Api Articles Assign Images All Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/{article_id}/auto-tag":{"post":{"tags":["articles"],"summary":"derive content-grounded tags and merge with existing (admin)","description":"run the article auto-tagger for a single article.\n\nNEVER overwrites manually-set tags — only adds tags derived from article\ncontent. Returns the before/added/after sets so callers can see exactly\nwhat changed.","operationId":"auto_tag_article_api_articles__article_id__auto_tag_post","parameters":[{"name":"article_id","in":"path","required":true,"schema":{"type":"integer","title":"Article Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Auto Tag Article Api Articles  Article Id  Auto Tag Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/auto-tag-all":{"post":{"tags":["articles"],"summary":"bulk auto-tag every article missing tags or with empty tags (admin)","description":"run the auto-tagger across every article. by default only fills in\narticles whose tags are null/empty so we don't churn manually-curated\ntag sets. Set only_missing=false to merge derived tags into ALL articles.","operationId":"auto_tag_all_api_articles_auto_tag_all_post","parameters":[{"name":"only_missing","in":"query","required":false,"schema":{"type":"boolean","description":"only run on articles where tags is null or an empty array","default":true,"title":"Only Missing"},"description":"only run on articles where tags is null or an empty array"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Auto Tag All Api Articles Auto Tag All Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/articles/{article_id}/export.csv":{"get":{"tags":["articles"],"summary":"export article dataset as csv (pro)","description":"export player_game_stats for the most recent season, filtered by the\narticle's primary tag/position. requires lab pass (pro tier).","operationId":"export_article_csv_api_articles__article_id__export_csv_get","parameters":[{"name":"article_id","in":"path","required":true,"schema":{"type":"integer","title":"Article Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"csv file download","content":{"application/json":{"schema":{}},"text/csv":{}}},"404":{"description":"article not found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/export/rankings.csv":{"get":{"tags":["export"],"summary":"composite rankings export — full ranked list with tier + bye + projection","description":"csv export of the latest forgestat composite ranking.\n\ncolumns: ``overall_rank,position_rank,name,position,team,tier,bye_week,projection_ppg``\n\nonly rows from the canonical composite ranker (v2 with v1 fallback) are\nemitted; we DO NOT fabricate ranks. when projected_pts is null in the\nrankings row, projection_ppg is left blank.","operationId":"export_rankings_csv_api_export_rankings_csv_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"PPR | HALF_PPR | STANDARD","default":"PPR","title":"Scoring"},"description":"PPR | HALF_PPR | STANDARD"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"redraft | best_ball | dynasty","default":"redraft","title":"Format"},"description":"redraft | best_ball | dynasty"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":2000,"minimum":1,"description":"cap rows returned","default":400,"title":"Limit"},"description":"cap rows returned"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/export/players.csv":{"get":{"tags":["export"],"summary":"full player roster export — every active offensive skill player","description":"csv export of the active player roster (QB/RB/WR/TE/K + DST).\n\ncolumns: ``player_id,name,first_name,last_name,position,team,jersey_number,\nage_years,height_inches,weight_lbs,college,draft_year,draft_round,draft_pick,bye_week,status``","operationId":"export_players_csv_api_export_players_csv_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/export/dynasty-rookies.csv":{"get":{"tags":["export"],"summary":"2026 dynasty rookie tier sheet export","description":"csv export of the 2026 rookie tier sheet from rookie_tier_service.\n\ncolumns: ``tier,tier_label,position,name,team,draft_round,draft_pick,\ncapital_tier,dynasty_score,draft_capital,landing_spot,athletic_profile,\nproduction,position_premium,college_data_status``","operationId":"export_dynasty_rookies_csv_api_export_dynasty_rookies_csv_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"PPR | HALF | STANDARD | SUPERFLEX | TE_PREMIUM","default":"PPR","title":"Scoring"},"description":"PPR | HALF | STANDARD | SUPERFLEX | TE_PREMIUM"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"QB | RB | WR | TE — single position filter","title":"Position"},"description":"QB | RB | WR | TE — single position filter"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts/system":{"get":{"tags":["alerts"],"summary":"recent system-generated alerts (pro)","description":"return the most recent system-generated alerts for a season (breakout, injury, snap surge, etc.).","operationId":"system_alerts_api_alerts_system_get","parameters":[{"name":"season","in":"query","required":true,"schema":{"type":"integer","description":"NFL season year","title":"Season"},"description":"NFL season year"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response System Alerts Api Alerts System Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts":{"get":{"tags":["alerts"],"summary":"user's custom alerts (pro)","description":"list all alerts for the authenticated user.","operationId":"list_alerts_api_alerts_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response List Alerts Api Alerts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["alerts"],"summary":"create custom alert (pro)","description":"create a new custom alert (injury, news, projection change, etc.).\n\nbody keys: alert_type, player_id, team_id, notify_email, notify_push, notify_sms","operationId":"create_alert_endpoint_api_alerts_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Alert Endpoint Api Alerts Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/alerts/{alert_id}":{"put":{"tags":["alerts"],"summary":"update a custom alert (pro)","description":"update an existing alert. only the alert owner can modify it.","operationId":"update_alert_endpoint_api_alerts__alert_id__put","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Alert Endpoint Api Alerts  Alert Id  Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["alerts"],"summary":"delete a custom alert (pro)","description":"delete an alert. only the alert owner can delete it.","operationId":"delete_alert_endpoint_api_alerts__alert_id__delete","parameters":[{"name":"alert_id","in":"path","required":true,"schema":{"type":"integer","title":"Alert Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft/rankings":{"get":{"tags":["draft"],"summary":"draft rankings (pro, preseason)","description":"preseason draft rankings. pro tier required.","operationId":"draft_rankings_api_draft_rankings_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"positions","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"comma-separated positions to filter","title":"Positions"},"description":"comma-separated positions to filter"},{"name":"superflex","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Superflex"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Draft Rankings Api Draft Rankings Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft/adp":{"get":{"tags":["draft"],"summary":"aggregated ADP across platforms (pro)","description":"average draft position aggregated across major platforms.","operationId":"draft_adp_api_draft_adp_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"platforms","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"comma-separated: espn,yahoo,sleeper,underdog","title":"Platforms"},"description":"comma-separated: espn,yahoo,sleeper,underdog"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Draft Adp Api Draft Adp Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/badges":{"get":{"tags":["draft-guide"],"summary":"ml risk badges for a single player","description":"return the (up to 5) ml risk/upside badges for ``player_id``.","operationId":"get_badges_api_draft_guide_badges_get","parameters":[{"name":"player_id","in":"query","required":true,"schema":{"type":"integer","description":"sleeper player id","title":"Player Id"},"description":"sleeper player id"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Badges Api Draft Guide Badges Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["draft-guide"],"summary":"ml risk badges for many players (batch)","description":"return ``{player_id_str: [badges]}`` for every requested player.","operationId":"post_badges_batch_api_draft_guide_badges_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BadgeBatchRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object"}},"title":"Response Post Badges Batch Api Draft Guide Badges Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/composite":{"get":{"tags":["draft-guide"],"summary":"composite house ranking with per-source breakdown","description":"Returns the house composite ranking — a weighted blend of every registered expert source — alongside a per-source breakdown so callers can see which experts contributed to each player's rank. Supports scoring (ppr/half/std), format (redraft/dynasty), position filter, and a limit cap.","operationId":"composite_api_draft_guide_composite_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter to a single position (QB/RB/WR/TE/K/DST)","title":"Position"},"description":"filter to a single position (QB/RB/WR/TE/K/DST)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompositeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/arbitrage":{"get":{"tags":["draft-guide"],"summary":"ADP vs consensus arbitrage — steals (going late) or fades (going early)","description":"Computes the gap between consensus expert ranking and live ADP. Players going LATER than their consensus rank are steals; players going EARLIER are fades. Sorted by absolute gap so the biggest mispricings surface first.","operationId":"arbitrage_api_draft_guide_arbitrage_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}},{"name":"direction","in":"query","required":false,"schema":{"type":"string","pattern":"^(steal|fade)$","default":"steal","title":"Direction"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ArbitrageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/sleepers":{"get":{"tags":["draft-guide"],"summary":"house top-75 players whose ADP is outside the top 100","description":"Surfaces sleeper candidates: players the house ranks inside the top 75 but whose live ADP places them outside the top 100. These are the highest-conviction late-round upside picks for redraft leagues.","operationId":"sleepers_api_draft_guide_sleepers_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SleepersResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/busts":{"get":{"tags":["draft-guide"],"summary":"top-30-ADP players flagged by ML signals (high CV, no breakout, replacement-level cluster)","description":"Returns top-30-ADP players that ML risk models flag as bust candidates. Triggers include high week-to-week coefficient of variation, no breakout score signal, and assignment to a replacement-level performance cluster.","operationId":"busts_api_draft_guide_busts_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BustsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/tiers":{"get":{"tags":["draft-guide"],"summary":"composite ranking grouped by tier","description":"Same composite ranking as /composite, but bucketed into draft tiers — useful when you want to know which players are interchangeable at a given draft slot vs which represent a real drop-off.","operationId":"tiers_api_draft_guide_tiers_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TiersResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/tier-breaks":{"get":{"tags":["draft-guide"],"summary":"per-position tier summary — players per tier, last-overall pick, next tier break","description":"summarize the per-position tier structure of the composite rankings.\n\nresponse shape (per the contract):\n    {\n      \"scoring\": \"PPR\",\n      \"format\": \"redraft\",\n      \"tiers\": [\n        {\"position\":\"RB\", \"tier_num\":1, \"tier_label\":\"SMASH_START\",\n         \"count\":6, \"first_overall\":1, \"last_overall\":6,\n         \"first_position_rank\":1, \"last_position_rank\":6,\n         \"next_tier_starts_at\":7,\n         \"players\":[\"Bijan\",\"Gibbs\",...]},\n        ...\n      ]\n    }\n\nnotes:\n    * per-position tiers are written by composite_rankings with\n      _POSITION_TIER_STEP=6 (every 6 position_ranks promotes a tier).\n    * we PREFER the per-position composite slice (notes->>'position_filter'\n      matches the position) because that's the one the tier-step constant\n      was designed for. if no per-position slice exists, we fall back to\n      deriving tiers from the OVERALL slice's tier_num field.\n    * first_overall / last_overall come from the OVERALL composite slice\n      (position_filter IS NULL) so the ui can map \"tier-break alarm\" to a\n      real overall pick number.","operationId":"tier_breaks_api_draft_guide_tier_breaks_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"PPR","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TierBreaksResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/movers":{"get":{"tags":["draft-guide"],"summary":"rank movement vs N days ago, averaged across all sources","description":"Tracks how much each player's average expert rank has moved over the last N days. Use this to spot rapid risers (training camp buzz, depth chart wins) and fallers (injuries, demotions) before ADP has fully adjusted.","operationId":"movers_api_draft_guide_movers_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":60,"minimum":1,"default":7,"title":"Days"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoversResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/scarcity":{"get":{"tags":["draft-guide"],"summary":"position scarcity curves — overall rank of the Nth-best at each position","description":"Returns scarcity curves showing the overall draft rank of the Nth-best player at each position. Steeper curves indicate that waiting is risky; flat curves mean depth at the position is plentiful.","operationId":"scarcity_api_draft_guide_scarcity_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScarcityResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/scarcity-heatmap":{"get":{"tags":["draft-guide"],"summary":"per-round x per-position scarcity grid + starter-tier ETA callouts","description":"build a 4 (positions) x N (rounds) grid showing how many players at\neach position have been drafted and how many starter-tier players remain\nby round, using the composite ranking (ADP-blended) as the draft order.\n\ngrid + ETAs feed the position scarcity heatmap UI so drafters can see when\neach position's starter pool runs out (e.g. \"RB1 tier exhausted by pick\n11\" — wait too long and you're left with replacement-level RBs).","operationId":"scarcity_heatmap_api_draft_guide_scarcity_heatmap_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}},{"name":"teams","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":2,"default":12,"title":"Teams"}},{"name":"max_rounds","in":"query","required":false,"schema":{"type":"integer","maximum":25,"minimum":1,"default":15,"title":"Max Rounds"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScarcityHeatmapResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/handcuffs":{"get":{"tags":["draft-guide"],"summary":"for an RB, find the next-best running back on the same team","description":"Given a starting RB, returns the next-best running back on the same NFL team — the canonical handcuff pick. Includes composite rank and ADP for the handcuff so you can decide whether the insurance is worth the cost.","operationId":"handcuffs_api_draft_guide_handcuffs_get","parameters":[{"name":"player_id","in":"query","required":true,"schema":{"type":"integer","minimum":1,"description":"RB player_id to find a handcuff for","title":"Player Id"},"description":"RB player_id to find a handcuff for"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HandcuffResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/sources":{"get":{"tags":["draft-guide"],"summary":"registered expert ranking sources with freshness and weight metadata","description":"Lists every registered expert ranking source feeding the composite, with last-refresh timestamp and the weight used in the blend. Use this to audit which experts are stale or to debug a surprising composite rank.","operationId":"sources_api_draft_guide_sources_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcesResponse"}}}}}}},"/api/draft-guide/idp/composite":{"get":{"tags":["draft-guide"],"summary":"IDP composite ranking — defensive players only, separate from offensive composite","description":"Returns the house composite ranking restricted to IDP (Individual Defensive Players) — DL, LB, DB. Kept separate from the offensive composite because IDP scoring varies wildly across leagues.","operationId":"idp_composite_api_draft_guide_idp_composite_get","parameters":[{"name":"scoring","in":"query","required":false,"schema":{"type":"string","default":"ppr","title":"Scoring"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"redraft","title":"Format"}},{"name":"bucket","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter to a single IDP bucket: DL / LB / DB. omit for combined overall IDP.","title":"Bucket"},"description":"filter to a single IDP bucket: DL / LB / DB. omit for combined overall IDP."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IDPCompositeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/draft-guide/idp/sources":{"get":{"tags":["draft-guide"],"summary":"IDP-only expert ranking sources (slug LIKE 'fantasypros_ecr_idp_%')","description":"Lists the subset of expert ranking sources that publish IDP rankings (currently FantasyPros ECR IDP feeds). Mirrors /sources but scoped to the defensive composite.","operationId":"idp_sources_api_draft_guide_idp_sources_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcesResponse"}}}}}}},"/api/draft-guide/rounds":{"get":{"tags":["draft-guide"],"summary":"round-by-round draft guide with value tags and decision drivers","description":"build the full round-by-round payload for a draft guide ui.\n\nresponse shape:\n    {\n      \"rounds\": [\n        {\n          \"round\": 1,\n          \"picks_in_round\": <teams>,\n          \"picks\": [{pick_in_round, overall_pick, player_id, name,\n                     position, team_abbr, headshot_url, overall_rank,\n                     adp_rank, adp_delta, tier, value_tag, drivers[],\n                     news[]}, ...]\n        }, ...\n      ],\n      \"meta\": {teams, max_round, adp_is_fallback, include_news}\n    }","operationId":"rounds_api_draft_guide_rounds_get","parameters":[{"name":"teams","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":2,"description":"league size","default":12,"title":"Teams"},"description":"league size"},{"name":"scoring","in":"query","required":false,"schema":{"type":"string","description":"ppr / half_ppr / standard / superflex","default":"ppr","title":"Scoring"},"description":"ppr / half_ppr / standard / superflex"},{"name":"format","in":"query","required":false,"schema":{"type":"string","description":"redraft / dynasty / best_ball","default":"redraft","title":"Format"},"description":"redraft / dynasty / best_ball"},{"name":"max_round","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"cap rounds returned (top N*teams players)","default":10,"title":"Max Round"},"description":"cap rounds returned (top N*teams players)"},{"name":"include_news","in":"query","required":false,"schema":{"type":"boolean","description":"when true, hit SearXNG for top-2 news per player (slower)","default":false,"title":"Include News"},"description":"when true, hit SearXNG for top-2 news per player (slower)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoundsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/teams/standings":{"get":{"tags":["teams"],"summary":"all 32 team standings (public)","description":"compute W-L records from nfl_games for every team in a single query.","operationId":"team_standings_api_teams_standings_get","parameters":[{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (defaults to current)","title":"Season"},"description":"nfl season year (defaults to current)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Team Standings Api Teams Standings Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/schedule":{"get":{"tags":["teams"],"summary":"current season schedule (public)","description":"current season schedule. public endpoint.","operationId":"get_schedule_api_schedule_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/scores/live":{"get":{"tags":["teams"],"summary":"live game scores (public)","description":"live game scores during game windows. public endpoint.","operationId":"live_scores_api_scores_live_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LiveScore"},"title":"Response Live Scores Api Scores Live Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/teams/{team_abbr}/dashboard":{"get":{"tags":["teams"],"summary":"full team overview (public, personalised for pro users)","description":"full team overview — record, key players, schedule, injuries.\npublic endpoint; auth is optional (pro users get enhanced data later).","operationId":"team_dashboard_api_teams__team_abbr__dashboard_get","parameters":[{"name":"team_abbr","in":"path","required":true,"schema":{"type":"string","title":"Team Abbr"}},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (defaults to current)","title":"Season"},"description":"nfl season year (defaults to current)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamDashboard"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/teams/{team_abbr}/schedule":{"get":{"tags":["teams"],"summary":"team season schedule","description":"full season schedule for a team.\n\nwhen ``season`` isn't supplied and the resolved season has no games yet\n(e.g. 2026 schedule not released), automatically falls back to the prior\nseason and surfaces ``schedule_status: 'tbd_using_2025'`` so callers can\nshow a banner. the games array is always returned under both ``schedule``\nand ``games`` keys for back-compat with older list-shape consumers.","operationId":"team_schedule_api_teams__team_abbr__schedule_get","parameters":[{"name":"team_abbr","in":"path","required":true,"schema":{"type":"string","title":"Team Abbr"}},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year","title":"Season"},"description":"nfl season year"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Team Schedule Api Teams  Team Abbr  Schedule Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/teams/{team_abbr}/schedule-widgets":{"get":{"tags":["teams"],"summary":"HomeTeam-style schedule widgets (grid, traps, sparkline)","description":"schedule-grid + trap-week + opponent-strength sparkline payload.\n\nfalls back to the prior season silently if the requested season has no\ngames stored yet, mirroring the /schedule endpoint's behaviour. callers\ncan check `actual_season` to know which season was actually rendered.","operationId":"team_schedule_widgets_api_teams__team_abbr__schedule_widgets_get","parameters":[{"name":"team_abbr","in":"path","required":true,"schema":{"type":"string","title":"Team Abbr"}},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year","title":"Season"},"description":"nfl season year"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Team Schedule Widgets Api Teams  Team Abbr  Schedule Widgets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/teams/{team_abbr}/roster":{"get":{"tags":["teams"],"summary":"team roster grouped by position","description":"all players on the team, grouped by position group.","operationId":"team_roster_api_teams__team_abbr__roster_get","parameters":[{"name":"team_abbr","in":"path","required":true,"schema":{"type":"string","title":"Team Abbr"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Team Roster Api Teams  Team Abbr  Roster Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/salary-cap/{team_abbr}":{"get":{"tags":["teams"],"summary":"team salary cap breakdown (public, detailed data for pro)","description":"salary cap breakdown by player. public endpoint; pro users get enhanced contract details later.","operationId":"salary_cap_api_salary_cap__team_abbr__get","parameters":[{"name":"team_abbr","in":"path","required":true,"schema":{"type":"string","title":"Team Abbr"}},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year","title":"Season"},"description":"nfl season year"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalaryCapBreakdown"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/odds/weekly/{week}":{"get":{"tags":["odds"],"summary":"betting lines for all games (pro)","description":"spreads, totals, and moneylines for all games in a given week.","operationId":"weekly_odds_api_odds_weekly__week__get","parameters":[{"name":"week","in":"path","required":true,"schema":{"type":"integer","title":"Week"}},{"name":"season","in":"query","required":false,"schema":{"type":"integer","description":"nfl season year (defaults to current)","title":"Season"},"description":"nfl season year (defaults to current)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WeeklyOddsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/trends/trending":{"get":{"tags":["trends"],"summary":"dashboard trending players (pro)","description":"find players with the biggest positive or negative trend over the last 4 weeks.","operationId":"trending_players_api_trends_trending_get","parameters":[{"name":"season","in":"query","required":true,"schema":{"type":"integer","description":"NFL season year","title":"Season"},"description":"NFL season year"},{"name":"week","in":"query","required":true,"schema":{"type":"integer","maximum":18,"minimum":1,"description":"current or most recent week","title":"Week"},"description":"current or most recent week"},{"name":"position","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter by position (QB, RB, WR, TE)","title":"Position"},"description":"filter by position (QB, RB, WR, TE)"},{"name":"direction","in":"query","required":false,"schema":{"type":"string","description":"up or down","default":"up","title":"Direction"},"description":"up or down"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"number of results","default":10,"title":"Limit"},"description":"number of results"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Trending Players Api Trends Trending Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/trends/{player_id}":{"get":{"tags":["trends"],"summary":"trend analysis — target share, snap %, usage (pro)","description":"rolling trend data for a player — target share, snap %, usage rate, fantasy output.","operationId":"player_trends_api_trends__player_id__get","parameters":[{"name":"player_id","in":"path","required":true,"schema":{"type":"integer","title":"Player Id"}},{"name":"season","in":"query","required":true,"schema":{"type":"integer","description":"NFL season year","title":"Season"},"description":"NFL season year"},{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":17,"minimum":1,"description":"rolling window in weeks","default":4,"title":"Weeks"},"description":"rolling window in weeks"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Player Trends Api Trends  Player Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/reports/weekly/{week}":{"get":{"tags":["reports"],"summary":"downloadable weekly report PDF (pro)","description":"generate and return a weekly analysis report as PDF.","operationId":"weekly_report_api_reports_weekly__week__get","parameters":[{"name":"week","in":"path","required":true,"schema":{"type":"integer","title":"Week"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forge/analyze":{"get":{"tags":["forge"],"summary":"stream Forge analysis on NFL data (pro, SSE)","description":"SSE endpoint that streams ForgeStat analysis results in real time.\n\nthe client should connect with EventSource and listen for `data:` frames.\nthe stream terminates with `data: [DONE]`.","operationId":"forge_analyze_api_forge_analyze_get","parameters":[{"name":"prompt","in":"query","required":true,"schema":{"type":"string","description":"analysis prompt, e.g. 'compare mahomes vs allen ROS'","title":"Prompt"},"description":"analysis prompt, e.g. 'compare mahomes vs allen ROS'"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tools/forge-chat":{"post":{"tags":["forge"],"summary":"natural-language fantasy chat — routes to start/sit, compare, projection, waiver-trend, dst-streaming, trade-analyzer, or lineup-advisor based on intent. answers are templated from real service output; never fabricates stats.","description":"answer one chat-style fantasy question. session_id is round-tripped.","operationId":"forge_chat_api_tools_forge_chat_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgeChatRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Forge Chat Api Tools Forge Chat Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/news/latest":{"get":{"tags":["news"],"summary":"latest news articles from the pipeline","description":"return the most recent news articles generated by the pipeline.\n\npipeline-generated articles have model_used='news_pipeline_v1'.\noptionally filter by article type.","operationId":"latest_news_api_news_latest_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"article_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"filter by article type (e.g. INJURY_IMPACT, TRENDING_PLAYERS)","title":"Article Type"},"description":"filter by article type (e.g. INJURY_IMPACT, TRENDING_PLAYERS)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Latest News Api News Latest Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/news/trending":{"get":{"tags":["news"],"summary":"trending players with analysis context","description":"return sleeper trending add/drop players enriched with our statistical context.\n\neach player includes: avg ppg, trade value, trend slope, target share, snap %.","operationId":"trending_players_api_news_trending_get","parameters":[{"name":"direction","in":"query","required":false,"schema":{"type":"string","pattern":"^(add|drop)$","default":"add","title":"Direction"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":15,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Trending Players Api News Trending Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/news/run-pipeline":{"post":{"tags":["news"],"summary":"manually trigger the news pipeline (admin or demo mode)","description":"manually run the news pipeline. requires admin or demo mode.\n\nthis is the same as the celery task but triggered on-demand.","operationId":"trigger_pipeline_api_news_run_pipeline_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Trigger Pipeline Api News Run Pipeline Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/news/draft-ingest":{"post":{"tags":["news"],"summary":"ingest nfl draft picks and generate articles","description":"ingest nfl draft picks from sleeper and generate articles.\n\npulls the latest player data from sleeper, detects new draft picks,\ncreates player records if needed, and generates per-round articles\nwith historical draft analysis context.","operationId":"trigger_draft_ingest_api_news_draft_ingest_post","parameters":[{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"draft year (defaults to current)","title":"Year"},"description":"draft year (defaults to current)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Trigger Draft Ingest Api News Draft Ingest Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/search":{"get":{"tags":["search"],"summary":"global search across players, articles, teams, tools","description":"aggregated search for the site-wide header search bar.\n\nreturns up to 5 players, 3 articles, 2 teams, and matching tools. caps\nare fixed (not derived from ``limit``) so each result group always\nrenders predictably regardless of the slider.","operationId":"global_search_api_search_get","parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","description":"search query","default":"","title":"Q"},"description":"search query"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":25,"minimum":1,"description":"overall result cap (informational)","default":10,"title":"Limit"},"description":"overall result cap (informational)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Global Search Api Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/leagues/search":{"get":{"tags":["leagues"],"summary":"Search User","description":"find a sleeper user by username.","operationId":"search_user_api_leagues_search_get","parameters":[{"name":"username","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/leagues/sleeper/user/{username}":{"get":{"tags":["leagues"],"summary":"Search User By Path","description":"find a sleeper user by username (path param convenience route).","operationId":"search_user_by_path_api_leagues_sleeper_user__username__get","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/leagues/user/{user_id}/leagues":{"get":{"tags":["leagues"],"summary":"List Leagues","description":"list all nfl leagues for a sleeper user.","operationId":"list_leagues_api_leagues_user__user_id__leagues_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"season","in":"query","required":false,"schema":{"type":"integer","default":2025,"title":"Season"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/leagues/import/{league_id}":{"get":{"tags":["leagues"],"summary":"Import League","description":"import a user's roster from a sleeper league.","operationId":"import_league_api_leagues_import__league_id__get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"string","title":"League Id"}},{"name":"username","in":"query","required":true,"schema":{"type":"string","minLength":1,"title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dm/leagues":{"get":{"tags":["draft-monkeys"],"summary":"list Draft Monkeys leagues for the authenticated user","description":"fetch all leagues the user belongs to on Draft Monkeys.\n\nrequires a valid DM auth token passed via X-DM-Token header.","operationId":"list_dm_leagues_api_dm_leagues_get","parameters":[{"name":"X-DM-Token","in":"header","required":true,"schema":{"type":"string","description":"Draft Monkeys auth token","title":"X-Dm-Token"},"description":"Draft Monkeys auth token"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response List Dm Leagues Api Dm Leagues Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dm/import/{league_id}":{"get":{"tags":["draft-monkeys"],"summary":"import a Draft Monkeys league","description":"import a Draft Monkeys league roster, standings, and matchups.\n\nrequires:\n- league_id in the path\n- team_id as a query parameter\n- DM auth token via X-DM-Token header\n- valid ScrimmageLab auth via Authorization header\n\nreturns the full league import payload with matched players,\nrecord, and scoring information.","operationId":"import_dm_api_dm_import__league_id__get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"string","title":"League Id"}},{"name":"team_id","in":"query","required":true,"schema":{"type":"string","description":"your team ID within the league","title":"Team Id"},"description":"your team ID within the league"},{"name":"X-DM-Token","in":"header","required":true,"schema":{"type":"string","description":"Draft Monkeys auth token","title":"X-Dm-Token"},"description":"Draft Monkeys auth token"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Import Dm Api Dm Import  League Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/espn/league/{league_id}":{"get":{"tags":["espn"],"summary":"get ESPN league info","description":"fetch league settings, teams, and scoring type from ESPN.\n\nfor public leagues, no extra params are needed. for private leagues,\nprovide your espn_s2 and SWID cookies (found in browser DevTools >\nApplication > Cookies on espn.com).","operationId":"espn_league_info_api_espn_league__league_id__get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"integer","title":"League Id"}},{"name":"year","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2000,"default":2025,"title":"Year"}},{"name":"espn_s2","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"espn_s2 cookie for private leagues","title":"Espn S2"},"description":"espn_s2 cookie for private leagues"},{"name":"swid","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"SWID cookie for private leagues","title":"Swid"},"description":"SWID cookie for private leagues"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Espn League Info Api Espn League  League Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/espn/league/{league_id}/rosters":{"get":{"tags":["espn"],"summary":"get all rosters in an ESPN league","description":"fetch all team rosters from an ESPN league.\n\nreturns every team's roster with player names, positions, and lineup slots.","operationId":"espn_league_rosters_api_espn_league__league_id__rosters_get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"integer","title":"League Id"}},{"name":"year","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2000,"default":2025,"title":"Year"}},{"name":"espn_s2","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"espn_s2 cookie for private leagues","title":"Espn S2"},"description":"espn_s2 cookie for private leagues"},{"name":"swid","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"SWID cookie for private leagues","title":"Swid"},"description":"SWID cookie for private leagues"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Espn League Rosters Api Espn League  League Id  Rosters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/espn/league/{league_id}/import":{"post":{"tags":["espn"],"summary":"import your ESPN team roster","description":"import your team's roster from an ESPN league.\n\nmatches espn players against our nfl_players table using espn_id first,\nthen falling back to name matching. returns the full roster with match\nstatus and team record.\n\nfor private leagues, include espn_s2 and swid in the request body.","operationId":"espn_import_team_api_espn_league__league_id__import_post","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"integer","title":"League Id"}},{"name":"year","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2000,"default":2025,"title":"Year"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EspnImportRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Espn Import Team Api Espn League  League Id  Import Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/yahoo/league/{league_key}":{"get":{"tags":["yahoo"],"summary":"get Yahoo league info","description":"try to fetch league info from Yahoo Fantasy.\n\nyahoo requires oauth2 for all api access. if no access_token is provided,\nreturns instructions for manual import as a fallback.\n\naccepts league_key in multiple formats:\n- nfl.l.123456\n- 449.l.123456\n- just the numeric id: 123456\n- full url: https://football.fantasysports.yahoo.com/f1/123456","operationId":"yahoo_league_info_api_yahoo_league__league_key__get","parameters":[{"name":"league_key","in":"path","required":true,"schema":{"type":"string","title":"League Key"}},{"name":"access_token","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"yahoo oauth2 access token (if you have one)","title":"Access Token"},"description":"yahoo oauth2 access token (if you have one)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Yahoo League Info Api Yahoo League  League Key  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/yahoo/import-manual":{"post":{"tags":["yahoo"],"summary":"import Yahoo roster manually","description":"import a Yahoo Fantasy roster by manually entering player names.\n\nthis is the fallback for when yahoo oauth isn't available. users can\ncopy their roster from yahoo's website and paste the player names here.\n\neach player needs at minimum a `name` field. position and yahoo_player_id\nare optional but improve matching accuracy.\n\nexample request body:\n```json\n{\n  \"league_name\": \"My Yahoo League\",\n  \"team_name\": \"Team Awesome\",\n  \"league_id\": \"123456\",\n  \"players\": [\n    {\"name\": \"Patrick Mahomes\", \"position\": \"QB\", \"slot\": \"QB\"},\n    {\"name\": \"Derrick Henry\", \"position\": \"RB\", \"slot\": \"RB\"},\n    {\"name\": \"CeeDee Lamb\", \"position\": \"WR\", \"slot\": \"WR\"},\n    {\"name\": \"Travis Kelce\", \"position\": \"TE\", \"slot\": \"TE\"},\n    {\"name\": \"Josh Allen\", \"position\": \"QB\", \"slot\": \"BN\"}\n  ]\n}\n```","operationId":"yahoo_manual_import_api_yahoo_import_manual_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/YahooManualImportRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Yahoo Manual Import Api Yahoo Import Manual Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mfl/league/{league_id}":{"get":{"tags":["mfl"],"summary":"get MFL league info","description":"fetch league name, settings, scoring, and franchise list from MFL.","operationId":"mfl_league_info_api_mfl_league__league_id__get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"string","title":"League Id"}},{"name":"year","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2000,"default":2025,"title":"Year"}},{"name":"server","in":"query","required":false,"schema":{"type":"string","default":"api","title":"Server"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Mfl League Info Api Mfl League  League Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mfl/league/{league_id}/rosters":{"get":{"tags":["mfl"],"summary":"get all MFL league rosters","description":"fetch all team rosters with MFL player IDs.","operationId":"mfl_league_rosters_api_mfl_league__league_id__rosters_get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"string","title":"League Id"}},{"name":"year","in":"query","required":false,"schema":{"type":"integer","maximum":2030,"minimum":2000,"default":2025,"title":"Year"}},{"name":"server","in":"query","required":false,"schema":{"type":"string","default":"api","title":"Server"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Mfl League Rosters Api Mfl League  League Id  Rosters Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mfl/league/{league_id}/import":{"post":{"tags":["mfl"],"summary":"import a franchise roster from MFL","description":"import a specific franchise's roster from an MFL league.\n\nmatches MFL player names against our nfl_players table for\nseamless analytics integration.\n\nbody:\n- franchise_id: the MFL franchise identifier (e.g. \"0001\")\n- year: season year (default 2025)\n- server: MFL server (default \"api\")","operationId":"mfl_import_api_mfl_league__league_id__import_post","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"string","title":"League Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MflImportRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Mfl Import Api Mfl League  League Id  Import Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rts/league/{league_id}":{"get":{"tags":["rtsports"],"summary":"get RTSports league info","description":"try to fetch league info from RTSports.\n\nRTSports api access is limited — this may return a partial result\nwith a suggestion to use the roster paste import instead.","operationId":"rts_league_info_api_rts_league__league_id__get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"string","title":"League Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Rts League Info Api Rts League  League Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/rts/import":{"post":{"tags":["rtsports"],"summary":"import roster from pasted RTSports data","description":"import a roster from pasted text (CSV, tab-delimited, or plain text).\n\nRTSports allows users to export or copy their roster data. paste it\nhere and we'll parse player names, match them against our nfl_players\ntable, and return a structured roster.\n\naccepted formats:\n- \"QB Patrick Mahomes KC\"\n- \"Patrick Mahomes, QB, KC\"\n- \"Patrick Mahomes\\tQB\\tKC\"\n- one player name per line","operationId":"rts_import_api_rts_import_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RtsRosterPaste"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Rts Import Api Rts Import Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cbs-import/roster":{"post":{"tags":["cbs-sports"],"summary":"import cbs sports roster from pasted text","description":"import a roster from cbs sports by pasting exported csv/text.\n\ncbs allows exporting rosters as csv. paste the contents here\nand we'll match players against our database.\n\naccepts formats like:\n- \"Patrick Mahomes,QB,KC\"\n- \"Patrick Mahomes\\tQB\\tKC\"\n- one player per line, any reasonable format","operationId":"import_cbs_api_cbs_import_roster_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CbsRosterInput"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Import Cbs Api Cbs Import Roster Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nfl-import/league/{league_id}":{"get":{"tags":["nfl-fantasy"],"summary":"import nfl.com fantasy league via api","description":"import a league from nfl.com fantasy football.\n\ntries the nfl fantasy api first (public leagues). if the api is\nunavailable or the league is private, returns instructions for\nmanual import via POST /api/nfl-import/manual.\n\nnfl.com uses GSISIDs which we cross-reference for high-confidence matching.","operationId":"import_nfl_league_endpoint_api_nfl_import_league__league_id__get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"string","title":"League Id"}},{"name":"season","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"nfl season year (defaults to current)","title":"Season"},"description":"nfl season year (defaults to current)"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Import Nfl League Endpoint Api Nfl Import League  League Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nfl-import/manual":{"post":{"tags":["nfl-fantasy"],"summary":"manual nfl.com roster import from pasted text","description":"manual nfl.com roster import — paste roster data from nfl.com.\n\nuse this when the api can't access the league (private leagues).\naccepts any reasonable text format with player names.","operationId":"import_nfl_manual_endpoint_api_nfl_import_manual_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NflManualInput"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Import Nfl Manual Endpoint Api Nfl Import Manual Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fantrax-import/league/{league_id}":{"get":{"tags":["fantrax"],"summary":"import fantrax league via api","description":"import a league from fantrax.\n\ntries the fantrax api for public leagues. if the league is private\nor the api is unavailable, returns instructions for manual import\nvia POST /api/fantrax-import/manual.","operationId":"import_fantrax_league_endpoint_api_fantrax_import_league__league_id__get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"string","title":"League Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Import Fantrax League Endpoint Api Fantrax Import League  League Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fantrax-import/manual":{"post":{"tags":["fantrax"],"summary":"manual fantrax roster import from pasted text","description":"manual fantrax roster import — paste roster data from fantrax csv export.\n\nuse this when the api can't access the league. accepts any reasonable\ntext format with player names.","operationId":"import_fantrax_manual_endpoint_api_fantrax_import_manual_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FantraxManualInput"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Import Fantrax Manual Endpoint Api Fantrax Import Manual Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fleaflicker/leagues":{"get":{"tags":["fleaflicker"],"summary":"find fleaflicker leagues by email","description":"fetch all nfl leagues for a fleaflicker user by email.\n\nfleaflicker's api is public — no password or auth token needed.\nreturns league id, name, and the user's team id in each league.","operationId":"fleaflicker_leagues_api_fleaflicker_leagues_get","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","minLength":3,"description":"fleaflicker account email","title":"Email"},"description":"fleaflicker account email"},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Fleaflicker Leagues Api Fleaflicker Leagues Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fleaflicker/roster/{league_id}/{team_id}":{"get":{"tags":["fleaflicker"],"summary":"get a fleaflicker team roster","description":"fetch a team's roster from a fleaflicker league.\n\nreturns player names, positions, teams, and lineup slots.","operationId":"fleaflicker_roster_api_fleaflicker_roster__league_id___team_id__get","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"integer","title":"League Id"}},{"name":"team_id","in":"path","required":true,"schema":{"type":"integer","title":"Team Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Fleaflicker Roster Api Fleaflicker Roster  League Id   Team Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fleaflicker/import/{league_id}/{team_id}":{"post":{"tags":["fleaflicker"],"summary":"import a fleaflicker roster","description":"import a team's roster from fleaflicker, matching players to our db.\n\nfetches the roster and league standings from fleaflicker, then matches\neach player against our nfl_players table by name. returns the full\nroster with match status, team record, and league info.","operationId":"fleaflicker_import_api_fleaflicker_import__league_id___team_id__post","parameters":[{"name":"league_id","in":"path","required":true,"schema":{"type":"integer","title":"League Id"}},{"name":"team_id","in":"path","required":true,"schema":{"type":"integer","title":"Team Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Fleaflicker Import Api Fleaflicker Import  League Id   Team Id  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/import/universal":{"post":{"tags":["universal-import"],"summary":"universal roster import — any platform, any format","description":"import a roster from any fantasy platform by pasting text/csv.\n\nthis is the catch-all fallback that works with any platform.\nsmart player name matching handles common formats:\n\n- \"Patrick Mahomes, QB, KC\"\n- \"Mahomes KC QB\"\n- \"1. Patrick Mahomes (QB) - KC\"\n- tab/csv/pipe-delimited tables\n- any mix of the above\n\nreturns matched players with confidence scores (0.0-1.0):\n- 1.0 = exact match\n- 0.85+ = high confidence\n- 0.5-0.85 = medium confidence (review recommended)\n- <0.5 = low confidence (likely wrong)","operationId":"universal_import_api_import_universal_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UniversalRosterInput"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Universal Import Api Import Universal Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/newsletter/subscribe":{"post":{"tags":["newsletter"],"summary":"subscribe to the newsletter","description":"add an email to the newsletter_subscribers table.","operationId":"subscribe_api_newsletter_subscribe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscribeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/pipeline/status":{"get":{"tags":["admin"],"summary":"data pipeline health (admin)","description":"check health of all data ingestion pipelines.","operationId":"pipeline_status_api_admin_pipeline_status_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/pipeline/trigger":{"post":{"tags":["admin"],"summary":"manually trigger data refresh (admin)","description":"manually kick off a data pipeline run.","operationId":"pipeline_trigger_api_admin_pipeline_trigger_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineTriggerRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineTriggerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/subscribers":{"get":{"tags":["admin"],"summary":"subscriber count and metrics (admin)","description":"subscriber and revenue metrics dashboard.","operationId":"subscriber_metrics_api_admin_subscribers_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriberMetrics"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/content/queue":{"get":{"tags":["admin"],"summary":"articles pending publication (admin)","description":"articles in draft / review / scheduled states.","operationId":"content_queue_api_admin_content_queue_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentQueueResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stripe/create-checkout":{"post":{"tags":["billing"],"summary":"start a stripe checkout session","description":"returns ``{checkout_url}`` or the not-configured payload.","operationId":"create_checkout_api_stripe_create_checkout_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Checkout Api Stripe Create Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stripe/create-portal":{"post":{"tags":["billing"],"summary":"open the stripe billing portal","description":"returns ``{portal_url}`` or the not-configured payload.\n\nauth is optional only so the not-configured branch can be reached\nwithout a session (the QA curl in PART D doesn't carry a token).\nonce stripe is configured we still require an authenticated user.","operationId":"create_portal_api_stripe_create_portal_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Portal Api Stripe Create Portal Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/stripe/webhook":{"post":{"tags":["billing"],"summary":"receive stripe webhook events","description":"verify signature and update users.subscription_tier / period_end.\n\nwhen env vars are unset we still return 200 so stripe's CLI doesn't\nspin in retry loops while Glenn is bootstrapping the integration.","operationId":"webhook_api_stripe_webhook_post","parameters":[{"name":"Stripe-Signature","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Webhook Api Stripe Webhook Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/subscription/status":{"get":{"tags":["billing"],"summary":"current subscription tier + period end","description":"returns ``{tier, current_period_end, configured}``.\n\nsafe to call without auth — anonymous callers get the free tier shape\nso the marketing pricing page can read ``configured`` without 401ing.","operationId":"subscription_status_api_subscription_status_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Subscription Status Api Subscription Status Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["health"],"summary":"health check","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"tags":["health"],"summary":"root redirect","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"ArbitragePlayer":{"properties":{"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"consensus_rank":{"type":"integer","title":"Consensus Rank"},"adp_rank":{"type":"number","title":"Adp Rank"},"delta":{"type":"number","title":"Delta"},"why":{"type":"string","title":"Why"}},"type":"object","required":["player_id","name","consensus_rank","adp_rank","delta","why"],"title":"ArbitragePlayer"},"ArbitrageResponse":{"properties":{"scoring":{"type":"string","title":"Scoring"},"direction":{"type":"string","title":"Direction"},"count":{"type":"integer","title":"Count"},"players":{"items":{"$ref":"#/components/schemas/ArbitragePlayer"},"type":"array","title":"Players"}},"type":"object","required":["scoring","direction","count","players"],"title":"ArbitrageResponse"},"BadgeBatchRequest":{"properties":{"player_ids":{"items":{"type":"integer"},"type":"array","maxItems":500,"minItems":1,"title":"Player Ids"}},"type":"object","required":["player_ids"],"title":"BadgeBatchRequest","description":"body for the batch badges POST endpoint."},"BenchAnalyzerRequest":{"properties":{"player_ids":{"items":{"type":"integer"},"type":"array","maxItems":20,"minItems":1,"title":"Player Ids","description":"10-15 player IDs forming a roster"},"season":{"type":"integer","title":"Season","description":"empirical-distribution season","default":2025},"scoring":{"type":"string","title":"Scoring","description":"PPR | HALF_PPR | STANDARD","default":"PPR"}},"type":"object","required":["player_ids"],"title":"BenchAnalyzerRequest"},"Body_refresh_token_api_auth_refresh_post":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"Body_refresh_token_api_auth_refresh_post"},"BustPlayer":{"properties":{"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"adp_rank":{"type":"number","title":"Adp Rank"},"warnings":{"items":{"$ref":"#/components/schemas/BustWarning"},"type":"array","title":"Warnings"}},"type":"object","required":["player_id","name","adp_rank","warnings"],"title":"BustPlayer"},"BustWarning":{"properties":{"type":{"type":"string","title":"Type"},"value":{"title":"Value"},"source_file":{"type":"string","title":"Source File"}},"type":"object","required":["type","value","source_file"],"title":"BustWarning"},"BustsResponse":{"properties":{"count":{"type":"integer","title":"Count"},"players":{"items":{"$ref":"#/components/schemas/BustPlayer"},"type":"array","title":"Players"}},"type":"object","required":["count","players"],"title":"BustsResponse"},"CbsRosterInput":{"properties":{"roster_text":{"type":"string","minLength":3,"title":"Roster Text","description":"pasted roster text — csv, tsv, or one player per line"},"league_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"League Id","description":"optional cbs league id for tracking purposes"}},"type":"object","required":["roster_text"],"title":"CbsRosterInput","description":"request body for cbs roster import."},"CoachingStaffEntry":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"source_url":{"type":"string","title":"Source Url"},"verdict":{"type":"string","title":"Verdict"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"is_new_2026":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is New 2026"},"prior_team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prior Team"}},"type":"object","required":["source_url","verdict"],"title":"CoachingStaffEntry"},"CompositePlayer":{"properties":{"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"overall_rank":{"type":"integer","title":"Overall Rank"},"position_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position Rank"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"weighted_rank":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Weighted Rank"},"mean_rank":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mean Rank"},"std_dev":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Std Dev"},"n_sources":{"type":"integer","title":"N Sources","default":0},"min_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Rank"},"max_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Rank"},"sharp_avg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sharp Avg"},"square_avg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Square Avg"},"disagreement_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Disagreement Score"}},"type":"object","required":["player_id","name","overall_rank"],"title":"CompositePlayer"},"CompositeResponse":{"properties":{"scoring":{"type":"string","title":"Scoring"},"format":{"type":"string","title":"Format"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"ranker":{"type":"string","title":"Ranker"},"count":{"type":"integer","title":"Count"},"players":{"items":{"$ref":"#/components/schemas/CompositePlayer"},"type":"array","title":"Players"}},"type":"object","required":["scoring","format","ranker","count","players"],"title":"CompositeResponse"},"ContentQueueItem":{"properties":{"article_id":{"type":"string","title":"Article Id"},"title":{"type":"string","title":"Title"},"status":{"type":"string","title":"Status","description":"draft | review | scheduled | published","default":"draft"},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["article_id","title","created_at"],"title":"ContentQueueItem"},"ContentQueueResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/ContentQueueItem"},"type":"array","title":"Items"},"total_draft":{"type":"integer","title":"Total Draft"},"total_review":{"type":"integer","title":"Total Review"},"total_scheduled":{"type":"integer","title":"Total Scheduled"}},"type":"object","required":["items","total_draft","total_review","total_scheduled"],"title":"ContentQueueResponse"},"DFSConstraint":{"properties":{"platform":{"type":"string","title":"Platform","description":"draftkings | fanduel","default":"draftkings"},"salary_cap":{"type":"integer","title":"Salary Cap","default":50000},"max_players_per_team":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Players Per Team"},"locked_players":{"items":{"type":"string"},"type":"array","title":"Locked Players"},"excluded_players":{"items":{"type":"string"},"type":"array","title":"Excluded Players"},"min_salary_remaining":{"type":"integer","title":"Min Salary Remaining","default":0}},"type":"object","title":"DFSConstraint"},"DFSLineup":{"properties":{"lineup":{"items":{"$ref":"#/components/schemas/DFSLineupEntry"},"type":"array","title":"Lineup"},"total_salary":{"type":"integer","title":"Total Salary"},"projected_points":{"type":"number","title":"Projected Points"},"salary_remaining":{"type":"integer","title":"Salary Remaining"}},"type":"object","required":["lineup","total_salary","projected_points","salary_remaining"],"title":"DFSLineup"},"DFSLineupEntry":{"properties":{"slot":{"type":"string","title":"Slot"},"player_id":{"type":"string","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"type":"string","title":"Position"},"team":{"type":"string","title":"Team"},"salary":{"type":"integer","title":"Salary"},"projected_points":{"type":"number","title":"Projected Points"}},"type":"object","required":["slot","player_id","name","position","team","salary","projected_points"],"title":"DFSLineupEntry"},"DFSOptimizeRequest":{"properties":{"week":{"type":"integer","title":"Week"},"constraints":{"$ref":"#/components/schemas/DFSConstraint"},"num_lineups":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Num Lineups","default":1},"scoring":{"type":"string","title":"Scoring","default":"ppr"}},"type":"object","required":["week","constraints"],"title":"DFSOptimizeRequest"},"DFSOptimizeResponse":{"properties":{"week":{"type":"integer","title":"Week"},"platform":{"type":"string","title":"Platform"},"lineups":{"items":{"$ref":"#/components/schemas/DFSLineup"},"type":"array","title":"Lineups"}},"type":"object","required":["week","platform","lineups"],"title":"DFSOptimizeResponse"},"DFSSalariesResponse":{"properties":{"week":{"type":"integer","title":"Week"},"platform":{"type":"string","title":"Platform","description":"draftkings | fanduel","default":"draftkings"},"players":{"items":{"$ref":"#/components/schemas/DFSSalary"},"type":"array","title":"Players"}},"type":"object","required":["week","players"],"title":"DFSSalariesResponse"},"DFSSalary":{"properties":{"player_id":{"type":"string","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"type":"string","title":"Position"},"team":{"type":"string","title":"Team"},"opponent":{"type":"string","title":"Opponent"},"salary":{"type":"integer","title":"Salary"},"projected_points":{"type":"number","title":"Projected Points"},"value":{"type":"number","title":"Value","description":"projected points per $1000 salary"},"ownership_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ownership Pct"}},"type":"object","required":["player_id","name","position","team","opponent","salary","projected_points","value"],"title":"DFSSalary"},"DFSSimpleRequest":{"properties":{"slate":{"type":"string","title":"Slate","description":"draftkings | fanduel","default":"draftkings"},"budget":{"type":"integer","title":"Budget","default":50000},"lockedPlayers":{"items":{"type":"string"},"type":"array","title":"Lockedplayers"},"excludedPlayers":{"items":{"type":"string"},"type":"array","title":"Excludedplayers"}},"type":"object","title":"DFSSimpleRequest"},"DefenseStats":{"properties":{"sacks":{"type":"number","title":"Sacks","default":0.0},"interceptions":{"type":"integer","title":"Interceptions","default":0},"fumble_recoveries":{"type":"integer","title":"Fumble Recoveries","default":0},"touchdowns":{"type":"integer","title":"Touchdowns","default":0},"points_allowed":{"type":"integer","title":"Points Allowed","default":0},"yards_allowed":{"type":"integer","title":"Yards Allowed","default":0},"safeties":{"type":"integer","title":"Safeties","default":0}},"type":"object","title":"DefenseStats"},"DriverItem":{"properties":{"label":{"type":"string","title":"Label"},"kind":{"type":"string","title":"Kind"},"source":{"type":"string","title":"Source"},"stickiness":{"anyOf":[{"$ref":"#/components/schemas/StickinessSlice"},{"type":"null"}]}},"type":"object","required":["label","kind","source"],"title":"DriverItem"},"EspnImportRequest":{"properties":{"team_id":{"type":"integer","title":"Team Id"},"espn_s2":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Espn S2"},"swid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Swid"}},"type":"object","required":["team_id"],"title":"EspnImportRequest","description":"request body for importing an espn league."},"FantraxManualInput":{"properties":{"roster_text":{"type":"string","minLength":3,"title":"Roster Text","description":"pasted roster text — csv, tsv, or one player per line"},"league_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"League Id","description":"optional fantrax league id for tracking"}},"type":"object","required":["roster_text"],"title":"FantraxManualInput","description":"request body for manual fantrax roster import."},"ForgeChatRequest":{"properties":{"message":{"type":"string","maxLength":1000,"minLength":1,"title":"Message"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"optional client session id"},"season":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Season","description":"default season override (e.g. 2024)"},"week":{"anyOf":[{"type":"integer","maximum":22.0,"minimum":1.0},{"type":"null"}],"title":"Week","description":"default week override"},"scoring":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scoring","description":"PPR | HALF_PPR | STANDARD","default":"PPR"}},"type":"object","required":["message"],"title":"ForgeChatRequest"},"GameOdds":{"properties":{"game_id":{"type":"string","title":"Game Id"},"week":{"type":"integer","title":"Week"},"home_team":{"type":"string","title":"Home Team"},"away_team":{"type":"string","title":"Away Team"},"spread_home":{"type":"number","title":"Spread Home"},"spread_away":{"type":"number","title":"Spread Away"},"moneyline_home":{"type":"integer","title":"Moneyline Home"},"moneyline_away":{"type":"integer","title":"Moneyline Away"},"over_under":{"type":"number","title":"Over Under"},"home_implied_total":{"type":"number","title":"Home Implied Total"},"away_implied_total":{"type":"number","title":"Away Implied Total"},"updated_at":{"type":"string","title":"Updated At"}},"type":"object","required":["game_id","week","home_team","away_team","spread_home","spread_away","moneyline_home","moneyline_away","over_under","home_implied_total","away_implied_total","updated_at"],"title":"GameOdds"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HandcuffEntry":{"properties":{"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"overall_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Overall Rank"},"position_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position Rank"}},"type":"object","required":["player_id","name"],"title":"HandcuffEntry"},"HandcuffResponse":{"properties":{"primary":{"$ref":"#/components/schemas/HandcuffEntry"},"handcuff":{"anyOf":[{"$ref":"#/components/schemas/HandcuffEntry"},{"type":"null"}]},"consensus_rank_diff":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Consensus Rank Diff"}},"type":"object","required":["primary"],"title":"HandcuffResponse"},"HeatmapCell":{"properties":{"drafted_cumulative":{"type":"integer","title":"Drafted Cumulative"},"drafted_in_round":{"type":"integer","title":"Drafted In Round"},"starters_remaining":{"type":"integer","title":"Starters Remaining"},"starters_drafted_cumul":{"type":"integer","title":"Starters Drafted Cumul"},"starter_pool_size":{"type":"integer","title":"Starter Pool Size"}},"type":"object","required":["drafted_cumulative","drafted_in_round","starters_remaining","starters_drafted_cumul","starter_pool_size"],"title":"HeatmapCell","description":"one cell in the round x position grid.\n\nfields:\n  drafted_cumulative      — total players at this position drafted by ADP/composite\n                            up to AND INCLUDING this round\n  drafted_in_round        — players at this position drafted in JUST this round\n  starters_remaining      — starter-tier players left at this position AFTER this round\n  starters_drafted_cumul  — starter-tier players drafted at this position through this round\n  starter_pool_size       — total starter-tier slots for this position (teams * starters_per)"},"HeatmapRound":{"properties":{"round":{"type":"integer","title":"Round"},"cells":{"additionalProperties":{"$ref":"#/components/schemas/HeatmapCell"},"type":"object","title":"Cells"}},"type":"object","required":["round","cells"],"title":"HeatmapRound"},"IDPCompositePlayer":{"properties":{"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"overall_rank":{"type":"integer","title":"Overall Rank"},"position_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position Rank"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"weighted_rank":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Weighted Rank"},"mean_rank":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mean Rank"},"std_dev":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Std Dev"},"n_sources":{"type":"integer","title":"N Sources","default":0},"min_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Rank"},"max_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Rank"},"sharp_avg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sharp Avg"},"square_avg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Square Avg"},"disagreement_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Disagreement Score"},"idp_bucket":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idp Bucket"}},"type":"object","required":["player_id","name","overall_rank"],"title":"IDPCompositePlayer"},"IDPCompositeResponse":{"properties":{"scoring":{"type":"string","title":"Scoring"},"format":{"type":"string","title":"Format"},"bucket":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bucket"},"ranker":{"type":"string","title":"Ranker"},"count":{"type":"integer","title":"Count"},"players":{"items":{"$ref":"#/components/schemas/IDPCompositePlayer"},"type":"array","title":"Players"}},"type":"object","required":["scoring","format","ranker","count","players"],"title":"IDPCompositeResponse"},"KickingStats":{"properties":{"fg_made":{"type":"integer","title":"Fg Made","default":0},"fg_attempted":{"type":"integer","title":"Fg Attempted","default":0},"fg_pct":{"type":"number","title":"Fg Pct","default":0.0},"xp_made":{"type":"integer","title":"Xp Made","default":0},"xp_attempted":{"type":"integer","title":"Xp Attempted","default":0},"longest":{"type":"integer","title":"Longest","default":0}},"type":"object","title":"KickingStats"},"LiveScore":{"properties":{"game_id":{"type":"string","title":"Game Id"},"home_team":{"type":"string","title":"Home Team"},"away_team":{"type":"string","title":"Away Team"},"home_score":{"type":"integer","title":"Home Score"},"away_score":{"type":"integer","title":"Away Score"},"quarter":{"type":"integer","title":"Quarter"},"time_remaining":{"type":"string","title":"Time Remaining"},"possession":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Possession"},"down_distance":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Down Distance"},"status":{"type":"string","title":"Status"}},"type":"object","required":["game_id","home_team","away_team","home_score","away_score","quarter","time_remaining","status"],"title":"LiveScore"},"MatchupPreview":{"properties":{"game_id":{"type":"string","title":"Game Id"},"week":{"type":"integer","title":"Week"},"home_team":{"$ref":"#/components/schemas/TeamMatchupPreview"},"away_team":{"$ref":"#/components/schemas/TeamMatchupPreview"},"spread":{"type":"number","title":"Spread"},"over_under":{"type":"number","title":"Over Under"},"game_time":{"type":"string","title":"Game Time"},"network":{"type":"string","title":"Network"}},"type":"object","required":["game_id","week","home_team","away_team","spread","over_under","game_time","network"],"title":"MatchupPreview"},"MflImportRequest":{"properties":{"franchise_id":{"type":"string","title":"Franchise Id"},"year":{"type":"integer","title":"Year","default":2025},"server":{"type":"string","title":"Server","default":"api"}},"type":"object","required":["franchise_id"],"title":"MflImportRequest"},"MockDraftPickRequest":{"properties":{"player_id":{"type":"integer","title":"Player Id","description":"player_id to draft (negative for DST picks)"}},"type":"object","required":["player_id"],"title":"MockDraftPickRequest"},"MockDraftStartRequest":{"properties":{"teams":{"type":"integer","maximum":16.0,"minimum":2.0,"title":"Teams","default":12},"scoring":{"type":"string","title":"Scoring","description":"PPR | HALF_PPR | STANDARD","default":"PPR"},"format":{"type":"string","title":"Format","description":"h2h (default — head-to-head snake, 15 rounds, K+DST) | best_ball (Underdog BBM-style snake, 18 rounds, no K/DST by default) | snake (backward-compat alias for h2h)","default":"h2h"},"slot":{"type":"integer","maximum":16.0,"minimum":1.0,"title":"Slot","description":"user's draft slot (1-based)","default":5},"rounds":{"anyOf":[{"type":"integer","maximum":25.0,"minimum":1.0},{"type":"null"}],"title":"Rounds","description":"defaults to 15 (h2h) or 18 (best_ball) when omitted"},"league_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"League Id","description":"optional league UUID; auto-generated if omitted"},"keep_kicker":{"type":"boolean","title":"Keep Kicker","description":"best_ball only — leave K in the pool (DraftKings-flavoured custom format)","default":false}},"type":"object","title":"MockDraftStartRequest"},"MoverPlayer":{"properties":{"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"avg_rank_old":{"type":"number","title":"Avg Rank Old"},"avg_rank_new":{"type":"number","title":"Avg Rank New"},"avg_rank_change":{"type":"number","title":"Avg Rank Change"},"n_sources":{"type":"integer","title":"N Sources"}},"type":"object","required":["player_id","name","avg_rank_old","avg_rank_new","avg_rank_change","n_sources"],"title":"MoverPlayer"},"MoversResponse":{"properties":{"days":{"type":"integer","title":"Days"},"snapshot_old":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snapshot Old"},"snapshot_new":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Snapshot New"},"risers":{"items":{"$ref":"#/components/schemas/MoverPlayer"},"type":"array","title":"Risers"},"fallers":{"items":{"$ref":"#/components/schemas/MoverPlayer"},"type":"array","title":"Fallers"}},"type":"object","required":["days","risers","fallers"],"title":"MoversResponse"},"NewsItem":{"properties":{"title":{"type":"string","title":"Title"},"url":{"type":"string","title":"Url"},"content":{"type":"string","title":"Content"}},"type":"object","required":["title","url","content"],"title":"NewsItem"},"NflManualInput":{"properties":{"roster_text":{"type":"string","minLength":3,"title":"Roster Text","description":"pasted roster text — csv, tsv, or one player per line"},"league_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"League Id","description":"optional nfl.com league id for tracking"}},"type":"object","required":["roster_text"],"title":"NflManualInput","description":"request body for manual nfl.com roster import."},"PassingStats":{"properties":{"completions":{"type":"integer","title":"Completions","default":0},"attempts":{"type":"integer","title":"Attempts","default":0},"yards":{"type":"integer","title":"Yards","default":0},"touchdowns":{"type":"integer","title":"Touchdowns","default":0},"interceptions":{"type":"integer","title":"Interceptions","default":0},"passer_rating":{"type":"number","title":"Passer Rating","default":0.0},"sacks":{"type":"integer","title":"Sacks","default":0},"sack_yards":{"type":"integer","title":"Sack Yards","default":0}},"type":"object","title":"PassingStats"},"PipelineStatus":{"properties":{"pipeline":{"type":"string","title":"Pipeline"},"status":{"type":"string","title":"Status","description":"healthy | degraded | down"},"last_run":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Run"},"next_run":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Run"},"records_processed":{"type":"integer","title":"Records Processed","default":0},"errors":{"items":{"type":"string"},"type":"array","title":"Errors","default":[]}},"type":"object","required":["pipeline","status"],"title":"PipelineStatus"},"PipelineStatusResponse":{"properties":{"pipelines":{"items":{"$ref":"#/components/schemas/PipelineStatus"},"type":"array","title":"Pipelines"},"overall_health":{"type":"string","title":"Overall Health","description":"healthy | degraded | down"}},"type":"object","required":["pipelines","overall_health"],"title":"PipelineStatusResponse"},"PipelineTriggerRequest":{"properties":{"pipeline":{"type":"string","title":"Pipeline","description":"stats | projections | odds | injuries | articles | all"},"force":{"type":"boolean","title":"Force","default":false}},"type":"object","required":["pipeline"],"title":"PipelineTriggerRequest"},"PipelineTriggerResponse":{"properties":{"pipeline":{"type":"string","title":"Pipeline"},"task_id":{"type":"string","title":"Task Id"},"status":{"type":"string","title":"Status","default":"queued"},"message":{"type":"string","title":"Message"}},"type":"object","required":["pipeline","task_id","message"],"title":"PipelineTriggerResponse"},"PlayerCompareResponse":{"properties":{"players":{"items":{"$ref":"#/components/schemas/PlayerDetail"},"type":"array","title":"Players"},"comparison_stats":{"items":{"type":"object"},"type":"array","title":"Comparison Stats"},"recommendation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recommendation"}},"type":"object","required":["players","comparison_stats"],"title":"PlayerCompareResponse"},"PlayerDetail":{"properties":{"player_id":{"type":"string","title":"Player Id","description":"unique player identifier"},"name":{"type":"string","title":"Name"},"position":{"$ref":"#/components/schemas/Position"},"team":{"type":"string","title":"Team","description":"three-letter team abbreviation"},"number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Number"},"height":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Height"},"weight":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Weight"},"age":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Age"},"college":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"College"},"experience":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Experience","description":"years in NFL"},"headshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headshot Url"},"status":{"type":"string","title":"Status","description":"active / injured / suspended / free_agent","default":"active"},"birth_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Birth Date"},"draft_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Draft Year"},"draft_round":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Draft Round"},"draft_pick":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Draft Pick"},"injury_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Injury Status"},"injury_body_part":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Injury Body Part"},"bye_week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bye Week"},"fantasy_points_ytd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fantasy Points Ytd"},"next_opponent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Opponent"},"projections":{"items":{"$ref":"#/components/schemas/ProjectionLine"},"type":"array","title":"Projections"},"profile":{"anyOf":[{"$ref":"#/components/schemas/PlayerProfileNarrative"},{"type":"null"}]}},"type":"object","required":["player_id","name","position","team"],"title":"PlayerDetail","description":"full player profile."},"PlayerProfileNarrative":{"properties":{"body_html":{"type":"string","title":"Body Html"},"length_chars":{"type":"integer","title":"Length Chars"},"qa_verdict":{"type":"string","title":"Qa Verdict"},"profile_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Type"},"written_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Written At"}},"type":"object","required":["body_html","length_chars","qa_verdict"],"title":"PlayerProfileNarrative"},"PlayerStatsResponse":{"properties":{"player_id":{"type":"string","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"type":"string","title":"Position"},"team":{"type":"string","title":"Team"},"stat_lines":{"items":{"$ref":"#/components/schemas/WeeklyStatLine"},"type":"array","title":"Stat Lines"},"season_totals":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Season Totals"},"averages":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Averages"}},"type":"object","required":["player_id","name","position","team","stat_lines"],"title":"PlayerStatsResponse"},"Position":{"type":"string","enum":["QB","RB","WR","TE","K","DST","DL","LB","DB"],"title":"Position"},"PositionScarcity":{"properties":{"position":{"type":"string","title":"Position"},"points":{"items":{"$ref":"#/components/schemas/ScarcityPoint"},"type":"array","title":"Points"}},"type":"object","required":["position","points"],"title":"PositionScarcity"},"ProjectionLine":{"properties":{"season":{"type":"integer","title":"Season"},"week":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Week"},"format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Format","description":"PPR / HALF_PPR / STANDARD"},"scoringFormat":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scoringformat","description":"alias of format for camelCase consumers"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"projFantasyPts":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Projfantasypts"},"projPprPts":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Projpprpts","description":"only populated when this row is PPR; null for HALF_PPR/STANDARD rows"},"floor":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Floor"},"ceiling":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ceiling"},"confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Confidence"}},"type":"object","required":["season"],"title":"ProjectionLine"},"ReceivingStats":{"properties":{"targets":{"type":"integer","title":"Targets","default":0},"receptions":{"type":"integer","title":"Receptions","default":0},"yards":{"type":"integer","title":"Yards","default":0},"touchdowns":{"type":"integer","title":"Touchdowns","default":0},"yards_per_reception":{"type":"number","title":"Yards Per Reception","default":0.0},"longest":{"type":"integer","title":"Longest","default":0}},"type":"object","title":"ReceivingStats"},"RoundEntry":{"properties":{"round":{"type":"integer","title":"Round"},"picks_in_round":{"type":"integer","title":"Picks In Round"},"picks":{"items":{"$ref":"#/components/schemas/RoundPick"},"type":"array","title":"Picks"}},"type":"object","required":["round","picks_in_round","picks"],"title":"RoundEntry"},"RoundPick":{"properties":{"pick_in_round":{"type":"integer","title":"Pick In Round"},"overall_pick":{"type":"integer","title":"Overall Pick"},"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team_abbr":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team Abbr"},"headshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headshot Url"},"overall_rank":{"type":"integer","title":"Overall Rank"},"adp_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Adp Rank"},"adp_delta":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Adp Delta"},"tier_num":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tier Num"},"tier_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier Name"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"value_tag":{"type":"string","title":"Value Tag"},"format_sensitivity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Format Sensitivity"},"tier_break_alarm":{"type":"boolean","title":"Tier Break Alarm","default":false},"drivers":{"items":{"$ref":"#/components/schemas/DriverItem"},"type":"array","title":"Drivers"},"news":{"items":{"$ref":"#/components/schemas/NewsItem"},"type":"array","title":"News"}},"type":"object","required":["pick_in_round","overall_pick","player_id","name","overall_rank","value_tag","drivers"],"title":"RoundPick"},"RoundsMeta":{"properties":{"teams":{"type":"integer","title":"Teams"},"max_round":{"type":"integer","title":"Max Round"},"adp_is_fallback":{"type":"boolean","title":"Adp Is Fallback"},"include_news":{"type":"boolean","title":"Include News"}},"type":"object","required":["teams","max_round","adp_is_fallback","include_news"],"title":"RoundsMeta"},"RoundsResponse":{"properties":{"rounds":{"items":{"$ref":"#/components/schemas/RoundEntry"},"type":"array","title":"Rounds"},"meta":{"$ref":"#/components/schemas/RoundsMeta"}},"type":"object","required":["rounds","meta"],"title":"RoundsResponse"},"RtsRosterPaste":{"properties":{"players_text":{"type":"string","title":"Players Text"}},"type":"object","required":["players_text"],"title":"RtsRosterPaste"},"RushingStats":{"properties":{"carries":{"type":"integer","title":"Carries","default":0},"yards":{"type":"integer","title":"Yards","default":0},"touchdowns":{"type":"integer","title":"Touchdowns","default":0},"yards_per_carry":{"type":"number","title":"Yards Per Carry","default":0.0},"longest":{"type":"integer","title":"Longest","default":0},"fumbles":{"type":"integer","title":"Fumbles","default":0}},"type":"object","title":"RushingStats"},"SalaryCapBreakdown":{"properties":{"team_id":{"type":"string","title":"Team Id"},"team_name":{"type":"string","title":"Team Name"},"season":{"type":"integer","title":"Season"},"total_cap":{"type":"number","title":"Total Cap"},"cap_spent":{"type":"number","title":"Cap Spent"},"cap_remaining":{"type":"number","title":"Cap Remaining"},"dead_money":{"type":"number","title":"Dead Money"},"players":{"items":{"$ref":"#/components/schemas/SalaryCapEntry"},"type":"array","title":"Players"},"position_spending":{"additionalProperties":{"type":"number"},"type":"object","title":"Position Spending","description":"position -> total cap allocated"}},"type":"object","required":["team_id","team_name","season","total_cap","cap_spent","cap_remaining","dead_money","players"],"title":"SalaryCapBreakdown"},"SalaryCapEntry":{"properties":{"player_id":{"type":"string","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"type":"string","title":"Position"},"cap_hit":{"type":"number","title":"Cap Hit"},"base_salary":{"type":"number","title":"Base Salary"},"signing_bonus":{"type":"number","title":"Signing Bonus"},"dead_cap":{"type":"number","title":"Dead Cap"},"contract_years_remaining":{"type":"integer","title":"Contract Years Remaining"}},"type":"object","required":["player_id","name","position","cap_hit","base_salary","signing_bonus","dead_cap","contract_years_remaining"],"title":"SalaryCapEntry"},"ScarcityETA":{"properties":{"position":{"type":"string","title":"Position"},"starter_pool_size":{"type":"integer","title":"Starter Pool Size"},"starters_drafted":{"type":"integer","title":"Starters Drafted"},"exhausted_by_pick":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Exhausted By Pick"},"exhausted_by_round":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Exhausted By Round"},"callout":{"type":"string","title":"Callout"}},"type":"object","required":["position","starter_pool_size","starters_drafted","exhausted_by_pick","exhausted_by_round","callout"],"title":"ScarcityETA","description":"when starter-tier inventory at each position runs out.\n\nstarter_pool_size = teams * starters_per_slot\nexhausted_by_pick = overall pick number at which the LAST starter-tier\n                    player at this position is drafted (None if pool extends\n                    past the data we have)\nexhausted_by_round = round containing that pick\ncallout = human-readable summary for the sidebar"},"ScarcityHeatmapResponse":{"properties":{"scoring":{"type":"string","title":"Scoring"},"format":{"type":"string","title":"Format"},"teams":{"type":"integer","title":"Teams"},"rounds":{"items":{"$ref":"#/components/schemas/HeatmapRound"},"type":"array","title":"Rounds"},"eta":{"items":{"$ref":"#/components/schemas/ScarcityETA"},"type":"array","title":"Eta"},"methodology":{"type":"string","title":"Methodology"}},"type":"object","required":["scoring","format","teams","rounds","eta","methodology"],"title":"ScarcityHeatmapResponse"},"ScarcityPoint":{"properties":{"position_rank":{"type":"integer","title":"Position Rank"},"overall_rank":{"type":"integer","title":"Overall Rank"}},"type":"object","required":["position_rank","overall_rank"],"title":"ScarcityPoint"},"ScarcityResponse":{"properties":{"scoring":{"type":"string","title":"Scoring"},"positions":{"items":{"$ref":"#/components/schemas/PositionScarcity"},"type":"array","title":"Positions"}},"type":"object","required":["scoring","positions"],"title":"ScarcityResponse"},"ScheduleGame":{"properties":{"game_id":{"type":"string","title":"Game Id"},"week":{"type":"integer","title":"Week"},"home_team":{"type":"string","title":"Home Team"},"away_team":{"type":"string","title":"Away Team"},"date":{"type":"string","title":"Date"},"time":{"type":"string","title":"Time"},"venue":{"type":"string","title":"Venue"},"broadcast":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Broadcast"},"home_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Home Score"},"away_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Away Score"},"status":{"type":"string","title":"Status","description":"scheduled | in_progress | final","default":"scheduled"}},"type":"object","required":["game_id","week","home_team","away_team","date","time","venue"],"title":"ScheduleGame"},"ScheduleResponse":{"properties":{"season":{"type":"integer","title":"Season"},"week":{"type":"integer","title":"Week"},"games":{"items":{"$ref":"#/components/schemas/ScheduleGame"},"type":"array","title":"Games"}},"type":"object","required":["season","week","games"],"title":"ScheduleResponse"},"SeasonProjection":{"properties":{"player_id":{"type":"string","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"type":"string","title":"Position"},"team":{"type":"string","title":"Team"},"season":{"type":"integer","title":"Season"},"games_projected":{"type":"integer","title":"Games Projected"},"total_points":{"type":"number","title":"Total Points"},"floor":{"type":"number","title":"Floor"},"ceiling":{"type":"number","title":"Ceiling"},"per_game_avg":{"type":"number","title":"Per Game Avg"},"positional_rank":{"type":"integer","title":"Positional Rank"},"tier":{"type":"integer","title":"Tier"},"passing_yards":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Passing Yards"},"passing_tds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Passing Tds"},"rushing_yards":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rushing Yards"},"rushing_tds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rushing Tds"},"receptions":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Receptions"},"receiving_yards":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Receiving Yards"},"receiving_tds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Receiving Tds"},"scoring":{"type":"string","title":"Scoring","default":"ppr"},"risk_level":{"type":"string","title":"Risk Level","description":"low | medium | high","default":"medium"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["player_id","name","position","team","season","games_projected","total_points","floor","ceiling","per_game_avg","positional_rank","tier"],"title":"SeasonProjection"},"SleeperPlayer":{"properties":{"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"composite_rank":{"type":"integer","title":"Composite Rank"},"adp_rank":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Adp Rank"},"gap":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Gap"}},"type":"object","required":["player_id","name","composite_rank"],"title":"SleeperPlayer"},"SleepersResponse":{"properties":{"count":{"type":"integer","title":"Count"},"players":{"items":{"$ref":"#/components/schemas/SleeperPlayer"},"type":"array","title":"Players"}},"type":"object","required":["count","players"],"title":"SleepersResponse"},"SourceInfo":{"properties":{"id":{"type":"integer","title":"Id"},"slug":{"type":"string","title":"Slug"},"name":{"type":"string","title":"Name"},"site":{"type":"string","title":"Site"},"type":{"type":"string","title":"Type"},"scoring":{"type":"string","title":"Scoring"},"format":{"type":"string","title":"Format"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"last_pulled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Pulled At"},"last_success_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Success At"},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"},"weight":{"type":"number","title":"Weight"},"accuracy_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Accuracy Score"},"is_active":{"type":"boolean","title":"Is Active"}},"type":"object","required":["id","slug","name","site","type","scoring","format","weight","is_active"],"title":"SourceInfo"},"SourcesResponse":{"properties":{"count":{"type":"integer","title":"Count"},"sources":{"items":{"$ref":"#/components/schemas/SourceInfo"},"type":"array","title":"Sources"}},"type":"object","required":["count","sources"],"title":"SourcesResponse"},"StickinessSlice":{"properties":{"sticky_r":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sticky R"},"predictive_r":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Predictive R"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},"type":"object","title":"StickinessSlice","description":"year-over-year correlation slice attached to each driver chip.\n\nsurfaces the predictive vs sticky-only vs noisy distinction so the ui\ncan warn users when an \"advanced\" stat is style-only and not a true\nforecast signal. populated from backend/app/data/metric_stickiness.json."},"SubscribeRequest":{"properties":{"email":{"type":"string","title":"Email"}},"type":"object","required":["email"],"title":"SubscribeRequest"},"SubscribeResponse":{"properties":{"message":{"type":"string","title":"Message"},"email":{"type":"string","title":"Email"}},"type":"object","required":["message","email"],"title":"SubscribeResponse"},"SubscriberMetrics":{"properties":{"total_users":{"type":"integer","title":"Total Users"},"free_users":{"type":"integer","title":"Free Users"},"pro_users":{"type":"integer","title":"Pro Users"},"mrr":{"type":"number","title":"Mrr","description":"monthly recurring revenue"},"churn_rate_30d":{"type":"number","title":"Churn Rate 30D"},"new_signups_7d":{"type":"integer","title":"New Signups 7D"},"active_users_24h":{"type":"integer","title":"Active Users 24H"},"top_endpoints":{"items":{"type":"object"},"type":"array","title":"Top Endpoints"}},"type":"object","required":["total_users","free_users","pro_users","mrr","churn_rate_30d","new_signups_7d","active_users_24h","top_endpoints"],"title":"SubscriberMetrics"},"SubscriptionTier":{"type":"string","enum":["FREE","SPIDER_MONKEY","ORANGUTAN","SILVERBACK","ADMIN"],"title":"SubscriptionTier"},"TeamArticleSummary":{"properties":{"id":{"type":"string","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"excerpt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Excerpt"},"cover_image":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Image"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"published_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Published At"}},"type":"object","required":["id","slug","title"],"title":"TeamArticleSummary"},"TeamDashboard":{"properties":{"team":{"$ref":"#/components/schemas/TeamInfo"},"roster":{"items":{"$ref":"#/components/schemas/TeamRosterPlayer"},"type":"array","title":"Roster"},"coaching_staff":{"additionalProperties":{"$ref":"#/components/schemas/CoachingStaffEntry"},"type":"object","title":"Coaching Staff"},"offensive_rank":{"type":"integer","title":"Offensive Rank"},"defensive_rank":{"type":"integer","title":"Defensive Rank"},"points_per_game":{"type":"number","title":"Points Per Game"},"points_allowed_per_game":{"type":"number","title":"Points Allowed Per Game"},"yards_per_game":{"type":"number","title":"Yards Per Game"},"recent_results":{"items":{"type":"string"},"type":"array","title":"Recent Results","description":"last 5 game results e.g. ['W 27-20', 'L 14-21']"},"upcoming_opponent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Upcoming Opponent"},"bye_week":{"type":"integer","title":"Bye Week"},"bye_week_season":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bye Week Season"},"turnover_diff":{"type":"integer","title":"Turnover Diff","default":0},"key_stats":{"type":"object","title":"Key Stats"},"snapshot":{"anyOf":[{"$ref":"#/components/schemas/TeamSnapshotNarrative"},{"type":"null"}]},"top_fantasy_assets":{"items":{"$ref":"#/components/schemas/TopFantasyAsset"},"type":"array","title":"Top Fantasy Assets"},"team_articles":{"items":{"$ref":"#/components/schemas/TeamArticleSummary"},"type":"array","title":"Team Articles"},"articles_total":{"type":"integer","title":"Articles Total","default":0},"storylines":{"items":{"$ref":"#/components/schemas/TeamStoryline"},"type":"array","title":"Storylines"}},"type":"object","required":["team","roster","offensive_rank","defensive_rank","points_per_game","points_allowed_per_game","yards_per_game","recent_results","bye_week"],"title":"TeamDashboard"},"TeamInfo":{"properties":{"team_id":{"type":"string","title":"Team Id"},"name":{"type":"string","title":"Name"},"abbreviation":{"type":"string","title":"Abbreviation"},"conference":{"type":"string","title":"Conference"},"division":{"type":"string","title":"Division"},"record":{"type":"string","title":"Record"},"logo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Logo Url"}},"type":"object","required":["team_id","name","abbreviation","conference","division","record"],"title":"TeamInfo"},"TeamMatchupPreview":{"properties":{"team":{"type":"string","title":"Team"},"record":{"type":"string","title":"Record"},"points_per_game":{"type":"number","title":"Points Per Game"},"yards_per_game":{"type":"number","title":"Yards Per Game"},"key_injuries":{"items":{"type":"string"},"type":"array","title":"Key Injuries"}},"type":"object","required":["team","record","points_per_game","yards_per_game","key_injuries"],"title":"TeamMatchupPreview"},"TeamRosterPlayer":{"properties":{"player_id":{"type":"string","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"type":"string","title":"Position"},"number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Number"},"status":{"type":"string","title":"Status","default":"active"},"injury_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Injury Status"}},"type":"object","required":["player_id","name","position"],"title":"TeamRosterPlayer"},"TeamSnapshotNarrative":{"properties":{"body_html":{"type":"string","title":"Body Html"},"length_chars":{"type":"integer","title":"Length Chars"},"qa_verdict":{"type":"string","title":"Qa Verdict"},"written_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Written At"}},"type":"object","required":["body_html","length_chars","qa_verdict"],"title":"TeamSnapshotNarrative"},"TeamStoryline":{"properties":{"title":{"type":"string","title":"Title"},"body":{"type":"string","title":"Body"},"source":{"type":"string","title":"Source"},"source_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Label"}},"type":"object","required":["title","body","source"],"title":"TeamStoryline"},"TierBreakSummary":{"properties":{"position":{"type":"string","title":"Position"},"tier_num":{"type":"integer","title":"Tier Num"},"tier_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier Label"},"count":{"type":"integer","title":"Count"},"first_overall":{"type":"integer","title":"First Overall"},"last_overall":{"type":"integer","title":"Last Overall"},"first_position_rank":{"type":"integer","title":"First Position Rank"},"last_position_rank":{"type":"integer","title":"Last Position Rank"},"next_tier_starts_at":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Tier Starts At"},"players":{"items":{"type":"string"},"type":"array","title":"Players"}},"type":"object","required":["position","tier_num","count","first_overall","last_overall","first_position_rank","last_position_rank","players"],"title":"TierBreakSummary","description":"one position-tier summary row for the /tier-breaks endpoint.\n\nfields:\n    position:              QB / RB / WR / TE\n    tier_num:              integer tier within the position (1 = best)\n    tier_label:            ranking_tier enum string (SMASH_START, SOLID, ...)\n    count:                 how many players are in this tier\n    first_overall:         lowest overall_rank (across all positions) of any\n                           player in this position-tier; useful for \"earliest\n                           this tier comes off the board\" decisions\n    last_overall:          highest overall_rank of any player in the tier\n                           (the tier-break alarm threshold)\n    first_position_rank:   position_rank of the first (best) player in the tier\n    last_position_rank:    position_rank of the last player in the tier\n    next_tier_starts_at:   overall_rank of the first player in the NEXT tier\n                           at this position (None if no next tier exists yet)\n    players:               ordered list of player names within the tier"},"TierBreaksResponse":{"properties":{"scoring":{"type":"string","title":"Scoring"},"format":{"type":"string","title":"Format"},"tiers":{"items":{"$ref":"#/components/schemas/TierBreakSummary"},"type":"array","title":"Tiers"}},"type":"object","required":["scoring","format","tiers"],"title":"TierBreaksResponse"},"TierGroup":{"properties":{"tier_number":{"type":"integer","title":"Tier Number"},"tier_label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier Label"},"avg_rank":{"type":"number","title":"Avg Rank"},"players_count":{"type":"integer","title":"Players Count"},"players":{"items":{"$ref":"#/components/schemas/TierGroupPlayer"},"type":"array","title":"Players"}},"type":"object","required":["tier_number","avg_rank","players_count","players"],"title":"TierGroup"},"TierGroupPlayer":{"properties":{"player_id":{"type":"integer","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"overall_rank":{"type":"integer","title":"Overall Rank"},"position_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position Rank"}},"type":"object","required":["player_id","name","overall_rank"],"title":"TierGroupPlayer"},"TiersResponse":{"properties":{"scoring":{"type":"string","title":"Scoring"},"format":{"type":"string","title":"Format"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"tiers":{"items":{"$ref":"#/components/schemas/TierGroup"},"type":"array","title":"Tiers"}},"type":"object","required":["scoring","format","tiers"],"title":"TiersResponse"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"type":"string","title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["access_token","refresh_token","expires_in"],"title":"TokenResponse"},"TopFantasyAsset":{"properties":{"player_id":{"type":"string","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"type":"string","title":"Position"},"jersey_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Jersey Number"},"headshot_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Headshot Url"},"overall_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Overall Rank"},"position_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Position Rank"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"projected_pts":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Projected Pts"}},"type":"object","required":["player_id","name","position"],"title":"TopFantasyAsset"},"UniversalRosterInput":{"properties":{"roster_text":{"type":"string","minLength":3,"title":"Roster Text","description":"pasted roster text in any format — csv, tsv, pipe-delimited, or freeform one-player-per-line"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform","description":"source platform name (e.g. 'myfantasyleague', 'rtssports', 'fleaflicker'). optional — used for tracking only"},"league_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"League Id","description":"optional league id from the source platform"}},"type":"object","required":["roster_text"],"title":"UniversalRosterInput","description":"request body for universal roster import."},"UserCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","maxLength":128,"minLength":8,"title":"Password"},"display_name":{"type":"string","maxLength":64,"minLength":1,"title":"Display Name"}},"type":"object","required":["email","password","display_name"],"title":"UserCreate"},"UserLogin":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","minLength":1,"title":"Password"}},"type":"object","required":["email","password"],"title":"UserLogin"},"UserProfile":{"properties":{"user_id":{"type":"string","title":"User Id"},"email":{"type":"string","title":"Email"},"display_name":{"type":"string","title":"Display Name"},"tier":{"$ref":"#/components/schemas/SubscriptionTier"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"stripe_customer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Customer Id"},"subscription_active":{"type":"boolean","title":"Subscription Active","default":false},"subscription_end":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Subscription End"}},"type":"object","required":["user_id","email","display_name","tier","created_at"],"title":"UserProfile"},"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"},"WaiverTargetRequest":{"properties":{"season":{"type":"integer","title":"Season","default":2025},"week":{"type":"integer","title":"Week","default":18},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position","description":"filter to QB, RB, WR, TE"}},"type":"object","title":"WaiverTargetRequest"},"WeeklyMatchups":{"properties":{"week":{"type":"integer","title":"Week"},"season":{"type":"integer","title":"Season"},"matchups":{"items":{"$ref":"#/components/schemas/MatchupPreview"},"type":"array","title":"Matchups"}},"type":"object","required":["week","season","matchups"],"title":"WeeklyMatchups"},"WeeklyOddsResponse":{"properties":{"week":{"type":"integer","title":"Week"},"season":{"type":"integer","title":"Season"},"games":{"items":{"$ref":"#/components/schemas/GameOdds"},"type":"array","title":"Games"},"source":{"type":"string","title":"Source","default":"consensus"}},"type":"object","required":["week","season","games"],"title":"WeeklyOddsResponse"},"WeeklyProjection":{"properties":{"player_id":{"type":"string","title":"Player Id"},"name":{"type":"string","title":"Name"},"position":{"type":"string","title":"Position"},"team":{"type":"string","title":"Team"},"week":{"type":"integer","title":"Week"},"opponent":{"type":"string","title":"Opponent"},"projected_points":{"type":"number","title":"Projected Points"},"floor":{"type":"number","title":"Floor","description":"10th-percentile outcome"},"ceiling":{"type":"number","title":"Ceiling","description":"90th-percentile outcome"},"confidence":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Confidence","description":"model confidence 0-1"},"passing_yards":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Passing Yards"},"passing_tds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Passing Tds"},"rushing_yards":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rushing Yards"},"rushing_tds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Rushing Tds"},"receptions":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Receptions"},"receiving_yards":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Receiving Yards"},"receiving_tds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Receiving Tds"},"scoring":{"type":"string","title":"Scoring","default":"ppr"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["player_id","name","position","team","week","opponent","projected_points","floor","ceiling","confidence"],"title":"WeeklyProjection"},"WeeklyStatLine":{"properties":{"week":{"type":"integer","title":"Week"},"season":{"type":"integer","title":"Season"},"opponent":{"type":"string","title":"Opponent"},"passing":{"anyOf":[{"$ref":"#/components/schemas/PassingStats"},{"type":"null"}]},"rushing":{"anyOf":[{"$ref":"#/components/schemas/RushingStats"},{"type":"null"}]},"receiving":{"anyOf":[{"$ref":"#/components/schemas/ReceivingStats"},{"type":"null"}]},"kicking":{"anyOf":[{"$ref":"#/components/schemas/KickingStats"},{"type":"null"}]},"defense":{"anyOf":[{"$ref":"#/components/schemas/DefenseStats"},{"type":"null"}]},"fantasy_points":{"type":"number","title":"Fantasy Points","default":0.0},"snap_pct":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Snap Pct"}},"type":"object","required":["week","season","opponent"],"title":"WeeklyStatLine"},"YahooManualImportRequest":{"properties":{"players":{"items":{"$ref":"#/components/schemas/YahooPlayerEntry"},"type":"array","title":"Players"},"league_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"League Name"},"team_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team Name"},"league_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"League Id"}},"type":"object","required":["players"],"title":"YahooManualImportRequest","description":"request body for manual yahoo roster import."},"YahooPlayerEntry":{"properties":{"name":{"type":"string","title":"Name"},"position":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Position"},"yahoo_player_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Yahoo Player Id"},"team":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Team"},"slot":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slot"}},"type":"object","required":["name"],"title":"YahooPlayerEntry","description":"a single player for manual roster import."}}},"tags":[{"name":"auth","description":"registration, login, token management"},{"name":"dashboard","description":"aggregated dashboard data"},{"name":"players","description":"player profiles, stats, comparisons"},{"name":"rankings","description":"weekly positional rankings"},{"name":"projections","description":"weekly and season-long projections"},{"name":"matchups","description":"game matchup analysis"},{"name":"tools","description":"trade analyzer, start/sit, waiver ranker, DFS"},{"name":"articles","description":"AI-generated analysis articles"},{"name":"alerts","description":"custom player/team alerts"},{"name":"draft","description":"draft rankings and ADP (preseason)"},{"name":"teams","description":"team dashboards, salary cap, schedule, live scores"},{"name":"odds","description":"betting lines and odds"},{"name":"trends","description":"player usage and performance trends"},{"name":"reports","description":"downloadable PDF reports"},{"name":"forge","description":"ForgeStat AI analytics (SSE streaming)"},{"name":"news","description":"automated NFL news pipeline with analysis context"},{"name":"newsletter","description":"email newsletter subscriptions"},{"name":"admin","description":"admin-only pipeline and subscriber management"},{"name":"leagues","description":"league import from Sleeper"},{"name":"draft-monkeys","description":"Draft Monkeys league import"},{"name":"espn","description":"ESPN Fantasy Football league import"},{"name":"yahoo","description":"Yahoo Fantasy Football league import"},{"name":"mfl","description":"MyFantasyLeague (MFL) league import"},{"name":"rtsports","description":"RTSports league import"},{"name":"cbs-sports","description":"CBS Sports Fantasy league import"},{"name":"nfl-fantasy","description":"NFL.com Fantasy league import"},{"name":"fantrax","description":"Fantrax Fantasy league import"},{"name":"universal-import","description":"Universal manual roster import — any platform"},{"name":"fleaflicker","description":"Fleaflicker Fantasy league import"},{"name":"search","description":"global search aggregator (header search bar)"}]}