SportsProvider interface and are registered in teamarr/providers/__init__.py.
Provider chain
Provider summary
| Provider | Priority | Leagues covered | Auth | Rate limit |
|---|---|---|---|---|
| ESPN | 0 | 52 pre-configured + 240+ soccer | None (public API) | Generous (DNS is usually the bottleneck) |
| MLB Stats | 40 | 5 (MiLB) | None (public API) | None observed |
| HockeyTech | 50 | 14 | Public client keys | None observed |
| TSDB | 100 | 11 | API key in URL path | 30/min free, 100/min premium |
SportsProvider interface
All providers implement these methods, defined inteamarr/core/interfaces.py:
| Method | Required | Description |
|---|---|---|
name | Yes | Provider identifier (e.g., "espn") |
supports_league(league) | Yes | Whether this provider handles the given league code |
get_events(league, date) | Yes | All events for a league on a specific date |
get_team_schedule(team_id, league, days_ahead) | Yes | Upcoming schedule for a specific team |
get_team(team_id, league) | Yes | Team details by ID |
get_event(event_id, league) | Yes | Single event by ID |
get_team_stats(team_id, league) | No | Detailed team statistics |
get_league_teams(league) | No | All teams in a league (used by cache refresh) |
get_supported_leagues() | No | List of supported league codes |
League mapping format
Each league inschema.sql maps to a provider via the provider and provider_league_id columns. The format of provider_league_id varies by provider:
| Provider | Format | Example |
|---|---|---|
| ESPN | sport/league | football/nfl, soccer/eng.1 |
| MLB Stats | sport_id | 11 (Triple-A) |
| HockeyTech | client_code | ohl, ahl |
| TSDB | league_id | 4460 (IPL) |
Design principles
No direct DB access
Providers receive configuration via dependency injection at instantiation time. Database access stays at the factory boundary in
teamarr/providers/__init__.py.Lazy initialization
Providers are created on-demand via factory functions. A provider is only instantiated when first needed.
Thread-safe HTTP clients
All providers use connection pooling with configurable limits to handle concurrent requests safely.
Exponential backoff
All providers retry with jitter on failure. Base delay 0.5s, capped at 10s. Rate limit (429) responses use a longer backoff: 5s base, capped at 60s, respecting
Retry-After headers.Provider registration
Providers are registered inteamarr/providers/__init__.py using ProviderRegistry.register(). This is the single place where providers are configured:
- Create a provider module under
teamarr/providers/newprovider/. - Register it in
teamarr/providers/__init__.pywith a factory function and priority. - Add league configuration to the
leaguestable inteamarr/database/schema.sql.