Skip to content

Feed integration

Replication Protocol

For reliable data delivery, a simple replication protocol is implemented. From an API point of view, it consists of two methods:

  1. getting a snapshot of all sport events
  2. getting logs(patches) regarding the version

Snapshot

A snapshot is the current state of a sport event. A snapshot has a version that sequentially progresses as the sport event changes. The version is unique across all sport events and it always ascends. The object of a sport event consists of:

  • fixture - all data on a sport event: status, type, sport, tournament, participants, venue, links to streams, etc.
  • markets - the list of markets with outcomes, odds, and statuses
  • bet_stop - when it's true placing bets on this match is suspended at the moment
  • extensions - describes additional extensions that could be attached to the sport event (e.g. see Widgets)
An example of sport event snapshot The output is formatted for readability, in the real response it will be a single line
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
{
  "id": "238dcc48-daa5-46af-81e9-3365901f4fd7",
  "meta": {},
  "markets": {
    "1": {
      "id": "1",
      "odds": {
        "1": {
          "id": "1",
          "value": "1.880000000000",
          "status": 5,
          "template": "{$competitor1}",
          "is_active": true
        },
        "2": {
          "id": "2",
          "value": "1.840000000000",
          "status": 5,
          "template": "{$competitor2}",
          "is_active": true
        }
      },
      "status": 0,
      "type_id": 1,
      "template": "Winner",
      "specifiers": {}
    },
    "20": {
      "id": "20",
      "odds": {
        "1": {
          "id": "1",
          "value": "1.900000000000",
          "status": 0,
          "template": "{$competitor1}",
          "is_active": true
        },
        "2": {
          "id": "2",
          "value": "1.860000000000",
          "status": 0,
          "template": "draw",
          "is_active": true
        },
        "3": {
          "id": "3",
          "value": "1.860000000000",
          "status": 0,
          "template": "{$competitor2}",
          "is_active": true
        }
      },
      "status": 0,
      "type_id": 20,
      "template": "1x2",
      "specifiers": {}
    },
    "14h2_5t2_5": {
      "id": "14h2_5t2_5",
      "odds": {
        "1": {
          "id": "1",
          "value": "1.920000000000",
          "status": 0,
          "template": "over {total}",
          "is_active": true
        },
        "2": {
          "id": "2",
          "value": "1.840000000000",
          "status": 0,
          "template": "under {total}",
          "is_active": true
        }
      },
      "status": 0,
      "type_id": 14,
      "template": "Total maps",
      "specifiers": {
        "hcp": "2.5",
        "total": "2.5"
      }
    }
  },
  "fixture": {
    "id": "238dcc48-daa5-46af-81e9-3365901f4fd7",
    "meta": {},
    "type": 0,
    "status": 3,
    "streams": {},
    "sport_id": "esports_counter_strike",
    "template": "{$competitor1} vs {$competitor2}",
    "start_time": "2019-04-01T15:29:31Z",
    "tournament": {
      "id": "betting:0: AOC CyberGamer Premier League  Spring. Best of 1",
      "name": " AOC CyberGamer Premier League  Spring. Best of 1",
      "master_id": "betting:0: AOC CyberGamer Premier League  Spring. Best of 1"
    },
    "updated_at": "2019-04-02T12:53:46Z",
    "competitors": {
      "betting:0:1003": {
        "id": "betting:0:1003",
        "meta": {},
        "name": "AKARA",
        "type": 2,
        "scores": {
          "total": {
            "id": "total",
            "type": "total",
            "number": 0,
            "points": "4"
          }
        },
        "home_away": 1,
        "master_id": "betting:0:1003",
        "template_position": 1
      },
      "betting:0:1015-esports_counter_strike": {
        "id": "betting:0:1015-esports_counter_strike",
        "meta": {},
        "name": "VG.J Thunder",
        "type": 2,
        "scores": {
          "total": {
            "id": "total",
            "type": "total",
            "number": 0,
            "points": "0"
          }
        },
        "home_away": 2,
        "master_id": "betting:0:1015-esports_counter_strike",
        "template_position": 2
      }
    },
    "live_coverage": false
  },
  "updated_at": "2019-04-02T12:53:46.476241Z"
}
#### Retention policy A `snapshot` of a sport event is retained for 5 days after the end of the sport event (after the sport event fixture has transit to one of the statuses: ended, closed, cancelled, abondoned). Once the retention period has expired, the `snapshot` is no longer available.

Log

A log (patch) is a set of changes to a sport event. Every log has a version (v field) which corresponds to the version of the sport event snapshot at the time when the log was created. It means that the current version of the sport event snapshot is equal to the version of the latest log entry of the corresponding sport event. There are several type of logs: match_new / match_update / bet_rollback

Retention policy

A log(patch) is retained for 3 days. Once the retention period has expired, the log is no longer available. If you try to subscribe with a log version that has already expired, the API will return a 409 HTTP code. It means that log with requested version is unavailable. If API returns 409 HTTP code for your latest processed log version it means that you must to resync all sport events by following steps from usage section.

match_new

A match_new Log contains a snapshot of a sport event (a sport event has been added or the client has requested it)

An example of match_new log entry
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
{
  "v": "1sCUN633IGv000004gfLSQ",
  "sport_event_id": "e60e4333-bfd0-42b3-a377-b9abd314acb5",
  "type": "match_new",
  "timestamp": 1573029081,
  "sport_event": {
    "id": "e60e4333-bfd0-42b3-a377-b9abd314acb5",
    "meta": {},
    "fixture": {
      "id": "e60e4333-bfd0-42b3-a377-b9abd314acb5",
      "meta": {},
      "type": 0,
      "status": 0,
      "streams": {},
      "sport_id": "handball",
      "template": "{$competitor1} vs {$competitor2}",
      "start_time": "2019-11-06T17:30:00Z",
      "tournament": {
        "id": "gin:03ddd714-6121-4ee7-b5fc-5534a4e44363",
        "name": "Denmark. HTH Ligaen. Women. Season 2019/2020",
        "master_id": "gin:03ddd714-6121-4ee7-b5fc-5534a4e44363"
      },
      "updated_at": "2019-11-06T08:31:20Z",
      "competitors": {
        "betting:1:sr:competitor:37693": {
          "id": "betting:1:sr:competitor:37693",
          "meta": {},
          "name": "HC Odense W",
          "type": 2,
          "scores": {
            "total": {
              "id": "total",
              "type": "total",
              "number": 0,
              "points": "0"
            }
          },
          "home_away": 1,
          "master_id": "betting:1:sr:competitor:37693",
          "template_position": 1
        },
        "gin:55b00ce6-fd86-43d3-9ca9-36c0bc5427af": {
          "id": "gin:55b00ce6-fd86-43d3-9ca9-36c0bc5427af",
          "meta": {},
          "name": "EH Aalborg W",
          "type": 2,
          "scores": {
            "total": {
              "id": "total",
              "type": "total",
              "number": 0,
              "points": "0"
            }
          },
          "home_away": 2,
          "master_id": "gin:55b00ce6-fd86-43d3-9ca9-36c0bc5427af",
          "template_position": 2
        }
      },
      "live_coverage": false
    },
    "markets": {},
    "updated_at": "2019-11-06T08:31:20Z"
  }
}
Markets
  • The match_new event may or may not contain market data. This means that when you first receive a match_new event, the market data could be missing.
  • Do not assume that the initial match_new event will always include markets.
  • Markets that were missing in the initial match_new event could be added in subsequent match_update events.

match_update

For this type of log, the changes field contains the paths along the nodes of the sport event object (separated by /) and the new value of this node. The protocol implies the impossibility of deleting a part of the object.

An example of match_update log entry
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
{
  "v": "1sCUN63gD6o000004gfRat",
  "sport_event_id": "e60e4333-bfd0-42b3-a377-b9abd314acb5",
  "type": "match_update",
  "timestamp": 1573029081,
  "changes": {
    "markets/20": {
      "id": "20",
      "odds": {
        "1": {
          "id": "1",
          "value": "1.010000000000",
          "status": 0,
          "template": "{$competitor1}",
          "is_active": true
        },
        "2": {
          "id": "2",
          "value": "22.000000000000",
          "status": 0,
          "template": "Draw",
          "is_active": true
        },
        "3": {
          "id": "3",
          "value": "20.000000000000",
          "status": 0,
          "template": "{$competitor2}",
          "is_active": true
        }
      },
      "status": 0,
      "type_id": 20,
      "template": "1x2",
      "specifiers": {}
    },
    "markets/841m2t44_5/status": 3,
    "markets/349/odds/1/value": "13",
    "markets/349/odds/2/value": "3.5",
    "updated_at": "2019-11-06T08:31:20Z"
  }
}

The current log means the following:

  1. market 20 has been added
  2. market (841m2t44_5) status has been updated (new status is 3)
  3. market (349) odd (1) value has changed (new value is 13)
  4. market (349) odd (1) value has changed (new value is 3.5)
bet stop flag

bet stop flag is activated when a log with bet_stop equals true is received, placing bets on this match must be suspended until a bet stop is deactivated (a log with bet_stop equals false is received). By default bet_stop is deactivated (or in case of fetching sport event snapshot it equals SportEvent.bet_stop).

An example of log entry when placing bets on this match must be suspended
1
2
3
4
5
6
7
8
9
{
  "v": "1sCUN63gD6o000214gfRat",
  "sport_event_id": "e60e4333-bfd0-42b3-a377-b9abd314acb5",
  "type": "match_update",
  "timestamp": 1573029182,
  "changes": {
    "bet_stop": true
  }
}
extensions

The extensions entry appears whether there are any updates for at a single extension at least.

Supported extensions:

  • app.data.bet/widget - defines which Widgets could be attached to the sport event.
An example of log entry when extensions on the match updated
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
  "v": "1sCUN63gD6o000214gfRat",
  "sport_event_id": "e60e4333-bfd0-42b3-a377-b9abd314acb5",
  "type": "match_update",
  "timestamp": 1573029182,
  "changes": {
    "extensions": {
      "app.data.bet/widget": {
         "types": ["pitch_tracker", "stream", "scoreboard", "h2h_statistics", "games_statistics", "teams_statistics"]
      }
    }
  }
}

Note

Extensions are optional to implement and their updates could be omited.

bet_rollback

The client must roll back all bets on the specified markets within a given period.

Important: Rolling Back All Bets

If the market_ids field is an empty array, all bets associated with the given sport_event_id must be rolled back. This ensures that no bets remain active when the rollback action is intended to apply to the entire event. The absence of specific market_ids signifies that the rollback is not limited to particular

These are possible reasons for the rollback:
1. 322 ā€“ The bet has been canceled due to suspicion of unfair play or match-fixing.
2. event_postponed_for_48_hours ā€“ The event was postponed for more than 48 hours.
3. match_was_canceled ā€“ The match did not take place as it was canceled.
4. competitor_is_incorrect ā€“ There was an error in specifying the participants: the wrong competitor was listed.
5. partial_technical_lose ā€“ The match ended partially due to technical reasons (e.g., one of the participants could not continue due to non-game-related circumstances).
6. technical_lose ā€“ The match result was decided by a technical defeat (without full gameplay).
7. crash_of_the_game ā€“ The game was interrupted due to technical issues (beyond our control), preventing the outcome from being determined.
8. after_goal ā€“ The bet was placed after the decisive event (e.g. goal) had already occurred, making it invalid (commonly referred to as a "late bet").
9. technical_error_in_coefficient ā€“ A technical error caused an incorrect coefficient to be specified in the bet.
10. pre_match_bets_after_match_start ā€“ The pre-match bet was placed after the match had already started, making it invalid.
11. wrong_match_format ā€“ The match format or conditions changed (e.g. football match had 40-minute halves instead of 45 minutes), resulting in partial refunds of the bets.
12. unplayed_market ā€“ The selected market (bet event type) was not played or did not occur.
13. competitor_refusal ā€“ One of the participants refused to participate, the match outcome was declared void.
14. duplicate_bet ā€“ A duplicate bet was detected and canceled.
15. streamsniping ā€“ The bet was canceled due to an unfair advantage (e.g. watching live streams in real-time).
16. product_ban ā€“ The bets were refunded to users who were banned from our product.
17. marketing ā€“ Bets were refunded for marketing accounts. These bets were placed for testing purposes.
18. competitor_has_been_replaced - The competitor was changed in the match.
19. options ā€“ This function was used when none of the predefined reasons applied.

An example of a bet_rollback log entry
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
{
  "v": "1sCXRWyLJkO000dnRKGnzm",
  "sport_event_id": "eb1a6310-8d37-4f67-a4c3-2ff1078788bb",
  "type": "bet_rollback",
  "timestamp": 1573039897,
  "match_id": "eb1a6310-8d37-4f67-a4c3-2ff1078788bb",
  "market_ids": [
    "1",
    "2"
  ],
  "reason": "after_goal",
  "dt_start": "2019-08-08T14:21:52Z",
  "dt_end": "2019-08-08T14:21:52Z"
}

Heartbeat message

Heartbeat is a message used to notify a consumer that a trading feed is alive. Recommended heartbeat interval is 5 seconds. If the client does not receive 2 messages in a row, it is better to reconnect to the feed.
Message contains 2 fields:
- timestamp - date (unix timestamp) when heartbeat is generated
- type - heartbeat (string constant)

An example of a message:

1
2
3
4
{
  "timestamp": 1730322895,
  "type": "heartbeat"
}

Client specified heartbeat interval in seconds via query param heartbeat_interval. For instance (client requests heartbeat message every 5 seconds):

1
2
3
4
5
6
stdbuf -oL curl --request GET \
     --url https://feed.int.databet.cloud/log?heartbeat_interval=5 \
     --cert    client.crt \
     --key     client.key \
     --header  'Last-Version: 22hAUGMBUcD000004gfQzu' \
     --verbose

Received messages
1
2
3
4
5
6
7
8
{"type":"heartbeat","timestamp":1730322895}
{"type":"heartbeat","timestamp":1730322900}
{"v":"23otd13rhgH000004gfKxs","sport_event_id":"26659569-89a6-460d-855f-d75143ad1f99","type":"match_update","timestamp":1730322901,"changes":{"updated_at":"2024-10-30T21:15:01Z","markets/20/odds/1/value":"21.26","markets/20/odds/2/value":"7.98","markets/20/odds/3/value":"1.1"}}
{"v":"23otd2ymPBZ000004gfUYG","sport_event_id":"26659569-89a6-460d-855f-d75143ad1f99","type":"match_update","timestamp":1730322903,"changes":{"updated_at":"2024-10-30T21:15:03Z","markets/20/odds/1/value":"22.54","markets/20/odds/2/value":"6.82","markets/20/odds/3/value":"1.12"}}
{"type":"heartbeat","timestamp":1730322905}
{"type":"heartbeat","timestamp":1730322910}
{"v":"23otdC3q1uH000004gfMRs","sport_event_id":"26659569-89a6-460d-855f-d75143ad1f99","type":"match_update","timestamp":1730322911,"changes":{"updated_at":"2024-10-30T21:15:11Z","markets/20/odds/1/value":"21.26","markets/20/odds/2/value":"7.98","markets/20/odds/3/value":"1.1"}}
{"v":"23otdDyRlZy000004gfFRG","sport_event_id":"26659569-89a6-460d-855f-d75143ad1f99","type":"match_update","timestamp":1730322913,"changes":{"meta/time":"601000","updated_at":"2024-10-30T21:15:13Z","fixture/statistics_version":"29"}}

Usage

The correct way to use the feed API is the following:

  1. Request all snapshots via GET /all. In the response, the latest snapshot version will be indicated in the Last-Version header, and the sport events themselves will appear in the body, each in a separate line. Chunked transfer encoding is used for streaming sport events in HTTP 1.1 (if the sport event does not fit in one line, it can be split into several lines (according to the encoding)).

    Get a snapshot request via curl `client.crt` and `client.key` will be provided by the DATA.BET integration team.
    1
    2
    3
    4
    5
    stdbuf -oL curl --request GET \
         --url https://feed.int.databet.cloud/all \
         --cert    client.crt \
         --key     client.key \
         --verbose \ 
    
    The response:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    ...
    < Last-Version: 1znkQdjQYSW000004gfKZM
    < Last-Version-Hex: 174213d5391edf1000000001000050b8
    < X-Api-Version: 2
    < Date: Thu, 09 Feb 2023 06:28:20 GMT
    < Transfer-Encoding: chunked
    < 
    7576
    {"id":"1c43b19f-ba50-4e78-adfd-e347b1605e58","meta":{"bo": 3, "map": 1, "time": "0", "timer_running": false},"markets":{},"fixture":{"id": "1c43b19f-ba50-4e78-adfd-e347b1605e58", "meta": {"bo": 3, "map": 1, "time": "0", "timer_running": false}, "type": 0, "status": 0, "streams": {}, "version": 12, "sport_id": "esports_dota_2", "template": "{$competitor1} vs {$competitor2}","start_time": "2022-12-01T20:20:00Z", "tournament": {"id": "betting:1:sr:simple_tournament:66859", "name": "Indonesia, Pro Circuit, Minor 2018, Playoffs", "master_id": "betting:1:sr:simple_tournament:66859", "country_code": ""}, "updated_at": "2022-12-01T20:16:03Z", "competitors": {"betting:0:2-esports_dota_2": {"id": "betting:0:2-esports_dota_2", "meta": {}, "name": "Liquid", "type": 2, "scores": {"map:1": {"id": "map:1", "type": "map", "number": 1, "points": "0"}, "total": {"id": "total", "type": "total", "number": 0, "points": "0"}}, "home_away": 1, "master_id": "betting:0:2-esports_dota_2", "country_code": "ALB", "template_position": 1}, "betting:0:40-esports_dota_2": {"id": "betting:0:40-esports_dota_2", "meta": {}, "name": "qwerqwer", "type": 2, "scores": {"map:1": {"id": "map:1", "type": "map", "number": 1, "points": "0"}, "total": {"id": "total", "type": "total", "number": 0, "points": "0"}}, "home_away": 2, "master_id": "betting:0:40-esports_dota_2", "country_code": "", "template_position": 2}},"live_coverage": false},"bet_stop":false,"sources":[{"id": "dp:grid:18", "type": "grid"}],"updated_at":"2023-02-04T20:24:21.828841Z"}
    ...
    9cd7
    {"id":"4e6f3b19-b5df-4042-99d0-c8fa918be78b","meta":{"bo": 3, "map": 1, "time": "0", "timer_running": false},"markets":{},"fixture":{"id": "4e6f3b19-b5df-4042-99d0-c8fa918be78b", "meta": {"bo": 3, "map": 1, "time": "0", "timer_running": false}, "type": 0, "status": 0, "streams": {}, "version": 12, "sport_id": "esports_dota_2", "template": "{$competitor1} vs {$competitor2}","start_time": "2022-12-01T20:22:00Z", "tournament": {"id": "betting:0:test-esports_dota_2-esports_dota_2", "name": "", "master_id": "betting:0:test-esports_dota_2-esports_dota_2", "country_code": ""}, "updated_at": "2022-12-01T20:22:16Z", "competitors": {"betting:0:40-esports_dota_2": {"id": "betting:0:40-esports_dota_2", "meta": {}, "name": "qwerqwer", "type": 2, "scores": {"map:1": {"id": "map:1", "type": "map", "number": 1, "points": "0"}, "total": {"id": "total", "type": "total", "number": 0, "points": "0"}}, "home_away": 1, "master_id": "betting:0:40-esports_dota_2", "country_code": "", "template_position": 1}, "betting:0:47-esports_dota_2": {"id": "betting:0:47-esports_dota_2", "meta": {}, "name": "CSW", "type": 2, "scores": {"map:1": {"id": "map:1", "type": "map", "number": 1, "points": "0"}, "total": {"id": "total", "type": "total", "number": 0, "points": "0"}}, "home_away": 2, "master_id": "betting:0:47-esports_dota_2", "country_code": "", "template_position": 2}},"live_coverage": false},"bet_stop":false,"sources":[{"id": "dp:steam:00000000-0000-0000-0000-000000000000", "type": "steam"}],"updated_at":"2023-02-04T20:33:01.471877Z"}
    

  2. Save the snapshots and version (Last-Version header) from the previous response

  3. Subscribe to sport events updates using GET /log specifying the last saved version from step 1. The version value should be set in the Last-Version header. In the response, the server will send a line-by-line log of sports event updates. Chunked transfer encoding is used for streaming logs in HTTP 1.1 (if the log does not fit in one line, it can be split into several lines (according to the encoding)).

    Get a log request (curl) `client.crt` and `client.key` will be provided by the DATA.BET integration team.
    1
    2
    3
    4
    5
    6
    stdbuf -oL curl --request GET \
         --url https://feed.int.databet.cloud/log \
         --cert    client.crt \
         --key     client.key \
         --header  'Last-Version: 1znkFqdSqYk000004gfTOF' \
         --verbose \ 
    
    The response:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    ...
    < HTTP/1.1 200 OK
    < Cache-Control: no-cache, no-store, must-revalidate
    < Content-Type: text/event-stream; charset=utf-8
    < X-Api-Version: 2
    < Date: Thu, 09 Feb 2023 06:19:26 GMT
    < Transfer-Encoding: chunked
    <
    8000
    {"v":"1znkLg245Jk000004gfFMU","sport_event_id":"2c33429b-83b2-408a-826f-bd13aa8e005e","type":"match_new","timestamp":1675923535,"sport_event":{"id":"2c33429b-83b2-408a-826f-bd13aa8e005e","meta":{"bo":1,"game_state":"map","match_format":"default","state_number":1,"timer_running":false},"fixture":{"id":"2c33429b-83b2-408a-826f-bd13aa8e005e","meta":{"bo":1,"game_state":"map","match_format":"default","state_number":1,"timer_running":false},"type":0,"status":3,"streams":{},"sport_id":"esports_counter_strike","
    1d1
    template":"{$competitor1} vs {$competitor2}","start_time":"2025-09-27T21:00:00Z","tournament":{"id":"betting:0:aaa-esports_battlegrounds-esports_battlegrounds","name":"OLOLOLOŠ²","master_id":"betting:0:aaa-esports_battlegrounds-esports_battlegrounds","country_code":"WW-OCEANIA"},"updated_at":"2023-02-09T06:18:55Z","competitors":{"betting:0:10-esports_counter_strike":{"id":"betting:0:10-esports_counter_strike","meta":{},"name":"team1","type":2,"scores":{"map:1":{"id":"map:1","type":"map","number":1,"points":"0"},"total":{"id":"total","type":"total","number":0,"points":"0"}},"home_away":1,"master_id":"betting:0:10-esports_counter_strike","country_code":"","template_position":1},"betting:0:24-esports_counter_strike":{"id":"betting:0:24-esports_counter_strike","meta":{},"name":"","type":2,"scores":{"map:1":{"id":"map:1","type":"map","number":1,"points":"0"},"total":{"id":"total","type":"total","number":0,"points":"0"}},"home_away":2,"master_id":"betting:0:24-esports_counter_strike","country_code":"","template_position":2}},"live_coverage":false},"markets":{},"updated_at":"2023-02-09T06:18:55Z"}}
    ...
    7434
    {"v":"1znkeVDlTrX000004gfQoX","sport_event_id":"1cbfc304-b10f-4c5c-b257-de1bff68de9f","type":"match_update","timestamp":1675924605,"changes":{"updated_at":"2023-02-09T06:36:45Z","fixture/competitors/betting:7:sr:competitor:103141/score/golden_set/points":"4"}}
    

Most common issues:

1
2
  - received 400 HTTP code: requested version is not specified in `Last-Version` header
  - received 409 HTTP code: requested version has already [expired](#retention-policy-1), you must to resync all sport events (go to step 1)
  1. Every log contains the version (v field), after applying changes from the log, the version should be saved (similar to step 2) in order to be used for re-subscription (if the client's server restarts, the client has to start from step 3)

Refetch the snapshot for a specific sport event

The client can refetch a snapshot for a specific sport event (due to the logs of the sports being lost or incorrectly applied) by sending the request POST /refetch/sport-event/{sportEventId}, A match_new log entry will be added to the log with the latest version of sport event.

Conditions for accepting bets

In case if our Managed trading services (MTS) is not used some sport event properties should be taken into account when accepting bets.

Fixture status

There are 9 fixture statuses:
0 - not started (prematch sport event)
1 - live (live sport event)
2 - suspended (live sport event, sport event should be visible for bettors but placing bets should be temporarily suspended, sport event could return to Live (1))
3 - ended (sport event is ended)
4 - closed (the acceptance of bets on a sport event is closed, sport event will never become live/prematch)
5 - cancelled (deprecated) (sport event is cancelled, will never become live/prematch)
6 - abandoned (deprecated) (should be hidden for the match list, will never become valid)
7 - delayed (sport event postponed to a different time, can become live/prematch)
8 - unknown (status applies when none of the other statuses would be correct, regardless of whether the event is new, can become live/prematch)

Placing bets must be allowed only in not started (0) and live (1) statuses.
Sport event must be visible for bettors in not started (0) and live (1) and suspended (2) statuses.

Market status

There are 5 market statuses:
0 - active (bets are allowed)
1 - suspended (bets are currently not allowed but market could return to the active state)
2 - deactivated (market is not active, bets are not allowed)
3 - resulted (market has settled, bets are not allowed)
4 - cancelled (market is cancelled, bets are not allowed)

Placing bets must be allowed only in active (0) status.
Suspended markets must be visible for bettor but their odds should be hidden(bets are currently not allowed, but market could return to the active state)

Odd status and its active state

There are 7 odd statuses:
0 - not resulted (bets are allowed)
1 - win
2 - loss
3 - half win (asian handicaps)
4 - half loss (asian handicaps)
5 - refunded (all the bets should be refunded because market could not be resulted, for example: market winner for the 5th round could not be resulted if a game ended in the 3rd round)
6 - cancelled (deprecated) (all the bets should be refunded because of the reason that doesn't match refunded)

And Odd has property is_active - if it is false - placing bets should be suspended. Therefore placing bets on Odd must be allowed only if Odd is active (is_active is true) AND odd status is not resulted (0).

Bet stop

If a bet stop flag is activated placing bets on this match must be suspended. Here is a description of the conditions when the flag is activated and deactivated, as well as the event that triggers this changes.

Summary

Placing bets must be allowed if only ALL conditions are met:
Fixture status is not started (0) OR live (1) AND
Market status is active (0) AND
Odd status is not resulted (0) and Odd is_active AND
bet stop flag is deactivated

An example of sport event
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
{
   "id": "e60e4333-bfd0-42b3-a377-b9abd314acb5",
   "meta": {},
   "fixture": {
      "id": "e60e4333-bfd0-42b3-a377-b9abd314acb5",
      "meta": {},
      "type": 0,
      "status": 0,
      "streams": {},
      "sport_id": "handball",
      "template": "{$competitor1} vs {$competitor2}",
      "start_time": "2019-11-06T17:30:00Z",
      "tournament": {
         "id": "gin:03ddd714-6121-4ee7-b5fc-5534a4e44363",
         "name": "Denmark. HTH Ligaen. Women. Season 2019/2020",
         "master_id": "gin:03ddd714-6121-4ee7-b5fc-5534a4e44363"
      },
      "updated_at": "2019-11-06T08:31:20Z",
      "competitors": {
         "betting:1:sr:competitor:37693": {
            "id": "betting:1:sr:competitor:37693",
            "meta": {},
            "name": "HC Odense W",
            "type": 2,
            "scores": {
               "total": {
                  "id": "total",
                  "type": "total",
                  "number": 0,
                  "points": "0"
               }
            },
            "home_away": 1,
            "master_id": "betting:1:sr:competitor:37693",
            "template_position": 1
         },
         "gin:55b00ce6-fd86-43d3-9ca9-36c0bc5427af": {
            "id": "gin:55b00ce6-fd86-43d3-9ca9-36c0bc5427af",
            "meta": {},
            "name": "EH Aalborg W",
            "type": 2,
            "scores": {
               "total": {
                  "id": "total",
                  "type": "total",
                  "number": 0,
                  "points": "0"
               }
            },
            "home_away": 2,
            "master_id": "gin:55b00ce6-fd86-43d3-9ca9-36c0bc5427af",
            "template_position": 2
         }
      },
      "live_coverage": false
   },
   "markets": {
      "20": {
         "id": "20",
         "odds": {
            "1": {
               "id": "1",
               "value": "1.010000000000",
               "status": 0,
               "template": "{$competitor1}",
               "is_active": false
            },
            "2": {
               "id": "2",
               "value": "22.000000000000",
               "status": 0,
               "template": "Draw",
               "is_active": true
            },
            "3": {
               "id": "3",
               "value": "20.000000000000",
               "status": 0,
               "template": "{$competitor2}",
               "is_active": true
            }
         },
         "status": 0,
         "type_id": 20,
         "template": "1x2",
         "specifiers": {}
      },
      "21": {
         "id": "22",
         "odds": {
            "1": {
               "id": "1",
               "value": "1.300000000000",
               "status": 0,
               "template": "{$competitor1}",
               "is_active": false
            },
            "2": {
               "id": "2",
               "value": "22.000000000000",
               "status": 0,
               "template": "Draw",
               "is_active": true
            },
            "3": {
               "id": "3",
               "value": "20.000000000000",
               "status": 0,
               "template": "{$competitor2}",
               "is_active": true
            }
         },
         "status": 1,
         "type_id": 21,
         "template": "Winner",
         "specifiers": {}
      }
   }
}

It's allowed to place bets on market.id 20 and its odds with id 2 and 3 because fixture status is not started (0) AND market status is active AND odd status is not_resulted (0) AND odd is active (is_active=true).
It's forbidden to place bets on market.id 20 and its odd with id 1 because odd is NOT active (is_active=false).
It's forbidden to place bets on any outcome of market.id 21 because market status is suspended (NOT active).

Swagger