Documentation

PulseScore API Docs

Everything you need to integrate real-time Bet365 odds into your application. REST API, WebSocket, and code examples for every major language.

Quick Start

Get live odds data in 3 steps:

  1. Create an account — Sign up at pulsescore.net (free BASIC plan: 100 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 -X GET "https://api.pulsescore.net/api/v2/bet365/live-events?sport=soccer" \
  -H "X-Secret: YOUR_API_KEY"

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 responses. All endpoints use the base URL:

text
https://api.pulsescore.net/api/v2/bet365

Standard HTTP status codes indicate success or failure. Responses are returned as JSON arrays or objects.

Endpoints

Live Events

GET/live-events

Fetch all currently live events with real-time odds and market groups.

Parameters

NameTypeRequiredDescription
sportstringNoFilter by sport: soccer (default), tennis, basketball, ice-hockey, volleyball, handball, table-tennis, e-sports, american-football, baseball, rugby-league, rugby-union

Response

json
[
  {
    "fi": "98734521",
    "sport": "Soccer",
    "league": "Premier League",
    "home": "Liverpool",
    "away": "Man City",
    "live": 1,
    "tab": "Popular",
    "mg": [
      {
        "name": "Fulltime Result",
        "ma": [
          { "name": "Liverpool", "pa": [{ "decimal": "2.10" }] },
          { "name": "Draw", "pa": [{ "decimal": "3.40" }] },
          { "name": "Man City", "pa": [{ "decimal": "3.25" }] }
        ]
      },
      {
        "name": "Over/Under 2.5 Goals",
        "ma": [
          { "name": "Over 2.5", "pa": [{ "decimal": "1.75" }] },
          { "name": "Under 2.5", "pa": [{ "decimal": "2.05" }] }
        ]
      }
    ]
  }
]
GET/live-events/sports

Get a list of all sports that currently have live events.

Response

json
[
  { "sport": "Soccer", "count": 42 },
  { "sport": "Tennis", "count": 18 },
  { "sport": "Basketball", "count": 8 }
]
GET/live-events/:id

Fetch a single live event by its ID.

Parameters

NameTypeRequiredDescription
idstringYesEvent ID from /live-events response

Response

json
{
  "fi": "98734521",
  "sport": "Soccer",
  "league": "Premier League",
  "home": "Liverpool",
  "away": "Man City",
  "live": 1,
  "mg": [ ... ]
}

Pre-Match (by Sport)

Pre-match data is organized by sport. Replace {sport} with: soccer (root), tennis, basketball, ice-hockey, american-football, horse-racing, volleyball, handball, table-tennis, e-sports, baseball, greyhounds. Soccer uses the root path (no sport prefix).

GET/{sport}/leagues

Get all available leagues for a sport. For soccer, use /leagues (no prefix).

Response

json
[
  {
    "league": "Premier League",
    "sport": "Soccer",
    "live": 0,
    "events": [
      { "home": "Arsenal", "away": "Chelsea", "fi": "45921003" },
      { "home": "Liverpool", "away": "Tottenham", "fi": "45921004" }
    ]
  }
]
GET/{sport}/events

Get events for a specific league. For soccer, use /events (no prefix).

Parameters

NameTypeRequiredDescription
leaguestringYesLeague name from /leagues response
tabstringNoMarket tab filter (e.g., Popular)

Response

json
[
  {
    "fi": "45921003",
    "sport": "Soccer",
    "league": "Premier League",
    "home": "Arsenal",
    "away": "Chelsea",
    "live": 0,
    "tab": "Popular",
    "mg": [
      {
        "name": "Fulltime Result",
        "ma": [
          { "name": "Arsenal", "pa": [{ "decimal": "2.30" }] },
          { "name": "Draw", "pa": [{ "decimal": "3.20" }] },
          { "name": "Chelsea", "pa": [{ "decimal": "3.10" }] }
        ]
      }
    ]
  }
]
GET/{sport}/events/:fi

Fetch a single pre-match event by fixture ID. For soccer, use /events/:fi.

Parameters

NameTypeRequiredDescription
fistringYesFixture ID from /leagues or /events response

Response

json
{
  "fi": "45921003",
  "sport": "Soccer",
  "league": "Premier League",
  "home": "Arsenal",
  "away": "Chelsea",
  "live": 0,
  "mg": [ ... ]
}

WebSocket

The WebSocket feed provides real-time streaming updates. Available on PRO and MAX plans.

Connection URL

wss://api.pulsescore.net/api/v2/bet365/ws/live?key=YOUR_API_KEY&sport=soccer

Query Parameters

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

Message Format

The server sends broadcast messages containing all live events for the subscribed sport:

json
{
  "type": "data",
  "timestamp": 1709474521000,
  "events": [
    {
      "fi": "98734521",
      "sport": "Soccer",
      "league": "Premier League",
      "home": "Liverpool",
      "away": "Man City",
      "live": 1,
      "mg": [
        {
          "name": "Fulltime Result",
          "ma": [
            { "name": "Liverpool", "pa": [{ "decimal": "2.10" }] },
            { "name": "Draw", "pa": [{ "decimal": "3.40" }] },
            { "name": "Man City", "pa": [{ "decimal": "3.25" }] }
          ]
        }
      ]
    }
  ]
}

Connection Limits

PlanMax Connections
BASIC (Free)0 (REST only)
PRO1 concurrent
MAX3 concurrent

Code Examples

cURL

bash
# Fetch live soccer events
curl -X GET "https://api.pulsescore.net/api/v2/bet365/live-events?sport=soccer" \
  -H "X-Secret: YOUR_API_KEY"

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

# Fetch events for a league
curl -X GET "https://api.pulsescore.net/api/v2/bet365/events?league=Premier%20League" \
  -H "X-Secret: YOUR_API_KEY"

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

# Fetch a single event by fixture ID
curl -X GET "https://api.pulsescore.net/api/v2/bet365/events/98734521" \
  -H "X-Secret: YOUR_API_KEY"

Python

python
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.pulsescore.net/api/v2/bet365"

# Fetch live events
response = requests.get(
    f"{BASE_URL}/live-events",
    headers={"X-Secret": API_KEY},
    params={"sport": "soccer"}
)

events = response.json()
for event in events:
    home = event["home"]
    away = event["away"]
    for mg in event["mg"]:
        print(f"{home} vs {away} — {mg['name']}")
        for ma in mg["ma"]:
            odds = ma["pa"][0]["decimal"]
            print(f"  {ma['name']}: {odds}")

Node.js

javascript
const API_KEY = "YOUR_API_KEY";
const BASE_URL = "https://api.pulsescore.net/api/v2/bet365";

// Fetch live events
const response = await fetch(`${BASE_URL}/live-events?sport=soccer`, {
  headers: { "X-Secret": API_KEY },
});

const events = await response.json();

for (const event of events) {
  console.log(`${event.home} vs ${event.away}`);
  for (const mg of event.mg) {
    console.log(`  ${mg.name}:`);
    for (const ma of mg.ma) {
      console.log(`    ${ma.name}: ${ma.pa[0].decimal}`);
    }
  }
}

WebSocket (Node.js)

javascript
const WebSocket = require("ws");

const API_KEY = "YOUR_API_KEY";
const ws = new WebSocket(
  `wss://api.pulsescore.net/api/v2/bet365/ws/live?key=${API_KEY}&sport=soccer`
);

ws.on("open", () => {
  console.log("Connected to PulseScore WebSocket");
});

ws.on("message", (data) => {
  const msg = JSON.parse(data);
  if (msg.type === "data") {
    console.log(`Received ${msg.events.length} live events`);
    for (const event of msg.events) {
      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"
URL = f"wss://api.pulsescore.net/api/v2/bet365/ws/live?key={API_KEY}&sport=soccer"

async def stream():
    async with websockets.connect(URL) as ws:
        print("Connected")
        async for message in ws:
            data = json.loads(message)
            if data.get("type") == "data":
                for event in data["events"]:
                    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 limit reachedNo
4004Invalid sportNo
4005Bookmaker access deniedNo
4010API key expiredNo
4011Plan downgrade — reconnect requiredYes
4012Session replaced by new connectionYes
4029Connection limit reachedNo

Rate Limits

PlanRequestsRateWebSocketPrice
BASIC100/month3 req/secNoneFree
PROUnlimited3 req/sec1 connection€79/mo
MAXUnlimited3 req/sec3 connections€149/mo

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