# 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": []
}
```


---

# 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.odds88.io/integration-process/recommended-integration-flow/delta-feed-new-version.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.
