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.

Compare plans β†’ Data features per league β†’

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

  1. 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.type on a fixture endpoint gives you this in one request.

  2. 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.

  3. 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.

  4. 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

  1. Simple standings or points data: Use the Standings endpoints, which are optimised for table displays.

  2. Goal events (scorers, minute of goal): Use include=events on 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.

3. Choosing the right statistics endpoint

Statistics are available on multiple entities. Choose based on what you're building:

What you want
Entity
Where to get it
Sub-tutorial

Stats for a single match

Fixture

include=statistics on fixture endpoint

Season aggregates per team

Team

Team statistics endpoint

Per-player stats across a season

Player

Player statistics endpoint

Season-level rollups

Season

Season statistics endpoint

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:

Field
Type
Description

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

This 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

Statistics by scope

Related data

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/types and cache them in a Map at startup

  • Use include=statistics on fixture requests for match-level stats

  • Use the dedicated statistics endpoints for team and player seasonal aggregates

  • Check data feature coverage per league before building stats-heavy features

❌ DON'T:

  • Include .type on statistics in production

  • Assume 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?