# Bet365 Odds Scraper - Live, Pre-Match & Player Props (`crawloop/bet365-odds-scraper`) Actor

Scrape Bet365 betting odds in one run: live in-play, pre-match 1X2, player props, and outrights across 30+ sports. Event, market, selection, plus decimal, American, and fractional prices. Unofficial Bet365 API alternative — Python, Node.js, MCP.

- **URL**: https://apify.com/crawloop/bet365-odds-scraper.md
- **Developed by:** [Andrej Kiva](https://apify.com/crawloop) (community)
- **Categories:** AI, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.49 / 1,000 odds selections

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bet365 Odds Scraper - Live, Pre-Match & Player Props

> Unofficial community Actor. Not affiliated with Bet365 or Hillside. For informational and research use only — this Actor does not place bets or provide betting advice. You are responsible for complying with applicable laws and platform terms.

**Bet365 scraper** and **Bet365 API alternative** for **live in-play odds**, **pre-match lines**, **player props**, **outrights**, and the sports / competition catalog. One run returns one row per selection (or catalog entity) you can export as JSON, CSV, or Excel, call from **Python** or **Node.js**, or drive from **MCP** / AI assistants. No Bet365 login.

### Sports betting suite

| Actor | Role |
| --- | --- |
| Bet365 Odds Scraper ◄── you are here | Bet365 live, pre-match, props, outrights |
| [PrizePicks Player Props Scraper](https://apify.com/crawloop/prizepicks-player-props-scraper) | US DFS pick'em lines |
| [Underdog Fantasy Player Props](https://apify.com/crawloop/underdog-fantasy-player-props-scraper-real-time-lines-odds) | Underdog props & odds |
| [DFS Multi-Source Props Scraper](https://apify.com/crawloop/dfs-multi-source-props-scraper) | Cross-platform props board |
| [FotMob Scraper](https://apify.com/crawloop/fotmob-scraper) | Football scores, xG, ratings |

**Suite next step:** after a Bet365 snapshot, run [DFS Multi-Source Props Scraper](https://apify.com/crawloop/dfs-multi-source-props-scraper) to compare sportsbook lines with PrizePicks / Underdog / Pick6 boards, or [FotMob Scraper](https://apify.com/crawloop/fotmob-scraper) for match xG and ratings.

### When to use

- Pull a **live in-play board** (event, market, current prices) for soccer, tennis, basketball, and 30+ other sports
- Snapshot **pre-match 1X2 and listed markets** for a sport
- Expand a match into **player props / extra markets** via event mode
- Export **outrights** (league winner, top scorer, futures)
- Build a **sports and competition directory** (PDs and event ids) to feed later runs

**When not to use:** historical closing-line warehouses, multi-book aggregators, or account-gated bet history. This Actor reads the public sportsbook board only.

### Key features

- **Six modes** — `sports`, `competitions`, `inplay`, `prematch`, `event`, `outrights` (+ `auto`)
- **One row per selection** — CSV-friendly unroll (market × outcome), plus catalog rows when you only need the directory
- **Three odds formats** — decimal (default), American, fractional; all three stored when a price exists
- **30+ sports** — soccer, tennis, NBA/WNBA, NFL, MLB, NHL, MMA, esports, golf, cricket, darts, rugby, racing, …
- **Geo hosts** — `es` (default English sportsbook), `de`, `it`, `nl`, `com`
- **Browser intercept for prices** — Camoufox captures live splash / in-play coupons; catalog stays on HTTP
- **Residential ES/GB proxy required for odds** — datacenter IPs typically see empty coupons
- **Empty coupons not billed as odds** — failed price lookups are not written as fake selections

### Input

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | `prematch` | `auto`, `sports`, `competitions`, `inplay`, `prematch`, `event`, `outrights` |
| `sport` | string | `soccer` | Sport slug, or `all` |
| `eventIds` | string\[] | `[]` | Event / competition ids (event mode) |
| `eventPds` | string\[] | `[]` | Native path descriptors |
| `eventUrls` | string\[] | `[]` | Sportsbook hash URLs |
| `oddsFormat` | string | `decimal` | `decimal` / `american` / `fractional` |
| `site` | string | `es` | `es`, `de`, `it`, `nl`, `com` |
| `language` | string | `en` | Menu language |
| `maxItems` | integer | `0` | Cap dataset size (`0` = unlimited) |
| `proxyConfiguration` | object | residential ES | Apify Proxy; **residential Spain or UK** for live / pre-match odds |

Example — live soccer in-play:

```json
{
  "mode": "inplay",
  "sport": "soccer",
  "oddsFormat": "decimal",
  "site": "es"
}
```

Example — Premier League PD (from competitions mode) then event markets:

```json
{
  "mode": "event",
  "eventPds": ["#AC#B1#C1#D1002#E91422157#G40#"],
  "oddsFormat": "american",
  "site": "es"
}
```

Example URL inside input (not a markdown link):

```json
{
  "mode": "event",
  "eventUrls": ["https://www.bet365.es/#/AC/B1/C1/D8/E149821034/F2/"]
}
```

### Output

| Field | Description |
| --- | --- |
| `recordType` | `sport` · `competition` · `event` · `odds` |
| `sport` / `sportSlug` / `sportId` | Classification |
| `league` / `eventName` / `eventId` / `pd` | Fixture keys (reuse `pd` in event mode) |
| `homeTeam` / `awayTeam` | Split from event name when possible |
| `marketName` / `selection` / `handicap` | Market unroll |
| `odds` | Price in `oddsFormat` |
| `oddsDecimal` / `oddsAmerican` / `oddsFractional` | Always filled together when a price exists |
| `isInPlay` / `suspended` / `capturedAt` | Live flags + UTC snapshot |

Example odds row:

```json
{
  "recordType": "odds",
  "sport": "Football",
  "sportSlug": "soccer",
  "league": "MLS",
  "eventName": "Inter Miami v Toronto FC",
  "eventId": "199038810",
  "homeTeam": "Inter Miami",
  "awayTeam": "Toronto FC",
  "marketName": "Full Time Result",
  "selection": "Inter Miami",
  "odds": "1.36",
  "oddsDecimal": 1.36,
  "oddsAmerican": "-278",
  "oddsFractional": "4/11",
  "isInPlay": false,
  "capturedAt": "2026-08-21T22:51:18.000Z"
}
```

### Use cases

- **In-play monitoring** — schedule the Actor on soccer/tennis live boards
- **Pre-match dumps** — daily coupon snapshot for modeling or CMS widgets
- **Props research** — event mode after you have a Bet365 event id from competitions
- **DFS line shop** — join Bet365 player markets with PrizePicks / Underdog on player name
- **Outrights tracker** — league winner / top scorer futures into a sheet

### Integration examples

#### Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('crawloop/bet365-odds-scraper').call({
  mode: 'prematch',
  sport: 'soccer',
  oddsFormat: 'decimal',
  site: 'es',
  maxItems: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("crawloop/bet365-odds-scraper").call(
    run_input={"mode": "inplay", "sport": "soccer", "site": "es"}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("eventName"), item.get("selection"), item.get("odds"))
```

#### cURL

```bash
curl "https://api.apify.com/v2/acts/crawloop~bet365-odds-scraper/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"mode":"sports","site":"es","maxItems":50}'
```

### MCP and AI assistants

Use this Actor from AI tools via [Apify MCP](https://docs.apify.com/platform/integrations/mcp). Add the Apify MCP server in Claude Desktop, Cursor, or any MCP client, connect your Apify account, then call this Actor by its Store name `crawloop/bet365-odds-scraper`.

Example prompts:

- "Run Bet365 Odds Scraper in inplay mode for soccer and return the top 30 rows as JSON"
- "Scrape Bet365 pre-match basketball odds in American format and summarize the shortest prices"
- "Chain Bet365 Odds Scraper then DFS Multi-Source Props Scraper for the same NBA slate"

### FAQ

**Is this an official Bet365 API?** No. It is an unofficial scraper of the public sportsbook board.

**Why do I get catalog rows instead of odds?** Live prices are geo-sensitive. Set `site` to `es` and use Apify **residential** proxies in Spain or the UK (`apifyProxyCountry: ES` or `GB`), then rerun `inplay` or `prematch`. Catalog modes (`sports`, `competitions`) do not need prices.

**How do I get a match’s player props?** Run `competitions` or `prematch` first, copy `eventId` / `pd`, then run `event` mode.

**Does it need a Bet365 account?** No. Login-gated pages are out of scope.

**Python, Node.js, or MCP?** All three. Use the Apify client snippets above, or call the Actor from an MCP-connected assistant.

### Related Actors

- [PrizePicks Player Props Scraper](https://apify.com/crawloop/prizepicks-player-props-scraper)
- [Betr Picks Scraper](https://apify.com/crawloop/betr-picks-scraper)
- [DraftKings Pick6 Scraper](https://apify.com/crawloop/draftkings-pick6-scraper)
- [Underdog Fantasy Player Props](https://apify.com/crawloop/underdog-fantasy-player-props-scraper-real-time-lines-odds)
- [FotMob Scraper](https://apify.com/crawloop/fotmob-scraper)

# Actor input Schema

## `mode` (type: `string`):

What to scrape. sports = classification catalog; competitions = promoted leagues/events; inplay = live board; prematch = upcoming fixtures for a sport; event = full markets for match ids or PDs; outrights = futures; auto picks from filled inputs.

## `sport` (type: `string`):

Sport slug for inplay / prematch / competitions / outrights. Use all for every classification on the menu.

## `eventIds` (type: `array`):

Bet365 event or competition ids for event mode (from competitions output eventId).

## `eventPds` (type: `array`):

Raw Bet365 PDs such as #AS#B1#K^5# or #AC#B1#C1#D1002#E91422157#G40#.

## `eventUrls` (type: `array`):

Sportsbook hash URLs. The fragment is converted to a PD automatically.

## `oddsFormat` (type: `string`):

Value written to the odds field. Dataset also always includes oddsDecimal, oddsAmerican, and oddsFractional when prices exist.

## `site` (type: `string`):

Geo host. es is the default working English sportsbook. com may bounce to a local licence domain.

## `language` (type: `string`):

UI language id sent to content APIs (names in NA fields).

## `maxItems` (type: `integer`):

Stop after this many dataset records (0 = unlimited).

## `requestDelaySecs` (type: `number`):

Throttle between HTTP requests.

## `proxyConfiguration` (type: `object`):

Apify Proxy. Residential ES or GB is required for live/pre-match odds (browser intercept). Catalog often works on the same proxy.

## Actor input object example

```json
{
  "mode": "prematch",
  "sport": "soccer",
  "eventIds": [],
  "eventPds": [],
  "eventUrls": [],
  "oddsFormat": "decimal",
  "site": "es",
  "language": "en",
  "maxItems": 0,
  "requestDelaySecs": 0.2,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

Default dataset items (one record per sport, competition, or market selection).

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("crawloop/bet365-odds-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("crawloop/bet365-odds-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call crawloop/bet365-odds-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,crawloop/bet365-odds-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/aJpqiBEYb13lNRaYM/builds/YJVTp0HPHWaxwRDTT/openapi.json
