---
id: match-model
title: 'Модель данных: матч'
description: Описание основной модели матча и связей события со спортом, турниром, командами, счётом и коэффициентами.
version: v1
language: ru
---

# Модель данных: матч


## Что считается матчем

Матч — основной объект Sport Line API. Он связывает:

- вид спорта;
- страну и турнир;
- команды или участников;
- время начала;
- Prematch- или Live-данные;
- счёт, период и таймер;
- коэффициенты;
- статистику;
- субматчи;
- видео и Live 3D Tracker.

Разные методы возвращают один и тот же матч с разной детализацией. Поэтому клиенту не
следует ожидать, что каждое поле будет присутствовать или содержать данные во всех
ответах.

Полный перечень JSON-полей, типов и значений находится в
[«Едином справочнике полей Sport Line API»](field-reference.md).

## Основной идентификатор

Для работы с матчем используется `game_id`.

```json
{
  "game_id": 746146992
}
```

По этому значению можно запросить подробные данные:

```http
GET https://YOUR_API_DOMAIN/v1/event/746146992/group/live/ru
```

`game_id` нужно брать из актуального ответа API. Не формируйте его самостоятельно и не
используйте вместо него `sgame_id`, `stat_id`, `game_num`, `vi` или `zp`.

## Основной матч и субматч

Для связи основного матча с его субматчами используются два поля:

| Поле | Значение |
|---|---|
| `game_id` | ID текущего объекта — основного матча или субматча |
| `game_mid` | ID основного матча |

У основного матча значения обычно совпадают:

```json
{
  "game_id": 746146992,
  "game_mid": 746146992,
  "game_dop_name": ""
}
```

У субматча собственный `game_id`, а `game_mid` указывает на основной матч:

```json
{
  "game_id": 746147010,
  "game_mid": 746146992,
  "game_dop_name": "Угловые"
}
```

Из этого примера:

- `746147010` — ID субматча «Угловые»;
- `746146992` — ID основного матча;
- для получения коэффициентов на угловые нужно запросить `event` по `746147010`.

Нельзя подменять `game_id` значением `game_mid`: они совпадают у основного матча, но
решают разные задачи у субматча.

## Где возвращается объект матча

### `events`

Метод [`events`](../api-reference/events.md) группирует матчи по турнирам:

```text
body
└── турнир
    └── events_list
        └── матч
```

Объект содержит основные данные матча и короткий набор лучших коэффициентов. Поля
`sub_games` и `event_plan` здесь возвращаются как пустые массивы.

### `event`

Метод [`event`](../api-reference/event.md) возвращает один подробный объект непосредственно в
`body`:

```text
body
└── подробный объект матча или субматча
```

Только здесь нужно получать:

- полный доступный список коэффициентов;
- список субматчей в `sub_games`;
- заполненный `event_plan` с полным составом команд группового матча;
- подробные данные выбранного матча.

### `topmatches` и `toplist`

По умолчанию методы возвращают сокращённые карточки. При `full=true` каждый элемент
становится расширенным объектом, близким к матчу из `events`, но список коэффициентов
остаётся кратким.

`full=true` не заменяет запрос `event`.

### `search`

Метод [`search`](../api-reference/search.md) возвращает краткую карточку найденного матча с ID
страны и турнира, но без коэффициентов, статистики, субматчей, видео и трекера.

## Доступность данных в разных методах

| Данные | `events` | `event` | `topmatches` / `toplist` | С `full=true` | `search` |
|---|---:|---:|---:|---:|---:|
| `game_id`, `game_mid`, `game_start` | да | да | да | да | да |
| Названия команд и турнира | да | да | да | да | да |
| ID страны и турнира | да | да | нет | да | да |
| ID команд и массивы участников | да | да | нет | да | нет |
| Краткий список коэффициентов | да | нет | нет | да | нет |
| Полный список коэффициентов | нет | да | нет | нет | нет |
| Поле `stat_list` | да | да | нет | нет | нет |
| Заполненный `sub_games` | нет | да | нет | нет | нет |
| Заполненный `event_plan` | нет | да | нет | нет | нет |
| `va`, `vi`, `zp` | да | да | да | да | нет |

В таблице «да» означает, что поле или соответствующие данные предусмотрены структурой.
Массив может быть пустым, а необязательное значение — `null`. Статистика в `stat_list`
предоставляется только для Live-запросов `events` и `event`.

В колонке «С `full=true`» имеются в виду расширенные ответы `topmatches` и `toplist`.

## Вид спорта, страна и турнир

Матч может содержать:

```json
{
  "sport_id": 1,
  "sport_name": "Футбол",
  "country_id": 231,
  "country_name": "Англия",
  "tournament_id": 88637,
  "tournament_name": "Чемпионат Англии. Премьер-лига"
}
```

Для логики и связей используйте числовые ID. Названия зависят от языка запроса и
предназначены для отображения.

Не связывайте объекты только по `sport_name`, `country_name` или `tournament_name`:
названия могут отличаться между языками.

## Команды и участники

Основные поля сторон матча:

```json
{
  "opp_1_id": 50679,
  "opp_1_ids": [50679],
  "opp_1_name": "Арсенал",
  "opp_1_icon": "08a25897e35d75d7261a8095b9599aad.png",
  "opp_2_id": 2074,
  "opp_2_ids": [2074],
  "opp_2_name": "Ковентри Сити",
  "opp_2_icon": "2074.png"
}
```

`opp_1_ids` и `opp_2_ids` нужны, когда одна сторона состоит из нескольких участников.
Например, это могут быть теннисные пары или групповые соревнования.

В сокращённых ответах `topmatches`, `toplist` и `search` ID участников могут
отсутствовать. Если они нужны, запросите `event` по `game_id`.

### Иконки участников

Значения `opp_1_icon` и `opp_2_icon` являются именами файлов. Удалите исходное расширение
и подставьте имя в URL:

```text
https://cdn.sportapi.net/opp/v1/color/{iconName}.webp
```

Например:

```text
opp_1_icon: 8bd073a686a067e6732d8d1688a517c0.png
iconName:    8bd073a686a067e6732d8d1688a517c0
```

```text
https://cdn.sportapi.net/opp/v1/color/8bd073a686a067e6732d8d1688a517c0.webp
```

## Время начала

`game_start` содержит дату и время начала в формате Unix Timestamp, в секундах:

```json
{
  "game_start": 1787338800
}
```

Преобразовывайте значение в дату и часовой пояс на стороне приложения.

Не определяйте только по `game_start`, находится ли матч в Live. Для этого учитывайте
метод и тип линии, из которых получен объект.

## Prematch и Live — разные объекты

Prematch-матч может исчезнуть из `line` и позднее появиться в `live`, но Live-версия
получает новый `game_id`.

```text
Prematch: game_id A
        матч исчезает из line
Live:     game_id B
```

Sport Line API не предоставляет надёжного поля, которое однозначно связывает эти два
объекта. Поэтому нельзя автоматически объединять Prematch- и Live-версии одного матча.

Не пытайтесь связывать их по:

- одинаковым названиям команд;
- одинаковому `game_start`;
- турниру;
- `sgame_id` или `stat_id`.

Совпадение этих значений не является подтверждённой связью.

## Счёт и состояние Live-матча

Основные Live-поля:

| Поле | Назначение |
|---|---|
| `score_full` | Общий текущий счёт |
| `score_period` | Счёт по периодам или текущему игровому отрезку |
| `score_extra` | Дополнительный счёт, например счёт гейма в теннисе |
| `period_name` | Название текущего периода |
| `timer` | Текущее значение таймера матча в секундах |
| `extra_time` | Добавленное время, например `+10` |
| `finale` | Признак завершения, доступный не для всех матчей |
| `pitch` | ID подающего участника для соответствующих видов спорта |

Формат счёта и периодов зависит от вида спорта. Не применяйте футбольные правила разбора
ко всем видам спорта.

В Prematch эти поля обычно содержат начальные значения, пустые строки или `null`.

### Как преобразовать `timer` в минуты

`timer` передаётся в секундах. Чтобы получить минуты, разделите значение на `60`:

```text
minutes = timer / 60
```

Для отображения в формате `MM:SS`:

```js
const minutes = Math.floor(timer / 60);
const seconds = timer % 60;
const value = `${minutes}:${String(seconds).padStart(2, '0')}`;
```

Например, `timer=3376` соответствует `56:16`.

Если интерфейс показывает только номер минуты, результат деления можно округлить по
правилам интерфейса. Для количества полностью прошедших минут используйте
`Math.floor(timer / 60)`.

## Завершение доступности матча

Если Prematch-матч больше недоступен по прежнему `game_id`, метод `event` может вернуть:

```json
{
  "status": 1,
  "page": "/v1/event",
  "body": {
    "message": "Game id finished"
  }
}
```

Это сообщение не объясняет точную причину. Матч мог:

- перейти из Prematch в Live с новым ID;
- быть отменён;
- исчезнуть из линии по другой причине.

API не возвращает отдельный надёжный статус для каждого из этих случаев. После сообщения
`Game id finished` прекратите запросы по старому `game_id`, но не помечайте матч
автоматически как завершённый или отменённый.

## Субматчи

В подробном ответе `event` поле `sub_games` содержит ссылки на доступные субматчи:

```json
{
  "sub_games": [
    {
      "game_id": 746147013,
      "game_num": 150080,
      "game_name": "2-й тайм"
    },
    {
      "game_id": 746147010,
      "game_num": 205978,
      "game_name": "Угловые"
    }
  ]
}
```

Элементы `sub_games` не содержат коэффициенты. Для каждого нужного субматча выполните
отдельный запрос `event` по его `game_id`.

В `events`, `topmatches?full=true` и `toplist?full=true` поле `sub_games` возвращается как
пустой массив.

## Групповые матчи

Для группового матча подробный метод `event` может вернуть заполненный `event_plan`.
Основной матч может называться «Хозяева — Гости», а внутри перечисляется полный список
конкретных команд, играющих на стороне хозяев и на стороне гостей.

В списке `events` поле всегда пустое:

```json
{
  "event_plan": []
}
```

Заполненный `event_plan` нужно получать только через конкретный `event`.

Подробное описание дополнительных матчей, субматчей и отличий `sub_games` от
`event_plan` находится в документе
[«Дополнительные матчи и субматчи»](sub-events.md).

## Коэффициенты

`game_oc_counter` показывает общее количество доступных ставок или исходов матча.
`game_oc_list` содержит сами группы и исходы.

Структура зависит от метода:

- `events`, `topmatches?full=true`, `toplist?full=true` — краткий список лучших
  коэффициентов;
- `event` с форматом `group` — полный доступный список, организованный по группам и
  вложенным колонкам.

Для конкретного матча рекомендуется использовать `group`, потому что данные уже
сформированы по колонкам и отсортированы по значениям. Сохраняйте порядок из
ответа API: самостоятельно перестраивать и повторно сортировать исходы не требуется.

Подробная структура групп, колонок и исходов описана в документе
[«Коэффициенты и группы ставок»](odds.md).

## Статистика

Live-статистика находится в `stat_list`. Набор показателей зависит от вида спорта и
конкретного матча.

Пример четырёх показателей из реального Live-матча:

```json
"stat_list": [
  {
    "id": 93,
    "name": "xG",
    "opp1": "1.45",
    "opp2": "0.03"
  },
  {
    "id": 45,
    "name": "Атаки",
    "opp1": "61",
    "opp2": "54"
  },
  {
    "id": 58,
    "name": "Опасные атаки",
    "opp1": "44",
    "opp2": "19"
  },
  {
    "id": 29,
    "name": "Владение мячом %",
    "opp1": "65",
    "opp2": "35"
  }
]
```

| Поле | Описание |
|---|---|
| `id` | ID показателя статистики |
| `name` | Название показателя на языке запроса |
| `opp1` | Значение первой команды или участника из `opp_1_name` |
| `opp2` | Значение второй команды или участника из `opp_2_name` |

Значения `opp1` и `opp2` передаются строками, даже если внутри находится целое или
десятичное число. Для отображения можно использовать строки как есть. Для вычислений их
нужно преобразовать в числовой тип с учётом возможного формата конкретного показателя.

Отсутствие показателя или пустой `stat_list` не нужно интерпретировать как нулевое
значение статистики.

Подробное описание структуры, типов значений и подтверждённых показателей находится в
документе [«Статистика матча»](live-statistics.md).

## Видеотрансляция

| Поле | Значение |
|---|---|
| `va` | `1` — видеотрансляция доступна; `null` — недоступна |
| `vi` | ID видеотрансляции Live-матча или `null` |

Значение `va=0` не используется.

`vi` является строковым ID, а не готовым URL. SportAPI не транслирует матчи топовых
лиг. Подробные правила проверки и использования полей находятся в документе
[«Видеотрансляции в Sport Line API»](../additional-services/video-streaming.md).

## Live 3D Tracker

| Поле | Значение |
|---|---|
| `zp` | ID готового виджета Live 3D Tracker или `null` |

Для Live 3D Tracker выполняется соответствие:

```text
gameid трекера = zp спортивной линии
```

Если `zp` равно `null`, трекер для матча недоступен.

`game_id`, `vi` и `zp` имеют разное назначение и не заменяют друг друга.

Краткая связь со спортивной линией и список поддерживаемых видов спорта описаны в
документе [«Live 3D Tracker в Sport Line API»](../additional-services/live-3d-tracker.md).
[Полная инструкция по встраиванию](https://sportapi.net/ru/docs/live-3d-tracker/service-overview.html) находится в документации сервиса.

## Поля, на которые нельзя опираться

Следующие поля являются старыми, тестовыми или зарезервированными:

| Поле | Статус |
|---|---|
| `sgame_id` | Тестовое поле для будущей статистики матча, команд и игроков |
| `stat_id` | Тестовое поле для будущей подробной статистики |
| `game_num` | Старое поле, которое планируется удалить |
| `stat_list_extra` | Зарезервированное тестовое поле |
| `game_plan` | Зарезервированное тестовое поле |

Не используйте эти значения как обязательные ID, связи или признаки состояния матча.

## Рекомендуемая последовательность работы

```text
menu
  ↓
events
  ↓ game_id
event основного матча
  ├── полные коэффициенты
  ├── stat_list
  ├── sub_games ── game_id ──> event субматча
  ├── event_plan
  ├── vi
  └── zp
```

1. Получите список матчей через `events`.
2. Используйте `game_id` выбранного матча для запроса `event`.
3. Если нужны ставки на субматч, возьмите его ID из `sub_games` и выполните новый
   запрос `event`.
4. Обновляйте Prematch- и Live-матчи отдельно.
5. Не связывайте Prematch- и Live-версии матча без подтверждённого идентификатора связи.

## Связанные документы

- [`events` — список матчей](../api-reference/events.md)
- [`event` — конкретный матч](../api-reference/event.md)
- [Основные понятия](../getting-started/core-concepts.md)
- [Рекомендации по обновлению](../getting-started/update-guidelines.md)
- [Обработка ошибок](../getting-started/error-handling.md)
- [Единый справочник полей](field-reference.md)
