Official Node.js client for UKOddsApi — live football odds from 25+ UK bookmakers.
Bet365 · Sky Bet · Paddy Power · William Hill · Ladbrokes · Coral · Betfred · BetVictor · 888sport · Unibet · BoyleSports · Betway · Betfair Exchange · Matchbook · Smarkets · and more
npm install ukoddsapiconst { UKOddsApi } = require("ukoddsapi");
const client = new UKOddsApi("your_api_key");
async function main() {
// Get today's Premier League fixtures
const events = await client.getEvents({
league: "premier-league",
scheduleDate: "2026-04-25",
});
// Get odds from all UK bookmakers
const odds = await client.getOdds(events.events[0].event_id);
for (const market of odds.markets) {
console.log(market.market_name);
for (const sel of market.selections) {
console.log(` ${sel.selection_name}: ${sel.odds} @ ${sel.bookmaker_name}`);
}
}
}
main();- 25+ UK bookmakers — every major UK high street brand plus exchanges
- 100+ markets — match odds, player props, team props, corners, cards
- Arbitrage detection — built-in endpoint with stake plans (Scale plan)
- Best odds — instantly find the highest price per selection
- Batch requests — odds for up to 50 events in one call
- ETag caching — skip unchanged data and save API calls
- Historical odds — track odds movement over time
- TypeScript types — full type definitions included
- Zero dependencies — uses native
fetch(Node 18+) - Automatic retries — handles rate limits and server errors
const odds = await client.getOdds("evt_arsenal_chelsea_2026_04_25");
for (const market of odds.markets) {
for (const sel of market.selections) {
console.log(`${sel.selection_name}: ${sel.odds} @ ${sel.bookmaker_name}`);
}
}const best = await client.getBestOdds("evt_arsenal_chelsea_2026_04_25");
for (const market of best.markets) {
for (const sel of market.selections) {
console.log(`${sel.selection_name}: ${sel.odds} @ ${sel.bookmaker_name}`);
}
}// Bet365 only
const odds = await client.getOdds("evt_arsenal_chelsea_2026_04_25", {
bookmakerCodes: "UO004",
});
// Bet365 + Sky Bet
const odds2 = await client.getOdds("evt_arsenal_chelsea_2026_04_25", {
bookmakerCodes: "UO004,UO020",
});const odds = await client.getOdds("evt_arsenal_chelsea_2026_04_25", {
package: "full",
market: "goalscorer",
});
for (const market of odds.markets) {
for (const sel of market.selections) {
console.log(`${sel.selection_name}: ${sel.odds} @ ${sel.bookmaker_name}`);
}
}const arbs = await client.getArbitrage({
date: "2026-04-25",
minProfit: 0.5,
totalStake: 500,
});
for (const arb of arbs.arbitrages) {
console.log(`${arb.event_title} — ${arb.market_name}`);
console.log(`Profit: ${arb.profit_percentage.toFixed(2)}%`);
for (const leg of arb.stake_plan.legs) {
console.log(` ${leg.bookmaker_name}: ${leg.selection} @ ${leg.odds} — £${leg.stake_amount_final}`);
}
}const events = await client.getEvents({ league: "premier-league" });
const eventIds = events.events.slice(0, 20).map((e) => e.event_id);
const batch = await client.getOddsBatch(eventIds);
console.log(`Fetched odds for ${batch.returned} events`);setInterval(async () => {
const odds = await client.getOdds("evt_arsenal_chelsea_2026_04_25", {
useEtag: true,
});
if (odds === null) {
console.log("No change");
} else {
console.log(`Updated: ${odds.captured_at}`);
// Process new odds...
}
}, 30000);const timeline = await client.getOddsTimeline({
eventId: "evt_arsenal_chelsea_2026_04_25",
marketId: 101,
selectionName: "Arsenal",
bookmakerCode: "UO004",
});// Decimal (default)
const decimal = await client.getOdds(eventId, { oddsFormat: "decimal" });
// Fractional (UK-style)
const fractional = await client.getOdds(eventId, { oddsFormat: "fractional" });
// American
const american = await client.getOdds(eventId, { oddsFormat: "american" });const { UKOddsApi, RateLimitError, AuthenticationError, UKOddsApiError } = require("ukoddsapi");
const client = new UKOddsApi("your_api_key");
try {
const odds = await client.getOdds("evt_example");
} catch (err) {
if (err instanceof AuthenticationError) {
console.log("Invalid API key");
} else if (err instanceof RateLimitError) {
console.log(`Rate limited — retry after ${err.retryAfter} seconds`);
} else if (err instanceof UKOddsApiError) {
console.log(`API error ${err.statusCode}: ${err.detail}`);
}
}| Method | Description | Plan |
|---|---|---|
verify() |
Check API key is valid | All |
getBookmakers() |
List all 25+ UK bookmakers | All |
getSports() |
List supported sports | All |
getLeagues() |
List football leagues | All |
getCountries() |
List football countries | All |
getCompetitions() |
List competitions (catalog) | All |
getMarkets() |
List available market types | All |
getEvents() |
List fixtures by date/league | All |
getEventMarkets() |
Markets available on an event | All |
getOdds() |
Full odds from all bookmakers | Starter+ |
getBestOdds() |
Best price per selection | Starter+ |
getOddsBatch() |
Odds for up to 50 events | Starter+ |
getArbitrage() |
Find arb opportunities by date | Scale |
getEventArbitrage() |
Arbs on a specific event | Scale |
getOddsTimeline() |
Historical odds movement | Pro+ |
getAccount() |
Account info and usage | All |
This table is a partial excerpt of common UK bookmakers. The full (and most up-to-date) list is returned by the API.
| Code | Bookmaker | Type |
|---|---|---|
| UO004 | Bet365 | Sportsbook |
| UO020 | Sky Bet | Sportsbook |
| UO018 | Paddy Power | Sportsbook |
| UO027 | William Hill | Sportsbook |
| UO015 | Ladbrokes | Sportsbook |
| UO013 | Coral | Sportsbook |
| UO007 | Betfred | Sportsbook |
| UO005 | BetVictor | Sportsbook |
| UO002 | 888sport | Sportsbook |
| UO024 | Unibet | Sportsbook |
| UO012 | BoyleSports | Sportsbook |
| UO008 | Betway | Sportsbook |
| UO006 | Betfair | Exchange |
| UO017 | Matchbook | Exchange |
Fetch the full list:
const { UKOddsApi } = require("ukoddsapi");
const client = new UKOddsApi(process.env.UKODDS_API_KEY);
const { bookmakers } = await client.getBookmakers();
console.log(bookmakers.map((b) => `${b.bookmaker_code} ${b.name} (${b.type})`).join("\n"));- Node.js 18+ (uses native
fetch)
- UKOddsApi — sign up for an API key
- API documentation
- Python SDK
MIT