← Developer Blog

Streaming live tennis scores over WebSocket

Stop polling. Subscribe to the Live Tennis API WebSocket feed in Python or JavaScript and receive a frame the moment a point changes, with reconnection and heartbeats handled for you.

Polling a scores endpoint every few seconds is wasteful and always slightly stale. The Live Tennis API has a native WebSocket feed that pushes a frame the instant a score changes.

The feed is on the ULTRA plan.

Python

pip install "livetennisapi[ws]"
from livetennisapi import LiveScoreStream

with LiveScoreStream() as stream:
    for update in stream:
        print(update.match_id, update.score.sets, update.score.points)

That is the whole program. No reconnect loop, no heartbeat handling, no subscribe handshake — the client does all of it.

JavaScript / TypeScript

npm install livetennisapi
import { LiveScoreStream } from 'livetennisapi';

const stream = new LiveScoreStream({ apiKey: process.env.LIVETENNISAPI_KEY });

for await (const update of stream) {
  console.log(update.match_id, update.sets, update.points);
}

Watch one match instead of all of them

stream = LiveScoreStream(topics=["match:18953"])
new LiveScoreStream({ topics: ['match:18953'] });

What the client handles for you

Heartbeats. The server sends a ping roughly every 15 seconds to keep the connection alive. These are consumed internally — iterate the stream and you only ever see real score changes.

The subscribe deadline. The server drops the socket if the subscribe frame arrives late, so the client sends it immediately on open and waits for the subscribed acknowledgement before yielding anything.

Reconnection, with a caveat worth knowing. The stream reconnects with exponential backoff and re-subscribes. But it deliberately does not reconnect on a bad key, an insufficient plan, or the service being disabled — those raise immediately, because retrying them just hammers a closed door.

from livetennisapi import Unauthorized, UpgradeRequired

try:
    for update in stream:
        ...
except UpgradeRequired:
    print("the WebSocket feed needs the ULTRA plan")
except Unauthorized:
    print("check LIVETENNISAPI_KEY")

The backoff also only resets after a connection has stayed up for a minute. A server that accepts and then immediately drops would otherwise pin the delay at its first step forever and never surface a failure.

Streaming from the terminal

livetennis watch                  # every live match
livetennis watch --match 18953    # one match
npx livetennisapi watch           # same thing, no install

Where to go next

Built with the Live Tennis API — real-time scores, players, odds and model win-probability for ATP, WTA, Challenger and ITF.

API reference SDKs on GitHub Plans from $9.99/mo