Frequently Asked Questions

DDE Load Testing Requirements

If you wish to do any load testing across any environment (likely DDE SIMS/STAGING), please ensure you first contact so we are aware of this ahead of time. Please ensure we have 2-3 days notice period.

integrations@imgarena.com

How should we interpret coverage downgrades within the IMG Data Feeds (REST API & Websockets)?

It is possible that coverage levels will change pre match or live during a match due to connectivity issues, data collector sickness, hardware issues with our collection tablet or otherwise. These should be more infrequent instances given we anticipate being in venue for our Official collected competitions. However, we appreciate it is important for customers to be notified in the best way and quickest way. For definitions of all collectionStatus values please use doc page here. Here is the typical behaviour

Pre-Match

  • If a match gets dropped before the match start, clients should poll the Fixtures REST API (e.g. https://dde-api.data.imgarena.com/soccer/fixtures/{fixtureId}), and utilise the collectionStatus to denote what happened. Example snippet showing "collectionStatus": "CollectionDropped". We just polling every 30 seconds during any live matches

{
    "id": "a777703c-3c72-4a09-ad3a-355a965067ad",
    "name": "Nyköbing FC v FC Helsingör",
    "status": "Unverified",
    "collectionStatus": "CollectionDropped",
    "type": "Official",
    "coverageLevel": "No Coverage",
    "startDateUTC": "2023-02-25T14:00:00",
    "teams": [
        {
            "id": "6df3101e-aae1-4ac8-8ddb-f0874ced1ed7",
            "name": "Nyköbing FC",
            "club": {
                "id": "525f6e10-0ec0-42d6-b018-c3ee864fdcbc",
                "name": "NYKÖBING FC"

Live

  • At the point a match goes live and a match gets dropped or suspended, we will update both the Fixtures REST API (e.g. https://dde-api.data.imgarena.com/soccer/fixtures/{fixtureId}), and the live actions (wss://dde-streams.data.imgarena.com/{sport}/fixtures/{fixtureId}/actions) websocket with that information. Note the websocket would stay connected in this instance and users can still get access to all data to that point it was then subsequently dropped/suspended. Here are some examples showing behaviour of the Fixtures REST API and actions websocket.

Fixtures REST API

{
    "id": "0d336f29-aebf-4ed3-a90d-2e6e0d99d0c2",
    "name": "Dunav Ruse v Etar Veliko Tarnovo",
    "status": "Completed",
    "collectionStatus": "CollectionDropped",
    "type": "Official",
    "coverageLevel": "No Coverage",
    "startDateUTC": "2023-02-19T12:00:00",
    "teams": [
        {
            "id": "411faad1-4ab5-4946-971e-f5cc1e2e8764",
            "name": "Dunav Ruse",

Actions Websocket

{
   "traceId":"3d9619f1dc5eb749508713e2328069e8",
   "version":1,
   "finished":false,
   "fixtureAction":{
      "period":0,
      "actionId":"593ea1ea-03db-4f81-a9a0-6827bbb934ca",
      "metadata":{
         "fixtureStatus":7,
         "collectionStatus":4
      },
      "sendType":"Confirmed",
      "clockTime":"00:00",
      "fixtureId":"0d336f29-aebf-4ed3-a90d-2e6e0d99d0c2",
      "timestamp":"2023-02-22T08:42:36.463604Z",
      "sendTypeId":5,
      "fixtureSeqNum":595,
      "timelineSequence":0.0000000000000595,
      "fixtureActionType":"Status Updated",
      "fixtureActionTypeId":22
   },
   "fixtureSummary":{
      "isTied":true,
      "periods":[
         {
            "id":1,
            "end":"2023-02-19T12:51:37",
            "type":"Regular",
            "label":"1st half",
            "start":"2023-02-19T12:04:31",
            "awayTeamScore":0,
            "homeTeamScore":0,
            "awayTeamPeriodScore":0,
            "homeTeamPeriodScore":0
         },
         {
            "id":2,
            "end":"2023-02-19T13:56:59",
            "type":"Regular",
            "label":"2nd half",
            "start":"2023-02-19T13:08:09",
            "awayTeamScore":0,
            "homeTeamScore":0,
            "awayTeamPeriodScore":0,
            "homeTeamPeriodScore":0
         }
      ],
      "finished":false,
      "awayTeamScore":0,
      "currentPeriod":2,
      "currentStatus":"Unverified",
      "homeTeamScore":0,
      "collectionStatus":"CollectionDropped",
      "currentClockTime":"45:00",
      "isHomeTeamInPossesion":true
   }
}
Under which situations will scouts send possible VAR?

The VAR can be used only in three situations; Penalty, Goal & Red Card

First one is "Possible Video Check". Choosing this button means possibility of the Data Collector's decision of taking a VAR by referee during handballs or unclear fouls within the penalty area or dangerous attacks that can result in a red card.

Is there an End of Possible VAR or No VAR action code?

Not at this moment in time, when the ball is out of play after the Data Collector clicks "possible VAR", and the referee does not stop the game to check the VAR. Please note we will be adding a No VAR button in due course.

Are scouts allowed to continue reporting before 'resolving' Possible VAR (either with VAR start or No VAR)?

Yes - they would keep scoring and would send a message that a Possible Var has happened, and the referee may check it when the ball is out of play.

In a VAR competition, if a player is fouled in the area but the penalty is not immediately given, how exactly will the scout report on this?

In this case, the Data Collector would click "Possible VAR" button, and would then select "Potential Penalty Awarded" as the sub type. Then the Data Collector would continue scoring.

When exactly will the scout send the Possible VAR action - when the player is fouled, or when the scout believes the foul might be being reviewed by VAR?

The Data Collector would click "Possible VAR" button when they believe that the foul might be being reviewed by VAR later once the ball is out of play.

Is there a separate Possible Penalty action, or only one embedded in the Possible VAR workflow (6401)?

Only the one embedded in the "Possible VAR" button - there are three sub types in "Possible VAR":

  • "Potential Penalty Awarded"

  • "Potential Red Card"

  • "Other"

Relating to penalties, will you always 'resolve' these either by Goal or Penalty Missed?

There is also a 3rd option for penalty result which is "Penalty Retake", however, once it's retaken the result would be either:

  • "Goal" - sub type:

    • "Penalty Goal"

    OR

  • "Penalty Missed" - sub type:

    • "Woodwork",

    • "Wide/Over"

    • "Saved"

How do I Interpret and use lineup Information with the /actions Websocket?

Within the /actions websocket, we have a specific fixtureActionType packet for 'Lineups'. This will notify a user of the starting lineup & substitutes information prior to a match KO. Typically this can come in anytime within 1 hour of Kick off.

In the soccer example below, there is a startingLineup which includes the start 11 players and then the substitutes for the players on the bench. Typically this is used by onward consumers of the data to display a team list and is often important information for both Betting Operators/Traders and Media customers.

{
   "fixtureAction":{
      "timestamp":"2022-07-08T15:17:16.324929Z",
      "actionId":"f52ab76d-5102-4090-87fd-4a2219c41e59",
      "fixtureSeqNum":10,
      "clockTime":"00:00",
      "fixtureActionType":"Lineups",
      "fixtureActionTypeId":3,
      "sendTypeId":5,
      "sendType":"Confirmed",
      "team":{
         "id":"aba100e8-a29a-4bc3-8f87-eb669b34c5a7",
         "name":"Botev Plovdiv"
      },
      "fixtureId":"4781718f-bba3-4e7b-a16f-1ccddf91c28d",
      "metadata":{
         "startingLineup":[
            {
               "fullName":"Hidajet  Hankić",
               "lastName":"Hankić",
               "firstName":"Hidajet ",
               "id":"1811defb-e308-4f72-9a41-450aba7bae85",
               "shirtNumber":"13"
            },
            {
               "fullName":"Viktor  Genev",
               "lastName":"Genev",
               "firstName":"Viktor ",
               "id":"465dbb46-231e-4f42-b55d-ede0b51dbf21",
               "shirtNumber":"4"
            },
            {
               "fullName":"Emmanuel  Toku",
               "lastName":"Toku",
               "firstName":"Emmanuel ",
               "id":"e1696259-db6f-4f83-8d3c-e4f2c245b94b",
               "shirtNumber":"10"
            },
            {
               "fullName":"Jasper  van Heertum",
               "lastName":"van Heertum",
               "firstName":"Jasper ",
               "id":"b4216142-3d54-44cb-ac02-ae85134b9553",
               "shirtNumber":"24"
            },
            {
               "fullName":"Pa  Konate",
               "lastName":"Konate",
               "firstName":"Pa ",
               "id":"0f2ccd1d-5966-4026-bd8d-9e78cc11f498",
               "shirtNumber":"3"
            },
            {
               "fullName":"Antoine  Baroan",
               "lastName":"Baroan",
               "firstName":"Antoine ",
               "id":"914112d5-c839-409f-b436-8ad111227d09",
               "shirtNumber":"11"
            },
            {
               "fullName":"Dimitar  Tonev",
               "lastName":"Tonev",
               "firstName":"Dimitar ",
               "id":"a831e6ba-5783-46df-a51a-4522e7d6c2eb",
               "shirtNumber":"23"
            },
            {
               "fullName":"Roberto Puncec",
               "lastName":"Puncec",
               "firstName":"Roberto",
               "id":"d1f476f8-f17f-49a1-bf59-6def49a1745e",
               "shirtNumber":"44"
            },
            {
               "fullName":"Tochukwu  Nadi",
               "lastName":"Nadi",
               "firstName":"Tochukwu ",
               "id":"ca565d32-b89e-4eca-835a-eb5955a5a588",
               "shirtNumber":"21"
            },
            {
               "fullName":"Dylan  Mertens",
               "lastName":"Mertens",
               "firstName":"Dylan ",
               "id":"fe748c54-e038-41a6-9654-b9aafa90a66f",
               "shirtNumber":"6"
            },
            {
               "fullName":"Nikolay  Minkov",
               "lastName":"Minkov",
               "firstName":"Nikolay ",
               "id":"da7bad00-3340-4e3d-94f7-1664ee5cc6c8",
               "shirtNumber":"17"
            }
         ],
         "substitutes":[
            {
               "fullName":"Georgi  Argilashki",
               "lastName":"Argilashki",
               "firstName":"Georgi ",
               "id":"46564a3a-2894-4055-b466-acc997c7b3cc",
               "shirtNumber":"1"
            },
            {
               "fullName":"Biser  Bonev",
               "lastName":"Bonev",
               "firstName":"Biser ",
               "id":"6145d88e-fec2-48c4-bc0a-fb46c5c96436",
               "shirtNumber":"14"
            },
            {
               "fullName":"Lachezar  Baltanov",
               "lastName":"Baltanov",
               "firstName":"Lachezar ",
               "id":"ee56d6de-0cbd-4a0a-b5f9-2dd0b40e463f",
               "shirtNumber":"20"
            },
            {
               "fullName":"Hristiyan Slavkov",
               "lastName":"Slavkov",
               "firstName":"Hristiyan",
               "id":"27569b0b-27a8-4ddc-9a1d-209f7ef2ae6a",
               "shirtNumber":"84"
            },
            {
               "fullName":"Atanas Chernev",
               "lastName":"Chernev",
               "firstName":"Atanas",
               "id":"d1125214-0a83-46ea-809f-6095894437ab",
               "shirtNumber":"27"
            },
            {
               "fullName":"Monir Al-Bodarin",
               "lastName":"Al-Bodarin",
               "firstName":"Monir",
               "id":"5896e7e0-6550-4ef6-995e-a9e7bbc4cbac",
               "shirtNumber":"38"
            },
            {
               "fullName":"Samuel Akere",
               "lastName":"Akere",
               "firstName":"Samuel",
               "id":"4ffb8153-2280-4651-9617-78e5a0264123",
               "shirtNumber":"16"
            }
         ],
         "teamId":"aba100e8-a29a-4bc3-8f87-eb669b34c5a7"
      },
      "period":0
   },
   "fixtureSummary":{
      "awayTeamScore":0,
      "currentClockTime":"00:00",
      "periods":[
         
      ],
      "homeTeamScore":0,
      "isTied":true,
      "isHomeTeamInPossesion":false,
      "finished":false,
      "currentPeriod":1,
      "currentStatus":"LineUps"
   },
   "version":1
}
How should we deal with Data Corrections?

Given all our fastpath betting data is collected in venue by humans, there is a risk of real-time corrections being made given that human error can occur. We have added a sendType value within the /actions websocket to denote the following:

1 Pending (possible action packet) 2 Updated (updates info on confirmed packets) 3 Cancelled (invalidates pending packet) 4 Deleted (deletes confirmed packets) 5 Confirmed (confirmed packet and can be added)

Note that Pending actions can be cancelled, Confirmed actions can be deleted and typically all key actions (card, goal, penalty) start with the Pending state. Please note that "Updated" is not only used for actions that have been deleted. It also used for any change of players or sub types or anything else regarding a previously "Confirmed" action.

Upon Deleted message (goal deletion), you will have a linked relatedFixtureActionsTypeIds with the UUID of the original deleted goal

How should we best create a clock timer logic using /actions websocket?

The scoreboard clock timer on our Data Console product is run on a browser based 1 second update function, which on each interval, checks for an active Websocket connection, as well as the isClockActive flag. If either are false the clock will not update on the subsequent second.

If the clock update function is running. All packets that include a clockTime value will update the clock state, and the update function will add a second to the updated value. The clock value will only update if the time is later than what is persisted in state. In some cases action messages have a clock time that is before what is stored in local state, in which case the clock will not use the clockTime in the latest message.

Websocket fixture action IDs that set the isClockActive flag to true (start clock):

  • Period Start: fixtureActionTypeId (6)

  • Start Clock: fixtureActionTypeId (8)

  • Edit Clock: fixtureActionTypeId (10)

  • Goal: fixtureActionTypeId (104)

  • Red Card: fixtureActionTypeId (105)

  • Yellow Card: fixtureActionTypeId (107)

  • Shootout Penalty Goal: fixtureActionTypeId (123)

Websocket fixture action IDs that set the isClockActive flag to false (stop clock):

  • Stop Clock: fixtureActionTypeId (9)

  • Period End: fixtureActionTypeId (7)

If a clock is stopped, an action message that enables it will update the time to the latest value, before enabling the second by second update function.

If no message is received that updates the isClockActive flag to true, the clock will not start at all.

Logic for 'Cancelled' actions

Q: Can you help me confirm the workflow around "Cancelled". In one example I can see it has gone from Pending>Cancelled. I just wanted to confirm this is always the case, as for "Deleted" the logic is Pending>Confirmed>Deleted

A: Pending is sent for every action that needs a manual confirmation. E.g. if a collector presses Corner Awarded, that sends a pending message to the console and a pop up to the collector's tablet. That pop up has an option for Cancel or Confirm - whichever of those buttons you press, sends Cancelled or Confirmed. Think of Pending as:

  • Pending confirmation

  • Pending further information (e.g. recipient of the yellow card)

As for deletions, you can only delete something you've confirmed

What happens with a Scorer Disconnection?

We send heartbeats every 10 seconds from the venue to our server. If the scorer is disconnected from internet (i.e. missing actions or heartbeats) the customer will receive a "disconnected" message after 60 seconds via the DDE. If within that 60 seconds the scorer reconnects to the internet then there will be no message sent via DDE. Therefore, if scorer is only disconnected for 59 seconds or less, we would not send a message to customers as it is only a very small outage.

Last updated