How-to build a match page
Welcome to our how-to guide about creating a match page that is filled with events, statistics and lineups. This is a follow-up on the how-to build your livescore website guide. The livescore page only shows the live score of the match and sometimes the bigger events such as goals, substitutions, and cards.
You are going to need the following tools:
- Sportmonks API token
- Code editor (Visual studio used in examples)
- Postman or your browser
You can find a link to another article where we discuss the tools in-depth on our Developer Tools Guide.
At Sportmonks we offer the following events:
- Goal (own goal, penalty)
- Cards (Yellow card, Red card, Yellow/Red card)
- Substitutions VAR (Goal disallowed, Goal under review)
- Extra time
- Score at the end of the first half and end of the match
- Corners Shots (On/off target)
- Offsides
For match statistics, think about anything that can happen during a match, such as: The number of shots, passes, attacks, fouls, corners, offsides, yellow/red cards, saves, substitutions, goal attempts, penalties, injuries, and many more.
Player statistics are all the relevant statistics regarding a player, such as the number of goals scored, how many fouls he made, the number of cards received, etc.
The standard events include, consists of all the events mentioned above.
Player and match statistics do not have endpoints, but instead can be evoked with includes.
- Match statistics use the include
statistics
. - Player statistics use the include
lineups.details.
Since this is about a single match page with various events and stats, we will need the specific fixture ID. That’s why we’ll work with the fixtures by id endpoint.
It’s also possible to include both stats and lineups includes in the same request, but expect a lengthy response in that case.
Another nice feature to add is comparing the two teams’ past results against each other. This is often used to see how one team performs against another. This endpoint is called GET Fixture by Head To Head.
Next up is creating the request. For that you will need the base URL of our API for a request regarding Football which is:
https://api.sportmonks.com/v3/football/
Then we need to specify the endpoint we would like to receive.
Fixture by ID
Fixture by Head to Head
https://api.sportmonks.com/v3/football/
fixtures/{ID}
https://api.sportmonks.com/v3/football/
fixtures/head-to-head/{team_id_1}/{team_id_2}
After that we need to add the includes mentioned above. You can do that by adding
&include=statistics;lineups.details
to your request.If you add your own API token by adding
?api_token=YOUR_TOKEN
to your request, you are ready to request!We will use the match between the Netherlands and Senegal as an example.
First, we want to know what formation both teams used. Luckily, this information is included in the
metadata
include you can use on our fixtures/livescores endpoints.Before we fill in the formation, let us first explain formation positions. Players have different formation_positions. So for example, one player has the player's formation_position: 1, another has formation_position: 2, etc. Our API slots formations from right to left, meaning that the visitorteam_formation will look like the one down below.

Senegal vs Netherlands Lineups
You can use the formation numbers in combination with the lineup formation to display formations. The formation number is by order of the lineup formation.
So, for example, formation 4-3-3:
Formation number 1: Keeper
Formation number 2: Right back
Formation number 3: Central defender
Formation number 4: Central defender
Formation number 5: Left back
Formation number 6: Central midfielder
Formation number 7: Central midfielder
Formation number 8: Central midfielder
Formation number 9: Right winger
Formation number 10: Striker
Formation number 11: Left winger
For the first example, we will look at fixture ID (18841624) and Liverpool's (4-3-3) formation.

Liverpool 433 formation
You can add the players to the grid according to their player formation.
This gives the following result:
Formation 4-3-3 | Formation_position |
---|---|
Goalkeeper | 1 (Allison) |
Defender | 2 (Trent Alexander-Arnold) |
Defender | 3 (Ibrahima Konaté) |
Defender | 4 (Virgil van Dijk) |
Defender | 5 (Andrew Robertson) |
Midfielder | 6 (Dominik Szoboszlai) |
Midfielder | 7 (Alexis Mac Allister) |
Midfielder | 8 (Cody Gakpo) |
Attacker | 9 (Mohamed Salah) |
Attacker | 10 (Diogo Jota) |
Attacker | 11 (Luis Díaz) |
For another example of a formation, we will look at fixture ID (18867332) and Inter's (3-5-2) formation.

Inter formation 352
You can add the players to the grid according to their player formation.
This gives the following result:
Formation: 3-5-2 | Formation_position |
---|---|
Goalkeeper | 1 (Yann Sommer) |
Defender | 2 (Matteo Darmian) |
Defender | 3 (Stefan de Vrij) |
Defender | 4 (Alessandro Bastoni) |
Midfielder | 5 (Denzel Dumfries) |
Midfielder | 6 (Nicolò Barella) |
Midfielder | 7 (Hakan Çalhanoğlu) |
Midfielder | 8 (Henrikh Mkhitaryan) |
Midfielder | 9 (Federico Dimarco) |
Attacker | 10 (Lautaro Martínez) |
Attacker | 11 (Marcus Thuram) |
Cody Gakpo
{
"id": 910131127,
"sport_id": 1,
"fixture_id": 18493993,
"player_id": 30062,
"team_id": 18694,
"position_id": 26,
"formation_field": "4:1",
"type_id": 11,
"formation_position": 9,
"player_name": "Cody Gakpo",
"jersey_number": 8,
"details": [
{
"id": 285939816,
"fixture_id": 18493993,
"player_id": 30062,
"team_id": 18694,
"lineup_id": 910131127,
"type_id": 106,
"data": {
"value": 2
},
"type": {
"id": 106,
"name": "Duels Won",
"code": "duels-won",
"developer_name": "DUELS_WON",
"model_type": "statistic",
"stat_group": "offensive"
}
},
{
"id": 285939839,
"fixture_id": 18493993,
"player_id": 30062,
"team_id": 18694,
"lineup_id": 910131127,
"type_id": 42,
"data": {
"value": 1
},
"type": {
"id": 42,
"name": "Shots Total",
"code": "shots-total",
"developer_name": "SHOTS_TOTAL",
"model_type": "statistic",
"stat_group": "offensive"
}
},
//And more
Here, we can see the detailed player statistics of the player named Cody Gakpo. Apart from standard player information such as which team he belongs to, what his player id or position is. We can see the total number of shots, goals, fouls, cards, passing, dribbles and duels. There’s also an ‘other’ tab with even more information, but we won’t go into detail for that one.
{
"data": {
"id": 18493993,
"sport_id": 1,
"league_id": 732,
"season_id": 18017,
"stage_id": 77452386,
"group_id": 246691,
"aggregate_id": null,
"round_id": 238362,
"state_id": 5,
"venue_id": 343332,
"name": "Senegal vs Netherlands",
"starting_at": "2022-11-21 16:00:00",
"result_info": "Netherlands won after full-time.",
"leg": "1/1",
"details": null,
"length": 90,
"placeholder": false,
"last_processed_at": "2023-03-02 17:49:01",
"has_odds": true,
"starting_at_timestamp": 1669046400,
"statistics": [
{
"id": 7694500,
"fixture_id": 18493993,
"type_id": 83,
"participant_id": 18694,
"data": {
"value": 0
},
"location": "away"
},
{
"id": 7694488,
"fixture_id": 18493993,
"type_id": 83,
"participant_id": 18558,
"data": {
"value": 0
},
"location": "home"
},
{
"id": 7694491,
"fixture_id": 18493993,
"type_id": 78,
"participant_id": 18558,
"data": {
"value": 14
},
"location": "home"
},
//And more
As its name suggests, we can see the team statistics of the home team, Senegal. We can see the number of shots, passes, attacks, and a plethora of other data of the entire team.
Goal
Substitution
Yellow Card
{
"id": 70555262,
"fixture_id": 18493993,
"period_id": 4510900,
"participant_id": 18694,
"type_id": 14,
"section": "event",
"player_id": 30062,
"related_player_id": 26536,
"player_name": "C. Gakpo",
"related_player_name": "Frenkie de Jong",
"result": "0-1",
"info": "Header",
"addition": "1st Goal",
"minute": 84,
"extra_minute": null,
"injured": null,
"on_bench": false,
"coach_id": null,
"sub_type_id": null
},
{
"id": 70555186,
"fixture_id": 18493993,
"period_id": 4510900,
"participant_id": 18694,
"type_id": 18,
"section": "event",
"player_id": 29184,
"related_player_id": 4230,
"player_name": "T. Koopmeiners",
"related_player_name": "Steven Berghuis ",
"result": null,
"info": null,
"addition": null,
"minute": 79,
"extra_minute": null,
"injured": false,
"on_bench": false,
"coach_id": null,
"sub_type_id": null
},
{
"id": 70555306,
"fixture_id": 18493993,
"period_id": 4510900,
"participant_id": 18558,
"type_id": 19,
"section": "event",
"player_id": 4679,
"related_player_id": null,
"player_name": "Nampalys Mendy",
"related_player_name": null,
"result": null,
"info": "Foul",
"addition": null,
"minute": 90,
"extra_minute": 4,
"injured": null,
"on_bench": false,
"coach_id": null,
"sub_type_id": null
},
Events show goals, cards, and substitutions and at which exact minute this happened. So, we can see that in the 84th-minute player C. Gakpo scored the 0-1 and got an assist from F. de Jong. Player S. Berghuis got substituted for T. Koopmeiners in the 79th minute. And finally, player N. Mendy got a yellow card in the 94th minute.
Last modified 2d ago