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:
- Create an account - Sign up at pulsescore.net (free BASIC plan: 500 requests/month)
- Generate an API key - Go to Dashboard → Generate API Key
- Make your first call - Use the key in the
X-Secretheader
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:
| Header | Value |
|---|---|
| X-Secret | Your 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:
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 bookieThe 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, Pythonrequests/httpx, Gonet/http— on by default, nothing to do. - cURL — add
--compressed(every example on this page does). - .NET
HttpClient— off by default; construct it withnew SocketsHttpHandler { AutomaticDecompression = DecompressionMethods.All }. - Java
HttpClient— off by default; set the header yourself and wrap the body in aGZIPInputStream.
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
| Field | Use | When to fall back |
|---|---|---|
| canonicalMarket | Normalized market key (e.g. match_winner, total_goals). | Primary identifier — switch on this. |
| period | Normalized period (e.g. fulltime, first_half). | If period looks wrong or unmapped, read rawName. |
| rawName | Original 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.
| Field | Use |
|---|---|
| name | Normalized outcome label (e.g. Over 2.5, team name). |
| rawName | Original 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
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
{
"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 }
]
}
]
}
]
}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
{
"total": 67,
"sports": [
{ "name": "basketball", "eventCount": 5 },
{ "name": "soccer", "eventCount": 17 },
{ "name": "table_tennis", "eventCount": 17 },
{ "name": "tennis", "eventCount": 28 }
]
}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
{
"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.
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
{
"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": [ ... ]
}
]
}
]
}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
{
"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": [ ... ]
}
]
}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
{
"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 }
]
}
]
}
]
}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
{
"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.
Upcoming horse racing meetings on bet365 with every runner. Prices fill in as the off time approaches.
Response
{
"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" }
}
]
}
]
}Upcoming greyhound meetings on bet365 with every runner and its each-way price.
Response
{
"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:
wss://api.pulsescore.net/api/{bookmaker}/ws/live?key=YOUR_API_KEY&sport=SPORTBet365 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
| Bookmaker | URL |
|---|---|
| Bet365 | wss://api.pulsescore.net/api/v3/bet365/ws/live |
| Betfair(OrbitExch) | 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 |
| Unibet AU | 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 |
| Paddy Power | 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(CO.UK) | 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 |
| Betway MW | wss://api.pulsescore.net/api/betwaymw/ws/live |
| 10Bet(CO.UK) | wss://api.pulsescore.net/api/10bet/ws/live |
| Sportsbet AU | wss://api.pulsescore.net/api/sportsbet-com-au/ws/live |
| Thunderpick | wss://api.pulsescore.net/api/thunderpick/ws/live |
| Betfair Sportsbook | wss://api.pulsescore.net/api/betfair-sb/ws/live |
| Sky Bet | wss://api.pulsescore.net/api/skybet/ws/live |
| Cloudbet | wss://api.pulsescore.net/api/cloudbet/ws/live |
| Bet-at-home | 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(US) | 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 |
| Star Sports | 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 |
| 1xBet | wss://api.pulsescore.net/api/onexbet/ws/live |
| Hard Rock Bet | 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 |
| NEO.bet | wss://api.pulsescore.net/api/neobet/ws/live |
| Unibet UK | wss://api.pulsescore.net/api/unibet-uk/ws/live |
| Merkur Bets | 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 |
All endpoints require ?key=YOUR_API_KEY&sport=SPORT as query parameters.
Valid Sports per Bookmaker
| Bookmaker | Sports |
|---|---|
| Bet365 | soccer, 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 |
| PS3838 | soccer, basketball, tennis, american-football, ice-hockey, baseball, rugby-league, esports |
| Polymarket | american-football, baseball, basketball, boxing, cricket, esports, lacrosse, mma, pickleball, soccer, table-tennis, tennis, volleyball |
| Unibet AU | american-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 |
| Fanduel | american-football, baseball, basketball, boxing, cricket, darts, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis |
| Bwin | american-football, baseball, basketball, cricket, darts, futsal, handball, ice-hockey, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball |
| DraftKings | american-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 |
| Ladbrokes | american-football, baseball, basketball, boxing, cricket, darts, esports, greyhounds, handball, horse-racing, ice-hockey, mma, rugby-league, rugby-union, soccer, table-tennis, tennis, volleyball |
| Paddy Power | american-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 |
| Betfred | baseball, 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 |
| Stake | american-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, ice-hockey, mma, rugby-union, soccer, table-tennis, tennis, volleyball, water-polo |
| Betway MW | american-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 AU | american-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball |
| Thunderpick | american-football, australian-rules, badminton, baseball, basketball, cricket, darts, esports, ice-hockey, martial-arts, rugby-league, rugby-union, soccer, table-tennis, tennis, volleyball |
| Betfair Sportsbook | american-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, ice-hockey, mma, rugby-league, snooker, soccer, table-tennis, tennis, volleyball |
| Sky Bet | american-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball |
| Cloudbet | american-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-home | american-football, australian-rules, baseball, basketball, cricket, ice-hockey, rugby-league, soccer, tennis |
| Tipsport | american-football, australian-rules, badminton, baseball, basketball, beach-volley, boxing, esports, handball, ice-hockey, mma, padel, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis |
| TAB | american-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 |
| BetRivers | american-football, baseball, basketball, boxing, cricket, darts, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball |
| Betway | american-football, australian-rules, baseball, basketball, boxing, cricket, cycling, darts, esports, field-hockey, formula-1, futsal, golf, mma, rugby-union, soccer, table-tennis, tennis |
| Star Sports | american-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 |
| Melbet | american-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 |
| Kalshi | american-football, australian-rules, baseball, basketball, boxing, cricket, darts, esports, golf, lacrosse, mma, rugby-union, soccer, table-tennis, tennis |
| Chance | american-football, australian-rules, badminton, baseball, basketball, beach-volley, boxing, esports, handball, ice-hockey, mma, rugby-league, snooker, soccer, table-tennis, tennis, volleyball |
| 1xBet | american-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 Bet | american-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 |
| BetPARX | american-football, baseball, basketball, boxing, cricket, darts, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis |
| Borgata | american-football, australian-rules, baseball, basketball, boxing, cricket, handball, ice-hockey, lacrosse, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis |
| Bovada | american-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 |
| Mozzart | american-football, baseball, basketball, darts, esports, futsal, handball, ice-hockey, soccer, table-tennis, tennis, volleyball |
| Betclic | american-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 FR | american-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 |
| Winamax | american-football, australian-rules, badminton, baseball, basketball, boxing, handball, ice-hockey, mma, rugby-league, rugby-union, snooker, soccer, table-tennis, tennis, volleyball |
| NetBet | american-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.bet | american-football, australian-rules, baseball, basketball, boxing, cycling, darts, formula-1, golf, handball, ice-hockey, motorsports, rugby-league, rugby-union, snooker, soccer, tennis, volleyball |
| Unibet UK | american-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 Bets | american-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 |
| PMU | american-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
| Param | Required | Description |
|---|---|---|
| key | Yes | Your API key |
| sport | Yes | Sport to stream (soccer, tennis, etc.) |
Message Format
On successful connection, the server sends a confirmation message:
{
"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:
{
"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
| Plan | Max Connections |
|---|---|
| BASIC (Free) | 0 (REST only) |
| STARTER (€20/mo) | 0 (REST only) |
| PRO | 1 concurrent |
| MAX | 3 concurrent |
| ULTRA | 6 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.
Code Examples
cURL
# --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
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
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)
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)
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
| Code | Meaning |
|---|---|
| 200 | Success |
| 401 | Invalid or missing API key |
| 403 | Access denied (plan restriction) |
| 404 | Resource not found |
| 429 | Rate limit exceeded |
| 500 | Internal server error |
WebSocket Close Codes
| Code | Meaning | Retry? |
|---|---|---|
| 4001 | Authentication failed | No |
| 4003 | Plan too low (PRO, MAX or ULTRA required) | No |
| 4004 | Invalid sport for this bookmaker | No |
| 4010 | Subscription expired | No |
| 4011 | Plan downgrade - reconnect required | Yes |
| 4012 | Session replaced by new connection | Yes |
| 4029 | Connection limit reached | No |
Rate Limits
| Plan | Requests | Rate (per bookmaker) | WebSocket | Price |
|---|---|---|---|---|
| BASIC | 500/month | 1 req/sec | None | Free |
| STARTER | 30,000/month | 1 req/min | None | €20/mo |
| PRO | Unlimited | 1 req/sec | 1 connection | €79/mo |
| MAX | Unlimited | 3 req/sec | 3 connections | €149/mo |
| ULTRA | Unlimited | 6 req/sec | 6 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.