Skip to main content
The Sportrix Data WebSocket stream gives you a persistent, low-latency connection for real-time live scores and statistics. Rather than polling the REST API, you subscribe to one or more matches and receive an immediate snapshot followed by pushed updates whenever the match state changes.

Endpoint

wss://scores.sportrixdata.com/v1/stream
Required scope: live_scores_statistics

Authentication

Pass your API key as a ?key= query parameter or an X-API-Key header. The query parameter is the most convenient option for WebSocket clients that cannot set custom headers:
wss://scores.sportrixdata.com/v1/stream?key=sk_your_api_key_here
The connection is rejected with HTTP 401 if the key is invalid, disabled, expired, or does not have the live_scores_statistics scope.

Keepalive (ping/pong)

The server sends a WebSocket ping control frame every 30 seconds to keep idle connections alive — for example between matches, or when nothing is changing on a quiet match. This prevents proxies and clients from closing the connection on a read/idle timeout.
  • No client action is required. Most WebSocket libraries (browser WebSocket, Python websockets, websocket-client, Go gorilla/websocket, etc.) reply with a pong automatically. You do not need to send anything yourself.
  • Set your read/idle timeout above 30 seconds. 60 seconds is a safe value. Because the ping is a received frame, it resets your read deadline and prevents premature disconnects.
  • Do not set a read timeout below 30 seconds, or you’ll close the connection between pings. There is no application-level ping message to send from the client — the protocol-level ping/pong is handled by your WebSocket library.

Library examples

import asyncio, websockets

async def run():
    # Defaults already keep the connection healthy. You can also rely
    # purely on the server's 30s ping by raising the timeouts.
    async with websockets.connect(
        "wss://scores.sportrixdata.com/v1/stream?key=sk_your_api_key_here",
        ping_interval=20,
        ping_timeout=60,
    ) as ws:
        async for msg in ws:
            print(msg)

asyncio.run(run())

How it works

  1. Connect to the endpoint with your API key.
  2. Send a subscribe message with the match_id of the match you want to follow (the same id returned by the REST /matches endpoints).
  3. Receive a snapshot immediately after subscribing, then receive update frames whenever the match state changes.
  4. Send an unsubscribe message when you no longer need updates for a match.
A single connection can subscribe to multiple matches simultaneously. Every data frame includes a match_id field so you can demultiplex frames from different matches on the same connection.

Subscribe and unsubscribe

Send JSON control messages to the server:
{"action": "subscribe", "match_id": 41282}
{"action": "unsubscribe", "match_id": 41282}
Only matches in your enabled sports can be subscribed. Attempting to subscribe to a match outside your sport allowlist returns an error frame instead of a snapshot.

Python example

import json, websocket  # websocket-client

ws = websocket.create_connection(
    "wss://scores.sportrixdata.com/v1/stream?key=sk_your_api_key_here"
)
ws.send(json.dumps({"action": "subscribe", "match_id": 41282}))
while True:
    msg = json.loads(ws.recv())
    if msg["op"] in ("snapshot", "update"):
        d = msg["data"]
        if d["sport"] == "cricket":  # cricket has its own shape (no clock/phase)
            s = d["score"]
            print(f'{d["batting"]} {s["runs"]}/{s["wickets"]} ({s["overs"]}) '
                  f'- {d["last_event"]["label"]}')
        else:  # soccer
            clock = d["clock"]
            print(f'{d["home"]} {d["score"]["home"]}-{d["score"]["away"]} {d["away"]} '
                  f'[{clock["minute"]}:{clock["second"]:02d} {clock["period"]}] {d["phase"]["label"]}')
    elif msg["op"] == "error":
        print("error:", msg["error"])
Always branch on data["sport"] — the snapshot schema is sport-specific (soccer carries clock/phase/stats/events; cricket carries score/over/batsmen/bowler/scorecard). See the live snapshot reference for both shapes.
If you only need scores without full match statistics, the REST GET /matches/{id}/live endpoint with the live_scores scope may be simpler than maintaining a WebSocket connection.

Next steps

See the WebSocket Message Reference for the complete specification of every client message and server frame.