How to create a Telegram bot that predicts the outcome of a match?

How the Telegram bot for sports predictions works

A Telegram bot with sports predictions is not «magic,» but a combination of several understandable components. The user sends a command or message to the bot, the bot processes the request, queries an external sports API for fresh data on the match, odds, and statistics, then calculates the probability of the outcome and sends the result back to the chat. An important point: Telegram itself is only responsible for message exchange, while all «analytics» and data processing is handled by your server, which is integrated with the sports API.

Schematic process looks like this: the user selects a sport (football, basketball, tennis, esports, etc.), then a tournament or a specific match. The bot retrieves a list of available events via the API, filtering them by date, tournament, or team. After selecting a match, the script requests detailed information: lineups, estadísticasDelPartido (shots, possession, xG-like metrics), live events, and block oddsBase with bookmaker coefficients. Based on these indicators, the bot builds a simple or advanced forecasting algorithm and generates a response in a user-friendly format.

Using the data provided by API de eventos deportivos, it is possible to implement not only pre-match predictions but also dynamic recommendations in live mode: reacting to goals, red cards, a series of dangerous attacks, and changes in coefficients. The Telegram bot becomes a full-fledged analytical assistant that monitors matches in football, hockey, basketball, table tennis, and esports 24/7. Soon, this will be complemented by an even faster update format via WebSocket and scenarios using AI models for in-depth analysis.

Choosing an API for sports events to predict match outcomes

The key to a useful and accurate Telegram bot is the right choice of sports API. For forecasting tasks, you need not just a list of matches, but detailed data: the current status of the meeting, the score, lineups, advanced statistics, and bookmaker coefficients. This allows building models that take into account both the history and form of teams, as well as market expectations. The platform api-sport.ru provides a unified API for popular sports: football, hockey, basketball, tennis, table tennis, esports, and other disciplines that are regularly added to the catalog.

When choosing a data provider for your bot, it is important to pay attention to several criteria. First, the completeness of information: the availability of endpoints for matches, tournaments, teams, players, and historical data. Second, the frequency of updates and support for live mode — without this, the bot will not be able to respond promptly to key events in the match. Third, the presence of a coefficients block oddsBase, which allows relying on market estimates of outcomes (1X2, totals, handicaps, and other markets). Fourth, transparent and detailed documentation: OpenAPI specification, request examples, field descriptions, and error codes.

A separate advantage of the API from api-sport.ru is a unified format for different sports and a stable response structure. For example, for football, you work with the path /v2/fútbol/partidos, for basketball — with /v2/basketball/matches, but the logic of the filters (date, tournament, team, status) remains predictable. This greatly simplifies the development of the bot: today you launch predictions for football, and tomorrow, without serious code restructuring, you add hockey or esports. In the future, with the emergence of WebSocket and AI functions, the API will become an even more convenient tool for building intelligent forecasting systems.

How to get a key and connect the sports API to the Telegram bot

For the Telegram bot to access the sports API, you need a personal access key (API key). The connection process begins with registration in the system. Go to the personal account of API Sport, create an account and choose the desired tariff plan. After activation of the tariffs in the interface, your unique API key will appear, which must be used in every request to the server. This key is passed in the header Autorización and serves for the identification and protection of your application.

Before integration, it is recommended to test the key in a test environment: send several requests to the endpoints /v2/deporte (list of sports), /v2/{sportSlug}/partidos (matches by date) and /v2/{sportSlug}/matches/{matchId} (details of a specific event). This way you will ensure that the key is active, limits are correctly configured, and a complete set of fields is returned — including estadísticasDelPartido, eventosEnVivo и oddsBase, which will be needed for building predictions.

In the bot’s code, the connection looks as simple as possible: you set the base URL https://api.api-sport.ru, form the headers, and perform HTTP requests using your favorite library (for example, requests in Python). Below is a minimal example of a request for a list of football matches on a specific date, which can then be integrated into Telegram bot handlers.

import requests
API_KEY = "ВАШ_API_КЛЮЧ"
BASE_URL = "https://api.api-sport.ru"
headers = {
    "Authorization": API_KEY,
}
params = {
    "date": "2025-09-03",  # дата в формате YYYY-MM-DD
}
response = requests.get(f"{BASE_URL}/v2/football/matches", params=params, headers=headers)
response.raise_for_status()
data = response.json()
print("Всего матчей:", data.get("totalMatches"))

Obtaining match data and team statistics through the API

After the key is obtained and the basic connection is set up, you can move on to the main task — collecting data for predictions. The main working endpoint for most scenarios — /v2/{sportSlug}/partidos. With its help, your Telegram bot receives a list of matches filtered by date, tournament, season, team, or status (for example, only upcoming events with the status no comenzado or current live matches with the status en progreso). This gives the user flexible options: from «matches of my team this week» to «all today’s Champions League games.».

For detailed analysis of a specific event, the endpoint is used /v2/{sportSlug}/matches/{matchId}. In the response, you receive an extended match object: tournament, season, stadium, lineups, current score, minute of the game (minutoDelPartidoActual), array eventosEnVivo and the key block for forecasts estadísticasDelPartido — structured statistics on ball possession, shots, dangerous moments, duels, and other metrics. There is also oddsBase — a set of markets with odds that can be used to assess bookmakers’ expectations and build your own probability model.

Below is an example of a simple request for detailed match information and the selection of necessary blocks for subsequent analysis in the bot. Such code can be called from the command handler /match or by clicking on a button for a specific game.

import requests
API_KEY = "ВАШ_API_КЛЮЧ"
BASE_URL = "https://api.api-sport.ru"
SPORT = "football"
MATCH_ID = 14570728  # пример ID матча
headers = {"Authorization": API_KEY}
resp = requests.get(f"{BASE_URL}/v2/{SPORT}/matches/{MATCH_ID}", headers=headers)
resp.raise_for_status()
match = resp.json()
statistics = match.get("matchStatistics", [])
odds_markets = match.get("oddsBase", [])
print("Статистика по периодам:", len(statistics))
print("Доступно рынков коэффициентов:", len(odds_markets))

The same scheme can be applied to other sports: just change sportSlug (for example, to baloncesto or deportes electrónicos). A unified approach to data structure allows building cross-sport Telegram bots, where the user receives forecasts for football, hockey, basketball, tennis, and table tennis in one interface. And with the development of the service and the emergence of new disciplines, your bot will only benefit, without requiring a complete overhaul of the architecture.

How to calculate match outcome predictions based on statistics and odds

The forecasting algorithm can be simple or very complex, but it is always based on real data. The fastest way to get a reasonable estimate of probabilities is to use bookmakers’ odds from the block oddsBase. For the 1X2 market, you take decimal odds for the home win, draw, and away win, convert them into probabilities using the formula p = 1 / k and normalize them so that the sum equals one. This way, the bot will get a basic assessment of the chances, which already takes into account the vast amount of analytics embedded in the bookmakers’ lines.

On top of this basic assessment, you can apply adjustments based on statistics from estadísticasDelPartido and historical data. For example, if a team has a high home win percentage, many shots on goal, and an advantage in xG-like metrics, you increase its final probability by 2-5 percentage points. Similarly, you can react to live events: red cards, a series of dangerous moments, or dominance in ball possession. Such rules can easily be formalized as a set of coefficients and conditions in the bot’s code, gradually complicating the model.

An example of the simplest function for converting 1X2 odds into probabilities, which can be called from the Telegram bot handler after receiving data from the API:

def implied_probability(decimal_odds: float) -> float:
    return 1.0 / decimal_odds

def normalize_probabilities(odds_home: float, odds_draw: float, odds_away: float):
    p_home = implied_probability(odds_home)
    p_draw = implied_probability(odds_draw)
    p_away = implied_probability(odds_away)
    total = p_home + p_draw + p_away
    return p_home / total, p_draw / total, p_away / total

# пример использования
odds_home, odds_draw, odds_away = 1.80, 3.50, 4.20
ph, pd, pa = normalize_probabilities(odds_home, odds_draw, odds_away)
print(f"Победа хозяев: {ph:.2%}, ничья: {pd:.2%}, победа гостей: {pa:.2%}")

You can further enhance this basic model with any factors: team form over the last rounds, head-to-head statistics, schedule (fatigue after a tight schedule), adjustments for a specific sport. In the future, as AI tools emerge in the api-sport.ru ecosystem, these tasks will become easier to solve using machine learning models that automatically adapt to new data and market behavior.

Example code for a Telegram bot in Python using a sports API

Below is a simplified example of a Telegram bot in Python, which upon the command /predict selects the nearest football match of the current day, queries the sports events API, extracts the 1X2 market odds, and calculates the probabilities of outcomes. To run it, you will need a bot token (obtained from BotFather) and an API key from the sports data service. The popular package is used as the Telegram library. python-telegram-bot, and for HTTP requests — requests.

import os
import datetime as dt
import requests
from telegram import Update
from telegram.ext import Updater, CommandHandler, CallbackContext
API_KEY = os.getenv("SPORT_API_KEY", "ВАШ_API_КЛЮЧ")
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN", "ВАШ_TELEGRAM_ТОКЕН")
BASE_URL = "https://api.api-sport.ru"
SPORT = "football"

def implied_probability(decimal_odds: float) -> float:
    return 1.0 / decimal_odds

def normalize_probabilities(odds_home: float, odds_draw: float, odds_away: float):
    p_home = implied_probability(odds_home)
    p_draw = implied_probability(odds_draw)
    p_away = implied_probability(odds_away)
    total = p_home + p_draw + p_away
    return p_home / total, p_draw / total, p_away / total

def get_today_match():
    today = dt.date.today().isoformat()
    headers = {"Authorization": API_KEY}
    params = {"date": today, "status": "notstarted"}
    resp = requests.get(f"{BASE_URL}/v2/{SPORT}/matches", params=params, headers=headers)
    resp.raise_for_status()
    data = resp.json()
    matches = data.get("matches", [])
    return matches[0] if matches else None

def build_prediction_text(match: dict) -> str:
    home = match["homeTeam"]["name"]
    away = match["awayTeam"]["name"]
    odds_markets = match.get("oddsBase", [])
    market_1x2 = None
    for m in odds_markets:
        if m.get("group") == "1X2":
            market_1x2 = m
            break
    if not market_1x2:
        return f"Матч {home} — {away}Коэффициенты 1X2 недоступны."
    odds_map = {c["name"]: c["decimal"] for c in market_1x2.get("choices", [])}
    odds_home = odds_map.get("1")
    odds_draw = odds_map.get("X")
    odds_away = odds_map.get("2")
    if not all([odds_home, odds_draw, odds_away]):
        return f"Матч {home} — {away}Не удалось получить полный набор коэффициентов."
    ph, pd, pa = normalize_probabilities(odds_home, odds_draw, odds_away)
    text = [
        f"Матч: {home} — {away}",
        f"Дата: {match['dateEvent']}",
        "",
        "Коэффициенты 1X2:",
        f"1: {odds_home}, X: {odds_draw}, 2: {odds_away}",
        "",
        "Оценка вероятностей:",
        f"Победа хозяев: {ph:.1%}",
        f"Ничья: {pd:.1%}",
        f"Победа гостей: {pa:.1%}",
    ]
    return "".join(text)

def start(update: Update, context: CallbackContext) -> None:
    update.message.reply_text(
        "Здравствуйте! Я бот-прогнозист. "
        "Отправьте /predict, чтобы получить прогноз на ближайший матч сегодня."
    )

def predict(update: Update, context: CallbackContext) -> None:
    match = get_today_match()
    if not match:
        update.message.reply_text("На сегодня не найдено предстоящих матчей.")
        return
    # при необходимости можно дополнительно запросить подробности матча по ID
    headers = {"Authorization": API_KEY}
    match_id = match["id"]
    resp = requests.get(f"{BASE_URL}/v2/{SPORT}/matches/{match_id}", headers=headers)
    resp.raise_for_status()
    full_match = resp.json()
    text = build_prediction_text(full_match)
    update.message.reply_text(text)

def main():
    updater = Updater(TELEGRAM_TOKEN)
    dp = updater.dispatcher
    dp.add_handler(CommandHandler("start", start))
    dp.add_handler(CommandHandler("predict", predict))
    updater.start_polling()
    updater.idle()

if __name__ == "__main__":
    main()

This example can be expanded almost infinitely: adding sport selection, filtering by tournaments, supporting live predictions, displaying video highlights from the field momentosDestacados, working with Webhook instead of long polling, and integrating with external AI modules. The main thing is that the foundation is already ready: the bot can safely interact with the API, obtain real odds, and return a structured prediction to the user.

Launching and hosting a Telegram bot with sports predictions on a server

Once the bot’s logic is implemented and the API integration is set up, the next step is a proper launch in production. The easiest way is to host the script on a VPS or dedicated server with Python installed. It is necessary to set up a virtual environment, install dependencies (python-telegram-bot, requests and others), set environment variables for the Telegram token and the API key of the sports service, and then run the process in 24/7 mode. For this, it is convenient to use systemd, supervisor or Docker — this way you will avoid downtime during updates and server reboots.

From the perspective of Telegram, you have two modes of operation: long polling (as in the demo code) and Webhook. The first is easier to set up and suitable for small projects, the second is more efficient and convenient for scaling, but requires an HTTPS-accessible domain and configuration of reverse requests from Telegram to your server. At the same time, you can work with the sports events API using both classic HTTP requests and, in the future, via WebSocket, which is planned to be launched on the platform. This will significantly reduce the load by eliminating frequent polling of endpoints and receiving updates on matches and odds in push mode.

For a serious project with predictions based on data api-sport.ru It is important to think through monitoring and logging.