---
title: Odds API
description: Multi-sport odds feed — per-bookmaker prices with tick history context, prematch closing prices and cross-sport coverage.
badge: addon
---

# Odds API

The Odds API is a dedicated odds product: per-bookmaker decimal prices across
football, tennis and other covered sports, including the last prematch price
for every market. It is separate from the per-sport APIs — those return
consensus or single odds; this one returns the full per-bookmaker book.

Base URL: `https://sports.bzzoiro.com/odds/api/`

> **Launch promo:** the Odds API is **free for all registered users until
> 2026-08-17**. After that it requires its own subscription ($5/month) —
> separate from the Sports Addon. See [/odds/pricing/](/odds/pricing/).

## Access

You need a free account token from [/register/](/register/), sent on every
request:

```bash
Authorization: Token YOUR_API_KEY
```

Without a valid token you get **401**. With a token but no active Odds API
subscription (after the promo window) you get **402**:

```json
{"error": "active Odds API subscription required",
 "subscribe_url": "/odds/pricing/"}
```

## Event identifiers: mod_id and bsd_id

Every event in this API carries two ids:

| Field | Meaning |
|---|---|
| `mod_id` | The odds-feed event id — use it for `/odds/api/events/{event_id}/` |
| `bsd_id` | The id of the same match in the main sports APIs (e.g. `/api/v2/events/{bsd_id}/` for football) — use it to join odds with match data. `null` if the event is not matched yet |

## Endpoints

| Endpoint | Description |
|---|---|
| `GET /odds/api/sports/` | Covered sports with current odds coverage |
| `GET /odds/api/events/` | Events with their current odds, by sport/date |
| `GET /odds/api/events/{event_id}/` | Full per-bookmaker book for one event |

## Sports

`GET /odds/api/sports/` lists each covered sport with how many events have
odds in the current 48-hour window and how many bookmakers are quoting:

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/odds/api/sports/"
```

```json
{"sports": [
  {"sport": "football", "events_with_odds": 412, "bookmakers": 14},
  {"sport": "tennis", "events_with_odds": 96, "bookmakers": 9}
]}
```

## Events

**Query parameters**

| Param | Type | Description |
|---|---|---|
| `sport` | string | Default `football` |
| `date` | date | `YYYY-MM-DD`; without it, the window starts 3 hours ago and looks forward |
| `status` | string | `live`, `upcoming`, `finished` — football only |
| `limit` | int | Default 20, **max 50** |
| `offset` | int | Pagination offset |

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/odds/api/events/?sport=football&date=2026-08-02&limit=2"
```

```json
{"count": 214, "results": [
  {"mod_id": 90211, "bsd_id": 61240, "sport": "football",
   "home_team": "River Plate", "away_team": "Boca Juniors",
   "kickoff_utc": "2026-08-02T21:30:00+00:00", "status": "upcoming",
   "league": "Primera División",
   "odds": [
     {"bookmaker": "pinnacle", "bookmaker_name": "Pinnacle",
      "market": "1x2", "kind": "match_winner", "line": null,
      "selection": "home", "price": 2.35,
      "observed_at": "2026-08-02T13:52:04+00:00",
      "prematch_price": null, "prematch_observed_at": null}
   ]}
]}
```

### prematch_price semantics

For live or finished events, each odds row also carries `prematch_price` and
`prematch_observed_at` — the **last price observed at or before kickoff**.
That is the closing line: compare it with in-play or settlement prices to
measure market movement without keeping your own history. Before kickoff both
fields are `null` (the current `price` *is* the prematch price).

## Event detail

`GET /odds/api/events/{event_id}/` takes the `mod_id` and an optional
`sport` param (default `football`). It groups the full book by bookmaker:

```bash
curl -H "Authorization: Token YOUR_API_KEY" \
  "https://sports.bzzoiro.com/odds/api/events/90211/?sport=football"
```

```json
{"mod_id": 90211, "bsd_id": 61240, "sport": "football",
 "home_team": "River Plate", "away_team": "Boca Juniors",
 "kickoff_utc": "2026-08-02T21:30:00+00:00", "league": "Primera División",
 "status": "upcoming",
 "bookmakers": [
   {"bookmaker": "pinnacle", "bookmaker_name": "Pinnacle",
    "markets": [
      {"market": "1x2", "kind": "match_winner", "line": null,
       "selection": "home", "price": 2.35,
       "observed_at": "2026-08-02T13:52:04+00:00"},
      {"market": "total", "kind": "over_under", "line": 2.5,
       "selection": "over", "price": 1.92,
       "observed_at": "2026-08-02T13:52:04+00:00"}
    ]}
 ]}
```

Returns **404** if the event has no odds.

> **Note:** markets priced by only one source still surface — sibling feeds
> for the same event are pooled server-side, so you never lose a market
> because of where it was quoted.

## Related

- [Odds & best prices guide](/docs/guides/odds/) — when to use this API vs
  the football `/api/v2/odds/` endpoints.
- Football consensus odds and per-match comparisons are part of the free
  [Football API](/docs/football/odds-predictions/).
