Skip to main content

Overview

The V1 WebSocket provides real-time score updates with adaptive polling: 1-second intervals when live games exist, 2-second when no live games. This delivers the fastest possible score updates.

Connection

wss://v1.{sport}.sportsapipro.com/ws?x-api-key=YOUR_API_KEY
Replace {sport} with any supported sport slug (e.g., football, tennis, baseball).
The WebSocket connection requires authentication via the x-api-key query parameter.

Welcome Message

On successful connection, you receive:
{
  "type": "connected",
  "version": "1.0",
  "sports": [
    { "id": 1, "name": "Football", "slug": "football" },
    { "id": 2, "name": "Basketball", "slug": "basketball" },
    { "id": 3, "name": "Tennis", "slug": "tennis" },
    { "id": 4, "name": "Hockey", "slug": "hockey" },
    { "id": 5, "name": "Handball", "slug": "handball" },
    { "id": 6, "name": "American Football", "slug": "american-football" },
    { "id": 7, "name": "Baseball", "slug": "baseball" },
    { "id": 8, "name": "Volleyball", "slug": "volleyball" },
    { "id": 9, "name": "Rugby", "slug": "rugby" }
  ],
  "channels": ["all", "live", "football", "basketball", "tennis", "hockey", "handball", "american-football", "baseball", "volleyball", "rugby"]
}

Client Messages

Subscribe

{ "type": "subscribe", "channel": "football" }
{ "type": "subscribe", "channel": "live" }
{ "type": "subscribe", "channel": "match:4467358" }

Unsubscribe

{ "type": "unsubscribe", "channel": "football" }

Ping / Pong

{ "type": "ping" }
Response:
{ "type": "pong", "ts": 1712345678000 }

Server Messages

Sport Channel Updates

{
  "type": "scores",
  "channel": "football",
  "games": [{ ... }],
  "updateId": 5612062220,
  "ts": 1712345678000
}

Live Channel (All Sports)

{
  "type": "scores",
  "channel": "live",
  "games": [{ ... }],
  "updateId": 5612062220,
  "ts": 1712345678000
}

Match-Specific Updates

{
  "type": "match-update",
  "channel": "match:4467358",
  "game": { ... },
  "updateId": 5612062220,
  "ts": 1712345678000
}

Available Channels

ChannelDescription
allAll updates across all sports (default on connect)
liveOnly live games across all 9 sports
footballFootball updates only
basketballBasketball updates only
tennisTennis updates only
hockeyHockey updates only
handballHandball updates only
american-footballAmerican Football updates only
baseballBaseball updates only
volleyballVolleyball updates only
rugbyRugby updates only
match:{gameId}Single game updates

Code Examples

const ws = new WebSocket('wss://v1.football.sportsapipro.com/ws?x-api-key=YOUR_API_KEY');

ws.onopen = () => {
  console.log('Connected to V1 WebSocket');
  ws.send(JSON.stringify({ type: 'subscribe', channel: 'live' }));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  
  if (msg.type === 'connected') {
    console.log(`Connected — ${msg.sports.length} sports available`);
  }
  
  if (msg.type === 'scores') {
    console.log(`${msg.channel}: ${msg.games.length} games updated`);
    msg.games.forEach(game => {
      console.log(`${game.homeCompetitor.name} ${game.homeCompetitor.score} - ${game.awayCompetitor.score} ${game.awayCompetitor.name}`);
    });
  }
  
  if (msg.type === 'match-update') {
    const g = msg.game;
    console.log(`Match update: ${g.homeCompetitor.name} ${g.homeCompetitor.score} - ${g.awayCompetitor.score} ${g.awayCompetitor.name}`);
  }
};

ws.onclose = () => console.log('Disconnected');

Update Frequency

ConditionPolling Interval
Live games in progress1 second
No live games2 seconds
The V1 WebSocket uses adaptive polling to minimize latency during live games while reducing server load during quiet periods.

World Cup reliability: pair V1 + V2

For high-stakes matches (World Cup knockouts, finals), run both the V1 and the V2 WebSocket in parallel. The two feeds sit on independent infrastructure paths with different upstream sources, so a hiccup on one side does not interrupt the other.
CapabilityV1 WebSocketV2 WebSocket
Per-match score updatesmatch:{gameId}match:{matchId}
Per-match incidents (goals, cards, subs, VAR)Use REST /api/v1/game/{id}/events between ticksmatch:{matchId}:incidents (sub-second)
Per-match aggregate statsUse REST /api/v1/game/{id}/statsmatch:{matchId}:stats (sub-second)
Data pathDirect feed, adaptive polling (1-2s)NATS push + safety-net poll
Best asStable fallback / score-of-truthPrimary real-time source
  1. Connect to V2 as the primary source for sub-second incidents and stats.
  2. Connect to V1 in parallel and subscribe to match:{gameId} for the same match — treat its match-update payload as a hot fallback for score and status.
  3. If V2 drops or stops emitting for more than a few seconds, your UI keeps updating from V1 without any user-visible gap.
  4. Combine with V1’s dedicated World Cup REST endpoints (/api/v1/world-cup/...) for tournament-level context (groups, brackets, predictions).
Both feeds are independent and counted separately for quota. Subscribe only to the channels you actually render — match:{gameId} on V1 plus match:{matchId} and match:{matchId}:incidents on V2 is a typical World Cup matchday setup.
Last modified on June 12, 2026