Tennis live channel#
Tennis streams over the multi-sport channel:
wss://sports.bzzoiro.com/ws/live/
Auth and close codes are the same as everywhere
(overview). The only difference: add
"sport": "tennis" when subscribing.
{"action": "subscribe", "event_id": 36835, "sport": "tennis"}
Match ids come from the REST API — GET /tennis/api/v2/matches/live/
(requires the Sports Addon; the WebSocket itself requires the
WebSocket addon). Not every match is live-covered; uncovered ids return an
error frame with code not_tracked.
Football subscriptions work on this same socket (without the sport key) —
the 10-subscription limit is shared.
event — full match state#
Sent on subscribe and whenever the match state changes:
{
"type": "event",
"event_id": 36835,
"sport": "tennis",
"home": { "id": 1207, "name": "Carlos Alcaraz", "short_name": "C. Alcaraz" },
"away": { "id": 1391, "name": "Jannik Sinner", "short_name": "J. Sinner" },
"score": {
"sets": [ [6, 4], [3, 6], [5, 4] ],
"home_sets": 1, "away_sets": 1,
"home_games": 5, "away_games": 4,
"point": "40-30", "server": "home", "set": 3
},
"status": { "name": "live" },
"tournament": { "id": 88, "name": "US Open", "surface": "hard" },
"stats": {
"home": { "aces": 7, "double_faults": 2, "first_serve_pct": 64,
"first_serve_won_pct": 78, "second_serve_won_pct": 51,
"break_points_saved_pct": 75 },
"away": { "aces": 9, "double_faults": 1, "first_serve_pct": 61,
"first_serve_won_pct": 74, "second_serve_won_pct": 55,
"break_points_saved_pct": 60 }
}
}
score — per point#
A compact frame after every point:
{
"type": "score",
"event_id": 36835,
"uts": 1785695254,
"sets": [ [6, 4], [3, 6], [5, 4] ],
"game": "5-4",
"point": "40-30",
"server": "home"
}
point uses tennis notation (0, 15, 30, 40, A for advantage);
uts is unix seconds.
Rendering tip#
Drive the scoreboard from score frames (they arrive per point) and refresh
serve statistics from the less frequent event frames. For pre/post-match
data (h2h, rankings, odds) use the Tennis REST API.