- What is xG analytics in football and why embed the xG widget on the website
- What data does the sports events API provide for xG analytics
- Requirements for the website and access keys for connecting to the xG API
- Step-by-step guide: how to embed the xG analytics widget on the website via API
- Examples of API requests and code for displaying the xG widget on the page
- Customizing the design and parameters of the xG analytics widget for your website
- Limitations, update speed, and cost of using the xG API
What is xG analytics in football and why embed the xG widget on the website
xG (expected goals) is a metric that shows how many dangerous moments a team created and how many goals it debería haber should score based on the quality of shots, rather than the actual score. The calculation takes into account the type of shot, distance to the goal, angle, position of defenders, type of pass, and many other factors. As a result, xG describes the actual game advantage much better than a score of 1:0 or 2:2 on the scoreboard.
The embeddable xG widget makes any football website noticeably more professional. The user sees not only the numbers for possession and shots but also a visual graph of expected goals throughout the match, comparison of team xG, and distribution of moment quality. This approach is used by leading sports media and analytical platforms to explain in more depth, why the team won or lost.
By connecting data through the sports events API, for example, from the service API-sport for developers and businesses, you can automatically build your xG widgets for any match: from top leagues to local tournaments. This allows:
- to increase audience engagement through deeper analytics;
- to increase time on site and depth of match page views;
- to support content for predictions and betting based on objective metrics;
- to strengthen the site’s brand by demonstrating an expert approach to statistics.
Unlike static images, the xG widget based on the API can be updated almost in real time, adapt to the site’s design, and easily scale to hundreds of matches simultaneously. In this article, we will discuss what data is needed for xG, how to obtain it through the API, and how to step by step integrate your own widget on the site.
What data does the sports events API provide for xG analytics
The classic xG model relies on detailed information about shots on goal and game episodes. In the API for football events, available through the base path /v2/football/ on the domain 2. api.api-sport.ru, there is already a significant amount of statistics that can be used as a basis for simplified or extended xG analytics.
Firstly, the endpoints /v2/fútbol/partidos и /v2/fútbol/partidos/{matchId} return an object estadísticasDelPartido. It groups key metrics by match periods (ALL, 1ST, 2ND): totalDisparosALaPortería, disparosALaPortería, totalDisparosDentroDelÁrea, totalShotsOutsideBox, granOportunidadCreada, granOportunidadMarcada, bigChanceMissed, as well as additional parameters for attacks, shots, duels, etc. These indicators allow assessing the quality of created chances even without frame-by-frame coordinates of each shot.
Secondly, through /v2/football/matches/{matchId}/events you get a chronology of key game episodes: goals, penalties, cards, substitutions, and other events. By correlating events with aggregated statistics, it is possible to build xG timelines and show in which segments of the match the team created the most dangerous chances.
For advanced projects, match data can be combined with information about tournaments, teams, and players available in the sections /v2/fútbol/equipos, /v2/fútbol/jugadores, as well as using bookmaker odds from the field oddsBase of the match. The combination of xG analytics and betting data allows for building more accurate models of odds value and creating unique products at the intersection of statistics and betting.
Requirements for the website and access keys for connecting to the xG API
To embed the xG widget based on API data, your site does not require any special infrastructure. Any modern engine (WordPress, custom solution on PHP/Node.js, frameworks like Laravel or Django) will suffice, as long as you can add your own JavaScript and make HTTP requests to the external API from the server.
It is important to note that authorization in the Sport Events API occurs through the header Autorización with your API key. For security reasons, it is not recommended to hard-code the key directly in JavaScript on the client side, as it can be seen in the page’s source code. It is more reliable to organize a simple backend proxy: the frontend calls your server, and the server calls the API https://api.api-sport.ru, adding the authorization header.
You can obtain a personal key in the API-SPORT personal account. After registration and selecting a plan, you will see the value of the API key and can use it in request headers. A test mode or limited plan is usually available for development: this is enough to debug the widget, set up caching, and check the load on the site during mass requests.
From the frontend perspective, it is advisable to ensure HTTPS support, proper CORS operation (if you are making direct requests from the browser), and set up API response caching on your server. The cache can be set for at least 15–60 seconds for live mode to reduce the number of requests and speed up the loading of the xG widget on the page.
Step-by-step guide: how to embed the xG analytics widget on the website via API
The integration of the xG widget can be conveniently broken down into several logical steps. First, you determine on which pages and in what format you want to display xG: it can be a block in the match card, a separate section «Advanced Analytics,» or an insertion in the material analyzing the game. At this stage, you think through the type of visualization: total xG by teams, xG graph by minutes, or a combined option.
Next, you need to obtain the match ID for API requests. It can be taken from the internal database, from the response of the endpoint /v2/football/matches?date=YYYY-MM-DD or from integration with another of your modules (for example, the betting line or broadcast schedule). Knowing matchId, you request match details through /v2/fútbol/partidos/{matchId} and, if necessary, events through /v2/football/matches/{matchId}/events.
On the server side, you implement the xG calculation function. In the simplest case, you can use aggregated statistics: assign weights for shots from inside and outside the penalty area, for big chances, for penalties. A simplified formula can serve as a starting point, and it can be refined as data accumulates. The result of the calculation is numerical xG values for each team and, optionally, an array of points for the time graph.
The final step is rendering the widget on the frontend. The server returns a JSON with pre-calculated xG values to the page, and the JavaScript code builds charts (bar, line, «progress bar,» etc.) in the desired style based on it. This division of responsibilities allows you to keep the API key secure while flexibly managing the logic and design of xG analytics.
Examples of API requests and code for displaying the xG widget on the page
Below is a simplified example of the integration: a request to the Sport Events API, extracting statistics, and calculating xG on the server or frontend. First, we will get detailed information about a specific match by its ID. The example uses JavaScript with a request through obtener. In a real project, similar code is better placed on the server.
fetch('https://api.api-sport.ru/v2/football/matches/14570728', {
headers: {
'Authorization': 'YOUR_API_KEY'
}
})
.then(response => response.json())
.then(match => {
const statsAll = match.matchStatistics.find(s => s.period === 'ALL');
const shotsGroup = statsAll.groups.find(g => g.groupName === 'Shots');
const insideBox = shotsGroup.statisticsItems.find(i => i.key === 'totalShotsInsideBox').homeValue;
const outsideBox = shotsGroup.statisticsItems.find(i => i.key === 'totalShotsOutsideBox').homeValue;
const bigChances = statsAll.groups
.find(g => g.groupName === 'Attack')
.statisticsItems.find(i => i.key === 'bigChanceCreated').homeValue;
// Пример простой модели xG для хозяев
const xgHome = insideBox * 0.15 + outsideBox * 0.05 + bigChances * 0.35;
console.log('xG домашней команды:', xgHome.toFixed(2));
})
.catch(console.error);
This is just a demonstration example: the weights (0.15, 0.05, 0.35) are given for illustration and are not a ready production model. In a live solution, you can use a more complex xG formula that takes into account additional parameters from estadísticasDelPartido and match events. It is important that the API already provides structured data that can be easily processed programmatically.
After calculating xG on the backend, it is convenient to send only clean JSON with the result to the frontend. Here is an example of a simple PHP proxy that fetches match data from the API, calculates xG, and returns it in a format ready for rendering in the widget:
<?php
$matchId = (int)($_GET['matchId'] ?? 0);
$apiKey = 'YOUR_API_KEY';
$ch = curl_init('https://api.api-sport.ru/v2/football/matches/' . $matchId);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: ' . $apiKey,
],
]);
$response = curl_exec($ch);
curl_close($ch);
$match = json_decode($response, true);
$statsAll = null;
foreach ($match['matchStatistics'] as $periodStats) {
if ($periodStats['period'] === 'ALL') {
$statsAll = $periodStats;
break;
}
}
$shotsGroup = array_values(array_filter($statsAll['groups'], fn($g) => $g['groupName'] === 'Shots'))[0];
$attackGroup = array_values(array_filter($statsAll['groups'], fn($g) => $g['groupName'] === 'Attack'))[0];
$findItem = function($items, $key) {
foreach ($items as $item) {
if ($item['key'] === $key) return $item;
}
return null;
};
$insideHome = $findItem($shotsGroup['statisticsItems'], 'totalShotsInsideBox')['homeValue'] ?? 0;
$outsideHome = $findItem($shotsGroup['statisticsItems'], 'totalShotsOutsideBox')['homeValue'] ?? 0;
$bigHome = $findItem($attackGroup['statisticsItems'], 'bigChanceCreated')['homeValue'] ?? 0;
$xgHome = $insideHome * 0.15 + $outsideHome * 0.05 + $bigHome * 0.35;
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'matchId' => $matchId,
'xg' => [
'home' => round($xgHome, 2),
],
]);
[/php]
<p>Фронтенд‑часть виджета считывает этот JSON и строит визуализацию — например, две горизонтальные шкалы xG для хозяев и гостей или линейный график. Благодаря тому, что вся тяжелая логика расчета и обращение к API сосредоточены на сервере, клиентский код остается легким и быстрым.</p>
</div>
<div class="universal_article">
<h2 id="contents-6">Настройка дизайна и параметров виджета xG‑аналитики под ваш сайт</h2>
<p>После того как базовый функционал xG‑виджета готов, самое время адаптировать его под визуальный стиль вашего ресурса. Для этого обычно достаточно набора CSS‑правил и небольшой конфигурации на JavaScript. Виджет должен естественно вписываться в общий дизайн: использовать те же шрифты, цветовую палитру, радиус скругления и отступы, что и остальные элементы сайта.</p>
<p>Один из распространенных подходов — задавать виджету конфигурацию через объект настроек: вы передаете цвета для домашней и гостевой команды, фон, тип диаграммы (столбцы, линии, прогресс‑бар), а также язык интерфейса. Эти параметры можно хранить в базе и управлять ими из админ‑панели. Ниже приведен упрощенный пример CSS‑стилей для xG‑блока.</p>
[code lang="css"]
.xg-widget {
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
background: #0b1020;
color: #ffffff;
border-radius: 12px;
padding: 16px 20px;
}
.xg-widget__bar {
display: flex;
align-items: center;
margin-bottom: 8px;
}
.xg-widget__bar-label {
width: 80px;
font-size: 13px;
}
.xg-widget__bar-track {
flex: 1;
height: 8px;
background: rgba(255, 255, 255, 0.08);
border-radius: 999px;
overflow: hidden;
}
.xg-widget__bar-fill--home {
height: 100%;
background: #1dd1a1;
}
.xg-widget__bar-fill--away {
height: 100%;
background: #ff9f43;
}
On the JavaScript side, you simply set the width .xg-widget__bar-fill--home и .xg-widget__bar-fill--away proportional to the calculated xG values. Thus, you get a neat, easily readable, and fully branded widget. If necessary, adaptive layout can be added so that on mobile devices the charts stack into a column or simplify to key figures.
If you plan to use xG analytics not only for football but also for other sports supported by the API-SPORT platform., It makes sense to extract common styles and components into a separate library. Then adding new widgets — for example, for basketball throws or dangerous moments in hockey — will require minimal code changes and will not disrupt the visual integrity of the project.
Limitations, update speed, and cost of using the xG API
Any integration based on an external API must take into account technical and commercial limitations. In the case of the xG widget, this primarily includes limits on the number of requests per unit of time, overall traffic restrictions, and reasonable caching. When designing the architecture, it is worth calculating how many matches you will be serving simultaneously, how often to update the data (for example, every 15–30 seconds for live mode), and what volume of statistics is needed for each request.
In terms of update speed, the Sport Events API is oriented towards a mode close to real-time: new events and statistics appear very quickly after they actually occur in the match. For most websites, this is more than enough, especially when using server-side caching. Additionally, the service team is developing the infrastructure: support for WebSocket connections is planned in the near future, which will allow updates to be received without constant HTTP requests and make xG graphs truly streaming.
The cost of use depends on the chosen tariff and the volume of data: levels usually differ by the number of requests, the set of available sports, and the depth of statistics. For small projects, you can start with a basic plan, and as the audience grows, switch to a more advanced one. You will find detailed terms and current capabilities (including deployable AI modules for intelligent analytics) on the website. API-SPORT — sports and betting API.
Special attention should be paid to the integration of the xG widget with the betting odds API, available through the field oddsBase in the match object. By correlating the dynamics of xG with changes in odds, you can build unique analytics panels for bettors and professional tipsters. Such a product increases the value of your resource and opens up additional monetization opportunities through affiliate programs and premium subscriptions for extended statistics.




