# Racing Post Horse Racing Scraper — Racecards, Odds & Runners (`ahmed_jasarevic/racingpost-scraper`) Actor

Scrapes UK and international horse racing results, form, runners, odds and racecards from Racing Post. Extracts meeting, horse, jockey, trainer, finishing position, SP odds, form, weight, distance, going, prize money, draw, rating, age, sex and pedigree.

- **URL**: https://apify.com/ahmed\_jasarevic/racingpost-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Categories:**
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

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

## Racing Post Horse Racing Scraper — Racecards, Runners, Form & Odds

Scrape **UK & international horse racing data** from **Racing Post** — racecards, runners, form figures, jockey/trainer, **starting-price odds**, ratings, breeding and prize money — for **betting models**, racing analytics and handicapping research. One flat row per runner covers GB, IRE, USA, France, Australia and Hong Kong in a single run.

### Main Use Cases

- **Horse racing analytics** — build statistical models from runner-level data
- **Racecards data for betting research** — capture runners, form, odds and ratings daily
- **Sports data feeds** — structured UK/international racing data for apps and websites
- **Handicapping** — compare form, official rating, topspeed and odds across runners
- **Historical racing data backfill** — scrape racecards for any date range
- **AI/ML prediction research** — feed pre-race features into prediction models

### How It Works

Give the actor one or more dates. It fetches racecards from Racing Post's internal **Next.js JSON API** (`/_next/data/...`) — the same structured data the site's own frontend uses — so it needs **no browser**, parses quickly with CheerioCrawler, and emits one flat JSON row per runner with the full race context. Fully proxy-routed to avoid IP bans.

### Build a Horse Racing Dataset Without a Manual Official API

Racing Post has no public bulk API for racecards. This actor turns any date's UK and international meetings into a clean, queryable dataset of runners, **form, odds, ratings and breeding** — for betting-model building, handicapping and racing research — at ~10x lower cost than browser scrapers.

### Input

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `dates` | array of strings | No | today | Dates to scrape in `YYYY-MM-DD` |
| `meetingFilter` | string | No | empty | Comma-separated meetings, e.g. `Ripon,Epsom` |
| `maxRaces` | integer | No | 50 | Max races per run (0 = unlimited) |
| `includeResults` | boolean | No | `false` | Also attempt results pages for completed races |
| `useApifyProxy` | boolean | No | `true` | Route requests through the Apify proxy |

### Output

Each dataset item is **one runner** in one race. Key fields (full schema on the actor page):

| Field | Description |
|---|---|
| `meetingName` / `meetingCountry` | Racecourse and country |
| `raceTitle` / `raceTime` / `raceClass` | Race identity and class |
| `going` / `distanceFurlongs` / `surfaceType` | Track condition and distance |
| `totalPrizeMoneyGBP` / `firstPrizeGBP` | Prize money |
| `horseName` / `horseId` | Horse identity |
| `draw` / `age` / `sex` | Draw, age, sex |
| `jockeyName` / `trainerName` / `ownerName` | Connections |
| `formFigures` / `officialRating` | Form and rating |
| `rpTopspeed` / `rpPostmark` | Racing Post speed ratings |
| `forecastOdds` | Starting-price odds |
| `weightCarriedLbs` | Weight carried |
| `sireName` / `damName` / `damsireName` | Breeding |

### Example Input

```json
{
  "dates": ["2026-08-31"],
  "meetingFilter": "Ripon,Epsom",
  "maxRaces": 50,
  "includeResults": false
}
```

### Example Output

```json
{
  "scrapeDate": "2026-08-31",
  "meetingName": "RIPON",
  "meetingCountry": "GB",
  "raceTitle": "Squadron Flyer At Aldwark Manor Estate EBF Restricted Maiden Stakes",
  "raceTime": "2026-08-31T13:55:00+01:00",
  "raceClass": "4",
  "distanceFurlongs": 6,
  "surfaceType": "Turf",
  "totalPrizeMoneyGBP": 10820.7,
  "horseName": "Arenite",
  "horseId": 9254368,
  "draw": 6,
  "age": 2,
  "sex": "b f",
  "jockeyName": "Connor Beasley",
  "trainerName": "Michael Dods",
  "formFigures": "22",
  "officialRating": 69,
  "rpTopspeed": 75,
  "forecastOdds": 1.5,
  "weightCarriedLbs": 125,
  "sireName": "Kameko",
  "raceUrl": "https://www.racingpost.com/racecards/49/ripon/2026-08-31/925805"
}
```

### Integrations & Automation

Results are available via the Apify API and export as JSON/CSV/Excel. **Schedule daily runs** in Apify Console to keep a rolling racecard dataset, and enable `includeResults` for completed races where reliable.

### Related Actors

Verified related actors on Apify that pair well with this one. All links point to real, publicly available actors.

- [Equibase US Horse Racing Scraper](https://apify.com/jungle_synthesizer/equibase-us-horse-racing-scraper)
- [Netkeiba Horse Racing Scraper](https://apify.com/cloud9_ai/netkeiba-horse-racing-scraper)
- [Horse Racing Nation Scraper](https://apify.com/crawlerbros/horse-racing-nation-scraper)

### FAQ

#### Why use this actor instead of an official Racing Post API?

Racing Post does not expose a public bulk API for racecards. This actor reads the same structured JSON (`/_next/data/...`) that the Racing Post website itself uses, producing clean data without browser-scraping overhead.

#### Is scraping Racing Post legal?

Scraping publicly available data for personal or research use is generally acceptable, but you should review Racing Post's Terms of Service before large-scale or commercial use. This actor is provided as-is for legitimate data collection.

#### Can I backfill historical racecards?

Yes. Pass a list of dates to the `dates` field to scrape multiple meetings across several days in one run.

#### Do results (finishing positions) work?

Racecards (runners, form, odds, ratings, breeding) work reliably. Results pages are more aggressively protected and need the Apify proxy (`includeResults` may fail from some IPs).

### SEO Keywords

racing post scraper, horse racing racecards api, uk horse racing data, horse racing runner data, racing post odds scraper, horse betting data model, form figures data, racing analytics api, international racecards, horse racing datasets, racing post json api, handicap racing data, horse breeding data, prize money racing data, racing ai prediction data

### For AI Agents & LLM Apps

**Purpose:** Return structured Racing Post racecard data — one flat row per runner with race context, form, odds, ratings and breeding.

**Minimal working input:**

```json
{
  "dates": ["2026-08-31"],
  "maxRaces": 10
}
```

**Output fields:** `meetingName`, `raceTitle`, `raceTime`, `horseName`, `jockeyName`, `trainerName`, `formFigures`, `officialRating`, `forecastOdds`, `weightCarriedLbs`, `sireName`, `damName`, `raceUrl` (full schema on the actor page).

**Behaviors an agent should know:**

- `dates` is the primary input — empty means **today**.
- `maxRaces: 0` means **unlimited**; default is 50 — cap it to control cost.
- `includeResults: false` by default because results pages are more protected; enable only if needed.

### Legal & Compliance Disclaimer

This actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Racing Post** (Racing Post Ltd). It accesses publicly available racecard pages via the site's public JSON endpoints (no login bypass, no CAPTCHA solving). You are responsible for compliance with Racing Post's Terms of Use and applicable law. This actor provides factual racing data and no betting advice.

# Actor input Schema

## `dates` (type: `array`):

List of dates to scrape racecards for (YYYY-MM-DD format). Defaults to today if empty.

## `meetingFilter` (type: `string`):

Optional comma-separated list of meeting names to filter (e.g. 'Ripon,Epsom'). Leave empty for all meetings.

## `maxRaces` (type: `integer`):

Maximum number of races to scrape per run. Set to 0 for unlimited.

## `includeResults` (type: `boolean`):

Whether to also attempt scraping results pages for completed races (requires proxy, may not work from all IPs).

## `useApifyProxy` (type: `boolean`):

Route requests through Apify proxy for better reliability.

## Actor input object example

```json
{
  "dates": [],
  "meetingFilter": "",
  "maxRaces": 50,
  "includeResults": false,
  "useApifyProxy": true
}
```

# Actor output Schema

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

No description

# 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 = {
    "dates": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/racingpost-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 = { "dates": [] }

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/racingpost-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 '{
  "dates": []
}' |
apify call ahmed_jasarevic/racingpost-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/racingpost-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/mEQcno1htunjGwOAX/builds/0bDYvAYmcspWc16V5/openapi.json
