LiveData API

LiveData API provides access to all match information with no delay covered by our Universal Data Format. The Universal Data Format provides unified representation of all sports - football, basketball, esports (CS:GO, LoL, Dota 2, EA FIFA, NBA2K, etc.) just to name a few. Sport specific information is pushed to the edges and explicitly tagged as such.

LiveData API sends JSON messages over WebSocket to allow easy integration in any modern programming language.

Different aspects of the Unified Data Format are sent over LiveData API via channels. The following channels are currently available - teams, score, in-game, incidents and outbound-messages. Each channel supports two actions - subscribe and get. Subscribe action pushes channel information to clients as soon as there is a change whereas get action - returns a single message with the current state of that channel. Note that upon subscribe a get call is always issued so a response is immediately received.

Channels teams, score, in-game, incidents are mainly used for visualisation and outbound-messages is well suited for betting purposes.

There are 2 types of outbound-messages game-status and in-play.

Connecting to the LiveData API

                
wss://api.hudstats.com/live

Command format:

{
    "action": <subscribe|get>,
    "channel": <teams|score|incidents|in-game|outbound-messages>,
    "token": <AUTH TOKEN>,
    "fixture": <FIXTURE IDENTIFIER>
}
        

Token is fetched via the authentication endpoint and fixture identifier - from the Covered incidents.

Example:

                
wscat --connect wss://api.hudstats.com/live

Connected (press CTRL+C to quit)
< {"version": ""0.38.2"}

> {
"action": "subscribe",
"channel": "in-game",
"token": "eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyIjoidXNlciIsImV4cCI6MTYwMjE2MzY4M30.ydn5qW6_PxPeTtWdXmCDGEpYqksvlD7e5m1wLK7WbL4"
"fixture": "esports:match:b20f4275-8060-4d17-a15c-8fb2963effa6",
}
        

Channel responses

Common response format:

                
{
    "status":  <ok|warning|error>
    "publishedAt": <timestamp in millis>,
    "id": <unique identifier for each message>,
    "channel": <channel name from originating command>,
    "action": <action from originating command>,
    "fixture": <fixture identifier from originating command>,
    "payload":{
      <channel/status specific payload>
   }
}
        

Channel specific payloads are described below. Warning and Error payload contain a single key message.

Example:

                
{
   "status":"warning",
   "publishedAt":1625779279246,
   "id":"b26db3b6-e907-48cd-9e5d-37bde6b3829e",
   "channel":"teams",
   "action":"subscribe",
   "fixture":"esports:match:b20f4275-8060-4d17-a15c-8fb2963effa6",
   "payload":{
      "message":"No active streams for this fixture."
   }
}
        

Note that warning completes the action. In this case the client is subscribed to team updates for that fixture and when a stream starts - updates will be pushed. Determining whether the fixture has already been covered or is in the future will be covered in a separate API for pre/post match.

Teams update payload format:

                
"payload":{
      "teams":{
         "home":{
            "id":<team identifier>,
            "name":<team name>,
            "lineup":[
               <player identifier>,
               <player identifier>,
               ...
            ],
            "logo":<URL with team logo’s PNG>,
            "fulltimeStatistics": <Sport specific team statistics>
         },
         "away":{
            "id":<team identifier>,
            "name":<team name>,
            "lineup":[
               <player identifier>,
               <player identifier>,
               ...
            ],
            "logo":<URL with team logo’s PNG>,
            "fulltimeStatistics": <Sport specific team statistics>
         },
         "players":{
            <player identifier>:{
               "id":<player identifier>,
               "name":<player name>,
               "team":<home|away>
            },
            <player identifier>:{
               "id":<player identifier>,
               "name":<player name>,
               "team":<home|away>
            },
            ...
         }
      },
      "sportName":<sport name like CS:GO, Dota2, LoL, etc>
      "sourceData":<official|unofficial>,
      "replay":<true|false>
   }
        

Score update payload format:

                
"payload":{
      "score":{
         "home":{
            "matchScore":<title specific>,
            "fixtureScore":<matches won in the fixture>,
            "side":<title specific>
         },
         "winner":<home|away|pending>,
         "tournament":<tournament name>,
         "currentMatchNumber":<number>,
         "matchEnded":<true|false>,
         "maxMatches":<number>,
         "home":{
            "matchScore":<title specific>,
            "fixtureScore":<matches won in the fixture>,
            "side":<title specific>
         },
         "fixtureEnded":<true|false>,
         "organizer":<organizer name>
      },
      "sportName":<sport name like CS:GO, Dota2, LoL, etc>
      "sourceData":<official|unofficial>,
      "replay":<true|false>
   }
        

Incident payload format:

                
"payload":{
      "incident": { <INCIDENT> },
      "sportName":<sport name like CS:GO, Dota2, LoL, etc>
      "sourceData":<official|unofficial>,
      "replay":<true|false>
   }
        

Unified incident format values are described in the “Incidents” section below.

In-game payload format:

                
"payload":{
      "inGame":{
         "time":<in-game time in milliseconds>,
         "players":[
            {
               "id":<player identifier>
               "team":<home|away>
               "position":{
                  "x":<integer coordinate>,
                  "y":<integer coordinate>,
                  ["z":<integer coordinate>]
               },
               "sportSpecific":{<sport specific player stats}
                                       },
                                       {
               "id":<player identifier>
               "team":<home|away>
               "position":{
                  "x":<integer coordinate>,
                  "y":<integer coordinate>,
                  ["z":<integer coordinate>]
               },
               "sportSpecific":{<sport specific player stats}
                                       },
                                       ...
                                       ],
         "stats":{
            "home":{<sport specific team stats},
            "away":{<sport specific team stats}
                           },
         "paused":<true|false>,
         "sportSpecific":{
            ;; LoL and Dota2 specific fields
            "pickAndBan":<true|false>,
            "structures":[...],
            "monsters":[...]

            ;; CS:GO specific fields
            "freezed":<true|false>,
            "freezeDuration":<freeze time in milliseconds>,
            "round":<round number>,
            "map":<CS:GO map name>,
            "bomb":{
               "position":{
                  "x":<integer coordinate>,
                  "y":<integer coordinate>,
                  "z":<integer coordinate>
               }
               "planted":<true|false>
            }
         }
      },
      "sportName":"LOL",
      "sourceData":"official",
      "replay":true
   }
        

Incident format

Here’s the common incident format:

                
{
      "name": <Sport specific - kill, dealt-damage, level-up, etc>,
      "type": <incident category - player, team, match>
      "time": <in-game time in milliseconds, interpretation of the value depends on the period value>,
      "period":
      {
          "type": <Sport specific. Currently could be round, match, pick-and-ban>,
          "value": <period identifier like round number>
      },
      "payload": <incident specific payload>
   }
        

Each type of incident has a specific payload. Here’s a list of all supported incidents per title.