Real-time Sports Scores in Home Assistant

May 8, 2026 ยท View on GitHub

This integration provides real-time scores for teams and athletes in multiple professional (NBA, NFL, NHL, MLB, MLS, and more), college (NCAA), and international (soccer, golf, tennis, racing, cricket) sports using the ESPN Scoreboard APIs, and creates a sensor with detailed data for the competition. Services exist to change and interact with the sensor.

This integration can be used with the ha-teamtracker-card to display the game information in the Home Assistant dashboard.

See the Wiki for FAQs, troubleshooting advise, and custom API configurations that have been already been validated. Please contribute to help others.

This integration is a fork of the excellent ha-nfl custom component by @zacs. Thanks for the starting place!

Version Compatibility

  • Releases for ha-teamtracker and ha-teamtracker-card follow the MAJOR.MINOR.PATCH convention.
  • All teamtracker and teamtracker-card releases with the same MAJOR and MINOR version numbers will be compatible, regardless of PATCH version.
  • For example, any teamtracker v0.2.x will be compatible with any teamtracker-card v0.2.y.
  • Compatibility is not guaranteed across different MAJOR or MINOR version numbers.
  • Beta functionality is not guaranteed to be supported in future releases and may require manual actions to reconfigure from release to release.

"Buy Me A Coffee"

Supported Teams and Leagues

TeamTracker will work for any of the hundreds of teams/leagues for which an ESPN scoreboard API exists.

A small subset of the most popular teams/leagues have been pre-configured to simplify their setup. This is referred to as native support. Unfortunately, given the large number of teams/leagues for which APIs exist, it is impossible to provide native support for all of them.

The remaining teams/leagues are still supported, however they require a couple extra steps to set up. This is referred to as configuring a Custom API.

There is also beta support for PWHL games through the hockeytech API. All non-ESPN APIs must be configured with a Custom API. Beta functionality may have defects or break in future releases.

Natively Supported (Pre-Configured) Sports / Leagues

The following leagues are supported natively:

  • Australian Football - AFL
  • Baseball - MLB
  • Basketball - NBA, WNBA, NCAAM, NCAAW, WNBA
  • Football - NFL, NCAAF, XFL
  • Golf - PGA
  • Hockey - NHL
  • MMA - UFC
  • U.S. Soccer - MLS, NWSL
  • International Soccer - BUND (German Bundesliga), CL (Champions League), CLA (Conmebol Libertadores), EPL (English Premiere League), LIGA (Spanish LaLiga), LIG1 (French Ligue 1), SERA (Italian Serie A), WC (World Cup), WWC (Women's World Cup)
  • Racing - F1, IRL
  • Tennis - ATP, WTA
  • Volleyball - NCAAVB, NCAAVBW

Sports / Leagues Supported by Configuring a Custom API

It is possible to configure Team Tracker to use any existing ESPN Scoreboard API, not just the pre-configured leagues. This is done by configuring a Custom API.

Sensors with Custom APIs require more steps to set up, however once set up, they behave the same as a natively supported sensor. There is no difference between a team playing in a natively supported soccer league or a non-natively supported soccer league other than the extra steps needed to initially set up the non-natively supported one.

Additionally, a Custom API can be configured using the league_path value of all to pull in soccer matches across multiple leagues and tournaments for the same team.

The Custom APIs section below provides more details for setting up Custom API Configurations.

Sports / Leagues Supported by non-ESPN APIs

Custom APIs can be configured for the following leagues using HockeyTech APIs

Leaguesport_pathleague_path
Professional Womens Hockey Leaguehockeytechpwhl
Canadian Hockey Leaguehockeytechchl
Ontario Hockey Leaguehockeytechohl
Western Hockey Leaguehockeytechwhl
Quebec Major Junior Hockey Leaguehockeytechlhjmq
American Hockey Leaguehockeytechahl
East Coast Hockey Leaguehockeytechechl
United States Hockey Leaguehockeytechushl
Ontario Junior Hockey Leaguehockeytechojhl
British Columbia Hockey Leaguehockeytechbchl
Saskatchewan Junior Hockey Leaguehockeytechsjhl
Alberta Junior Hockey Leaguehockeytechajhl
Manitoba Junior Hockey Leaguehockeytechmjhl
Maritime Junior Hockey Leaguehockeytechmhl

Installation

Manual Installation

Clone or download this repository and copy the "teamtracker" directory to your "custom_components" directory in your config directory

<config directory>/custom_components/teamtracker/...

Installation via HACS

Use this button:

Open your Home Assistant instance and open a repository inside the Home Assistant Community Store.

OR manually perform the followng steps:

  1. Open the HACS section of Home Assistant.
  2. In Integrations, click the "+ EXPLORE & DOWNLOAD REPOSITORIES" button in the bottom right corner.
  3. In the window that opens search for "Team Tracker Card".
  4. Select "Team Tracker Card" from the list
  5. Select the "Download" button in the buttom right corner.
  6. Select "Download" from the window to download the button.
  7. When given the Option, Reload.

Configuration

Configuration Keys

The following configuration keys can be used when setting up a Team Tracker sensor.

YAML NameUI LabelRequiredDescriptionValid Values
nameFriendly NameNoFriendly name for the sensorAny valid friendly name
league_idLeagueYesLeague IDSee below
team_idTeam / AthleteYesTeam Abbreviation, Team ID, Athlete Name, Regular Expression, or WildcardSee below
api_languageNoneNoOverrides default API languageISO language code
conference_idConference NumberOnly if league_id is an NCAA football or basketballConference IDSee below
sport_pathSport PathIf league_id is XXXSport Path for Custom APISee below
league_pathLeague PathIf league_id is XXXLeague Path for Custom API. The value all can be used for soccer teams to pull in all matches across all leagues and tournaments. The unique ESPN Team ID should be used for team_id when all is used.See below

Specify the League (league_id)

The league_id configuration key is used the specify the league for the sensor. The following values are valid:

  • ATP (Assc. of Tennis Professionals)
  • BUND (German Bundesliga)
  • CL (Champions League)
  • CLA (Conmebol Libertadores)
  • EPL (English Premiere League)
  • F1 (Formula 1 Racing)
  • IRL (Indy Racing League)
  • LIGA (Spanish LaLiga)
  • LIG1 (French Ligue 1)
  • MLB (Major League Baseball)
  • MLS (Major League Soccer)
  • NBA (National Basketball Assc.)
  • NCAAF (NCAA Football)
  • NCAAM (NCAA Men's Basketball)
  • NCAAW (NCAA Women's Basketball)
  • NCAAVB (NCAA Men's Volleyball)
  • NCAAVBW (NCAA Women's Volleyball)
  • NFL (National Football League)
  • NWSL (National Women's Soccer League)
  • PGA (Professional Golfers' Assc.)
  • SERA (Italian Serie A)
  • UFC (Ultimate Fighting Championship)
  • XFL (XFL)
  • WC (World Cup)
  • WNBA (Women's NBA)
  • WTA (Women's Tennis Assc.)
  • XXX (Custom: Specify Sport and League Path)

Using XXX or selecting "Custom: Specify Sport and League Path" from the UI enables the creation of a Custom API and requires the sport_path and league_path configuration keys to be defined.

Specify the Team (team_id)

The team_id configuration key is used the specifiy the competitor to track for the sensor. It can take the form of a Team Abbreviation, Team ID, Athlete Name, Regular Expression, or the Wildcard character (*).

FormDescription
Team AbbreviationThis is the 2-, 3- or 4-letter abbreviation (eg. "SEA" for Seattle or "NE" for New England) ESPN uses when space is limited. You can generally find them at https://espn.com/ in the top scores UI, but they can also be found in other pages with team stats as well.
Team IDESPN assigns a unique number to identify a team. This unique number shows up in URLs and other locations. The Team ID should be used when using the league_path of all for soccer teams.
Athlete NameFor sports involving individual athletes, you should use the athlete's name as the search string. You should use as much as is needed to uniquely identify the desired athlete.
RegExRegular expressions can be used to match team names, athlete names, and rosters in competitions like Doubles Tennis. See below for an example.
WildcardYou can use the single * character as a Wildcard. This will cause the sensor to match a team or athlete using sport-specific logic outlined below.

RegEx

For doubles in tennis, rosters are used instead of team names and are in the format of {Player 1} / {Player 2}. You can use a regular expression to match the roster. As an example, if you do not know the order in which the players are listed on the roster, the regular expression .*(?:NADAL|ALCARAZ).*/.*(?:NADAL|ALCARAZ).* will match a doubles match with Nadal and Alcaraz regardless of which player is listed first. The names are not case sensitive.

Wildcard

The Wildcard behavior varies based on the sport.

SportBehavior
GolfDisplays the current leader and competitor in second place
MMADisplays the current active fight or the next upcoming fight if none are active
RacingDisplays the current leader and competitor in second place
TennisResults will be unpredictable due to multiple tournaments and matches in progress at once
Team SportsMost useful for playoffs. Will continually reset to display whatever team competition is in progress in the league. Results will be unpredictable if multiple competitions are in progress at once

Override the API Language (api_language)

NOTE: Team Abbreviations and Names may vary based on your local language. While rare, changing the language after a sensor is set up can cause it to stop working.

TeamTracker will use your local language settings when calling the ESPN APIs. Some languages are supported more robustly than others. For example, one language may provide play-by-play updates while another will not. For this reason, you can override your local language. English appears to be the most robustly supported language.

If you set up the sensor using the Home Assistant UI, you can add the override language code via the sensor's Configure button after it has been created.

If you are setting up the sensor using YAML. You can add the api_language configuration key to your YAML configuration.

You should use a standard ISO language code when specifying an override.

Specify the Conference - for NCAA Sports only (conference_id)

The conference_id configuration key is used the specifiy the Conference for the sensor. It should only be used for NCAA sports. Using it for other leagues or sports will cause a NOT_FOUND state.

By default, NCAA sports will only find a game if at least one of the teams playing is ranked. In order to find games in which both teams are unranked, you must specify a Conference ID, which is a number used by ESPN to identify college conferences and other groups of teams. Conferences ID's are not consistent across sports.

The following is a list of the college conferences and the corresponding number ESPN uses for their Conference ID.

ConferenceFootballBasketballBaseballSoftballW. VolleyballW. Basketball
ACC123740492
Big 12484445518
Big Ten574849547
C-USA1211507911
FBS Independent18
Independent4353
MAC15146214
Mountain West174444
MVC186418
PAC-12921464769
SEC82327327123
Sun Belt37277527
America East1461
American151625762
ASUN17646565046
Atlantic 103483
Big East4524
Big Sky2055
Big South406136
Big West9559
CAA18105610
Horizon455945
Ivy22127612
MAAC13526113
MEAC24166316
MVFC21
NEC2519516619
OVC26202620
OVC-Big South179
Patriot27227022
Pioneer28
SWAC31267426
Southern29247224
Southland30255425
Summit4973, 77 (legacy)47
WAC163030
WCC295529

The following identifiers are also valid:

Additional GroupingsFootball Conference IDBasketball Conference IDDescription
FBS (1-A)80Subset of unranked FBS games
FCS (1-AA)81Subset of FCS games
DIVII/III35Subset of D2/D3 games
D150Subset of unranked D1 games
D1100NCAA Tournament

Custom APIs: How to Determine the Sport Path and League Path (sport_path, league_path)

Setting the league_id configuration key to XXX or selecting "Custom: Specify Sport and League Path" from the UI, invokes the Custom API Configuration mode. This requires you to set the sport_path and league_path configuration keys. This section explains how to determine the correct values for these keys.

All ESPN APIs use a URL in the following format: https://site.api.espn.com/apis/site/v2/sports/{SPORT_PATH}/{LEAGUE_PATH}/scoreboard where {SPORT_PATH} is the sport and {LEAGUE_PATH} is the league that the team plays in.

For example, for the NFL, the URL is https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard

The Custom API Configuration section of the Wiki contains more details on how to determine the {SPORT_PATH} and {LEAGUE_PATH} as well as some that have been verified to work and some that are known to not be compatible. Please update the Wiki if you try others.

The FAQ in the Wiki also contains an explanation of the types of sports that work with the teamtracker integration and those that currently do not.

Once you have used the resources referenced above to determine the correct values to use for sport_path and league_path, you should use those values in the YAML or UI configuration.

Configuration via the "Configuration->Integrations" section of the Home Assistant UI

  1. On the Integrations page, select the "+ Add Integration" button.
  2. Search for the integration labeled "Team Tracker" and select it.
  3. Select the desired League from the League List. Select "Custom: Specific sport and league path" to create a Custom API.
  4. Enter a value for team's ID in the UI prompt. This can be a the team abbreviation, team ID, athlete name, wildcard, or a regex as explained in the Team ID section.
  5. If NCAA football or basketball, enter the Conference ID from Conference ID section if desired.
  6. You can also enter a friendly name. If you keep the default, your sensor will be sensor.team_tracker, otherwise it will be sensor.friendly_name_you_entered.
  7. If you are setting up a Custom API, a second window will be displayed.
  8. Enter the value for the Sport Path for the Custom API.
  9. Enter the value for the League Path for the Custom API.

Once the sensor is set up with the UI, you can use the Options Menu to override the API language if desired.

Manual Configuration in your configuration.yaml file

To create a sensor via YAML, add the following configuration to your sensor definitions. Enclose the values in quotes to avoid unrealized conflicts w/ predefined terms in YAML (i.e. NO being interpreted as No):

- platform: teamtracker
  league_id: "NFL"
  team_id: "NO"

After you restart Home Assistant then you should have a new sensor called sensor.team_tracker in your system.

You can overide the sensor default name (sensor.team_tracker) to one of your choosing by setting the name option:

- platform: teamtracker
  league_id: "NFL"
  team_id: "NO"
  name: "Saints"

Using the configuration example above the sensor will then be called "sensor.saints".

To set a Conference ID for an NCAA football or basketball team, use the following:

  - platform: teamtracker
    league_id: "NCAAF"
    team_id: "BGSU"
    conference_id: 15
    name: "Falcons"

To set up a Custom API Configuration, set the league_id to 'XXX' and enter the desired values for sport_path and league_path.

- platform: teamtracker
  league_id: "XXX"
  team_id: "OSU"
  sport_path: "volleyball"
  league_path: "womens-college-volleyball"
  name: "Buckeyes_VB"

To override the API language to Spanish, set the api_lang to 'esp'.

- platform: teamtracker
  league_id: "NFL"
  team_id: "NO"
  name: "Saints"
  api_language: esp

Sensor Data

State

The sensor is pretty simple: the main state is PRE, IN, POST, BYE or NOT_FOUND, but there are attributes for pretty much all aspects of the game, when available. State definitions are as you'd expect:

  • PRE: The game is in pre-game state. This happens when ESPN publishes the pre-game info via their API. The lead time varies based on the league.
  • IN: The game is in progress.
  • POST: The game has completed.
  • BYE: Your given team has a bye week this week. Note that attributes available are limited in this case (only abreviation, name, logo, and last updated time will be available).
  • NOT_FOUND: There is no game found for your team, nor is there a bye. This can happen if an invalid league or team ID has been entered. It can also happen at the end of the season or mid-season when ESPN hasn't published the pre-game info for the next game. See the Wiki for help in troubleshooting tips when you believe the sensor is incorrectly in the NOT_FOUND state.

Attributes

The attributes available will change based on the sensor's state, a small number are always available (league, team abbreviation, team name, and logo), but otherwise the attributes only populate when in the current state. The table below lists which attributes are available in which states.

Some attributes are only available for certain sports.

NameValueRelevant States
sportName of the sport for the sensorPRE IN POST
sport_pathThe sport_path for the sensor used to generate the API URLPRE IN POST
leagueName of the league for the sensorPRE IN POST
league_pathThe league_path for the sensor used to generate the API URLPRE IN POST
league_logoURL for the logo of the leaguePRE IN POST
seasonIdentifies the type of season (i.e. pre, regular, post)PRE IN POST
dateDate and time of the gamePRE IN POST
kickoff_inHuman-readable string for how far away the game is (eg. "in 30 minutes" or "tomorrow")PRE IN POST
quarterThe current quarter of gameplayIN
clockThe clock value within the quarter (should never be higher than 15:00). Inning (MLB only).IN
event_nameThe name of the event being played (eg. "The Masters")PRE IN POST
series_summaryIf event is part of a series, provides a summary of the seriesPRE IN POST
event_urlAn ESPN URL for the eventPRE IN POST
venueThe name of the stadium where the game is being played (eg. "Arrowhead Stadium")PRE IN POST
locationThe city and state where the game is being played (eg. "Pittsburgh, PA")PRE IN POST
tv_networkThe TV network where you can watch the game (eg. "NBC" or "NFL"). Note that if there is a national feed, it will be listed here, otherwise the local affiliate will be listed.PRE IN POST
oddsThe betting odds for the game (eg. "PIT -5.0")PRE
overunderThe over/under betting line for the total points scored in the game (eg. "42.5").PRE
possessionThe ID of the team in possession of the ball. This will correlate to team_id or opponent_id below. Note that this value will be null in between posessions (after a score, etc).IN
last_playSentence describing the most recent play, usually including the participants from both offense and defense, and the resulting yards. Note this can be null on posession changes or in between quarters.IN
down_distance_textString for the down and yards to go (eg. "2nd and 7").IN
outsNumber of outs (MLB only).IN
ballsNumber of balls (MLB only)).IN
strikesNumber of strikes (MLB only).IN
on_firstBaserunner on first base (MLB only).IN
on_secondBaserunner on second base (MLB only).IN
on_thirdBaserunner on third base (MLB only).IN
team_total_shotsTotal shots by team (MLS only).IN
team_shots_on_targetShots on net by team (MLS only).IN
team_sets_wonSets won by team.IN
opponent_total_shotsTotal shots by opponent (MLS only).IN
opponent_shots_on_targetShots on net by opponent (MLS only).IN
opponent_sets_wonSets won by opponent.IN
team_abbrThe abbreviation for your team (ie. SEA for the Seahawks).PRE IN POST BYE
team_idA numeric ID for your team, used to match possession above.PRE IN POST
team_nameYour team's name (eg. "Seahawks"). Note this does not include the city name.PRE IN POST BYE
team_long_nameYour team's long name (eg. "Seatle Seahawks"). Note this includes the city name.PRE IN POST BYE
team_recordYour team's current record (eg. "2-3").PRE IN POST
team_rankYour team's current rank (null if unranked or does not apply).PRE IN POST
team_conference_idYour team's conference ID.PRE IN POST
team_homeawayYour team's home/away status. Either home or away.PRE IN POST
team_logoA URL for a 500px wide PNG logo for the team.PRE IN POST BYE
team_urlAn ESPN URL for the team.PRE IN POST BYE
team_colorsAn array with two hex colors. The first is your team's primary color, and the second is their secondary color. Unless you're the Browns, in which case they are the same.PRE IN POST
team_scoreYour team's score. An integer.IN POST
team_win_probabilityThe real-time chance your team has to win, according to ESPN. A percentage, but presented as a float. Note that this value can become null in between posession changes.IN
team_winnerFlag indicating whether the team has won the competition or not.POST
team_timeoutsThe number of remaining timeouts your team has.PRE IN POST
opponent_abbrThe abbreviation for your opponent (ie. SEA for the Seahawks).PRE IN POST BYE
opponent_idA numeric ID for your opponent, used to match possession above.PRE IN POST
opponent_nameYour opponent's name (eg. "Seahawks"). Note this does not include the city name.PRE IN POST BYE
opponent_long_nameYour opponent's long name (eg. "Seatle Seahawks"). Note this includes the city name.PRE IN POST BYE
opponent_recordYour opponent's current record (eg. "2-3").PRE IN POST
opponent_rankYour opponent's current rank (null if unranked or does not apply).PRE IN POST
opponent_conference_idYour opponent's conference ID.PRE IN POST
opponent_homeawayYour opponent's home/away status. Either home or away.PRE IN POST
opponent_logoA URL for a 500px wide PNG logo for the opponent.PRE IN POST BYE
opponent_urlAn ESPN URL for the opponent.PRE IN POST BYE
opponent_colorsAn array with two hex colors. The first is your opponent's primary color, and the second is their secondary color.PRE IN POST
opponent_scoreYour opponent's score. An integer.IN POST
opponent_win_probabilityThe real-time chance your opponent has to win, according to ESPN. A percentage, but presented as a float. Note that this value can become null in between posession changes.IN
opponent_winnerFlag indicating whether the opponent has won the competition or not.POST
opponent_timeoutsThe number of remaining timeouts your opponent has.PRE IN POST
last_updateA timestamp for the last time data was fetched for the game. If you watch this in real-time, you should notice it updating every 10 minutes, except for during the game (and for the ~20 minutes pre-game) when it updates every 5 seconds.PRE IN POST BYE
api_messageA message giving information to help troubleshoot when the sensor is statePRE IN POST BYE NOT_FOUND
api_urlThe URL of the ESPN API callPRE IN POST BYE NOT_FOUND

Services

TeamTracker supports the following services.

ServiceInput ParametersDescription
call_apisport_path, league_path, team_id, conference_id (optional)Dynamically changes the teamtracker sensor based on the input parameters, calls the ESPN API, and refreshes the sensor attributes. Sensor will revert to original configuration on reboot.

NOTE: The functionality and input parameters of the call_api service are subject to change as new uses emerge. If you have ideas or suggestions for specific use cases, open an Issue so they can be tracked.

Additional details available on the Services tab in Developer Tools.

Tutorials

You will find a german tutorial how to use this integration here: https://youtu.be/CYK7JrNmvfg, and https://youtu.be/hh3kCk-f2vY (Created by Tristan's Smartes Heim)