> For the complete documentation index, see [llms.txt](https://docs.odds88.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.odds88.io/integration-process/recommended-integration-flow/delta-feed-new-version.md).

# Delta Feed - New Version

{% content-ref url="/pages/JFJGQOsTKFaOcUqyg9Um" %}
[Delta Feed - New Version](/odds88-client-api/odds88-feeds/delta-feed-new-version.md)
{% endcontent-ref %}

We introduce a few changes that need to be considered in the new odds feed version which will become the main feed in the future.

## Changes:

### New & Deprecated Fields

New Fields

* **UpdateSequence -** Incremental sequence number for each delta message of an event
* **LastUpdatedTime -** Unix timestamp in seconds

Deprecated Field

* **Version -** Previously used as a recovery identifier. Now replaced by **UpdateSequence** and **LastUpdatedTime**. The old recovery logic required to reconnect using the last received versio&#x6E;**.**\
  This field is now **deprecated**.

### **New Recovery Logic** <a href="#id-2.-new-recovery-logic-using-lastupdatedtime" id="id-2.-new-recovery-logic-using-lastupdatedtime"></a>

Every delta now contains **LastUpdatedTime**, which acts as the recovery marker.

When reconnecting, its required to send the latest processed value: **revision={LastUpdatedTime}**

Odds88 will **resend all missed updates** from that timestamp to ensure catching up to the latest event state.

### **Initial Connection**

For the first-time connection, the **revision** parameter is optional.\
However, we recommend sending a **Unix timestamp for the last 1 hour** to reduce load on both sides:

* Prevents returning excessive historical data
* Ensures smoother bootstrapping process

### **UpdateSequence Behaviour & Requirements** <a href="#id-3.-updatesequence-behavior-and-client-requirements" id="id-3.-updatesequence-behavior-and-client-requirements"></a>

**UpdateSequence** increments by **1** for every delta message of **single event**.\
Expected Behaviou&#x72;**:**

* If the last received value is **12**, the next should be **13**
* Duplicate values may rarely occur and should be accepted: e.g. **12**, and next message again **12** which should be reprocessed.

**Missing Update Detection**

If there was a gap in the update sequence (e.g., 12 → 15) and the last received message **was not** a snapshot **(type=6)** it indicates that some deltas might have been missed and full **event snapshot** request from the API is required.

### **Recovery Stream Behaviour** <a href="#id-4.-recovery-stream-behavior" id="id-4.-recovery-stream-behavior"></a>

During recovery:

* The first recovery message is typically **type=6** (EventSnapshotDelta)
* Its required to **drop deltas** with an UpdateSequence **lower** than stored value

Example 1:\
Stored sequence = 10\
During recovery the first received message is: UpdateSequence = 15, type = 6\
This is acceptable - its a snapshot and **event snapshot** from API **is not required**.\
\
Example 2:\
Stored sequence = 10\
The first received message is for an event is: UpdateSequence = 15, type = 3\
This is not acceptable - not a snapshot and **it is required** to request event snapshot from API.\
\
Example 3:\
Event is missing from storage and the first received message for missing event is: UpdateSequence = 15, type = 3\
This is not acceptable - not a snapshot and **it is required** to request event snapshot from API.

{% hint style="warning" %}
If event is missing from storage but event snapshot was received during recovery then API request is not needed.
{% endhint %}

### **Heartbeat Support** <a href="#id-5.-heartbeat-support" id="id-5.-heartbeat-support"></a>

The new endpoint supports heartbeat messages so it's possible to differentiate idle periods from technical issues.

**Heartbeat Timing**

* Heartbeat every **10 seconds**
* Expected flow: Delta **or** Heartbeat message

**Connection Timeout Rules**\
If there is no delta **or** heartbeat messages received for 30 seconds then it's required to close current connection and reconnect using **LastUpdatedTime** from last processed message.\
Our system closes stale connections automatically.

### **Message Wrapper Structure** <a href="#id-6.-message-wrapper-structure" id="id-6.-message-wrapper-structure"></a>

All messages (deltas or heartbeats) are wrapped in the following structure:

```json
{
  "Payload": "Nullable<DeltaDto>",      /// Message payload. Null for ping messages.
  "PingId": "Nullable<string>",         /// Non-null only for ping messages.
  "TimestampUtc": "DateTime",           /// UTC timestamp when the message was generated by the Odds88 engine.
  "PublishTimestampUtc": "DateTime"     /// UTC timestamp when the message was published to the client.
}
```

### **Delta Structure** <a href="#id-7.-delta-structure" id="id-7.-delta-structure"></a>

The Delta message has a common structure that applies to all types:

```json
{
  "Type": "DeltaTypeEnum (long)",    /// Type of delta
  "EventId": "long",                 /// Id of changed event
  "Version": "long",                 /// Version of feed state (deprecated)
  "CorrelationId": "string",         /// Correlation id of the message to trace back.
  "CreationTime": "DateTime",        /// Captures the timestamp the dto was created.
  "SportId": "long",                 /// Id of the Sport
  "LocationId": "long",              /// Id of the Location
  "LeagueId": "long",                /// Id of the League
  "UpdateSequence": "long",          /// Event update sequence. Incremented with each sent delta.
  "LastUpdatedTime": "long"          /// Event update time.
}
```

## **Summary** <a href="#summary-of-client-responsibilities" id="summary-of-client-responsibilities"></a>

#### **On Connection** <a href="#on-connection" id="on-connection"></a>

* Send **revision=\<LastUpdatedTime>** - it is optional but recommended for first connection.

#### **While connected** <a href="#during-stream" id="during-stream"></a>

* Track **UpdateSequence** per event.
* Detect gaps and missing updates, then call snapshot API.
* Handle heartbeat logic.
* Reconnect after 30 seconds of inactivity.
* Request snapshot from API only when required.

#### **During Recovery** <a href="#during-recovery" id="during-recovery"></a>

* Drop messages with lower **UpdateSequence.**

***

### Data Elements

* Every event consists of 4 data elements. **eventInfo** - basic information about the event. **markets** - contains data about markets, selection and odds values. **scoreboard** - contains data about periods and score. **betCancellations** - contains data about the time period in which bets placed on specific markets should be cancelled.
* Every data element has a dedicated delta type that is used to send updates for this specific element. Two exceptions are **eventSnapshotDelta (type6),** which contains all data elements, and **eventStatusChangedDelta (type 1),** which is used to update **status** and **tradingStatus** that are located inside **eventInfo.**

### **Data Storage Recommendations**

* Recommended approach of storing data for events is following. **eventInfo** should be stored in a document database like MongoDB. **markets, scoreboard, betCancellation** data is stored in a cache like Redis. This allows for time critical data of **markets/odds** to be processed and forwarded to frontend as fast as it is possible.

### Establishing Connection

* After receiving credentials from TIS, the next step is to establish connection with Odds88 WebSocket delta feed. We **recommend** doing initial connection with **Unix timestamp for the last 1 hour** to reduce load on both sides as it prevents returning excessive historical data. After that you should connect with **Unix timestamp from last processed message.**

### Storing Data

* Subscribing with **revision = 0** will generate snapshots (**type 6** delta) for all events active in a Odds88 system. This type of delta contains full data about an event and includes **all 4 data elements**. If an event doesn’t exist in the your database, it should be created. If an event exists all data elements that changed should be updated.
* Upon receiving delta of **type 2** a new event should be created in your DB. If an event already exists, changed fields should be updated. Deltas of type 2 and 6 are the only two deltas that should create new events in your database.
* Next step is to process every other delta type that contains only updates for already existing events and update changed fields/properties in the database/cache for further use in your system/frontend solution. Structure of all delta types can be checked in swagger.
* Events can have from 0 to many markets.
* Markets can have from 1 to many selections.
* After message processing is implemented, you can populate your database by connecting to feed. We recommend sending a **Unix timestamp for the last 1 hour** to reduce load on both sides. In case of reconnection it should happen with **revision={LastUpdatedTime}**. Existing data should be enough to create frontend views of sports, leagues and events.
* To process messages it is required to use a multithreaded solution. Number of messages and their size can be significant during peak hours for a single threaded solution to handle the volume.
* It is recommended to use MongoDB + Redis, for quick and reliable forwarding of data to frontend.

### Market settlements

Delta Feed delivers selection-level market settlements — i.e. the outcome of each individual selection in a market. This tells your system “what happened on the field” for a market, independent of any specific player’s bet.\
There is no dedicated settlement delta type. Settlement data is carried as a regular field on each selection inside the standard delta types that include market data. When a market is settled, the selection’s `settlement` field changes from `0 (None)` to its final result.

Two delta types include selections, and therefore can carry settlement data:\
`6` - EventSnapshot\
`7` - MarketsChanged

The Delta Feed `SettlementResult` enum (used in `SelectionViewModelV2.settlement`):

| Value | Name       | Description                                      |
| ----- | ---------- | ------------------------------------------------ |
| 0     | `None`     | Not yet settled                                  |
| 1     | `Refund`   | Stake fully returned                             |
| 2     | `Lose`     | Selection lost                                   |
| 3     | `Win`      | Selection won                                    |
| 4     | `HalfLose` | Half stake lost (Asian handicap / quarter lines) |
| 5     | `HalfWin`  | Half stake won (Asian handicap / quarter lines)  |

Examples:

```json
{
  "type": 7,
  "eventId": 123456,
  "updateSequence": 42,
  "markets": [
    {
      "id": 555001,
      "tradingStatus": 2,
      "selections": [
        { "id": 777001, "name": "Team A", "status": 2, "settlement": 3 },
        { "id": 777002, "name": "Team B", "status": 2, "settlement": 2 }
      ]
    }
  ]
}
```

```json
{
  "type": 6,
  "eventId": 123456,
  "eventInfo": { "...": "..." },
  "markets": [
    {
      "id": 555001,
      "tradingStatus": 2,
      "selections": [
        { "id": 777001, "settlement": 3 },
        { "id": 777002, "settlement": 2 }
      ]
    }
  ],
  "scoreboard": { "...": "..." },
  "betCancellations": []
}
```
