> For the complete documentation index, see [llms.txt](https://info.soccerfootball.info/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://info.soccerfootball.info/websocket/channels/odds.md).

# ODDS

## ODDS Channel

The ODDS channel delivers complete odds snapshots periodically during live matches.

### Availability

| Plan  | Available |
| ----- | --------- |
| BASIC | No        |
| PRO   | No        |
| ULTRA | Yes       |
| MEGA  | Yes       |

### Update Frequency

Update frequency depends on your subscription scope:

* **`match` / `league` scope:** odds are delivered **immediately** when data changes
* **`all` scope:** odds are accumulated and delivered as a **batch every 30 seconds** (`batch_update`)

### Events

| Event         | Scope             | Description                              |
| ------------- | ----------------- | ---------------------------------------- |
| odds\_update  | `match`, `league` | Full odds snapshot (immediate)           |
| batch\_update | `all`             | Batched odds for all matches (every 30s) |

***

### odds\_update

Delivers a complete snapshot of all available betting odds.

#### Message

```json
{
  "type": "event",
  "channel": "ODDS",
  "scope": "match",
  "id": "12345",
  "eventType": "odds_update",
  "eventId": "def456",
  "ts": 1705314600000,
  "data": {
    "kickoff1x2": "2.10;3.40;3.50",
    "live1x2": "1.85;3.60;4.20",
    "starting1x2": "2.15;3.30;3.40",
    "kickoffOU": "1.90;1.90|2.5",
    "liveOU": "2.10;1.70|2.5",
    "startingOU": "1.85;1.95|2.5",
    "kickoffAH": "1.95;1.85|-0.5",
    "liveAH": "1.80;2.00|-0.5",
    "startingAH": "1.90;1.90|-0.5",
    "kickoffAsianCorners": "1.85;1.95|9.5",
    "liveAsianCorners": "1.90;1.90|9.5",
    "kickoff1hAH": "1.90;1.90|-0.25",
    "live1hAH": "1.85;1.95|-0.25",
    "kickoff1hGoals": "2.00;1.80|0.5",
    "live1hGoals": "2.20;1.65|0.5",
    "kickoff1hAsianCorners": "1.90;1.90|4.5",
    "live1hAsianCorners": "1.85;1.95|4.5",
    "kickoff1hResult": "2.50;2.20;3.00",
    "live1hResult": "2.30;2.40;3.20",
    "dropping1x2": "-0.05;+0.10;+0.15"
  }
}
```

#### Data Fields

**Full Time Markets**

| Field         | Format                  | Description                 |
| ------------- | ----------------------- | --------------------------- |
| `kickoff1x2`  | `"home;draw;away"`      | 1X2 odds at kickoff         |
| `live1x2`     | `"home;draw;away"`      | Current live 1X2 odds       |
| `starting1x2` | `"home;draw;away"`      | Opening 1X2 odds            |
| `kickoffOU`   | `"over;under\|line"`    | Over/Under at kickoff       |
| `liveOU`      | `"over;under\|line"`    | Current live Over/Under     |
| `startingOU`  | `"over;under\|line"`    | Opening Over/Under          |
| `kickoffAH`   | `"home;away\|handicap"` | Asian Handicap at kickoff   |
| `liveAH`      | `"home;away\|handicap"` | Current live Asian Handicap |
| `startingAH`  | `"home;away\|handicap"` | Opening Asian Handicap      |

**Asian Corners**

| Field                 | Format               | Description                |
| --------------------- | -------------------- | -------------------------- |
| `kickoffAsianCorners` | `"over;under\|line"` | Asian Corners at kickoff   |
| `liveAsianCorners`    | `"over;under\|line"` | Current live Asian Corners |

**First Half Markets**

| Field                   | Format                  | Description                    |
| ----------------------- | ----------------------- | ------------------------------ |
| `kickoff1hAH`           | `"home;away\|handicap"` | 1H Asian Handicap at kickoff   |
| `live1hAH`              | `"home;away\|handicap"` | Current 1H Asian Handicap      |
| `kickoff1hGoals`        | `"over;under\|line"`    | 1H Over/Under goals at kickoff |
| `live1hGoals`           | `"over;under\|line"`    | Current 1H Over/Under goals    |
| `kickoff1hAsianCorners` | `"over;under\|line"`    | 1H Asian Corners at kickoff    |
| `live1hAsianCorners`    | `"over;under\|line"`    | Current 1H Asian Corners       |
| `kickoff1hResult`       | `"home;draw;away"`      | 1H Result at kickoff           |
| `live1hResult`          | `"home;draw;away"`      | Current 1H Result              |

**Odds Movement**

| Field         | Format             | Description                  |
| ------------- | ------------------ | ---------------------------- |
| `dropping1x2` | `"home;draw;away"` | 1X2 odds change from opening |

***

### Odds Formats

#### 1X2 Format

```
"home;draw;away"
Example: "2.10;3.40;3.50"
- Home win: 2.10
- Draw: 3.40
- Away win: 3.50
```

#### Over/Under Format

```
"over;under|line"
Example: "1.90;1.90|2.5"
- Over 2.5: 1.90
- Under 2.5: 1.90
- Line: 2.5 goals
```

#### Asian Handicap Format

```
"home;away|handicap"
Example: "1.95;1.85|-0.5"
- Home -0.5: 1.95
- Away +0.5: 1.85
- Handicap: -0.5 for home team
```

#### Dropping Odds Format

```
"home;draw;away"
Example: "-0.05;+0.10;+0.15"
- Home: decreased by 0.05
- Draw: increased by 0.10
- Away: increased by 0.15
```

***

### batch\_update

Delivers a batch of odds snapshots for all live matches. Sent every 30 seconds to `all` scope subscribers only.

#### Message

```json
{
  "type": "batch_update",
  "channel": "ODDS",
  "scope": "all",
  "timestamp": 1705314600000,
  "matches": [
    {
      "matchId": "12345",
      "leagueId": "67890",
      "data": {
        "kickoff1x2": "2.10;3.40;3.50",
        "live1x2": "1.85;3.60;4.20",
        "liveOU": "2.10;1.70|2.5",
        "..."
      }
    },
    {
      "matchId": "12346",
      "leagueId": "67890",
      "data": {
        "kickoff1x2": "1.75;3.80;4.50",
        "live1x2": "1.60;4.00;5.00",
        "liveOU": "1.95;1.85|2.5",
        "..."
      }
    }
  ]
}
```

#### Fields

| Field                | Type    | Description                                         |
| -------------------- | ------- | --------------------------------------------------- |
| `type`               | string  | Always `"batch_update"`                             |
| `channel`            | string  | Always `"ODDS"`                                     |
| `scope`              | string  | Always `"all"`                                      |
| `timestamp`          | integer | Batch creation timestamp in milliseconds            |
| `matches`            | array   | Array of match updates accumulated since last batch |
| `matches[].matchId`  | string  | Match public ID                                     |
| `matches[].leagueId` | string  | League/Championship public ID                       |
| `matches[].data`     | object  | Odds snapshot (same fields as `odds_update` data)   |

> **Note:** If a match has multiple updates within a 30-second window, only the latest data for that `matchId` is included in the batch.

***

### Subscription Examples

#### Subscribe to all odds updates

```json
{"action": "subscribe", "channel": "ODDS", "scope": "all"}
```

#### Subscribe to a specific match

```json
{"action": "subscribe", "channel": "ODDS", "scope": "match", "id": "b01d28ac92221034"}
```

#### Subscribe to a league

```json
{"action": "subscribe", "channel": "ODDS", "scope": "league", "id": "f2b16fa54cb525d"}
```

***

### Example: Processing Odds

```javascript
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  if (msg.type !== 'odds_update') return;

  const odds = msg.data;

  // Parse 1X2 odds
  if (odds.live1x2) {
    const [home, draw, away] = odds.live1x2.split(';').map(parseFloat);
    console.log(`1X2: Home ${home} | Draw ${draw} | Away ${away}`);
  }

  // Parse Over/Under
  if (odds.liveOU) {
    const [values, line] = odds.liveOU.split('|');
    const [over, under] = values.split(';').map(parseFloat);
    console.log(`O/U ${line}: Over ${over} | Under ${under}`);
  }

  // Parse Asian Handicap
  if (odds.liveAH) {
    const [values, handicap] = odds.liveAH.split('|');
    const [home, away] = values.split(';').map(parseFloat);
    console.log(`AH ${handicap}: Home ${home} | Away ${away}`);
  }
};
```

### Example: Detecting Odds Movement

```javascript
function parseDropping(dropping1x2) {
  if (!dropping1x2) return null;

  const [home, draw, away] = dropping1x2.split(';').map(parseFloat);

  return {
    home: { value: home, direction: home < 0 ? 'down' : 'up' },
    draw: { value: draw, direction: draw < 0 ? 'down' : 'up' },
    away: { value: away, direction: away < 0 ? 'down' : 'up' }
  };
}

// Usage
const movement = parseDropping(odds.dropping1x2);
if (movement.home.direction === 'down') {
  console.log(`Home odds dropping by ${Math.abs(movement.home.value)}`);
}
```

***

### Notes

* Odds are only sent while the match is live
* Null values indicate the market is not available
* The snapshot includes ALL available markets, not just changed values
* For real-time delta updates, use the ODDS\_REALTIME channel (MEGA plan only)
* Odds are in decimal (European) format
