---
id: odds-model
title: 'Модель данных: коэффициенты и группы ставок'
description: Описание структуры коэффициентов, групп ставок и отдельных исходов в ответах Sport Line API.
version: v1
language: ru
---

# Модель данных: коэффициенты и группы ставок


## Что представляет объект коэффициента

Один объект внутри `oc_list` описывает конкретный исход ставки: победу команды, ничью,
тотал, фору, событие игрока или другой доступный вариант.

Пример обычного исхода Prematch:

```json
{
  "oc_group_name": "1X2",
  "oc_name": "П1",
  "oc_rate": 1.525,
  "oc_size": 0,
  "oc_pointer": "730321837|1|1|0",
  "oc_block": false,
  "op_id": null
}
```

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

## Где возвращаются коэффициенты

| Метод | Что находится в `game_oc_list` |
|---|---|
| [`events`](../api-reference/events.md) | Краткий список основных групп и лучших коэффициентов матча |
| [`event`](../api-reference/event.md) | Полный доступный список групп и коэффициентов конкретного матча |
| `topmatches?full=true` | Краткий список, аналогичный `events` |
| `toplist?full=true` | Краткий список, аналогичный `events` |
| `topmatches` и `toplist` без `full=true` | Коэффициенты отсутствуют |
| [`search`](../api-reference/search.md) | Коэффициенты отсутствуют |

Чтобы открыть все доступные ставки выбранного матча, выполните запрос `event` по его
`game_id`.

## Группа ставок в `game_oc_list`

Поле `game_oc_list` содержит группы ставок. Каждая группа объединяет связанные исходы,
например `1X2`, тоталы, форы или персональные ставки на игроков.

| Поле | Тип | Описание |
|---|---|---|
| `group_id` | number | Технический ID группы ставок |
| `group_name` | string | Название группы на языке запроса |
| `columns` | number | Рекомендуемое количество колонок для отображения группы |
| `oc_list` | array | Исходы группы; структура зависит от метода |

Для программной логики используйте `group_id`. Поля `group_name` и `oc_group_name`
предназначены для отображения и зависят от языка запроса.

### Структура группы в `events`

В кратком списке матчей `oc_list` является обычным плоским массивом исходов:

```text
game_oc_list[]
└── группа ставок
    └── oc_list[]
        └── исход
```

Реальный сокращённый пример:

```json
{
  "group_id": 1,
  "group_name": "1X2",
  "columns": 3,
  "oc_list": [
    {
      "oc_name": "П1",
      "oc_rate": 1.36,
      "oc_pointer": "745865082|1|1|0"
    },
    {
      "oc_name": "Ничья",
      "oc_rate": 5.35,
      "oc_pointer": "745865082|1|2|0"
    },
    {
      "oc_name": "П2",
      "oc_rate": 9.4,
      "oc_pointer": "745865082|1|3|0"
    }
  ]
}
```

Поле `columns` подсказывает, как расположить исходы в интерфейсе, но сам массив
`oc_list` в `events` не разделён на вложенные колонки.

Такая же краткая структура используется в `topmatches?full=true` и
`toplist?full=true`.

### Структура группы в `event/group`

В подробном ответе конкретного матча внешний массив `oc_list` содержит колонки, а
каждый вложенный массив — исходы соответствующей колонки:

```text
game_oc_list[]
└── группа ставок
    └── oc_list[]       ← колонки группы
        └── исходы выбранной колонки
```

`columns` задаёт рекомендуемую раскладку, но не является счётчиком вложенных массивов.
В реальных ответах количество элементов внешнего `oc_list` может отличаться от
`columns`. Не используйте строгое равенство этих значений для проверки ответа.

Формат `group` рекомендуется для конкретного матча, потому что API уже:

- разделяет исходы по группам ставок;
- формирует колонки внутри каждой группы;
- сортирует связанные значения внутри колонок;
- передаёт рекомендуемое количество колонок в поле `columns`.

Сохраняйте порядок групп, колонок и исходов из ответа API. Самостоятельно перестраивать
колонки и повторно сортировать их значения не требуется.

## Примеры групп

### `1X2`: три колонки

Для группы `1X2` API вернул три колонки: победа первой команды, ничья и победа второй
команды.

```json
{
  "group_id": 1,
  "group_name": "1X2",
  "columns": 3,
  "oc_list": [
    [
      {
        "oc_name": "П1",
        "oc_rate": 1.525,
        "oc_size": 0,
        "oc_pointer": "730321837|1|1|0"
      }
    ],
    [
      {
        "oc_name": "Ничья",
        "oc_rate": 5.08,
        "oc_size": 0,
        "oc_pointer": "730321837|1|2|0"
      }
    ],
    [
      {
        "oc_name": "П2",
        "oc_rate": 6.15,
        "oc_size": 0,
        "oc_pointer": "730321837|1|3|0"
      }
    ]
  ]
}
```

### Тотал: две колонки

В группе тотала первая колонка содержит исходы «Больше», вторая — «Меньше». Внутри
каждой колонки значения уже отсортированы по `oc_size`.

```json
{
  "group_id": 17,
  "group_name": "Тотал",
  "columns": 2,
  "oc_list": [
    [
      { "oc_name": "0.5 Б", "oc_size": "0.5", "oc_rate": 1.019 },
      { "oc_name": "1 Б",   "oc_size": "1",   "oc_rate": 1.02 },
      { "oc_name": "1.5 Б", "oc_size": "1.5", "oc_rate": 1.085 }
    ],
    [
      { "oc_name": "0.5 М", "oc_size": "0.5", "oc_rate": 22.0 },
      { "oc_name": "1 М",   "oc_size": "1",   "oc_rate": 16.5 },
      { "oc_name": "1.5 М", "oc_size": "1.5", "oc_rate": 5.45 }
    ]
  ]
}
```

Пример сокращён: в полном ответе каждая колонка содержит больше значений.

### Персональные ставки

Группа персональных ставок может иметь `columns: 1`, но при этом содержать несколько
вложенных наборов исходов. В сохранённом Prematch-ответе группа «Какой игрок забьет»
содержала два таких набора. Для различения исходов разных игроков или участников
учитывайте поле `op_id`.

Набор групп, число колонок и состав исходов зависят от вида спорта и конкретного матча.
Не создавайте фиксированную схему, рассчитанную только на `1X2`, тотал или фору.

## Поля одного исхода

| Поле | Тип | Описание |
|---|---|---|
| `oc_group_name` | string | Название группы ставки на языке запроса |
| `oc_name` | string | Название конкретного исхода на языке запроса |
| `oc_rate` | number | Текущий десятичный коэффициент |
| `oc_size` | string или number | Значение тотала, форы или другого параметра исхода; для исходов без отдельного значения обычно `0` |
| `oc_pointer` | string | Основной составной код ставки или исхода. В будущем передаётся в систему приёма и расчёта ставок |
| `oc_block` | boolean | `false` — исход доступен; `true` — исход заблокирован и недоступен |
| `op_id` | number или `null` | ID игрока или участника для персонального исхода, если применимо |

## `oc_group_name`

`oc_group_name` показывает, к какой группе относится исход:

```json
{
  "oc_group_name": "Тотал"
}
```

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

Технический ID группы находится в родительском объекте `group_id`.

## `oc_name`

`oc_name` — готовое название исхода для отображения:

```json
{
  "oc_name": "П1"
}
```

Другие примеры:

```text
Ничья
3.5 Б
3.5 М
1 -3.5
Да
Эрлинг Брёут Холанн - Да
```

Набор названий зависит от вида спорта и группы ставки:

- в футболе краткий список часто содержит `П1`, `Ничья`, `П2`;
- в теннисе ничьей нет;
- в баскетболе вместо `1X2` часто используются победа первой и победа второй команды;
- в персональных ставках название может содержать имя игрока.

Не создавайте фиксированную схему, в которой каждый матч обязан иметь `П1`, `Ничья` и
`П2`. Отображайте фактически полученные группы и исходы.

## `oc_rate`

`oc_rate` содержит текущий коэффициент в десятичном формате:

```json
{
  "oc_rate": 1.525
}
```

Значение является числом, а не строкой. Коэффициенты Live и Prematch могут изменяться
при следующем обновлении ответа.

При обновлении интерфейса:

1. Найдите исход по `oc_pointer`.
2. Обновите отображаемое значение `oc_rate`.
3. Проверьте новое значение `oc_block`.
4. Если исход больше не возвращается, не продолжайте показывать старый коэффициент как
   актуальный.

Не используйте `oc_rate` как идентификатор: значение коэффициента может измениться, а
сам исход при этом останется тем же.

## `oc_size`

`oc_size` содержит числовое значение, связанное с исходом. Например:

- линию тотала;
- значение форы;
- порог персонального события;
- другое значение, необходимое конкретному типу ставки.

### Исход без отдельного значения

```json
{
  "oc_name": "П1",
  "oc_size": 0
}
```

### Тотал

```json
{
  "oc_group_name": "Тотал",
  "oc_name": "3.5 Б",
  "oc_rate": 1.23,
  "oc_size": "3.5",
  "oc_pointer": "746146992|17|9|3.5",
  "oc_block": false,
  "op_id": null
}
```

### Отрицательная фора

```json
{
  "oc_group_name": "Фора",
  "oc_name": "1 -3.5",
  "oc_rate": 6.5,
  "oc_size": "-3.5",
  "oc_pointer": "730321837|2|7|-3.5",
  "oc_block": false,
  "op_id": null
}
```

В реальных ответах `oc_size` встречается и как число, и как строка. Клиент должен
поддерживать оба JSON-типа.

Не используйте проверку только по типу значения. Например, `0` может прийти числом, а
`"3.5"` или `"-3.5"` — строкой.

Для отображения можно использовать значение как текст. Для вычислений сначала выполните
явное и безопасное преобразование в число.

## `oc_pointer`

`oc_pointer` — основной технический код ставки или исхода:

```json
{
  "oc_pointer": "730321837|2|7|-3.5"
}
```

Текущая реализация формирует его из четырёх сегментов:

```text
{game_id}|{group_id}|{outcome_type_id}|{oc_size}
```

Для примера выше:

| Сегмент | Значение | Назначение |
|---|---|---|
| 1 | `730321837` | ID матча |
| 2 | `2` | ID группы ставки |
| 3 | `7` | Внутренний ID типа исхода |
| 4 | `-3.5` | Значение `oc_size` |

В клиентской интеграции рекомендуется воспринимать `oc_pointer` как готовую непрозрачную
строку:

- сохранять полностью;
- сравнивать целиком;
- не формировать самостоятельно;
- не заменять на `oc_name`;
- не использовать только отдельные сегменты как уникальный ID.

`oc_name` зависит от языка, а `oc_rate` может изменяться. Поэтому для сопоставления
обновлений одного исхода используйте полный `oc_pointer`.

### Использование в системе приёма ставок

Sport Line API предоставляет спортивную линию, но сам по себе не выполняет приём и
расчёт ставок. Если к проекту подключена отдельная система приёма и расчёта ставок и
исходов, именно полный `oc_pointer` нужно будет передавать в неё как код выбранной ставки.

```text
выбранный исход в Sport Line API
              ↓ oc_pointer
система приёма и расчёта ставок
```

Передавайте значение точно в том виде, в котором оно получено от Sport Line API. Не
собирайте `oc_pointer` самостоятельно и не заменяйте его названием `oc_name`.

Дальнейший процесс описан в документации Coupon API:

- [формат указателя ставки](https://sportapi.net/ru/docs/coupon/bet-placement/bet-pointer.html);
- [создание купона](https://sportapi.net/ru/docs/coupon/bet-placement/place-coupon.html);
- [обработка изменения коэффициента и блокировки исхода](https://sportapi.net/ru/docs/coupon/bet-placement/odds-changes.html).

## `oc_block`

`oc_block` определяет доступность исхода.

Доступный исход:

```json
{
  "oc_rate": 1.525,
  "oc_block": false
}
```

Заблокированный исход из реального Live-ответа:

```json
{
  "oc_group_name": "Двойной шанс",
  "oc_name": "1Х",
  "oc_rate": 1.001,
  "oc_size": 0,
  "oc_pointer": "746266481|8|4|0",
  "oc_block": true,
  "op_id": null
}
```

Если `oc_block=true`, исход нельзя считать доступным только потому, что в `oc_rate`
осталось числовое значение. В интерфейсе его нужно отключить или скрыть согласно логике
продукта.

При каждом обновлении проверяйте `oc_block` повторно: статус может измениться независимо
от значения коэффициента.

## `op_id`

В обычных исходах `op_id` чаще всего равен `null`:

```json
{
  "op_id": null
}
```

Для персональной ставки поле может содержать ID игрока или участника:

```json
{
  "oc_group_name": "Какой игрок забьет",
  "oc_name": "Эрлинг Брёут Холанн - Да",
  "oc_rate": 1.53,
  "oc_size": "0.5",
  "oc_pointer": "730321837|119|5869|0.5",
  "oc_block": false,
  "op_id": 133826394
}
```

Не требуйте `op_id` для каждого исхода. Поле нужно учитывать только там, где ставка
относится к конкретному игроку или участнику.

> **Требует уточнения:** в сохранённом Prematch-ответе одной персональной группы
> несколько исходов разных игроков имели одинаковый `oc_pointer`, но разные `op_id`.
> До уточнения контракта системы приёма ставок сохраняйте для персональных исходов оба
> поля: `oc_pointer` и `op_id`.

## Live и Prematch

Поля коэффициента имеют одинаковое назначение в Live и Prematch, но данные обновляются
независимо:

- у Live- и Prematch-версий матча разные `game_id`;
- `oc_pointer` содержит `game_id`, поэтому указатели также будут разными;
- коэффициенты и блокировки нужно обновлять из соответствующего типа линии;
- нельзя переносить коэффициент из Prematch в Live.

## Практические правила интеграции

1. Получайте краткий список коэффициентов из `events`.
2. Для полного списка запрашивайте `event` с форматом `group`.
3. Используйте полный `oc_pointer` для сопоставления обычных исходов между обновлениями;
   для персональных исходов дополнительно сохраняйте `op_id`.
4. Показывайте текущее значение `oc_rate`, а не сохранённое ранее.
5. Всегда проверяйте `oc_block`.
6. Поддерживайте `oc_size` и как строку, и как число.
7. Не ожидайте одинакового набора исходов у разных видов спорта.
8. Не связывайте Live- и Prematch-коэффициенты между собой.
9. Сохраняйте порядок групп, колонок и исходов, полученный в формате `group`.

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

- [Модель данных: матч](match.md)
- [`events` — список матчей](../api-reference/events.md)
- [`event` — конкретный матч](../api-reference/event.md)
- [Единый справочник полей](field-reference.md)
