API Usage Guide
SportsStack API Usage Guide
This comprehensive guide explains the SportsStack data model, shows how entities connect, and provides practical patterns for building sports applications.
Data Model Overview
SportsStack provides a unified data model that connects sports entities across multiple data providers. Understanding this model is key to effectively using the API.
Entity Relationship Diagram
The SportsStack data model consists of Core Entities (sports hierarchy), Statistics Entities (player/team performance), and Betting Entities (markets and odds).
flowchart TD
subgraph Core["Core Entities"]
SPORT --> LEAGUE
LEAGUE --> TEAM
LEAGUE --> SEASON
LEAGUE --> EVENT
TEAM --> PLAYER
EVENT --> PLAY
end
subgraph Stats["Statistics"]
EVENT_STATS
SEASON_STATS
PLAY_STATS
end
subgraph Betting["Betting"]
MARKET --> OUTCOME
OUTCOME --> ODD
end
EVENT --> EVENT_STATS
EVENT --> MARKET
PLAYER --> EVENT_STATS
TEAM --> EVENT_STATS
PLAYER --> SEASON_STATS
TEAM --> SEASON_STATS
PLAY --> PLAY_STATS
Key Relationships:
- Core Hierarchy: Sport → League → Team/Season/Event → Player/Play
- Statistics: Events and Players/Teams generate Event Stats; Players/Teams aggregate to Season Stats
- Betting: Events have Markets, Markets have Outcomes, Outcomes have Odds from each sportsbook
Entity Details
| Entity | Description | Key Fields |
|---|---|---|
| Sport | Top-level category | name, abbreviation |
| League | Competition structure | name, abbreviation, sport_id |
| Team | Participating organization | name, abbreviation, market, colors |
| Player | Individual athlete | full_name, position, number, team_id |
| Season | Time-bounded competition period | year, season_type, start_date, end_date |
| Event | Single game/match | title, scheduled_start_time, status, participants |
| Play | Individual play within event | play_type, description, clock |
| Event Stats | Per-game statistics | event_id, for_entity_id, for_entity_type, data |
| Season Stats | Aggregated season statistics | season_id, for_entity_id, data |
| Play Stats | Per-play statistics | play_id, player_id, data |
| Market | Betting market type | event_id, market_type, name |
| Outcome | Specific betting selection | market_id, name, selection, line |
| Odd | Price from sportsbook | outcome_id, sportsbook, price |
Core Entities
| Entity | Description | Key Relationships |
|---|---|---|
| Sport | Top-level category (football, basketball, etc.) | Parent of Leagues |
| League | Competition structure (NFL, NBA, EPL) | Contains Teams, Events, Seasons |
| Team | Organization/franchise | Belongs to League, has Players |
| Player | Individual athlete | Belongs to Team and League |
| Event | A game/match | Belongs to League, has Participants (Teams) |
| Season | Time-bounded competition period | Belongs to League |
Statistics Entities
| Entity | Description | Scope |
|---|---|---|
| Event Stats | Player/Team performance in a single game | Per-event |
| Season Stats | Aggregated performance across a season | Per-season |
| Play Stats | Granular stats for individual plays | Per-play |
| Play | Individual game actions (plays, possessions) | Per-event |
Betting Entities
| Entity | Description | Relationships |
|---|---|---|
| Market | Betting market type (moneyline, spread, etc.) | Belongs to Event |
| Odd | Specific odds from a sportsbook | Belongs to Market |
The Common Model ID
Every entity in SportsStack has a common_model_id - a UUID that uniquely identifies the same real-world entity across all data providers.
flowchart LR
SR[SportRadar ID] --> CM[common_model_id]
FTN[FTN ID] --> CM
ESPN[ESPN ID] --> CM
Example: Patrick Mahomes across providers
| Provider | Their ID | Our common_model_id |
|---|---|---|
| SportRadar | sr:player:12345 | 4af4c296-6fbc-4705-... |
| FTN | ftn-mahomes-67890 | 4af4c296-6fbc-4705-... |
| ESPN | espn-abc123 | 4af4c296-6fbc-4705-... |
Why this matters:
- Use
common_model_idto join data across different endpoints - Stats from SportRadar and odds from DraftKings use the same player ID
- Build applications without worrying about provider-specific identifiers
Authentication
All API requests require authentication via the Authorization header:
Authorization: Bearer YOUR_API_KEYBase URL:
https://api.sportsstack.com/api/v1
API Route Categories
The SportsStack API is organized into six main categories to help you find the endpoints you need:
Reference
Core entity endpoints for sports hierarchy:
- Sports -
GET /v1/sports,GET /v1/sports/:id - Leagues -
GET /v1/leagues,GET /v1/leagues/:id - Teams -
GET /v1/teams,GET /v1/teams/:id - Players -
GET /v1/players,GET /v1/players/:id - Seasons -
GET /v1/seasons,GET /v1/seasons/:id - Events -
GET /v1/events,GET /v1/events/:id - Tournaments -
GET /v1/tournaments,GET /v1/tournaments/:id,GET /v1/tournaments/:id/bracket
Mappings
Entity identity mapping endpoints for translating between provider IDs and common model IDs:
- Mappings -
GET /v1/mappings,GET /v1/mappings/:id
Stats & Data
Statistical endpoints for performance data and standings:
- Event Stats -
GET /v1/event-stats,GET /v1/event-stats/:id,GET /v1/events/:id/event-stats - Season Stats -
GET /v1/seasons/:season_year/season-stats - Standings -
GET /v1/standings,GET /v1/standings/:id - Plays -
GET /v1/events/:id/plays - Play Stats -
GET /v1/play-stats,GET /v1/events/:id/play-stats,GET /v1/players/:id/play-stats
Betting
Betting market and odds endpoints:
- Markets -
GET /v1/markets,GET /v1/markets/:id,GET /v1/market_odds - Futures -
GET /v1/futures,GET /v1/futures/:id - Odds -
GET /v1/odds,GET /v1/odds/latest,GET /v1/odds/:id,GET /v1/events/:id/odds - Outcomes -
GET /v1/outcomes,GET /v1/outcomes/:id
Content
News and injury information:
- News -
GET /v1/news,GET /v1/news/:id,GET /v1/news/league/:league_id,GET /v1/news/:type/:id - Injuries -
GET /v1/injuries
SportsStack
Platform-specific endpoints for data health and dictionary:
- Data Health -
GET /v1/data_health - Data Dictionary -
GET /v1/data-dictionary/stat-types,GET /v1/data-dictionary/market-types
Data Discovery Flow
Follow this recommended flow to explore available data:
flowchart TD
A[List Sports] --> B[Get Leagues]
B --> C[Get Teams]
B --> D[Get Players]
B --> E[Get Events]
E --> F[Get Event Stats]
E --> G[Get Betting Odds]
E --> I[Get Plays]
I --> J[Get Play Stats]
D --> H[Get Season Stats]
| Step | Endpoint | Description |
|---|---|---|
| 1 | GET /sports | List all available sports |
| 2 | GET /leagues?sport_id={id} | Get leagues for a sport |
| 3 | GET /teams?league_id={id} | Get teams in a league |
| 4 | GET /players?league_id={id} | Get players in a league |
| 5 | GET /events?league_id={id} | Get events/games |
| 6 | GET /event-stats?event_id={id} | Get statistics for an event |
| 7 | GET /odds?event_id={id} | Get betting odds for an event |
| 8 | GET /plays?event_id={id} | Get play-by-play data for an event |
| 9 | GET /play-stats?play_id={id} | Get statistics for a specific play |
| 10 | GET /season-stats?player_id={id} | Get player season statistics |
Step 1: Discover Sports & Leagues
curl -X GET "https://api.sportsstack.com/api/v1/sports" \
-H "Authorization: Bearer YOUR_API_KEY"const response = await fetch('https://api.sportsstack.com/api/v1/sports', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const { data: sports } = await response.json();import requests
headers = {'Authorization': 'Bearer YOUR_API_KEY'}
response = requests.get('https://api.sportsstack.com/api/v1/sports', headers=headers)
sports = response.json()['data']Response:
{
"data": [
{
"common_model_id": "4af4c296-6fbc-4705-8660-3b587c252e16",
"name": "basketball",
"abbreviation": "bball"
},
{
"common_model_id": "58e8c89b-72f8-4427-adbc-10f193c9b462",
"name": "football",
"abbreviation": "nfl"
}
]
}Step 2: Get Leagues
curl -X GET "https://api.sportsstack.com/api/v1/leagues?sport_id=SPORT_ID" \
-H "Authorization: Bearer YOUR_API_KEY"Step 3: Get Teams & Players
curl -X GET "https://api.sportsstack.com/api/v1/teams?league_id=LEAGUE_ID" \
-H "Authorization: Bearer YOUR_API_KEY"curl -X GET "https://api.sportsstack.com/api/v1/players?league_id=LEAGUE_ID&limit=50" \
-H "Authorization: Bearer YOUR_API_KEY"Step 4: Get Events
curl -X GET "https://api.sportsstack.com/api/v1/events?league_id=LEAGUE_ID&season_year=2024&limit=10" \
-H "Authorization: Bearer YOUR_API_KEY"Filter Options:
status- Filter by event status:scheduled,in_progress,completedseason_year- Filter by season yearseason_type- Filter by season type:PRE,REG,POSTfrom_date/to_date- Date range filtering
Working with Statistics
Event Statistics (Game Stats)
Get player or team performance for a specific game:
curl -X GET "https://api.sportsstack.com/api/v1/event-stats?event_id=EVENT_ID&for_entity_type=player" \
-H "Authorization: Bearer YOUR_API_KEY"const response = await fetch(
`https://api.sportsstack.com/api/v1/event-stats?event_id=${eventId}&for_entity_type=player`,
{ headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const { data: stats } = await response.json();Parameters:
| Parameter | Description |
|---|---|
event_id | The event's common_model_id |
for_entity_type | player or team |
for_entity_id | (Optional) Filter to specific player/team |
Season Statistics
Get aggregated stats across a season:
curl -X GET "https://api.sportsstack.com/api/v1/seasons/2024/season-stats?league_id=LEAGUE_ID&for_entity_type=player&limit=25" \
-H "Authorization: Bearer YOUR_API_KEY"Play-by-Play Data
Get detailed game actions:
curl -X GET "https://api.sportsstack.com/api/v1/events/EVENT_ID/plays?limit=50" \
-H "Authorization: Bearer YOUR_API_KEY"curl -X GET "https://api.sportsstack.com/api/v1/events/EVENT_ID/play-stats?limit=50" \
-H "Authorization: Bearer YOUR_API_KEY"Working with Betting Data
The SportsStack Betting API provides three main endpoints for accessing betting data:
Betting API Structure
| Endpoint | Description | Required Filters |
|---|---|---|
GET /markets | Event-scoped betting markets | league_id |
GET /markets?include_outcomes=true | Markets with outcomes | league_id |
GET /futures | Future markets (outrights, season totals) | league_id |
GET /futures?include_outcomes=true | Futures with outcomes | league_id |
GET /odds | Odds data from sportsbooks | league_id OR event_id |
GET /events/:id/odds | Structured event odds (6-box format) | - |
Get Odds
Retrieve betting odds across sportsbooks for an event:
curl -X GET "https://api.sportsstack.com/api/v1/odds?event_id=EVENT_ID" \
-H "Authorization: Bearer YOUR_API_KEY"const response = await fetch(
`https://api.sportsstack.com/api/v1/odds?event_id=${eventId}`,
{ headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }
);
const { data: odds } = await response.json();response = requests.get(
f'https://api.sportsstack.com/api/v1/odds?event_id={event_id}',
headers=headers
)
odds = response.json()['data']Parameters:
| Parameter | Description |
|---|---|
league_id | Filter by league (required if event_id not provided) |
event_id | Filter by event (required if league_id not provided) |
market_id | Filter by specific market |
outcome_id | Filter by specific outcome |
sportsbook | Filter by sportsbook (e.g., 'draftkings', 'fanduel') |
market_type | Filter by market type (e.g., 'moneyline', 'point_spread') |
is_main | Filter by main lines only (true/false) |
Get Structured Event Odds (6-Box Format)
For rendering betting pages, use the structured event odds endpoint:
curl -X GET "https://api.sportsstack.com/api/v1/events/EVENT_ID/odds" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"data": {
"main_lines": {
"away_team": {"team_id": "uuid", "name": "SF 49ers", "abbreviation": "SF"},
"home_team": {"team_id": "uuid", "name": "PHI Eagles", "abbreviation": "PHI"},
"markets": {
"spread": {
"away": {"line": "+2.5", "odds": [{"price": -102, "sportsbook": "draftkings"}]},
"home": {"line": "-2.5", "odds": [{"price": -120, "sportsbook": "draftkings"}]}
},
"moneyline": {
"away": {"odds": [{"price": 124, "sportsbook": "draftkings"}]},
"home": {"odds": [{"price": -146, "sportsbook": "draftkings"}]}
},
"total": {
"over": {"line": "45.5", "odds": [{"price": -115, "sportsbook": "draftkings"}]},
"under": {"line": "45.5", "odds": [{"price": -105, "sportsbook": "draftkings"}]}
}
}
},
"other_markets": [...]
}
}Get Future Markets
Retrieve future markets (tournament outrights, season totals):
curl -X GET "https://api.sportsstack.com/api/v1/futures?league_id=LEAGUE_ID&include_outcomes=true" \
-H "Authorization: Bearer YOUR_API_KEY"Parameters:
| Parameter | Description |
|---|---|
league_id | Filter by league |
tournament_id | Filter by tournament |
future_type | Filter by type (e.g., 'tournament_outright', 'season_total') |
is_main | Filter by main markets only |
include_outcomes | Include outcomes in response (true/false) |
Common Usage Patterns
Pattern 1: Live Game Dashboard
Build a real-time game tracker:
sequenceDiagram
participant App
participant API
App->>API: GET /events?status=in_progress
API-->>App: List of live events
loop Every 30 seconds
App->>API: GET /events/{id}?include_scoreboard=true
API-->>App: Updated scores & status
end
App->>API: GET /event-stats?event_id={id}
API-->>App: Player/team stats
// 1. Get live events
const liveEvents = await fetch(
'https://api.sportsstack.com/api/v1/events?status=in_progress&league_id=LEAGUE_ID',
{ headers }
).then(r => r.json());
// 2. Poll for updates
setInterval(async () => {
for (const event of liveEvents.data) {
const updated = await fetch(
`https://api.sportsstack.com/api/v1/events/${event.common_model_id}?include_scoreboard=true`,
{ headers }
).then(r => r.json());
updateUI(updated.data);
}
}, 30000); // Every 30 secondsPattern 2: Player Performance Analysis
Analyze a player's performance across games:
// 1. Get player info
const player = await fetch(
`https://api.sportsstack.com/api/v1/players/${playerId}`,
{ headers }
).then(r => r.json());
// 2. Get season stats
const seasonStats = await fetch(
`https://api.sportsstack.com/api/v1/seasons/2024/season-stats?for_entity_type=player&for_entity_id=${playerId}&league_id=${leagueId}`,
{ headers }
).then(r => r.json());
// 3. Get recent game performances
const recentEvents = await fetch(
`https://api.sportsstack.com/api/v1/events?league_id=${leagueId}&status=completed&limit=10`,
{ headers }
).then(r => r.json());
// 4. Get stats for each event
const gameStats = await Promise.all(
recentEvents.data.map(event =>
fetch(
`https://api.sportsstack.com/api/v1/event-stats?event_id=${event.common_model_id}&for_entity_id=${playerId}`,
{ headers }
).then(r => r.json())
)
);Pattern 3: Odds Comparison
Compare odds across sportsbooks:
import requests
# Get upcoming events
events = requests.get(
'https://api.sportsstack.com/api/v1/events',
params={'league_id': LEAGUE_ID, 'status': 'scheduled', 'limit': 5},
headers=headers
).json()['data']
# Get odds for each event
for event in events:
odds = requests.get(
'https://api.sportsstack.com/api/v1/odds',
params={'event_id': event['common_model_id'], 'is_main': 'true'},
headers=headers
).json()['data']
# Group by outcome and find best odds
from collections import defaultdict
by_outcome = defaultdict(list)
for odd in odds:
by_outcome[odd['outcome_name']].append(odd)
for outcome_name, outcome_odds in by_outcome.items():
best = max(outcome_odds, key=lambda x: float(x['price']))
print(f"{outcome_name}: Best at {best['sportsbook']} ({best['price']})")Pattern 4: Fantasy Sports Lineup Builder
// 1. Get all players in league
const players = await fetch(
`https://api.sportsstack.com/api/v1/players?league_id=${leagueId}&limit=500`,
{ headers }
).then(r => r.json());
// 2. Get season stats for all players
const seasonStats = await fetch(
`https://api.sportsstack.com/api/v1/seasons/2024/season-stats?league_id=${leagueId}&for_entity_type=player`,
{ headers }
).then(r => r.json());
// 3. Join players with stats
const playersWithStats = players.data.map(player => {
const stats = seasonStats.data.find(s => s.for_entity_id === player.common_model_id);
return { ...player, stats: stats?.data || {} };
});
// 4. Sort by fantasy-relevant metrics
const topPlayers = playersWithStats
.filter(p => p.stats.points_per_game)
.sort((a, b) => b.stats.points_per_game - a.stats.points_per_game)
.slice(0, 20);Entity ID Mappings
Need to know how a SportsStack entity maps to external provider IDs?
curl -X GET "https://api.sportsstack.com/api/v1/mappings?entity_type=player&common_model_id=PLAYER_ID" \
-H "Authorization: Bearer YOUR_API_KEY"Response:
{
"data": [
{
"entity_type": "player",
"common_model_id": "4af4c296-6fbc-4705-8660-3b587c252e16",
"source": "sportradar.basketball.nba",
"source_id": "sr:player:12345"
},
{
"entity_type": "player",
"common_model_id": "4af4c296-6fbc-4705-8660-3b587c252e16",
"source": "ftn.basketball.nba",
"source_id": "ftn-67890"
}
]
}Best Practices
Caching Recommendations
| Data Type | Cache Duration | Reason |
|---|---|---|
| Sports, Leagues | 24+ hours | Rarely changes |
| Teams | 24 hours | Roster changes are infrequent |
| Players | 1-6 hours | Roster updates, injuries |
| Events (scheduled) | 1 hour | Schedule changes possible |
| Events (live) | 30-60 seconds | Real-time updates needed |
| Odds | 10-30 seconds | Rapid market movements |
| Stats (completed) | 24+ hours | Final after game ends |
Rate Limiting
- Use pagination (
limit,offset) for large datasets - Batch related requests where possible
- Cache static reference data aggressively
Error Handling
try {
const response = await fetch(url, { headers });
if (!response.ok) {
if (response.status === 401) {
// Handle authentication error
throw new Error('Invalid API key');
}
if (response.status === 429) {
// Handle rate limiting
const retryAfter = response.headers.get('Retry-After');
await sleep(retryAfter * 1000);
return retry();
}
throw new Error(`API error: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Request failed:', error);
throw error;
}Related Resources
- Stat Types Reference - Complete reference of all statistical fields
- Market Types Reference - Complete reference of all betting market types
- Authentication Guide - Detailed auth setup
- Quickstart - Get started in 5 minutes
- API Reference - Full OpenAPI specification
Updated about 1 month ago
