What You'll Need
- A free PulseScore API key → grab one here (no credit card required)
- Basic knowledge of HTTP requests
- Node.js installed with TypeScript (
npm install -g typescript ts-node)
Step 1 — Get Your Free API Key
Head to pulsescore.net/dashboard and sign up for free. The Basic plan gives you 500 requests/month at no cost — more than enough to get started.
Once registered, copy your API key from the dashboard.
Step 2 — Define Your Types
One of TypeScript's biggest advantages is type safety. Let's define the response structure first:
interface Price {
decimal: string;
}
interface MarketOption {
name: string;
pa: Price[];
}
interface MarketGroup {
name: string;
ma: MarketOption[];
}
interface Match {
fi: string;
sport: string;
league: string;
home: string;
away: string;
live: 0 | 1;
tab?: string;
mg: MarketGroup[];
}
interface WebSocketMessage {
type: 'data';
timestamp: number;
events: Match[];
}
Step 3 — Fetch Live Odds (REST API)
All requests use the X-Secret header with your API key:
const API_KEY: string = 'YOUR_API_KEY';
const BASE_URL: string = 'https://api.pulsescore.net/api/v2/bet365';
async function getLiveOdds(sport: string = 'soccer'): Promise<Match[]> {
const response = await fetch(`${BASE_URL}/live-events?sport=${sport}`, {
headers: {
'X-Secret': API_KEY
}
});
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
return response.json() as Promise<Match[]>;
}
// Run it
getLiveOdds('soccer')
.then((matches) => {
matches.forEach((match) => {
console.log(`${match.home} vs ${match.away} — ${match.league}`);
match.mg.forEach((market) => {
console.log(` Market: ${market.name}`);
market.ma.forEach((option) => {
console.log(` ${option.name}: ${option.pa[0].decimal}`);
});
});
});
})
.catch(console.error);
Using cURL
curl -X GET "https://api.pulsescore.net/api/v2/bet365/live-events?sport=soccer" \
-H "X-Secret: YOUR_API_KEY"
Step 4 — Understanding the Response
The API returns clean JSON like this:
[
{
"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" }] }
]
}
]
}
]
Here's what each field means:
| Field | Description |
|---|---|
fi |
Unique match ID |
sport |
Sport type (Soccer, Tennis, Basketball...) |
league |
League name |
home / away
|
Team names |
live |
1 = live match, 0 = pre-match |
tab |
Market tab (e.g. Popular) |
mg |
Market groups (e.g. Fulltime Result) |
ma |
Market options with odds |
pa |
Price array with decimal odds |
Step 5 — Fetch Pre-Match Odds
Want odds for upcoming matches? First fetch the available leagues, then pull events:
// Step 1 — get available leagues
async function getLeagues(sport: string = 'soccer'): Promise<any[]> {
const path = sport === 'soccer' ? 'leagues' : `${sport}/leagues`;
const response = await fetch(`${BASE_URL}/${path}`, {
headers: { 'X-Secret': API_KEY }
});
return response.json();
}
// Step 2 — get events for a league
async function getEvents(league: string, sport: string = 'soccer'): Promise<Match[]> {
const path = sport === 'soccer' ? 'events' : `${sport}/events`;
const response = await fetch(
`${BASE_URL}/${path}?league=${encodeURIComponent(league)}`,
{ headers: { 'X-Secret': API_KEY } }
);
return response.json() as Promise<Match[]>;
}
// Usage
const leagues = await getLeagues('soccer');
const events = await getEvents('Premier League', 'soccer');
Supported sports: soccer, tennis, basketball, ice-hockey, american-football, horse-racing, volleyball, handball, table-tennis, e-sports, baseball, greyhounds.
Step 6 — Real-Time Odds via WebSocket
For apps that need odds updated every 2 seconds, use the WebSocket connection (available on Pro plan and above). The API key is passed as a query parameter:
import WebSocket from 'ws';
const API_KEY: string = 'YOUR_API_KEY';
const ws = new WebSocket(
`wss://api.pulsescore.net/api/v2/bet365/ws/live?key=${API_KEY}&sport=soccer`
);
ws.on('open', (): void => {
console.log('Connected to PulseScore live feed');
});
ws.on('message', (data: WebSocket.Data): void => {
const msg: WebSocketMessage = JSON.parse(data.toString());
if (msg.type === 'data') {
console.log(`Received ${msg.events.length} live events`);
msg.events.forEach((match) => {
console.log(` ${match.home} vs ${match.away} — ${match.league}`);
});
}
});
ws.on('error', (error: Error): void => {
console.error('WebSocket error:', error.message);
});
ws.on('close', (code: number, reason: Buffer): void => {
console.log(`Disconnected: ${code} ${reason}`);
});
This is perfect for building live odds dashboards, arbitrage bots, or trading desk tools.
What Can You Build With This?
Here are some ideas developers are already building with PulseScore:
- Odds comparison tools — compare Bet365 vs Paddy Power side by side
- Arbitrage betting bots — detect price differences across bookmakers automatically
- Sports analytics dashboards — visualize odds movement over time
- Fantasy sports apps — enrich your app with real-time data
- Trading algorithms — automate decisions based on live odds shifts
Pricing
| Plan | Price | Requests | WebSocket |
|---|---|---|---|
| Basic | Free | 500 req/month | None |
| Starter | €20/mo | 30,000 req/month | None |
| Pro | €79/mo | Unlimited | 1 connection |
| Max | €149/mo | Unlimited | 3 connections |
Wrap Up
In just a few lines of TypeScript you can pull live odds from the biggest bookmakers in the world. No scraping, no maintenance, no headaches.
- Free API key → pulsescore.net/dashboard
- Full docs → pulsescore.net/docs
- Live demo → pulsescore.net/live
Give it a try and drop a comment if you build something cool with it!
Top comments (0)