---
title: Football live channel
description: Frame-by-frame reference for wss://sports.bzzoiro.com/live/football/ — subscribed snapshots, score/stats, ball position, per-action events and odds.
badge: addon
---

# Football live channel

```
wss://sports.bzzoiro.com/live/football/
```

Auth, subscribe protocol and close codes are shared across channels — see
the [overview](/docs/websocket/). This page documents every server frame with
its real shape.

## Coverage: Basic vs Full (WS+)

Every covered match streams score, stats, positional data and odds. Matches
flagged `websocket_plus: true` on `GET /api/v2/events/live/` additionally
stream **`action` frames**: individual match actions (~100 ms latency) with
pitch coordinates and player info. The channel picks the best available
source automatically — the `subscribed` frame tells you which you got:

| `source` | You receive |
|---|---|
| `"basic"` | `event`, `livedata` (~5 s cadence), `odds` |
| `"full"` | Everything above + `action` frames + a `history` replay on subscribe |

## `subscribed` — snapshot on subscribe

```json
{
  "type": "subscribed",
  "event_id": 223510,
  "source": "full",
  "event":    { "…": "same shape as the event frame below" },
  "livedata": [ "… up to 30 recent livedata frames …" ],
  "history":  [ "… recent action frames (full only) …" ],
  "odds":     { "…": "same shape as the odds frame below" }
}
```

## `event` — score, clock and stats

Sent whenever match state changes:

```json
{
  "type": "event",
  "event_id": 223510,
  "home": { "id": 3021, "name": "Aldosivi", "short_name": "ALD" },
  "away": { "id": 3044, "name": "Gimnasia y Esgrima", "short_name": "GYE" },
  "score": { "home": 1, "away": 0 },
  "time": {
    "minute": 67, "second": 34, "display": "67'",
    "period": 2, "injury_time": null,
    "period_started_at_uts": 1785692700,
    "status": "live", "kickoff_at": "2026-08-02T17:30:00+00:00"
  },
  "stats": {
    "home": { "possession": 55, "shots_total": 11, "corners": 5, "xg": 1.42, "…": "…" },
    "away": { "possession": 45, "shots_total": 7,  "corners": 3, "xg": 0.71, "…": "…" }
  },
  "websocket_plus": true
}
```

> **Note:** the clock lives under `time` (`time.minute`, `time.display`) —
> not at the top level.

## `livedata` — ball position and situations

Positional/situation updates, ~5 s cadence:

```json
{
  "type": "livedata",
  "event_id": 223510,
  "uts": 1785695254,
  "side": "home",
  "situation": "dangerous_attack",
  "coordinates": [ { "x": 78.5, "y": 41.2 } ],
  "commentary": "Dangerous attack — Aldosivi"
}
```

- `uts` — unix timestamp in **seconds**
- `side` — `"home"`, `"away"` or `null`
- `coordinates` — an **array** of `{x, y}` points (percent of pitch length ×
  width, attacking left→right); usually one point
- `situation` values include: `goal`, `corner`, `freekick`, `throwin`,
  `offside`, `goalkeeper_saved`, `shotoffwoodwork`, `dangerous_attack`,
  `attack`, `possession`, `safe`

## `action` — per-action events (Full only)

Individual match actions with coordinates, ~100 ms after they happen:

```json
{
  "type": "action",
  "event_id": 223510,
  "action_type": "goal",
  "x": 87.3, "y": 51.2,
  "team": "home",
  "player": { "id": 40112, "name": "T. Fernández" },
  "score": { "home": 1, "away": 0 },
  "qualifiers": [ "left_foot" ],
  "minute": 67, "second": 34, "period": 2,
  "ts": 1785695254123
}
```

`action_type` values include: `goal`, `temp_goal`, `attempt_saved`,
`temp_save`, `post`, `corner_awarded`, `offside_pass`, `foul`, `card`,
`player_off`, `player_on`, `out`. (`temp_*` frames are provisional and
confirmed/corrected by a follow-up frame.)

## `odds` — consensus odds (~30 s)

```json
{
  "type": "odds",
  "event_id": 223510,
  "odds": {
    "match_winner": { "home": 2.10, "draw": 3.20, "away": 3.60 },
    "over_under": { "over_15": 1.28, "under_15": 3.75, "over_25": 2.05,
                    "under_25": 1.78, "over_35": 3.90, "under_35": 1.26 },
    "btts": { "yes": 2.00, "no": 1.80 }
  },
  "updated_at": "2026-08-02T18:37:02+00:00"
}
```

## `odds_book` — one bookmaker (~30 s)

Sent only if you subscribed with `bookmaker_slug`. Same `odds` block plus
`"bookmaker_slug"` and `"bookmaker_name"`. Slugs:
`GET /api/v2/bookmakers/`.

## Other frames

`unsubscribed`, `pong`, and `error` (codes listed in the
[overview](/docs/websocket/)).
