# Live P\&B Tracking

The P\&B Tracking websocket contains a live 'stream' of the team, player, ball and referee locations happening within a match. These are typically for clients wanting to integrate P\&B tracking data for visualisations but not live betting markets.

This websocket provides an updated list of player positions and speeds and describes actions as they occur, such as passes and player sprints. The authentication token provided will be required to make a connection to this websocket endpoint. Once you have the API token, any further data that you send over the connection will be ignored. This endpoint sends heartbeats in-between data packets to let you know that it is still connected.

## Endpoint URL

## Live P\&B Tracking

`CONNECT` `wss://dde-generic-datastream.dde-prod.imgarena.dev/ws/soccer/tracking/low_latency`

{% tabs %}
{% tab title="404: Not Found Unknown Fixture" %}

```javascript
{
    "message": "Could not find fixture topic soccer.tracking.enrichment.08456e52-9cf7-48cc-913c-f45ec",
    "level": "WARN"
}
```

{% endtab %}

{% tab title="400: Bad Request Failed Authentication Request" %}

```javascript
{
    "message": "Authentication message had incorrect format",
    "level": "ERROR"
}
```

{% endtab %}

{% tab title="200: OK " %}

```json
{
   "id":"5501b26a-1c44-4c3b-9ff5-9322084d41f9",
   "ix":0,
   "mt":5,
   "ph":1,
   "st":"running",
   "ut":1682899391822,
   "ba":{
      "jn":-1
   },
   "hm":[
      {
         "tr":"12",
         "ro":2,
         "jn":-1,
         "d":0.126,
         "v":0.168,
         "pn":[
            -19.08,
            -12.94
         ]
      },
      {
         "tr":"13",
         "ro":2,
         "jn":-1,
         "d":0.251,
         "v":0.114,
         "pn":[
            -20.57,
            1.94
         ]
      },
      {
         "tr":"15",
         "ro":2,
         "jn":-1,
         "d":0.256,
         "v":0.419,
         "pn":[
            -0.86,
            -15.46
         ]
      },
      {
         "tr":"16",
         "ro":2,
         "jn":-1,
         "d":1.828,
         "v":1.009,
         "pn":[
            -25.81,
            15.44
         ]
      },
      {
         "tr":"3",
         "ro":2,
         "jn":-1,
         "d":1.51,
         "v":1.068,
         "pn":[
            -12.6,
            7.05
         ]
      },
      {
         "tr":"6",
         "ro":2,
         "jn":-1,
         "d":1.134,
         "v":3.235,
         "pn":[
            0.55,
            -8.38
         ]
      },
      {
         "tr":"9",
         "ro":2,
         "jn":-1,
         "d":0.277,
         "v":0.287,
         "pn":[
            -3.38,
            -10.63
         ]
      },
      {
         "tr":"22",
         "ro":1,
         "jn":22,
         "pl":"302877e7-8943-4923-a335-599e9cb9ad27",
         "d":0.815,
         "v":0.386,
         "pn":[
            -47.28,
            0.66
         ]
      },
      {
         "tr":"8",
         "ro":2,
         "jn":39,
         "pl":"e1abeb34-55d6-427c-bca0-60122ac1d14e",
         "d":0.616,
         "v":1.008,
         "pn":[
            -1.08,
            9.72
         ]
      },
      {
         "tr":"19",
         "ro":2,
         "jn":44,
         "pl":"4f834b28-d15b-4cbb-9859-0bf8d42abc09",
         "d":0.916,
         "v":0.319,
         "pn":[
            -22.4,
            22.85
         ]
      },
      {
         "tr":"20",
         "ro":2,
         "jn":98,
         "pl":"a6d87f3d-74d4-4b90-b2fa-bb21a443fd15",
         "d":0.114,
         "v":0.188,
         "pn":[
            -6.14,
            23.5
         ]
      }
   ],
   "aw":[
      {
         "tr":"1",
         "ro":2,
         "jn":-1,
         "d":0.773,
         "v":1.169,
         "pn":[
            -0.43,
            0.05
         ]
      },
      {
         "tr":"11",
         "ro":2,
         "jn":-1,
         "d":0.634,
         "v":0.884,
         "pn":[
            19.38,
            0.96
         ]
      },
      {
         "tr":"14",
         "ro":2,
         "jn":-1,
         "d":0.346,
         "v":0.614,
         "pn":[
            19.76,
            15.1
         ]
      },
      {
         "tr":"17",
         "ro":2,
         "jn":-1,
         "d":0.36,
         "v":0.747,
         "pn":[
            0.14,
            -18.01
         ]
      },
      {
         "tr":"2",
         "ro":2,
         "jn":-1,
         "d":0.455,
         "v":0.751,
         "pn":[
            7.25,
            6.27
         ]
      },
      {
         "tr":"4",
         "ro":2,
         "jn":-1,
         "d":0.616,
         "v":2.21,
         "pn":[
            3.31,
            -7.91
         ]
      },
      {
         "tr":"5",
         "ro":2,
         "jn":-1,
         "d":0.114,
         "v":0.139,
         "pn":[
            8.17,
            -8.67
         ]
      },
      {
         "tr":"21",
         "ro":2,
         "jn":10,
         "pl":"44c87551-07c9-46bf-8159-cd0ab1595245",
         "d":1.685,
         "v":3.374,
         "pn":[
            -0.92,
            28.26
         ]
      },
      {
         "tr":"18",
         "ro":2,
         "jn":13,
         "pl":"0cce01c6-f2fb-451a-a1a8-126b73aaeb2e",
         "d":0.256,
         "v":0.123,
         "pn":[
            0.44,
            20.06
         ]
      },
      {
         "tr":"10",
         "ro":2,
         "jn":44,
         "pl":"ed555296-8161-42a1-a9af-b9e897aaa275",
         "d":0.232,
         "v":0.968,
         "pn":[
            0.15,
            12.51
         ]
      }
   ],
   "rf":[
      {
         "tr":"25",
         "ro":5,
         "jn":-1,
         "d":0.587,
         "v":0.468,
         "pn":[
            -24.1,
            -34.4
         ]
      },
      {
         "tr":"26",
         "ro":4,
         "jn":-1,
         "d":0.044,
         "v":0.004,
         "pn":[
            22.39,
            34.91
         ]
      },
      {
         "tr":"7",
         "ro":3,
         "jn":-1,
         "d":3.249,
         "v":1.58,
         "pn":[
            -7.39,
            7.35
         ]
      }
   ]
}
```

{% endtab %}
{% endtabs %}

## Polling limits

IMG Arena monitor the incoming traffic from our customers and strive to ensure that traffic is controlled, in-keeping with our guidelines and not unnecessarily excessive. We would suggest a polling rate of 5 requests per second, whilst we strive towards implementing rate limiting.

### Connection Protocol

This section defines how to connect to the websocket. This works well in Postman.

<details>

<summary>Submit Auth Request</summary>

1. Open websocket connection to the host and path for the data feed desired
2. Submit authentication request

a. Use the same bearer token used to access any other part of the DDE\
b.

```json
{
  "authToken": "<BEARER TOKEN>"
}
```

</details>

<details>

<summary>Successful Authentication Response</summary>

Successful authentication will return a json response\
{

```json
  "message":"Authorisation accepted",
  "level":"INFO"
}
```

</details>

<details>

<summary>Heartbeats</summary>

At this point a Heartbeat will be sent every 10seconds

```json
{
    "message": "Heartbeat sent at <ISO_DATE_TIME_STAMP>",
    "level": "INFO"
}
```

</details>

<details>

<summary>Submit a fixture request</summary>

```json
{
  "fixtureId": "<FIXTURE ID>", 
  "backfill": <BACKFILL>
}
```

1. Backfill Logic
   1. `n = null` -> all messages from start of feed + all future messages
   2. `n = -1` -> all messages from start of feed + all future messages
   3. `n = 0` -> all future messages ONLY
   4. `n > 0` -> last `n` messages + all future messages

If the fixture exists then the data feed will commence

**Once a fixture has been requested and accepted, any further fixture requests will be ignored.The connection must be closed and a new one opened to get a new fixture feed**

</details>

### Replay Fixture Request

This should be done by making the fixture request as below:

```json
{
  "fixtureId": "<FIXTURE ID>", 
  "backfill": <BACKFILL>,
  "replay": {
    "enabled" : <boolean true/false>,
    "packetsPerSecond": <PACKETS_PER_SECOND>,
    "looped": <boolean true/false>
  }
}
```

1. `enabled` is a boolean denoting if the replay functionality should be enabled or not. This allows you to use the same JSON body for all requests but to not have a request be a replay.
2. `packetsPerSecond` is an integer between 1 and a 1000 denoting the number of packets that should be sent per second.

   a. The upper limit of 1000 is currently due to the speed we can read off kafka and produce to the websocket
3. `looped` is a boolean denoting if the replay should loop when the end of the feed is reached. This allows you to request a match to keep replaying without making any further requests.

   a. Note that the replay will end when you close the websocket

<br>

## Response Fields

<table><thead><tr><th width="162">Properties</th><th width="151.33333333333331">Sub Properties</th><th>Description</th></tr></thead><tbody><tr><td>id<br><mark style="color:blue;">String</mark></td><td></td><td>fixtureId as defined in DDE</td></tr><tr><td>ix<br><mark style="color:blue;">Integer</mark></td><td></td><td>Index per channel and sub-type (event type in event channel)</td></tr><tr><td>mt<br><mark style="color:blue;">Integer</mark></td><td></td><td>Match time- time clock of the phase [milliseconds]</td></tr><tr><td>ph<br><mark style="color:blue;">Integer</mark></td><td></td><td>Phase - number of the current phase</td></tr><tr><td>st<br><mark style="color:blue;">String</mark></td><td></td><td>State of the current phase: [start] first message of the phase [running] phase is in progress [end] final message of the phase</td></tr><tr><td>ut<br><mark style="color:blue;">Integer</mark></td><td></td><td>UTC time, in milliseconds</td></tr><tr><td>ba<br><mark style="color:blue;">Integer</mark></td><td></td><td>Ball - Statistics on the ball</td></tr><tr><td></td><td>jn<br><mark style="color:blue;">Number</mark></td><td>Jersey number for the player, -1 for unknowns</td></tr><tr><td></td><td>pn<br><mark style="color:blue;">Number</mark></td><td>Position - (x, y, z) ball coordinates. Origin is the pitch centre in metres</td></tr><tr><td></td><td>tr<br><mark style="color:blue;">String</mark></td><td>Track Id of the ball</td></tr><tr><td></td><td>tm<br><mark style="color:blue;">String</mark></td><td>Team in possession of the ball</td></tr><tr><td>hm<br><mark style="color:blue;">Array</mark></td><td></td><td>Home Team - statistics on the home team's players</td></tr><tr><td></td><td>tr<br><mark style="color:blue;">String</mark></td><td>Track Id - track Id associated to the player</td></tr><tr><td></td><td>ro<br><mark style="color:blue;">Integer</mark></td><td>Role - Index identifying player's role, -1 for unknowns</td></tr><tr><td></td><td>jn<br><mark style="color:blue;">Integer</mark></td><td>Jersey number for the player, -1 for unknowns</td></tr><tr><td></td><td>pl<br><mark style="color:blue;">String</mark></td><td>Player id for the player. null for unknowns</td></tr><tr><td></td><td>d<br><mark style="color:blue;">Number</mark></td><td>Distance - distance traveled by the player since the beginning [meters]</td></tr><tr><td></td><td>v<br><mark style="color:blue;">Number</mark></td><td>Speed - current speed of the player [meters/second]</td></tr><tr><td>aw<br><mark style="color:blue;">Array</mark></td><td></td><td>Away Team - statistics on the away team's players</td></tr><tr><td></td><td>tr<br><mark style="color:blue;">String</mark></td><td>As Above</td></tr><tr><td></td><td>ro<br><mark style="color:blue;">Integer</mark></td><td>As Above</td></tr><tr><td></td><td>jn<br><mark style="color:blue;">Integer</mark></td><td>As Above</td></tr><tr><td></td><td>pl<br><mark style="color:blue;">String</mark></td><td>As Above</td></tr><tr><td></td><td>d<br><mark style="color:blue;">Number</mark></td><td>As Above</td></tr><tr><td></td><td>v<br><mark style="color:blue;">Number</mark></td><td>As Above</td></tr><tr><td>rf</td><td></td><td>Referees - statistics on the referees</td></tr><tr><td></td><td>tr<br><mark style="color:blue;">String</mark></td><td>As Above</td></tr><tr><td></td><td>ro<br><mark style="color:blue;">Integer</mark></td><td>As Above</td></tr><tr><td></td><td>jn<br><mark style="color:blue;">Integer</mark></td><td>As Above</td></tr><tr><td></td><td>d<br><mark style="color:blue;">Number</mark></td><td>As Above</td></tr><tr><td></td><td>v<br><mark style="color:blue;">Number</mark></td><td>As Above</td></tr><tr><td></td><td>pn<br><mark style="color:blue;">array</mark></td><td>As Above</td></tr></tbody></table>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sportradar.com/basketball/live-websockets/live-p-and-b-tracking.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
