Football Data
Setup
Before first use, check if the CLI is available:
which sports-skills || pip install sports-skills
If
pip install fails (package not found or Python version error), install from GitHub:
pip install git+https://github.com/machina-sports/sports-skills.git
The package requires Python 3.10+. If your default Python is older, use a specific version:
python3 --version # check version
# If < 3.10, try: python3.12 -m pip install sports-skills
# On macOS with Homebrew: /opt/homebrew/bin/python3.12 -m pip install sports-skills
No API keys required.
Quick Start
Prefer the CLI — it avoids Python import path issues:
CODEBLOCK3
Python SDK (alternative):
CODEBLOCK4
Choosing the Season
Derive the current year from the system prompt's date (e.g., currentDate: 2026-02-16 → current year is 2026).
- - If the user specifies a season, use it as-is.
- If the user says "current", "latest", or doesn't specify: Call
get_current_season(competition_id="...") to get the active seasonid. Do NOT guess or hardcode the year. - Season format: Always
{league-slug}-{year} (e.g., "premier-league-2025" for the 2025-26 season). The year is the start year of the season, not the end year. - MLS exception: MLS runs spring-fall within a single calendar year. Use
get_current_season(competition_id="mls") — don't assume MLS follows European calendar. - Never hardcode a seasonid. Always derive it via
get_current_season() or from the system date.
Data Coverage by League
Not all data is available for every league. Use the right command for the right league.
| Command | All 13 leagues | Top 5 only | PL only |
|---|
| getseasonstandings | x | | |
| getdailyschedule |
x | | |
| get
seasonschedule | x | | |
| get
seasonteams | x | | |
| search_team | x | | |
| get
teamschedule | x | | |
| get
teamprofile | x | | |
| get
eventsummary | x | | |
| get
eventlineups | x | | |
| get
eventstatistics | x | | |
| get
eventtimeline | x | | |
| get
currentseason | x | | |
| get_competitions | x | | |
| get
eventxg | | x | |
| get
eventplayers_statistics (with xG) | | x | |
| get
seasonleaders | | | x |
| get
missingplayers | | | x |
Top 5 leagues (Understat): EPL, La Liga, Bundesliga, Serie A, Ligue 1.
PL only (FPL): Premier League — injury news, player stats, ownership, ICT index.
All leagues: via ESPN — scores, standings, schedules, match summaries, lineups, team stats.
Transfermarkt: Works for any player with a tm_player_id — market values and transfer history.
Note: MLS uses a different season structure (spring-fall calendar). Use get_current_season(competition_id="mls") to detect the right season_id.
ID Conventions
- - seasonid:
{league-slug}-{year} e.g. "premier-league-2025", INLINECODE11 - competitionid: league slug e.g.
"premier-league", "serie-a", INLINECODE14 - teamid: ESPN team ID (numeric string) e.g.
"359" (Arsenal), "86" (Real Madrid) - eventid: ESPN event ID (numeric string) e.g. INLINECODE17
- fplid: FPL element ID or code (PL players only)
- tmplayer_id: Transfermarkt player ID e.g.
"433177" (Saka), "342229" (Mbappe)
Commands
getcurrentseason
Detect current season for a competition. Works for all leagues.
- -
competition_id (str, required): Competition slug
Returns data.competition and data.season:
CODEBLOCK5
get_competitions
List available competitions with current season info. No params. Works for all leagues.
Returns data.competitions[] with id, name, code, current_season.
getcompetitionseasons
Get available seasons for a competition. Works for all leagues.
- -
competition_id (str, required): Competition slug
getseasonschedule
Get full season match schedule. Works for all leagues.
- -
season_id (str, required): Season slug (e.g., "premier-league-2025")
Returns data.schedules[] — same shape as events below.
getseasonstandings
Get league table for a season. Works for all leagues.
- -
season_id (str, required): Season slug
Returns data.standings[].entries[]:
CODEBLOCK6
getseasonleaders
Get top scorers/leaders for a season.
Premier League only (via FPL).
- -
season_id (str, required): Season slug (must be premier-league-*)
Returns data.leaders[] — note: player name is nested under .player.name:
{
"player": {"id": "223094", "name": "Erling Haaland", "first_name": "Erling", "last_name": "Haaland", "position": "Forward"},
"team": {"id": "43", "name": "Man City"},
"goals": 22, "assists": 6, "penalties": 0, "played_matches": 25
}
Returns empty for non-PL leagues.
getseasonteams
Get teams in a season. Works for all leagues.
- -
season_id (str, required): Season slug
search_team
Search for a team by name across all leagues (or a specific one). Uses fuzzy matching.
- -
query (str, required): Team name to search (e.g., "Corinthians", "Barcelona", "Man Utd") - INLINECODE39 (str, optional): Limit search to one league (e.g., "serie-a-brazil", "premier-league")
Returns data.results[] with team, competition, and season for each match:
CODEBLOCK8
getteamprofile
Get basic team info (name, crest, venue).
Does not return squad/roster — use
get_season_leaders to find PL player IDs, then
get_player_profile for individual player data.
- -
team_id (str, required): ESPN team ID - INLINECODE47 (str, optional): League hint (faster resolution)
Returns data.team and data.venue. data.players[] is empty — see "Deep dive on a PL team" example below for the recommended workflow.
getdailyschedule
Get all matches for a specific date across all leagues.
- -
date (str, optional): Date in YYYY-MM-DD format. Defaults to today.
Returns data.date and data.events[]:
{
"id": "748381", "status": "not_started", "start_time": "2026-02-16T20:00Z",
"competition": {"id": "la-liga", "name": "La Liga"},
"season": {"id": "la-liga-2025", "year": "2025"},
"venue": {"name": "Estadi Montilivi", "city": "Girona"},
"competitors": [
{"team": {"id": "9812", "name": "Girona", "abbreviation": "GIR"}, "qualifier": "home", "score": 0},
{"team": {"id": "83", "name": "Barcelona", "abbreviation": "BAR"}, "qualifier": "away", "score": 0}
],
"scores": {"home": 0, "away": 0}
}
Status values:
"not_started",
"live",
"halftime",
"closed",
"postponed".
geteventsummary
Get match summary with scores. Works for all leagues.
- -
event_id (str, required): Match/event ID
Returns data.event (same shape as daily schedule events).
geteventlineups
Get match lineups. Works for all leagues (when available from ESPN).
- -
event_id (str, required): Match/event ID
Returns data.lineups[]:
CODEBLOCK10
geteventstatistics
Get match team statistics. Works for all leagues.
- -
event_id (str, required): Match/event ID
Returns data.teams[]:
CODEBLOCK11
geteventtimeline
Get match timeline/key events (goals, cards, substitutions). Works for all leagues.
- -
event_id (str, required): Match/event ID
Returns data.timeline[] with goal, card, and substitution events.
getteamschedule
Get schedule for a specific team — includes both past results and upcoming fixtures. Works for all leagues.
- -
team_id (str, required): ESPN team ID - INLINECODE68 (str, optional): League hint (faster resolution)
- INLINECODE69 (str, optional): Season year filter
- INLINECODE70 (str, optional): Filter results to a single competition (e.g., "serie-a-brazil", "premier-league")
getheadto_head
UNAVAILABLE — requires licensed data. Do not call this command; it will return empty results. Instead, use
get_team_schedule for both teams and filter overlapping matches manually.
- -
team_id (str, required): First team ID - INLINECODE73 (str, required): Second team ID
geteventxg
Get expected goals (xG) data from Understat.
Top 5 leagues only: EPL, La Liga, Bundesliga, Serie A, Ligue 1. Returns empty for other leagues.
- -
event_id (str, required): Match/event ID
Returns data.teams[] and data.shots[]:
{"team": {"id": "244", "name": "Brentford"}, "qualifier": "home", "xg": 1.812}
data.shots[] contains individual shot data with xG per shot. Note: very recent matches (last 24-48h) may not be indexed on Understat yet.
geteventplayers_statistics
Get player-level match statistics with xG enrichment. Works for all leagues (basic stats from ESPN). xG/xA enrichment only for top 5 leagues (Understat).
- -
event_id (str, required): Match/event ID
Returns data.teams[].players[]:
{
"id": "...", "name": "Bukayo Saka", "position": "Midfielder", "shirt_number": 7, "starter": true,
"statistics": {"appearances": "1", "shotsTotal": "3", "shotsOnTarget": "1", "foulsCommitted": "1", "xg": "0.45", "xa": "0.12"}
}
xg and
xa fields only present for top 5 leagues.
getmissingplayers
Get injured/missing/doubtful players.
Premier League only (via FPL). Returns empty for other leagues.
- -
season_id (str, required): Season slug (must be premier-league-*)
Returns data.teams[].players[]:
{
"id": "463748", "name": "Mikel Merino Zazón", "web_name": "Merino",
"position": "Midfielder", "status": "injured",
"news": "Foot injury - Unknown return date",
"chance_of_playing_this_round": 0, "chance_of_playing_next_round": 0
}
Status values:
"injured",
"unavailable",
"doubtful",
"suspended".
getseasontransfers
Get transfer history for specific players via Transfermarkt. Works for any league.
- -
season_id (str, required): Season slug (used to filter transfers by year) - INLINECODE90 (list, required): Transfermarkt player IDs
Returns data.transfers[]:
CODEBLOCK15
getplayerseason_stats
Get player season stats via ESPN overview endpoint. Works for any league with ESPN athlete IDs.
- -
player_id (str, required): ESPN athlete ID - INLINECODE93 (str, optional): League slug hint (e.g., "eng.1", "esp.1"). Defaults to auto-detect.
Returns season stats (goals, assists, appearances, etc.) and game log when available.
getplayerprofile
Get player profile. Works for any player if you have their Transfermarkt or FPL ID. At least one ID required.
- -
fpl_id (str, optional): FPL player ID (PL players only) - INLINECODE95 (str, optional): Transfermarkt player ID (any league)
With tm_player_id, returns data.player with:
CODEBLOCK16
With fpl_id, also includes data.player.fpl_data with FPL stats (points, form, ICT index, ownership, etc.).
Supported Leagues
Premier League, La Liga, Bundesliga, Serie A, Ligue 1, MLS, Championship, Eredivisie, Primeira Liga, Serie A Brazil, Champions League, European Championship, World Cup.
Data Sources
| Source | What it provides | League coverage |
|---|
| ESPN | Scores, standings, schedules, lineups, match stats, timelines | All 13 leagues |
| openfootball |
Schedules, standings, team lists (fallback when ESPN is down) | 10 leagues (all except CL, Euros, World Cup) |
| Understat | xG per match, xG per shot, player xG/xA | Top 5 (EPL, La Liga, Bundesliga, Serie A, Ligue 1) |
| FPL | Top scorers, injuries, player stats, ownership | Premier League only |
| Transfermarkt | Market values, transfer history | Any player (requires tm
playerid) |
For licensed data with full coverage across all sports (Sportradar, Opta, Genius Sports), see Machina Sports.
Examples
User: "Show me the Premier League table"
- 1. Call
get_current_season(competition_id="premier-league") to get the current season_id - Call INLINECODE101
- Present standings table with position, team, played, won, drawn, lost, GD, points
User: "How did Arsenal vs Liverpool go?"
- 1. Call
get_daily_schedule() or get_team_schedule(team_id="359") to find the event_id - Call
get_event_summary(event_id="...") for the score - Call
get_event_statistics(event_id="...") for possession, shots, etc. - Call
get_event_xg(event_id="...") for xG comparison (EPL — top 5 only) - Present match report with scores, key stats, and xG
User: "Deep dive on Chelsea's recent form"
- 1. Call
search_team(query="Chelsea") → team_id=363, competition=premier-league - Call
get_team_schedule(team_id="363", competition_id="premier-league") → find recent closed events - For each recent match, call in parallel:
-
get_event_xg(event_id="...") for xG comparison and shot map
-
get_event_statistics(event_id="...") for possession, shots, passes
-
get_event_players_statistics(event_id="...") for individual player xG/xA
- 4. Call
get_missing_players(season_id=<season_id>) → filter Chelsea's injured/doubtful players - Call
get_season_leaders(season_id=<season_id>) → filter Chelsea players, get their FPL IDs - Call
get_player_profile(fpl_id="...", tm_player_id="...") for key players — combine FPL stats (form, ownership, ICT) with Transfermarkt data (market value, transfer history) - Present: xG trend across matches, key player stats, injury report, market values
User: "What's Saka's market value?"
- 1. Call
get_player_profile(tm_player_id="433177") for Transfermarkt data - Optionally add
fpl_id for FPL stats if Premier League player - Present market value, value history, and transfer history
User: "Tell me about Corinthians"
- 1. Call
search_team(query="Corinthians") → team_id=874, competition=serie-a-brazil - Call
get_team_schedule(team_id="874", competition_id="serie-a-brazil") for fixtures - Pick a recent match and call
get_event_timeline(event_id="...") for goals, cards, subs - Note: xG, FPL stats, and season leaders are NOT available for Brazilian Serie A
Error Handling
When a command fails (wrong event_id, missing data, network error, etc.), do not surface the raw error to the user. Instead:
- 1. Catch it silently — treat the failure as an exploratory miss, not a fatal error.
- Try alternatives — e.g., if an event_id returns no data, call
get_daily_schedule() or get_team_schedule() to discover the correct ID. If ESPN is down, openfootball data may still be available via get_season_standings or get_season_schedule. - Only report failure after exhausting alternatives — and when you do, give a clean human-readable message (e.g., "I couldn't find that match — can you confirm the teams or date?"), not a traceback or raw CLI output.
This is especially important when the agent is responding through messaging platforms (Telegram, Slack, etc.) where raw exec failures look broken.
Common Mistakes
These are the ONLY valid commands. Do not invent or guess command names:
- - INLINECODE124
- INLINECODE125
- INLINECODE126
- INLINECODE127
- INLINECODE128
- INLINECODE129
- INLINECODE130
- INLINECODE131
- INLINECODE132
- INLINECODE133
- INLINECODE134
- INLINECODE135
- INLINECODE136
- INLINECODE137
- INLINECODE138
- INLINECODE139
- INLINECODE140
- INLINECODE141
- INLINECODE142
- INLINECODE143
- INLINECODE144
- INLINECODE145
Commands that DO NOT exist (commonly hallucinated):
- - ~~
get_standings~~ — the correct command is get_season_standings (requires season_id). - ~~
get_live_scores~~ — not available. Use get_daily_schedule() for today's matches; status field shows "live" for in-progress games. - ~~
get_team_squad~~ / ~~get_team_roster~~ — get_team_profile does NOT return players. Use get_season_leaders for PL player IDs, then get_player_profile for individual data. - ~~
get_transfers~~ — the correct command is get_season_transfers (requires season_id + tm_player_ids). - ~~
get_match_results~~ / ~~get_match~~ — use get_event_summary with an event_id. - ~~
get_player_stats~~ — use get_event_players_statistics for match-level stats, or get_player_profile for career data.
Other common mistakes:
- - Using
get_season_leaders or get_missing_players on non-PL leagues — they return empty. Check the Data Coverage table. - Using
get_event_xg on leagues outside the top 5 — returns empty. Only works for EPL, La Liga, Bundesliga, Serie A, Ligue 1. - Guessing
team_id or event_id instead of discovering them via search_team, get_daily_schedule, or get_season_schedule.
If you're unsure whether a command exists, check this list. Do not try commands that aren't listed above.
Troubleshooting
- -
sports-skills command not found: Package not installed. Run pip install sports-skills. If the package is not found on PyPI, install from GitHub: pip install git+https://github.com/machina-sports/sports-skills.git. Requires Python 3.10+ — see Setup section. ModuleNotFoundError: No module named 'sports_skills': Same as above — install the package. Prefer the CLI over Python imports to avoid path issues.- Empty results for PL-only commands on other leagues:
get_season_leaders and get_missing_players only return data for Premier League. They silently return empty for other leagues — check the Data Coverage table. get_team_profile returns empty players: This is expected — squad rosters are not available. To get player data for a PL team, use get_season_leaders to find players and their FPL IDs, then get_player_profile(fpl_id="...") for detailed stats. For Transfermarkt data, you need the player's tm_player_id.- Finding FPL IDs and Transfermarkt IDs: Use
get_season_leaders(season_id="premier-league-2025") to discover FPL IDs for PL players. Transfermarkt IDs must be looked up on transfermarkt.com — the ID is the number at the end of the player's URL. Well-known examples: Cole Palmer = 568177, Bukayo Saka = 433177, Mbappe = 342229. - No xG for recent matches: Understat data may lag 24-48 hours after a match ends. If
get_event_xg returns empty for a recent top-5 match, try again later. - Wrong seasonid format: Must be
{league-slug}-{year} e.g. "premier-league-2025". Not "2025-2026", not "EPL-2025". Use get_current_season() to discover the correct format. - Team/event IDs unknown: Use
search_team(query="team name") to find team IDs by name, or get_season_teams to list all teams in a season. Use get_daily_schedule or get_season_schedule to find event IDs. IDs are ESPN numeric strings.
足球数据
安装设置
首次使用前,检查CLI是否可用:
bash
which sports-skills || pip install sports-skills
如果pip install失败(包未找到或Python版本错误),从GitHub安装:
bash
pip install git+https://github.com/machina-sports/sports-skills.git
该包需要Python 3.10+。如果默认Python版本较旧,请使用特定版本:
bash
python3 --version # 检查版本
如果 < 3.10,尝试:python3.12 -m pip install sports-skills
在macOS上使用Homebrew:/opt/homebrew/bin/python3.12 -m pip install sports-skills
无需API密钥。
快速开始
推荐使用CLI——可避免Python导入路径问题:
bash
sports-skills football getdailyschedule
sports-skills football getseasonstandings --season_id=premier-league-2025
Python SDK(备选方案):
python
from sports_skills import football
standings = football.getseasonstandings(season_id=premier-league-2025)
schedule = football.getdailyschedule()
选择赛季
从系统提示的日期中推导当前年份(例如,currentDate: 2026-02-16 → 当前年份为2026)。
- - 如果用户指定了赛季,直接使用。
- 如果用户说当前、最新或未指定:调用getcurrentseason(competitionid=...)获取当前活跃的seasonid。不要猜测或硬编码年份。
- 赛季格式:始终为{联赛-slug}-{年份}(例如,2025-26赛季为premier-league-2025)。年份是赛季的起始年份,而非结束年份。
- MLS例外:MLS在一个自然年内进行春季-秋季赛程。使用getcurrentseason(competitionid=mls)——不要假设MLS遵循欧洲赛历。
- 切勿硬编码seasonid。始终通过getcurrentseason()或系统日期推导。
联赛数据覆盖范围
并非所有数据都适用于每个联赛。请为正确的联赛使用正确的命令。
| 命令 | 全部13个联赛 | 仅前5大联赛 | 仅英超 |
|---|
| getseasonstandings | x | | |
| getdailyschedule |
x | | |
| get
seasonschedule | x | | |
| get
seasonteams | x | | |
| search_team | x | | |
| get
teamschedule | x | | |
| get
teamprofile | x | | |
| get
eventsummary | x | | |
| get
eventlineups | x | | |
| get
eventstatistics | x | | |
| get
eventtimeline | x | | |
| get
currentseason | x | | |
| get_competitions | x | | |
| get
eventxg | | x | |
| get
eventplayers_statistics (含xG) | | x | |
| get
seasonleaders | | | x |
| get
missingplayers | | | x |
前5大联赛(Understat):英超、西甲、德甲、意甲、法甲。
仅英超(FPL):英超——伤病新闻、球员数据、所有权、ICT指数。
所有联赛:通过ESPN——比分、排名、赛程、比赛摘要、阵容、球队数据。
Transfermarkt:适用于任何拥有tmplayerid的球员——市场价值和转会历史。
注意:MLS使用不同的赛季结构(春季-秋季赛历)。使用getcurrentseason(competitionid=mls)检测正确的seasonid。
ID约定
- - seasonid:{联赛-slug}-{年份},例如premier-league-2025、la-liga-2025
- competitionid:联赛slug,例如premier-league、serie-a、champions-league
- teamid:ESPN球队ID(数字字符串),例如359(阿森纳)、86(皇家马德里)
- eventid:ESPN赛事ID(数字字符串),例如740847
- fplid:FPL元素ID或代码(仅限英超球员)
- tmplayer_id:Transfermarkt球员ID,例如433177(萨卡)、342229(姆巴佩)
命令
getcurrentseason
检测某个比赛的当前赛季。适用于所有联赛。
- - competition_id(字符串,必填):比赛slug
返回data.competition和data.season:
json
{competition: {id: premier-league, name: Premier League}, season: {id: premier-league-2025, name: 2025-26 English Premier League, year: 2025}}
get_competitions
列出可用比赛及其当前赛季信息。无参数。适用于所有联赛。
返回包含id、name、code、current_season的data.competitions[]。
getcompetitionseasons
获取某个比赛的可用赛季。适用于所有联赛。
- - competition_id(字符串,必填):比赛slug
getseasonschedule
获取完整赛季比赛赛程。适用于所有联赛。
- - season_id(字符串,必填):赛季slug(例如,premier-league-2025)
返回data.schedules[]——形状与下方赛事相同。
getseasonstandings
获取某个赛季的联赛积分榜。适用于所有联赛。
- - season_id(字符串,必填):赛季slug
返回data.standings[].entries[]:
json
{
position: 1,
team: {id: 359, name: Arsenal, short_name: Arsenal, abbreviation: ARS, crest: https://...},
played: 26, won: 17, drawn: 6, lost: 3,
goalsfor: 50, goalsagainst: 18, goal_difference: 32, points: 57
}
getseasonleaders
获取某个赛季的最佳射手/领先者。
仅限英超(通过FPL)。
- - season_id(字符串,必填):赛季slug(必须为premier-league-*)
返回data.leaders[]——注意:球员名称嵌套在.player.name下:
json
{
player: {id: 223094, name: Erling Haaland, firstname: Erling, lastname: Haaland, position: Forward},
team: {id: 43, name: Man City},
goals: 22, assists: 6, penalties: 0, played_matches: 25
}
非英超联赛返回空值。
getseasonteams
获取某个赛季的球队。适用于所有联赛。
- - season_id(字符串,必填):赛季slug
search_team
在所有联赛(或特定联赛)中按名称搜索球队。使用模糊匹配。
- - query(字符串,必填):要搜索的球队名称(例如,Corinthians、Barcelona、Man Utd)
- competition_id(字符串,可选):将搜索限制在一个联赛内(例如,serie-a-brazil、premier-league)
返回包含每次匹配的team、competition和season的data.results[]:
json
{team: {id: 874, name: Corinthians}, competition: {id: serie-a-brazil, name: Serie A Brazil}, season: {id: serie-a-brazil-2025, year: 2025}}
getteamprofile
获取基本球队信息(名称、队徽、球场)。
不返回阵容/球员名单——使用get
seasonleaders查找英超球员ID,然后使用get
playerprofile获取个人球员数据。
- - teamid(字符串,必填):ESPN球队ID
- leagueslug(字符串,可选):联赛提示(加快解析速度)
返回data.team和data.venue。data.players[]为空——参见下方深入分析英超球队示例以了解推荐工作流程。
getdailyschedule
获取所有联赛特定日期的所有比赛。
- - date(字符串,可选):YYYY-MM-DD格式的日期。默认为今天。
返回data.date和data.events[]: