> For the complete documentation index, see [llms.txt](https://docs.sportradar.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sportradar.com/imga-dl-trading-odds-distribution/odds-distribution-service/connecting.md).

# Connecting

To connect to the feed, you will need to generate an SSH public/private key pair, username and pass your public key on to IMG Arena. Your private key must be kept private from everyone -- if you suspect that it may have been exposed over an unencrypted channel or leaked in any way, please notify us to revoke access to the compromised keys. At that point you should generate a new pair and send the new public key to IMG Arena ([support@sportradar.com](mailto:support@imgarena.com)).

To establish the initial SSH connection, you should use your username as well as your private key for authentication. After connection, the client should then send this message::

```
{ "request": "init", "msg": {} }
```

Please note, if an "init" request isn't made within 10 seconds of connecting you will be disconnected. We will not start heartbeating a connection until after this "init" request has been made.

After establishing the SSH connection, the client should send this message:<br>

> Note: By default, snapshots only include tournaments that are currently active. If your use case requires referential completeness for recently finished tournaments — for example, to correctly interpret late or re-settlement messages that arrive after a tournament has concluded — you can opt in by adding `"include_finished": true` to the init payload:\
> `{ "request": "init", "msg": { "include_finished": true } }`\
> \
> \
> This flag applies for the lifetime of the session and affects both the post-init snapshot and the subscription snapshot. Clients that do not send the flag receive the same behaviour as today.

After this, the server will send push messages detailing the current offering on the feed:

* The `sport` message: `{"mode":"push","msg":{"id":"sp.golf","name":"Golf"},"type":"sport","publish_time":"2025-03-14 08:50:11.331473"}`
* One or more `competition` messages; these are the "tours" that have upcoming, or in-progress *events* (tournaments):

```
{
  "mode": "push",
  "msg": {
    "id": "comp.golf_1",
    "name": "PGA Tour",
    "sport_id": "sp.golf",
    "arena_id": "1"
  },
  "type": "competition",
  "publish_time": "2025-03-14 08:50:11.331473",
  "is_recovery": false
}
```

* One or more `event` messages; these list the tournaments that are either in progress or upcoming:

```
{
  "mode": "push",
  "msg": {
    "id": "ev.golf_1100",
    "name": "THE PLAYERS Championship",
    "competition_id": "comp.golf_1",
    "arena_competition_id": "1",
    "arena_id": "1100",
    "start_time": "2025-03-13 11:40:00.000000",
    "stage": "in_play",
    "meta": [
      {
        "event_id": "1100",
        "offering_levels": [
          "M1"
        ]
      }
    ]
  },
  "type": "event"
}
```

* `market_type` messages ; all market types that have at least one instance open at the moment:

```
{
  "mode": "push",
  "msg": {
    "id": "mt.winonly",
    "name": "Win Only (no each-way)"
  },
  "type": "market_type"
}
```

* `market` messages ; all markets that are currently available and open:

```
{
  "mode": "push",
  "msg": {
    "id": "golf_1100_winonly",
    "arena_id": "m-1",
    "name": "Win Only",
    "event_id": "ev.golf_1100",
    "arena_event_id": 1100,
    "tags": [
      "sp.golf",
      "mt.winonly",
      "ev.golf_1100",
      "comp.golf_1"
    ],
    "start_time": "2025-03-13 11:40:00.000000",
    "stage": "pre_play",
    "numwinners": 1
  },
  "type": "market"
}
```

* After `init` the odds distribution service starts to send heartbeats messages at regular intervals:

```
{
  "mode": "push",
  "type": "heartbeat",
  "msg": {
    "timestamp": "2025-01-01 10:00:00.000000"
  },
  "publish_time": "2025-01-01 10:00:00.000000"
}
```

The purpose of all this messaging post-init is to list everything that is currently available. The execution of the `init` command does not cause any market updates to start flowing but can be used to dynamically select from what is on offer.

\
To trigger the feed of market updates with actual prices, a subscription is needed.\
Note that just because a market type is not listed in this init snapshot only means there is none currently available but it remains possible to subscribe to those nonetheless.

The response to the "init" request will contain a unique `session_id`. Please provide this session id when raising any queries regarding the messages received for a given session.

If we have to close your connection for any reason, you will receive a push message::

```
{ "mode": "push", "status": "error", "session_id": <session_id>, reason": <reason>, "publish_time":"2025-03-20 10:05:50.353296" }
```

where `<reason>` will be one of: "no init sent", "max connections hit", "connection rate limit hit", "slow reader", "internal disconnection requested", or "service error".

In addition to rate limiting connections, API requests are also rate limited. The response to a request that breached a rate limit will be as follows::

```
{ "mode": "resp", "status": "error", "msg": "API limit breached", "request_id": <request_id>, "publish_time":"2025-03-20 10:05:50.353296" }
```

where `request_id` will only be present if you provided a request ID with the original request.

### Recovering from disconnection

If your connection is terminated for any reason (including deliberately on your part due to a missed heartbeat, you should try to reconnect as soon as possible, reconnection attempts should be made with a 30 second interval. While you do not have an open connection, you must treat all markets as suspended. Once your connection is re-established, you must treat each market as suspended until you have received a `<market-status-update>` for that market. Until you receive that market update, it is not possible to know if any changes occurred to the market since you were last connected.

### Details of SSH Connection

Once the SSH connection is established, the client should create a channel of type “session” and request a “shell” within that channel. All communication takes place on the “session” channel. A command line client will generally do this correctly. Some libraries may abstract away this level of detail as well.

If you are using a command line client to connect, either for testing or as a subprocess of the live client, you should tell it not to try to allocate a pseudo-tty. For the SSH client in most Linux distributions, this corresponds to the “-T” option. PuTTY for Windows uses the same option. It isn’t harmful to attempt to allocate a pseudo-tty, but it will result in a warning message.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.sportradar.com/imga-dl-trading-odds-distribution/odds-distribution-service/connecting.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
