Statistics
Plan availability varies
Statistics availability depends on your plan and the specific league. Some statistics types (e.g. expected goals, advanced player stats) are only available for select leagues and higher-tier plans.
Quick summary: This tutorial explains how statistics work in API v3, introduces the type-based system that underpins all stats data, and directs you to the appropriate sub-tutorial for fixture, team, player, and season-level statistics.
What you'll learn:
How the statistics type system works and why it matters
Which statistics endpoints to use for different scopes (fixture, team, player, season)
How to retrieve and resolve statistics types efficiently
Best practices for working with stats data at scale
Time to complete: 15 minutes (overview) + time per sub-tutorial Skill level: Intermediate Prerequisites: Authentication, Includes, Filter and Select Fields, Fixtures
1. When to use this feature
Statistics are one of the most requested data types in the API. They cover a wide range from basic match metrics (shots, corners, possession) to advanced per-player data (expected goals, progressive passes, pressures). Statistics in API v3 are scoped to four entities: fixtures, teams, players, and seasons.
Real-world use cases
Use case 1: Match stats overlay You're building a live match page and want to show possession, shots on target, and fouls side-by-side. Fixture statistics via
include=statistics.typeon a fixture endpoint gives you this in one request.Use case 2: Player performance profile You want a page per player showing their goals, assists, and expected goals across a season. Player statistics endpoints return per-player seasonal aggregates.
Use case 3: Team form analysis You want to show a team's average shots per game over the last five matches. Team statistics endpoints return season-level aggregates per team.
Use case 4: Season comparison dashboard You want to compare aggregate stats across two seasons for the same team. Season statistics endpoints provide the per-season rollups.
When NOT to use this feature
Simple standings or points data: Use the Standings endpoints, which are optimised for table displays.
Goal events (scorers, minute of goal): Use
include=eventson a fixture, not statistics. Events cover discrete in-match incidents; statistics cover accumulated metrics.
2. Understanding statistics types
Before working with statistics in API v3, you need to understand the type system. This is the most important concept in this tutorial.
Every statistic is identified by a type_id rather than a named field. For example, there is no shots_on_target key in the response, instead you get an array of stat objects, each with a type_id and a value.
To know that type_id: 41 means "Shots Total", you need the types reference data. See the Statistics Types tutorial for the full list.
The right way to work with types
Fetch all types once from the Types endpoint and store them in your database or application cache. Never include .type on large or frequently called endpoints.
Including .type on statistics is allowed but not recommended in production. It triggers a type join for every stat on every entity in the response, use it for exploration and testing only.
3. Choosing the right statistics endpoint
Statistics are available on multiple entities. Choose based on what you're building:
Each is covered in a dedicated sub-tutorial. This page provides the foundation concepts that apply to all of them.
4. How to retrieve statistics
Method A: Via fixture includes (most common)
The simplest way to get match statistics is to include them directly on a fixture request.
Method B: Via dedicated statistics endpoints
For team-level, player-level, or season-level aggregates, use the dedicated statistics endpoints. These are covered in full in the sub-tutorials linked above.
Team statistics example:
Player statistics example:
Step-by-step: Fixture statistics with type resolution
5. Working with the data
Understanding the response structure
Statistics returned via fixture include:
Key fields:
type_id
integer
Identifies the stat (resolve via the types endpoint)
participant_id
integer
Which team or player this stat belongs to
data.value
number/string
The stat value
fixture_id
integer
The fixture this stat is associated with
Processing the data
Split stats by team and display side-by-side:
Find a specific stat by type ID:
6. Common pitfalls
Pitfall 1: Including .type in production
.type in productionThis is the most common performance mistake when working with statistics.
Pitfall 2: Assuming all type IDs are always present
Type IDs are consistent across the API, but not all types are available for all leagues or all stat scopes. A type_id present in one fixture may not appear in another.
Pitfall 3: Using statistics instead of events for goal data
Statistics store aggregated totals (e.g. "5 goals scored"). For who scored, when they scored, and which type of goal, use include=events on the fixture.
Pitfall 4: Fetching statistics independently when fixture includes cover it
If you only need stats for one fixture, fetching them via the fixture's include parameter is more efficient than a separate statistics endpoint call.
7. Advanced usage
Advanced technique 1: Building a stats comparison dashboard
Fetch stats for multiple fixtures in parallel and aggregate them per team.
Advanced technique 2: Preloading types at app start
Make types available globally so any component can resolve them without additional API calls.
8. Common errors
401 Unauthorised
Cause: Missing or invalid api_token. Fix: Confirm the token is appended to every request. Retrieve it from MySportmonks.
Empty statistics array
Cause: Statistics are not available for this fixture or league. Not all leagues have full statistics coverage. Fix: Check Data Features per League to confirm coverage.
429 Too Many Requests
Cause: Statistics requests with .type includes are expensive and can hit rate limits quickly. Fix: Switch to the type-map pattern and remove .type from your includes. See the Rate Limiting guide.
See also
Prerequisites
Authentication : Setting up API access
Includes : Attaching stats to fixture responses
Fixtures : The most common way to access fixture-level stats
Statistics by scope
Statistics Types : Full reference of type IDs and names
Fixture Statistics : Per-match stats
Team Statistics : Season-level aggregates per team
Player Statistics : Per-player stats across a season
Season Statistics : Season-level rollups
Related data
Lineups and Formations : Combine with player stats for a full match analysis view
Expected Goals (xG) : Advanced expected stats alongside actual statistics
Standings : Contextualise team stats within the league table
10. FAQ
Q: Where do I find the full list of type IDs?
See the Statistics Types tutorial or fetch them directly from GET /v3/core/types.
Q: Why are statistics for some leagues empty?
Not every league has full statistics coverage. Advanced stats like expected goals are only available for select competitions. Check Data Features per League for a league-by-league breakdown.
Q: Can I get live in-match statistics?
Yes. Use include=statistics on the livescores endpoint to get real-time stats during a match. These update as events are processed.
Q: What's the difference between statistics and events?
Events represent discrete in-match incidents (goal at minute 37, yellow card at minute 52, substitution). Statistics represent accumulated totals (7 shots, 55% possession). Use events for scorers and incidents; use statistics for metrics.
Q: Are player statistics the same as player events?
No. Player events (via include=events) show what a player did in a specific match. Player statistics (via the player statistics endpoint) show aggregate totals for a player over a season or date range.
Q: Can I compare statistics across multiple fixtures?
Yes. Fetch statistics for each fixture and aggregate them. Use Promise.all to fetch in parallel and see the advanced usage section above.
Best practices summary
β DO:
Fetch types once from
/v3/core/typesand cache them in a Map at startupUse
include=statisticson fixture requests for match-level statsUse the dedicated statistics endpoints for team and player seasonal aggregates
Check data feature coverage per league before building stats-heavy features
β DON'T:
Include
.typeon statistics in productionAssume a type ID will always be present in a response
Use statistics to get goal scorer data and use events instead
Make separate requests for stats when fixture includes cover the same data
Last updated
Was this helpful?