Documentation

PulseScore API Docs

One normalized schema across every bookmaker. Same fields, same flat markets[] with canonicalMarket and selections[]. Your parser stays the same whether you call /v3/bet365, /fanduel, or any other bookmaker.

Bookmaker API References

Quick Start

Get live odds data in 3 steps:

  1. Create an account - Sign up at pulsescore.net (free BASIC plan: 500 requests/month)
  2. Generate an API key - Go to Dashboard → Generate API Key
  3. Make your first call - Use the key in the X-Secret header
Your first request
curl --compressed -X GET "https://api.pulsescore.net/api/v3/bet365/live-events?sport=soccer" \
  -H "X-Secret: YOUR_API_KEY"

--compressed asks for a gzip response — boards are 6–14× smaller on the wire. Always send Accept-Encoding: gzip from your own client too (see Compression).

Authentication

All API requests require an API key passed in the request header:

HeaderValue
X-SecretYour API key from the dashboard

API keys can be generated and revoked from your dashboard. Keep your keys secret - do not expose them in client-side code.

REST API

The REST API returns JSON in the normalized schema. Every bookmaker exposes the same endpoint paths and response shape — only the base prefix differs:

text
https://api.pulsescore.net/api/v3/bet365      # Bet365 (normalized)
https://api.pulsescore.net/api/fanduel        # Fanduel
https://api.pulsescore.net/api/bwin           # Bwin
https://api.pulsescore.net/api/ps3838         # PS3838
https://api.pulsescore.net/api/paddypower     # Paddy Power
https://api.pulsescore.net/api/{bookmaker}    # …same pattern for every bookie

The endpoints below use /api/v3/bet365 as the example base URL. Swap the prefix for any other bookmaker — the response shape is identical. Standard HTTP status codes indicate success or failure.

Compression — send Accept-Encoding: gzip

Every response is gzip-compressed when the request carries Accept-Encoding: gzip. A full board shrinks 6–14× on the wire (a 14.5 KB live-events reply becomes ~1 KB), which is the single biggest latency win for a polling client. Without the header you get the raw JSON.

Most clients already send it and inflate the reply for you:

  • Browsers, Node 18+ fetch, axios, Python requests / httpx, Go net/http — on by default, nothing to do.
  • cURL — add --compressed (every example on this page does).
  • .NET HttpClient — off by default; construct it with new SocketsHttpHandler { AutomaticDecompression = DecompressionMethods.All }.
  • Java HttpClient — off by default; set the header yourself and wrap the body in a GZIPInputStream.

Check with curl --compressed -sD - -o /dev/null …: a compressed reply carries Content-Encoding: gzip.

Schema & Fallback

Every event payload exposes a normalized layer alongside the original bookmaker labels. Use the canonical fields by default — they're stable across bookmakers and safe to switch on in your code. If a canonical value looks wrong or is missing, fall back to the bookmaker's raw label, available on both markets and selections.

Markets

FieldUseWhen to fall back
canonicalMarketNormalized market key (e.g. match_winner, total_goals).Primary identifier — switch on this.
periodNormalized period (e.g. fulltime, first_half).If period looks wrong or unmapped, read rawName.
rawNameOriginal market label from the bookmaker (e.g. "Full Time Result").Fallback when canonicalMarket or period are wrong or missing.

Selections / Outcomes

The same rule applies inside selections[]: use the normalized name, and fall back to rawName if it doesn't match what you expect.

FieldUse
nameNormalized outcome label (e.g. Over 2.5, team name).
rawNameOriginal outcome label from the bookmaker. Use as fallback when name looks wrong.

Recommended pattern: read canonicalMarket / period / name first, fall back to rawName when the normalized value is unexpected. Report mis-mapped markets to support so the normalization layer can be improved.

Endpoints

Paths are relative to the bookmaker prefix, e.g. /api/v3/bet365. Every list endpoint takes page (default 1) and limit (default 5, max 30) and returns the same envelope - total, page, limit, totalPages, hasNextPage, hasPrevPage - plus the items. Single-item endpoints wrap the document in data.

Live Events

GET/live-events

In-play events with full markets and the current score, soonest kick-off first. Without a sport filter every sport is returned.

Parameters

  • sportstring· optional

    Optional filter, kebab-case or underscore form: soccer, tennis, basketball, ice-hockey, table-tennis, e-sports (or esports), american-football, baseball, cricket, rugby-league, rugby-union, volleyball, handball. Echoed back as sport in the envelope (null when omitted).

  • pagenumber· optional

    Page number (default 1)

  • limitnumber· optional

    Items per page (default 5, max 30)

Response

json
{
  "total": 17,
  "page": 1,
  "limit": 5,
  "totalPages": 4,
  "hasNextPage": true,
  "hasPrevPage": false,
  "sport": "soccer",
  "events": [
    {
      "eventId": "196565074",
      "sport": "soccer",
      "league": "United Kingdom||England Premier League",
      "home": "Ipswich",
      "away": "Liverpool",
      "score": { "home": "0", "away": "1" },
      "markets": [
        {
          "canonicalMarket": "OVER_UNDER",
          "rawName": "Match Goals",
          "period": "FULL_TIME",
          "isActive": true,
          "marketId": "196565074:OVER_UNDER:FULL_TIME:match-goals",
          "selections": [
            { "canonicalOutcome": "OVER", "rawName": "Over", "odds": 1.5714, "line": 2.5, "isActive": true },
            { "canonicalOutcome": "UNDER", "rawName": "Under", "odds": 2.375, "line": 2.5, "isActive": true }
          ]
        },
        {
          "canonicalMarket": "BOTH_TEAMS_TO_SCORE",
          "rawName": "Both Teams to Score",
          "period": "FULL_TIME",
          "isActive": true,
          "marketId": "196565074:BOTH_TEAMS_TO_SCORE:FULL_TIME:both-teams-to-score",
          "selections": [
            { "canonicalOutcome": "YES", "rawName": "Yes", "odds": 1.7273, "isActive": true },
            { "canonicalOutcome": "NO", "rawName": "No", "odds": 2.1, "isActive": true }
          ]
        }
      ]
    }
  ]
}
GET/live-events/sports

Sports with at least one in-play event right now and how many, A-Z. Names use the underscore form (table_tennis, ice_hockey); the sport filter accepts either form.

Response

json
{
  "total": 67,
  "sports": [
    { "name": "basketball", "eventCount": 5 },
    { "name": "soccer", "eventCount": 17 },
    { "name": "table_tennis", "eventCount": 17 },
    { "name": "tennis", "eventCount": 28 }
  ]
}
GET/live-events/events/:eventId

One in-play event by id with every market. data is null once the event is no longer live.

Parameters

  • eventIdstring· required

    Event ID from the /live-events response

Response

json
{
  "data": {
    "eventId": "196565074",
    "sport": "soccer",
    "league": "United Kingdom||England Premier League",
    "home": "Ipswich",
    "away": "Liverpool",
    "score": { "home": "0", "away": "1" },
    "markets": [ ... ]
  }
}

Pre-Match (by Sport)

Pre-match boards are split by sport. On bet365 soccer sits at the root - /api/v3/bet365/leagues - and every other sport has a prefix: tennis, basketball, ice-hockey, american-football, baseball, cricket, rugby-league, rugby-union, volleyball, handball, e-sports (or esports). On every other bookmaker soccer has its own /soccer prefix like any sport, e.g. /api/fanduel/soccer/events. Each bookmaker's Swagger page lists the sports it carries.

GET/{sport}/leagues

Leagues for a sport, A-Z, each with its events embedded (markets included). Embedded events include in-play ones (live: true); /leagues/:league/events lists the pre-match ones. On bet365 v3, soccer answers both at /api/v3/bet365/soccer/leagues and at the root /api/v3/bet365/leagues.

Parameters

  • pagenumber· optional

    Page number (default 1)

  • limitnumber· optional

    Items per page (default 5, max 30)

Response

json
{
  "total": 318,
  "page": 1,
  "limit": 5,
  "totalPages": 64,
  "hasNextPage": true,
  "hasPrevPage": false,
  "leagues": [
    {
      "name": "United Kingdom||England Premier League",
      "league": "United Kingdom||England Premier League",
      "sport": "soccer",
      "events": [
        {
          "eventId": "196565074",
          "sport": "soccer",
          "league": "United Kingdom||England Premier League",
          "home": "Ipswich",
          "away": "Liverpool",
          "live": false,
          "startTime": "2026-09-04T20:00:00.000Z",
          "markets": [ ... ]
        }
      ]
    }
  ]
}
GET/{sport}/leagues/:league/events

Every pre-match event in one league with full markets. Pass the league exactly as /leagues returns it (case-insensitive), URL-encoded - on bet365 that is the Country||League value.

Parameters

  • leaguestring· required

    Full league value from /leagues, e.g. United%20Kingdom%7C%7CEngland%20Premier%20League

Response

json
{
  "total": 10,
  "events": [
    {
      "eventId": "196565074",
      "sport": "soccer",
      "league": "United Kingdom||England Premier League",
      "home": "Ipswich",
      "away": "Liverpool",
      "live": false,
      "startTime": "2026-09-04T20:00:00.000Z",
      "markets": [ ... ]
    }
  ]
}
GET/{sport}/events

Upcoming pre-match events for a sport, soonest first, with full markets. Events that have gone in-play are excluded.

Parameters

  • pagenumber· optional

    Page number (default 1)

  • limitnumber· optional

    Items per page (default 5, max 30)

Response

json
{
  "total": 1539,
  "page": 1,
  "limit": 5,
  "totalPages": 308,
  "hasNextPage": true,
  "hasPrevPage": false,
  "events": [
    {
      "eventId": "196565074",
      "sport": "soccer",
      "league": "United Kingdom||England Premier League",
      "home": "Ipswich",
      "away": "Liverpool",
      "live": false,
      "startTime": "2026-09-04T20:00:00.000Z",
      "markets": [
        {
          "canonicalMarket": "MATCH_RESULT",
          "rawName": "Full Time Result",
          "period": "FULL_TIME",
          "isActive": true,
          "marketId": "196565074:MATCH_RESULT:FULL_TIME:full-time-result",
          "selections": [
            { "canonicalOutcome": "HOME", "rawName": "Ipswich", "odds": 5.25, "isActive": true },
            { "canonicalOutcome": "DRAW", "rawName": "Draw", "odds": 4.75, "isActive": true },
            { "canonicalOutcome": "AWAY", "rawName": "Liverpool", "odds": 1.5, "isActive": true }
          ]
        },
        {
          "canonicalMarket": "OVER_UNDER",
          "rawName": "Goals Over/Under",
          "period": "FULL_TIME",
          "isActive": true,
          "marketId": "196565074:OVER_UNDER:FULL_TIME:goals-over-under",
          "selections": [
            { "canonicalOutcome": "OVER", "rawName": "Over", "odds": 1.3636, "line": 2.5, "isActive": true },
            { "canonicalOutcome": "UNDER", "rawName": "Under", "odds": 3.2, "line": 2.5, "isActive": true }
          ]
        }
      ]
    }
  ]
}
GET/{sport}/events/:eventId

One pre-match event by id with every market. data is null for an unknown id.

Parameters

  • eventIdstring· required

    Event ID from /events or /leagues/:league/events

Response

json
{
  "data": {
    "eventId": "196565074",
    "sport": "soccer",
    "league": "United Kingdom||England Premier League",
    "home": "Ipswich",
    "away": "Liverpool",
    "live": false,
    "startTime": "2026-09-04T20:00:00.000Z",
    "markets": [ ... ]
  }
}

Racing

Horse racing and greyhounds are race cards, not league boards, and are not paginated. On bet365 they live under /sports/horse-racing and /greyhounds; other bookmakers with racing use /horse-racing/races and /greyhounds/races, e.g. /api/betfair-sb/horse-racing/races. Runners carry jockey, trainer and each-way terms with fractional and decimal prices.

GET/sports/horse-racing/races

Upcoming horse racing meetings on bet365 with every runner. Prices fill in as the off time approaches.

Response

json
{
  "total": 105,
  "races": [
    {
      "id": "HorseRace::Australia & New Zealand::Mornington::20260904080000::9",
      "name": "Mornington",
      "region": "Australia & New Zealand",
      "startDate": "2026-09-04T08:00:00Z",
      "EW": "EW: 1/5 odds 3 places",
      "active": "true",
      "isInPlay": "unknown",
      "settled": false,
      "horses": [
        {
          "id": "2047569135",
          "number": "10",
          "name": "Silver Bullet",
          "jockey": "Joe Bowditch",
          "trainer": "",
          "active": true,
          "EW": { "status": "active", "fractional": "7/2", "decimal": "4.5000" }
        }
      ]
    }
  ]
}
GET/greyhounds/races

Upcoming greyhound meetings on bet365 with every runner and its each-way price.

Response

json
{
  "total": 260,
  "races": [
    {
      "id": "Greyhounds::UK & Ireland::Shelbourne::20260905204200::8.42",
      "name": "Shelbourne",
      "region": "UK & Ireland",
      "startDate": "2026-09-05T20:42:00Z",
      "EW": "EW: 1/4 odds 2 places",
      "active": "true",
      "isInPlay": "unknown",
      "settled": false,
      "greyhounds": [
        {
          "id": "2044427842",
          "name": "Ballymac Setanta",
          "active": true,
          "EW": { "status": "active", "fractional": "2/5", "decimal": "1.4000" }
        },
        {
          "id": "2044427860",
          "name": "Roaming Shelby",
          "active": true,
          "EW": { "status": "active", "fractional": "11/4", "decimal": "3.7500" }
        }
      ]
    }
  ]
}

WebSocket

The WebSocket feed provides real-time streaming of all in-play events for a chosen bookmaker and sport. Server pushes a frame every ~1 second containing every live event for the subscribed sport. Available on PRO, MAX, and ULTRA plans.

Connection Pattern

Every bookmaker uses the same connection pattern — only the path segment changes. Pass your API key and the desired sport as query parameters:

text
wss://api.pulsescore.net/api/{bookmaker}/ws/live?key=YOUR_API_KEY&sport=SPORT

Bet365 uses the versioned path /api/v3/bet365/ws/live; every other bookmaker follows /api/{bookmaker}/ws/live. All frames share the same normalized event schema. Full URLs in the table below.

Endpoints by Bookmaker

BookmakerURL
Bet365wss://api.pulsescore.net/api/v3/bet365/ws/live
Betfair(OrbitExch)wss://api.pulsescore.net/api/orbitxch/ws/live
PS3838wss://api.pulsescore.net/api/ps3838/ws/live
Polymarketwss://api.pulsescore.net/api/polymarket/ws/live
Unibet AUwss://api.pulsescore.net/api/unibetau/ws/live
Fanduelwss://api.pulsescore.net/api/fanduel/ws/live
Bwinwss://api.pulsescore.net/api/bwin/ws/live
DraftKingswss://api.pulsescore.net/api/draftkings/ws/live
Ladbrokeswss://api.pulsescore.net/api/ladbrokes/ws/live
Paddy Powerwss://api.pulsescore.net/api/paddypower/ws/live
Betfredwss://api.pulsescore.net/api/betfred/ws/live
Betano(DE)wss://api.pulsescore.net/api/betano-de/ws/live
Betano(BR)wss://api.pulsescore.net/api/betano-br/ws/live
BetMGM(CO.UK)wss://api.pulsescore.net/api/betmgm-couk/ws/live
BetMGM(NL)wss://api.pulsescore.net/api/betmgm-nl/ws/live
Stakewss://api.pulsescore.net/api/stake/ws/live
Betway MWwss://api.pulsescore.net/api/betwaymw/ws/live
10Bet(CO.UK)wss://api.pulsescore.net/api/10bet/ws/live
Sportsbet AUwss://api.pulsescore.net/api/sportsbet-com-au/ws/live
Thunderpickwss://api.pulsescore.net/api/thunderpick/ws/live
Betfair Sportsbookwss://api.pulsescore.net/api/betfair-sb/ws/live
Sky Betwss://api.pulsescore.net/api/skybet/ws/live
Cloudbetwss://api.pulsescore.net/api/cloudbet/ws/live
Bet-at-homewss://api.pulsescore.net/api/betathome/ws/live
Tipsportwss://api.pulsescore.net/api/tipsport/ws/live
TABwss://api.pulsescore.net/api/tab/ws/live
BetMGM(US)wss://api.pulsescore.net/api/betmgm/ws/live
BetRiverswss://api.pulsescore.net/api/betrivers/ws/live
Betwaywss://api.pulsescore.net/api/betway/ws/live
Star Sportswss://api.pulsescore.net/api/starsports/ws/live
Melbetwss://api.pulsescore.net/api/melbet/ws/live
Kalshiwss://api.pulsescore.net/api/kalshi/ws/live
Chancewss://api.pulsescore.net/api/chance/ws/live
1xBetwss://api.pulsescore.net/api/onexbet/ws/live
Hard Rock Betwss://api.pulsescore.net/api/hardrock/ws/live
BetPARXwss://api.pulsescore.net/api/betparx/ws/live
Borgatawss://api.pulsescore.net/api/borgata/ws/live
Bovadawss://api.pulsescore.net/api/bovada/ws/live
Mozzartwss://api.pulsescore.net/api/mozzart/ws/live
Betclicwss://api.pulsescore.net/api/betclic/ws/live
Unibet FRwss://api.pulsescore.net/api/unibet-fr/ws/live
Winamaxwss://api.pulsescore.net/api/winamax/ws/live
NetBetwss://api.pulsescore.net/api/netbet/ws/live
AdmiralBet(DE)wss://api.pulsescore.net/api/admiralbet-de/ws/live
NEO.betwss://api.pulsescore.net/api/neobet/ws/live
Unibet UKwss://api.pulsescore.net/api/unibet-uk/ws/live
Merkur Betswss://api.pulsescore.net/api/merkur/ws/live
Bwin (DE)wss://api.pulsescore.net/api/bwin-de/ws/live
PMUwss://api.pulsescore.net/api/pmu/ws/live

All endpoints require ?key=YOUR_API_KEY&sport=SPORT as query parameters.

Valid Sports per Bookmaker

BookmakerSports
Bet365soccer, basketball, tennis, ice-hockey, rugby-league, rugby-union, volleyball, handball, table-tennis, e-sports, american-football, baseball, greyhounds, horse-racing, cricket
Betfair(OrbitExch)american-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, gaelic-games, golf, ice-hockey, rugby-league, rugby-union, soccer, tennis, volleyball
PS3838soccer, basketball, tennis, american-football, ice-hockey, baseball, rugby-league, esports
Polymarketamerican-football, baseball, basketball, boxing, cricket, esports, lacrosse, mma, pickleball, soccer, table-tennis, tennis, volleyball
Unibet AUamerican-football, australian-rules, baseball, basketball, boxing, cricket, cycling, darts, esports, formula-1, futsal, golf, greyhounds, handball, horse-racing, ice-hockey, lacrosse, mma, motorsports, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Fanduelamerican-football, baseball, basketball, boxing, cricket, darts, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis
Bwinamerican-football, baseball, basketball, cricket, darts, futsal, handball, ice-hockey, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
DraftKingsamerican-football, australian-rules, baseball, basketball, boxing, cricket, cycling, darts, esports, golf, handball, ice-hockey, lacrosse, mma, motorsports, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis
Ladbrokesamerican-football, baseball, basketball, boxing, cricket, darts, esports, greyhounds, handball, horse-racing, ice-hockey, mma, rugby-league, rugby-union, soccer, table-tennis, tennis, volleyball
Paddy Poweramerican-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, golf, greyhounds, handball, horse-racing, ice-hockey, mma, motorsports, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Betfredbaseball, basketball, boxing, cricket, greyhounds, horse-racing, mma, rugby-league, soccer, tennis
Betano(DE)american-football, baseball, basketball, boxing, cricket, cycling, darts, formula-1, golf, handball, ice-hockey, motorsports, rugby-league, rugby-union, soccer, tennis, volleyball
Betano(BR)baseball, basketball, boxing, cricket, cycling, darts, esports, futsal, golf, handball, lacrosse, mma, snooker, soccer, tennis, volleyball
BetMGM(CO.UK)american-football, baseball, basketball, boxing, cricket, darts, handball, ice-hockey, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
BetMGM(NL)american-football, baseball, basketball, boxing, cricket, darts, handball, ice-hockey, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Stakeamerican-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, ice-hockey, mma, rugby-union, soccer, table-tennis, tennis, volleyball, water-polo
Betway MWamerican-football, australian-rules, baseball, basketball, beach-volley, boxing, cricket, darts, futsal, handball, ice-hockey, mma, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
10Bet(CO.UK)american-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, futsal, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Sportsbet AUamerican-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Thunderpickamerican-football, australian-rules, badminton, baseball, basketball, cricket, darts, esports, ice-hockey, martial-arts, rugby-league, rugby-union, soccer, table-tennis, tennis, volleyball
Betfair Sportsbookamerican-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, ice-hockey, mma, rugby-league, snooker, soccer, table-tennis, tennis, volleyball
Sky Betamerican-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Cloudbetamerican-football, australian-rules, badminton, baseball, basketball, boxing, cricket, cycling, esports, golf, ice-hockey, mma, rugby-league, rugby-union, soccer, table-tennis, tennis, volleyball
Bet-at-homeamerican-football, australian-rules, baseball, basketball, cricket, ice-hockey, rugby-league, soccer, tennis
Tipsportamerican-football, australian-rules, badminton, baseball, basketball, beach-volley, boxing, esports, handball, ice-hockey, mma, padel, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis
TABamerican-football, australian-rules, baseball, basketball, boxing, cricket, rugby-league, rugby-union, snooker, soccer
BetMGM(US)american-football, baseball, basketball, boxing, cricket, esports, ice-hockey, lacrosse, mma, rugby-league, soccer, table-tennis, tennis
BetRiversamerican-football, baseball, basketball, boxing, cricket, darts, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Betwayamerican-football, australian-rules, baseball, basketball, boxing, cricket, cycling, darts, esports, field-hockey, formula-1, futsal, golf, mma, rugby-union, soccer, table-tennis, tennis
Star Sportsamerican-football, australian-rules, baseball, basketball, boxing, cricket, cycling, darts, formula-1, golf, ice-hockey, mma, motorsports, politics, rugby-league, rugby-union, snooker, soccer, tennis, tv-specials, volleyball
Melbetamerican-football, australian-rules, badminton, baseball, basketball, beach-volley, boxing, cricket, esports, field-hockey, formula-1, futsal, golf, handball, ice-hockey, lacrosse, mma, motorsports, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Kalshiamerican-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, golf, lacrosse, mma, rugby-union, soccer, table-tennis, tennis
Chanceamerican-football, australian-rules, badminton, baseball, basketball, beach-volley, boxing, esports, handball, ice-hockey, mma, rugby-league, snooker, soccer, table-tennis, tennis, volleyball
1xBetamerican-football, australian-rules, baseball, basketball, boxing, cricket, esports, field-hockey, futsal, golf, handball, ice-hockey, lacrosse, mma, motorsports, padel, pickleball, rugby-union, snooker, soccer, table-tennis, tennis, volleyball, water-polo
Hard Rock Betamerican-football, baseball, basketball, boxing, cricket, cycling, darts, formula-1, futsal, golf, handball, ice-hockey, lacrosse, mma, motorsports, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
BetPARXamerican-football, baseball, basketball, boxing, cricket, darts, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis
Borgataamerican-football, australian-rules, baseball, basketball, boxing, cricket, handball, ice-hockey, lacrosse, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis
Bovadaamerican-football, australian-rules, badminton, baseball, basketball, boxing, cricket, cycling, darts, esports, formula-1, golf, horse-racing, ice-hockey, lacrosse, mma, motorsports, pro-wrestling, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Mozzartamerican-football, baseball, basketball, darts, esports, futsal, handball, ice-hockey, soccer, table-tennis, tennis, volleyball
Betclicamerican-football, australian-rules, badminton, baseball, basketball, boxing, cycling, formula-1, golf, handball, ice-hockey, mma, motorsports, rugby-league, rugby-union, snooker, soccer, tennis, volleyball
Unibet FRamerican-football, australian-rules, badminton, baseball, basketball, boxing, cycling, formula-1, golf, handball, ice-hockey, mma, motorsports, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
Winamaxamerican-football, australian-rules, badminton, baseball, basketball, boxing, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball
NetBetamerican-football, australian-rules, badminton, baseball, basketball, boxing, cricket, cycling, darts, esports, formula-1, futsal, golf, handball, ice-hockey, lacrosse, mma, motorsports, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball, water-polo
AdmiralBet(DE)american-football, australian-rules, baseball, basketball, cricket, cycling, darts, formula-1, golf, handball, ice-hockey, motorsports, rugby-league, rugby-union, snooker, soccer, tennis, volleyball
NEO.betamerican-football, australian-rules, baseball, basketball, boxing, cycling, darts, formula-1, golf, handball, ice-hockey, motorsports, rugby-league, rugby-union, snooker, soccer, tennis, volleyball
Unibet UKamerican-football, australian-rules, badminton, baseball, basketball, boxing, cricket, cycling, darts, esports, field-hockey, formula-1, golf, handball, ice-hockey, mma, motorsports, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball, water-polo
Merkur Betsamerican-football, australian-rules, baseball, basketball, cycling, handball, ice-hockey, rugby-league, soccer, tennis, volleyball
Bwin (DE)american-football, baseball, basketball, handball, ice-hockey, soccer, tennis, volleyball
PMUamerican-football, australian-rules, baseball, basketball, boxing, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball

Subscribing to a sport with no live events right now is allowed — the server will simply send empty broadcast frames until events appear. Asking for a sport not listed above closes the connection with code 4004.

Query Parameters

ParamRequiredDescription
keyYesYour API key
sportYesSport to stream (soccer, tennis, etc.)

Message Format

On successful connection, the server sends a confirmation message:

json
{
  "type": "connected",
  "bookmaker": "fanduel",
  "sport": "soccer",
  "plan": "pro",
  "validSports": ["soccer", "basketball", "tennis", "ice-hockey", "..."]
}

Then every ~1 second, the server pushes a frame containing all live events for the subscribed sport:

json
{
  "sport": "soccer",
  "timestamp": 1747767600000,
  "count": 12,
  "data": [
    {
      "eventId": "98734521",
      "sport": "soccer",
      "league": "Premier League",
      "home": "Liverpool",
      "away": "Man City",
      "score": "1-0",
      "live": true,
      "startTime": "2026-05-20T19:00:00.000Z",
      "markets": [
        {
          "canonicalMarket": "match_winner",
          "period": "fulltime",
          "selections": [
            { "name": "Liverpool", "decimal": "2.10" },
            { "name": "Draw", "decimal": "3.40" },
            { "name": "Man City", "decimal": "3.25" }
          ]
        }
      ]
    }
  ]
}

Connection Limits

PlanMax Connections
BASIC (Free)0 (REST only)
STARTER (€20/mo)0 (REST only)
PRO1 concurrent
MAX3 concurrent
ULTRA6 concurrent

Delta Streams

Delta streams are the low-bandwidth alternative to the WebSocket feed: one socket, as many bookmakers and sports as your plan allows, prematch and live. Each stream sends its full board once (in ~1 MB pages) and then, once per second, only what changed — keyed by market and selection, so a client keeps an exact copy of every board with a few KB/s instead of hundreds. Available on PRO, MAX and ULTRA, in beta; 53 bookmakers are streamable today.

The Stream API has its own documentation page: connecting, plan limits, every frame, the apply rules, resuming with since, what happens during our deploys, reconnect rules, close codes, filters, limits and the reference clients.

Read the Stream API documentation

Code Examples

cURL

bash
# --compressed sends Accept-Encoding: gzip and inflates the reply (6–14× less on the wire)

# Fetch live soccer events (normalized response)
curl --compressed -X GET "https://api.pulsescore.net/api/v3/bet365/live-events?sport=soccer" \
  -H "X-Secret: YOUR_API_KEY"

# Swap the prefix for any other bookmaker — same shape, same paths
curl --compressed -X GET "https://api.pulsescore.net/api/fanduel/live-events?sport=soccer" \
  -H "X-Secret: YOUR_API_KEY"

# Fetch soccer leagues (pre-match)
curl --compressed -X GET "https://api.pulsescore.net/api/v3/bet365/soccer/leagues" \
  -H "X-Secret: YOUR_API_KEY"

# Fetch events for a league
curl --compressed -X GET "https://api.pulsescore.net/api/v3/bet365/soccer/leagues/Premier%20League/events" \
  -H "X-Secret: YOUR_API_KEY"

# Fetch tennis leagues
curl --compressed -X GET "https://api.pulsescore.net/api/v3/bet365/tennis/leagues" \
  -H "X-Secret: YOUR_API_KEY"

# Fetch a single event by eventId
curl --compressed -X GET "https://api.pulsescore.net/api/v3/bet365/soccer/events/98734521" \
  -H "X-Secret: YOUR_API_KEY"

Python

python
import requests

API_KEY = "YOUR_API_KEY"

# Swap this prefix for any bookmaker — the parser below stays the same
BASE_URL = "https://api.pulsescore.net/api/v3/bet365"
# BASE_URL = "https://api.pulsescore.net/api/fanduel"
# BASE_URL = "https://api.pulsescore.net/api/bwin"

# Fetch live events. requests already sends Accept-Encoding: gzip and inflates
# the reply — the header is spelled out here so it is not lost in a port.
response = requests.get(
    f"{BASE_URL}/live-events",
    headers={"X-Secret": API_KEY, "Accept-Encoding": "gzip"},
    params={"sport": "soccer"}
)

events = response.json()
for event in events:
    home, away = event["home"], event["away"]
    for market in event["markets"]:
        print(f"{home} vs {away} — {market['canonicalMarket']}")
        for sel in market["selections"]:
            print(f"  {sel['name']}: {sel['decimal']}")

Node.js

javascript
const API_KEY = "YOUR_API_KEY";

// Swap this prefix for any bookmaker — the parser below stays the same
const BASE_URL = "https://api.pulsescore.net/api/v3/bet365";
// const BASE_URL = "https://api.pulsescore.net/api/fanduel";
// const BASE_URL = "https://api.pulsescore.net/api/bwin";

// Fetch live events. Node's fetch already sends Accept-Encoding: gzip and
// inflates the reply — spelled out here so it survives a port to http.request.
const response = await fetch(`${BASE_URL}/live-events?sport=soccer`, {
  headers: { "X-Secret": API_KEY, "Accept-Encoding": "gzip" },
});

const events = await response.json();

for (const event of events) {
  console.log(`${event.home} vs ${event.away}`);
  for (const market of event.markets) {
    console.log(`  ${market.canonicalMarket}:`);
    for (const sel of market.selections) {
      console.log(`    ${sel.name}: ${sel.decimal}`);
    }
  }
}

WebSocket (Node.js)

javascript
const WebSocket = require("ws");

const API_KEY = "YOUR_API_KEY";

// All bookmakers with live WebSocket support
const ENDPOINTS = {
  bet365:           "wss://api.pulsescore.net/api/v3/bet365/ws/live",
  orbitxch:         "wss://api.pulsescore.net/api/orbitxch/ws/live",
  ps3838:           "wss://api.pulsescore.net/api/ps3838/ws/live",
  polymarket:       "wss://api.pulsescore.net/api/polymarket/ws/live",
  unibetau:         "wss://api.pulsescore.net/api/unibetau/ws/live",
  fanduel:          "wss://api.pulsescore.net/api/fanduel/ws/live",
  bwin:             "wss://api.pulsescore.net/api/bwin/ws/live",
  draftkings:       "wss://api.pulsescore.net/api/draftkings/ws/live",
  ladbrokes:        "wss://api.pulsescore.net/api/ladbrokes/ws/live",
  paddypower:       "wss://api.pulsescore.net/api/paddypower/ws/live",
  betfred:          "wss://api.pulsescore.net/api/betfred/ws/live",
  betano-de:        "wss://api.pulsescore.net/api/betano-de/ws/live",
  betano-br:        "wss://api.pulsescore.net/api/betano-br/ws/live",
  betmgm-couk:      "wss://api.pulsescore.net/api/betmgm-couk/ws/live",
  betmgm-nl:        "wss://api.pulsescore.net/api/betmgm-nl/ws/live",
  stake:            "wss://api.pulsescore.net/api/stake/ws/live",
  betwaymw:         "wss://api.pulsescore.net/api/betwaymw/ws/live",
  10bet:            "wss://api.pulsescore.net/api/10bet/ws/live",
  sportsbet-com-au: "wss://api.pulsescore.net/api/sportsbet-com-au/ws/live",
  thunderpick:      "wss://api.pulsescore.net/api/thunderpick/ws/live",
  betfair-sb:       "wss://api.pulsescore.net/api/betfair-sb/ws/live",
  skybet:           "wss://api.pulsescore.net/api/skybet/ws/live",
  cloudbet:         "wss://api.pulsescore.net/api/cloudbet/ws/live",
  betathome:        "wss://api.pulsescore.net/api/betathome/ws/live",
  tipsport:         "wss://api.pulsescore.net/api/tipsport/ws/live",
  tab:              "wss://api.pulsescore.net/api/tab/ws/live",
  betmgm:           "wss://api.pulsescore.net/api/betmgm/ws/live",
  betrivers:        "wss://api.pulsescore.net/api/betrivers/ws/live",
  betway:           "wss://api.pulsescore.net/api/betway/ws/live",
  starsports:       "wss://api.pulsescore.net/api/starsports/ws/live",
  melbet:           "wss://api.pulsescore.net/api/melbet/ws/live",
  kalshi:           "wss://api.pulsescore.net/api/kalshi/ws/live",
  chance:           "wss://api.pulsescore.net/api/chance/ws/live",
  onexbet:          "wss://api.pulsescore.net/api/onexbet/ws/live",
  hardrock:         "wss://api.pulsescore.net/api/hardrock/ws/live",
  betparx:          "wss://api.pulsescore.net/api/betparx/ws/live",
  borgata:          "wss://api.pulsescore.net/api/borgata/ws/live",
  bovada:           "wss://api.pulsescore.net/api/bovada/ws/live",
  mozzart:          "wss://api.pulsescore.net/api/mozzart/ws/live",
  betclic:          "wss://api.pulsescore.net/api/betclic/ws/live",
  unibet-fr:        "wss://api.pulsescore.net/api/unibet-fr/ws/live",
  winamax:          "wss://api.pulsescore.net/api/winamax/ws/live",
  netbet:           "wss://api.pulsescore.net/api/netbet/ws/live",
  admiralbet-de:    "wss://api.pulsescore.net/api/admiralbet-de/ws/live",
  neobet:           "wss://api.pulsescore.net/api/neobet/ws/live",
  unibet-uk:        "wss://api.pulsescore.net/api/unibet-uk/ws/live",
  merkur:           "wss://api.pulsescore.net/api/merkur/ws/live",
  bwin-de:          "wss://api.pulsescore.net/api/bwin-de/ws/live",
  pmu:              "wss://api.pulsescore.net/api/pmu/ws/live",
};

const bookmaker = "ps3838"; // bet365 | orbitxch | ps3838 | polymarket | unibetau | fanduel | bwin | draftkings | ladbrokes | paddypower | betfred | betano-de | betano-br | betmgm-couk | betmgm-nl | stake | betwaymw | 10bet | sportsbet-com-au | thunderpick | betfair-sb | skybet | cloudbet | betathome | tipsport | tab | betmgm | betrivers | betway | starsports | melbet | kalshi | chance | onexbet | hardrock | betparx | borgata | bovada | mozzart | betclic | unibet-fr | winamax | netbet | admiralbet-de | neobet | unibet-uk | merkur | bwin-de | pmu
const sport = "soccer";
const ws = new WebSocket(
  `${ENDPOINTS[bookmaker]}?key=${API_KEY}&sport=${sport}`
);

ws.on("open", () => {
  console.log(`Connected to ${bookmaker} (${sport})`);
});

ws.on("message", (raw) => {
  const msg = JSON.parse(raw);
  if (msg.type === "connected") {
    console.log(`Subscribed to ${msg.bookmaker} ${msg.sport} (plan: ${msg.plan})`);
    console.log(`Valid sports: ${msg.validSports.join(", ")}`);
    return;
  }
  // Broadcast frame
  console.log(`${msg.count} live ${msg.sport} events`);
  for (const event of msg.data) {
    console.log(`  ${event.home} vs ${event.away}`);
  }
});

ws.on("close", (code, reason) => {
  console.log(`Disconnected: ${code} ${reason}`);
});

WebSocket (Python)

python
import asyncio
import json
import websockets

API_KEY = "YOUR_API_KEY"

# All bookmakers with live WebSocket support
ENDPOINTS = {
  "bet365":            "wss://api.pulsescore.net/api/v3/bet365/ws/live",
  "orbitxch":          "wss://api.pulsescore.net/api/orbitxch/ws/live",
  "ps3838":            "wss://api.pulsescore.net/api/ps3838/ws/live",
  "polymarket":        "wss://api.pulsescore.net/api/polymarket/ws/live",
  "unibetau":          "wss://api.pulsescore.net/api/unibetau/ws/live",
  "fanduel":           "wss://api.pulsescore.net/api/fanduel/ws/live",
  "bwin":              "wss://api.pulsescore.net/api/bwin/ws/live",
  "draftkings":        "wss://api.pulsescore.net/api/draftkings/ws/live",
  "ladbrokes":         "wss://api.pulsescore.net/api/ladbrokes/ws/live",
  "paddypower":        "wss://api.pulsescore.net/api/paddypower/ws/live",
  "betfred":           "wss://api.pulsescore.net/api/betfred/ws/live",
  "betano-de":         "wss://api.pulsescore.net/api/betano-de/ws/live",
  "betano-br":         "wss://api.pulsescore.net/api/betano-br/ws/live",
  "betmgm-couk":       "wss://api.pulsescore.net/api/betmgm-couk/ws/live",
  "betmgm-nl":         "wss://api.pulsescore.net/api/betmgm-nl/ws/live",
  "stake":             "wss://api.pulsescore.net/api/stake/ws/live",
  "betwaymw":          "wss://api.pulsescore.net/api/betwaymw/ws/live",
  "10bet":             "wss://api.pulsescore.net/api/10bet/ws/live",
  "sportsbet-com-au":  "wss://api.pulsescore.net/api/sportsbet-com-au/ws/live",
  "thunderpick":       "wss://api.pulsescore.net/api/thunderpick/ws/live",
  "betfair-sb":        "wss://api.pulsescore.net/api/betfair-sb/ws/live",
  "skybet":            "wss://api.pulsescore.net/api/skybet/ws/live",
  "cloudbet":          "wss://api.pulsescore.net/api/cloudbet/ws/live",
  "betathome":         "wss://api.pulsescore.net/api/betathome/ws/live",
  "tipsport":          "wss://api.pulsescore.net/api/tipsport/ws/live",
  "tab":               "wss://api.pulsescore.net/api/tab/ws/live",
  "betmgm":            "wss://api.pulsescore.net/api/betmgm/ws/live",
  "betrivers":         "wss://api.pulsescore.net/api/betrivers/ws/live",
  "betway":            "wss://api.pulsescore.net/api/betway/ws/live",
  "starsports":        "wss://api.pulsescore.net/api/starsports/ws/live",
  "melbet":            "wss://api.pulsescore.net/api/melbet/ws/live",
  "kalshi":            "wss://api.pulsescore.net/api/kalshi/ws/live",
  "chance":            "wss://api.pulsescore.net/api/chance/ws/live",
  "onexbet":           "wss://api.pulsescore.net/api/onexbet/ws/live",
  "hardrock":          "wss://api.pulsescore.net/api/hardrock/ws/live",
  "betparx":           "wss://api.pulsescore.net/api/betparx/ws/live",
  "borgata":           "wss://api.pulsescore.net/api/borgata/ws/live",
  "bovada":            "wss://api.pulsescore.net/api/bovada/ws/live",
  "mozzart":           "wss://api.pulsescore.net/api/mozzart/ws/live",
  "betclic":           "wss://api.pulsescore.net/api/betclic/ws/live",
  "unibet-fr":         "wss://api.pulsescore.net/api/unibet-fr/ws/live",
  "winamax":           "wss://api.pulsescore.net/api/winamax/ws/live",
  "netbet":            "wss://api.pulsescore.net/api/netbet/ws/live",
  "admiralbet-de":     "wss://api.pulsescore.net/api/admiralbet-de/ws/live",
  "neobet":            "wss://api.pulsescore.net/api/neobet/ws/live",
  "unibet-uk":         "wss://api.pulsescore.net/api/unibet-uk/ws/live",
  "merkur":            "wss://api.pulsescore.net/api/merkur/ws/live",
  "bwin-de":           "wss://api.pulsescore.net/api/bwin-de/ws/live",
  "pmu":               "wss://api.pulsescore.net/api/pmu/ws/live",
}

BOOKMAKER = "ps3838"  # bet365 | orbitxch | ps3838 | polymarket | unibetau | fanduel | bwin | draftkings | ladbrokes | paddypower | betfred | betano-de | betano-br | betmgm-couk | betmgm-nl | stake | betwaymw | 10bet | sportsbet-com-au | thunderpick | betfair-sb | skybet | cloudbet | betathome | tipsport | tab | betmgm | betrivers | betway | starsports | melbet | kalshi | chance | onexbet | hardrock | betparx | borgata | bovada | mozzart | betclic | unibet-fr | winamax | netbet | admiralbet-de | neobet | unibet-uk | merkur | bwin-de | pmu
SPORT = "soccer"
URL = f"{ENDPOINTS[BOOKMAKER]}?key={API_KEY}&sport={SPORT}"

async def stream():
    async with websockets.connect(URL) as ws:
        print(f"Connected to {BOOKMAKER} ({SPORT})")
        async for message in ws:
            msg = json.loads(message)
            if msg.get("type") == "connected":
                print(f"Subscribed to {msg['bookmaker']} {msg['sport']} (plan: {msg['plan']})")
                print(f"Valid sports: {', '.join(msg['validSports'])}")
                continue
            # Broadcast frame
            for event in msg["data"]:
                print(f"{event['home']} vs {event['away']}")

asyncio.run(stream())

Error Codes

CodeMeaning
200Success
401Invalid or missing API key
403Access denied (plan restriction)
404Resource not found
429Rate limit exceeded
500Internal server error

WebSocket Close Codes

CodeMeaningRetry?
4001Authentication failedNo
4003Plan too low (PRO, MAX or ULTRA required)No
4004Invalid sport for this bookmakerNo
4010Subscription expiredNo
4011Plan downgrade - reconnect requiredYes
4012Session replaced by new connectionYes
4029Connection limit reachedNo

Rate Limits

PlanRequestsRate (per bookmaker)WebSocketPrice
BASIC500/month1 req/secNoneFree
STARTER30,000/month1 req/minNone€20/mo
PROUnlimited1 req/sec1 connection€79/mo
MAXUnlimited3 req/sec3 connections€149/mo
ULTRAUnlimited6 req/sec6 connections€249/mo

Rate-limited requests return HTTP 429. Implement exponential backoff for retries. WebSocket connections automatically receive updates - no polling needed.

Over the limit you get 429 with X-RateLimit-* headers. A key that keeps going after that — ten rejections within ten seconds on one bookmaker — is paused for 60 seconds: every request and every legacy WebSocket handshake then answers 429 with a Retry-After header and a message that says so. Back off on the first 429 and the pause never happens. The Stream API has its own limits and is not affected by the pause.