# Equibase Horse Racing Scraper (`parsebird/equibase-horse-racing-scraper`) Actor

Scrape Equibase horse racing data: race entries, results, finish order, win/place/show and exotic payouts, scratches and race-day changes for every US and Canadian track, plus horse histories. Export JSON, CSV or Excel.

- **URL**: https://apify.com/parsebird/equibase-horse-racing-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.69 / 1,000 records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Equibase Horse Racing Scraper

Equibase Horse Racing Scraper extracts race entries, results and payouts from [Equibase](https://www.equibase.com), the official database of North American Thoroughbred racing. It covers every US, Canadian and Puerto Rico track Equibase lists for a date and returns runners, jockeys, trainers, morning line odds, finish order, win/place/show and exotic payouts, scratches and race-day changes.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Pick a date and get one clean record per race: the card with pedigree, owner, breeder, weight, medication and morning line for every runner, plus the official finish order, $2 win/place/show prices and every exotic payout (exacta, trifecta, superfecta, daily double, Pick 3 to Pick 6). Add horse histories with every career start, its Equibase Speed Figure and the last 60 days of workouts.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor or any other LLM to start using this Actor.

```
Use the Apify Actor "parsebird/equibase-horse-racing-scraper" (Equibase Horse Racing Scraper) to get horse racing entries, results, payouts and race-day changes from equibase.com for US, Canadian and Puerto Rico tracks. Call it with the apify-client package: Python `ApifyClient("<APIFY_TOKEN>").actor("parsebird/equibase-horse-racing-scraper").call(run_input={...})`, or JavaScript `new ApifyClient({ token }).actor('parsebird/equibase-horse-racing-scraper').call({...})`, then read items from the run's default dataset. Inputs (all optional): raceDate (string "MM/DD/YYYY" or "YYYY-MM-DD", default today in US Eastern time; results exist for about the last 30 days, entries for the coming days), dataMode ("both" default, "entries", "results", "late_changes" = today's scratches and changes), trackCodes (array of Equibase track codes, e.g. ["SA","GP","KEE","CD","BEL","SAR","WO"]; default all tracks), maxItems (int, default 50, max records saved), raceTypes (array of words matched against race type and name, e.g. ["claiming"], ["maiden"], ["stakes"], ["grade"]), filliesMaresOnly (bool, default false), includeHorseHistory (bool, default false: adds one horse_history record per runner), maxHorseProfiles (int, default 100), proxyConfiguration (object, default no proxy). Race records (record_type "race") have race_id (e.g. "KEE-2026-10-31-R12"), race_date, track_code, track_name, country, race_number, race_name, race_type, race_category, grade, breed, distance, distance_furlongs, surface, track_condition, purse, purse_currency, post_time, off_time, age_sex_restriction, conditions, wagers, entries_count, starters_count, scratched_count, entries (pipe string "program|horse|jockey|trainer|weight|morning line" joined by " | "), entries_detail (array: program_number, post_position, horse_name, horse_refno, sire, dam, dam_sire, age, sex, medication, claim_price, jockey, trainer, owner, breeder, weight, morning_line, is_scratched, scratch_reason, finish_position, win/place/show payouts), results_available, winner_horse, winner_jockey, winner_trainer, winner_owner, winner_breeder, winning_time, finish_order, finish_order_detail, win_payout, place_payout, show_payout, payouts_by_horse, exotic_payouts (JSON string {bet_type: payoff}), exotic_payouts_by_type (object with raw_label, wager_amount, winning_numbers, payoff), race_cancelled, cancellation_reason, entry_url, result_url. Race-day change records (record_type "late_change") have change_id, track_code, race_date, race_id, race_number, program_number, horse_name, change_type (scratch, scratch_reason, jockey, weight, overweight, apprentice_type, course_change, distance, owner, rail, first_start_as_gelding, coupled_entry, wagering, race_cancelled, track_conditions, announcement, note), old_value, new_value, reason, time_posted, time_posted_at. Horse history records (record_type "horse_history") have horse_refno, horse_name, sire, dam, dam_sire, foaled, sex, color, breeder, last_owner, last_trainer, last_jockey, career_starts, career_wins, career_seconds, career_thirds, career_earnings_usd, past_starts (race_date, track_name, race_number, race_type, finish_position, speed_figure) and workouts (date, track_name, distance, time, note, rank) from the last 60 days. Pricing: pay per record; horse histories are premium records. API docs: https://apify.com/parsebird/equibase-horse-racing-scraper/api. Get a token at https://console.apify.com/settings/integrations.
```

### What is Equibase Horse Racing Scraper?

**Equibase Horse Racing Scraper** turns [Equibase](https://www.equibase.com) race cards and result charts into structured JSON, CSV or Excel. Pick a date, and the Actor finds **every track racing that day** in the United States, Canada and Puerto Rico, reads each race card and results summary, and saves **one record per race** with the full field of runners, the official order of finish and all payouts.

It works as an **Equibase API alternative**. Equibase sells its data feeds to businesses but has no free public API, so Equibase Horse Racing Scraper collects the entries, results and race-day changes that Equibase publishes on its free website pages and hands them to you as a dataset.

To try it, open the Input tab and click **Start**. The prefill returns 20 races from today's cards. If no track races today, the Actor uses the next race day.

### What can Equibase Horse Racing Scraper do?

- 🏇 **Race entries**: every runner with program number, post position, horse, pedigree (sire, dam, dam sire), age, sex, state or country bred, medication, weight, claiming price, jockey, trainer, owner, breeder and morning line odds.
- 🏁 **Results and payouts**: official order of finish, winning time, winner's jockey, trainer, owner and breeder, $2 win/place/show prices for the top three and every exotic payout on the chart, including exacta, trifecta, superfecta, Super High Five, daily double, Pick 3, Pick 4, Pick 5 and Pick 6 with the winning numbers.
- ⚠️ **Race-day changes**: scratches with reasons, jockey changes, weight and overweight changes, surface and distance switches, rail settings, track conditions and track announcements, one record per change with the time Equibase posted it.
- 📋 **Race details**: race type, stakes name and grade, distance as text and in furlongs, surface, track condition, purse with currency (USD or CAD), post time, age and sex restrictions, full race conditions and the wagers offered.
- 🐎 **Horse histories**: profile, career record and earnings, every career start with its finish and Equibase Speed Figure, and workouts from the last 60 days for each horse in the races you saved.
- 🔎 **Filters**: keep only certain tracks, race types (claiming, maiden, allowance, stakes, graded stakes) or races for fillies and mares.
- ❌ **Cancellations**: races Equibase lists as cancelled are flagged with `race_cancelled` and the reason.
- ⚙️ **Built for automation**: [schedule runs](https://docs.apify.com/platform/schedules) every morning for the day's cards or every evening for the results, call the Actor through the [Apify API](https://apify.com/parsebird/equibase-horse-racing-scraper/api), send results to [Make, Zapier, n8n, Google Sheets, Slack and more](https://apify.com/integrations), and export as JSON, CSV, Excel or HTML.

### What data can you extract from Equibase?

Race records (`record_type: race`):

| Field | Description |
|-------|-------------|
| `race_id` | Track, date and race number, for example `KEE-2026-10-31-R12` |
| `race_date`, `track_code`, `track_name`, `country` | Race date, Equibase track code, track name and `USA`, `CAN` or `PR` |
| `race_number`, `race_name`, `race_type`, `race_category`, `grade` | Race number, stakes name (or race type), race type such as `Maiden Claiming`, a broad category and the stakes grade (`1`, `2`, `3`) |
| `breed` | `Thoroughbred`, or the breed Equibase shows for other races, such as `Quarter Horse` |
| `distance`, `distance_furlongs`, `surface`, `track_condition` | Distance as text (`1 1/16 Miles`) and in furlongs, `Dirt`, `Turf` or `All Weather`, and condition such as `Fast` or `Firm` |
| `purse`, `purse_currency` | Purse amount, in CAD for Canadian tracks and USD elsewhere |
| `post_time`, `off_time` | Scheduled post time (ET) and the time the race went off |
| `age_sex_restriction`, `conditions`, `wagers` | Short restriction such as `3yo+ F&M`, full race conditions and the wagers offered |
| `entries_count`, `starters_count`, `scratched_count` | Horses entered, horses that started and scratches |
| `entries` | Compact pipe string: `post|horse|jockey|trainer|weight|morning line` for each runner |
| `entries_detail` | One object per horse: program number, post position, horse, Equibase ID, sire, dam, dam sire, age, sex, medication, claiming price, jockey, trainer, owner, breeder, weight, morning line, scratch and reason, finish position and payouts |
| `winner_horse`, `winner_jockey`, `winner_trainer`, `winner_owner`, `winner_breeder`, `winning_time` | Winner details from the results chart |
| `finish_order`, `finish_order_detail` | Order of finish as text and as a list with program numbers, Equibase IDs and dead-heat flags |
| `win_payout`, `place_payout`, `show_payout`, `payouts_by_horse` | The winner's $2 win/place/show prices, and the place and show prices of the second and third horses |
| `exotic_payouts`, `exotic_payouts_by_type` | Exotic payoffs as a JSON string (`{"exacta": 31.3, ...}`) and as an object with the bet label, base amount and winning numbers |
| `race_cancelled`, `cancellation_reason` | Cancellation flag and reason from Equibase's cancellations list |
| `entry_url`, `result_url`, `scraped_at` | Source pages on Equibase and collection time |

Race-day change records (`record_type: late_change`) have `change_type`, `old_value`, `new_value`, `reason`, `race_number`, `program_number`, `horse_name`, `time_posted` and `time_posted_at` (UTC). Horse history records (`record_type: horse_history`) have the horse's profile, career totals, `past_starts` and `workouts`.

Fields that a record doesn't have are `null`. A race card for a future date has no results yet, and a results-only record has no morning line or race conditions.

### How to scrape Equibase

1. Open [Equibase Horse Racing Scraper](https://apify.com/parsebird/equibase-horse-racing-scraper) on Apify Store and go to the Input tab.
2. Set **Race date**, or leave it empty for today.
3. Choose **Data**: entries and results, entries only, results only, or today's race-day changes.
4. Optionally add **Track codes** such as `SA`, `GP` or `KEE`, and **Race types** such as `claiming` or `stakes`.
5. Set **Max records**. A full day across all tracks is often more than 100 races, so use 500 to get the whole day.
6. Turn on **Add horse histories** if you also want each runner's career and workouts.
7. Click **Start**. When the run finishes, download the dataset as JSON, CSV, Excel or HTML, or read it with the [dataset API](https://docs.apify.com/api/v2/dataset-items-get).

To get results for a whole day, run it in the evening after the last race or for a past date. Results appear on Equibase as races are run.

### Input parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `raceDate` | string | today (ET) | Date as `MM/DD/YYYY` or `YYYY-MM-DD` |
| `dataMode` | string | `both` | `both`, `entries`, `results` or `late_changes` |
| `trackCodes` | array | all tracks | Equibase track codes, for example `SA`, `GP`, `KEE`, `CD`, `BEL`, `SAR`, `WO` |
| `maxItems` | integer | `50` | Maximum race records (or race-day changes) to save |
| `raceTypes` | array | — | Words to match in the race type or name: `claiming`, `maiden`, `allowance`, `stakes`, `grade` |
| `filliesMaresOnly` | boolean | `false` | Keep only races where every runner is a filly or mare |
| `includeHorseHistory` | boolean | `false` | Add one `horse_history` record per runner in the saved races |
| `maxHorseProfiles` | integer | `100` | Maximum horse histories per run |
| `proxyConfiguration` | object | no proxy | Optional proxy. The Actor works without one |

Example input for the Breeders' Cup graded stakes at Keeneland, with horse histories:

```json
{
    "raceDate": "10/31/2026",
    "trackCodes": ["KEE"],
    "dataMode": "both",
    "raceTypes": ["grade"],
    "maxItems": 20,
    "includeHorseHistory": true,
    "maxHorseProfiles": 30
}
```

### Output example

A race record for the 2026 Breeders' Cup Classic. Lists are cut to the first items here to keep the example short.

```json
{
    "record_type": "race",
    "race_id": "KEE-2026-10-31-R12",
    "race_date": "2026-10-31",
    "track_code": "KEE",
    "track_name": "Keeneland",
    "country": "USA",
    "race_number": 12,
    "race_name": "Longines Breeders' Cup Classic",
    "race_type": "Stakes",
    "race_category": "Stakes",
    "grade": "1",
    "breed": "Thoroughbred",
    "distance": "1 1/4 Miles",
    "distance_furlongs": 10.0,
    "surface": "Dirt",
    "track_condition": "Fast",
    "purse": 7000000,
    "purse_currency": "USD",
    "post_time": "6:16 PM ET",
    "off_time": "6:19",
    "age_sex_restriction": "3yo+",
    "wagers": "Exacta / Trifecta / Superfecta Super High Five",
    "entries_count": 8,
    "starters_count": 7,
    "scratched_count": 1,
    "entries": "1|T O Password|K Kimura|D Takayanagi|126|30/1 | 2|Sovereignty|J Alvarado|W I Mott|126|5/2 | 3|Golden Tempo|J L Ortiz|C DeVaux|122|5/1 | ...",
    "entries_detail": [
        {
            "program_number": "1",
            "post_position": 1,
            "horse_name": "T O Password",
            "state_bred": "JPN",
            "horse_refno": "11442038",
            "sire": "Copano Rickey (JPN)",
            "dam": "T O Rachel (JPN)",
            "dam_sire": "King Kamehameha (JPN)",
            "age": 5,
            "sex": "H",
            "jockey": "K Kimura",
            "trainer": "D Takayanagi",
            "owner": "Tomoya Ozasa",
            "breeder": "Yanagawa Bokujo",
            "weight": 126,
            "morning_line": "30/1",
            "is_scratched": false,
            "finish_position": 4
        }
    ],
    "results_available": true,
    "winner_horse": "Sovereignty",
    "winner_program_number": "2",
    "winner_jockey": "Junior Alvarado",
    "winner_trainer": "William I. Mott",
    "winner_owner": "Godolphin, LLC",
    "winner_breeder": "Godolphin",
    "winning_time": "2:00.36",
    "finish_order": "1. Sovereignty, 2. The Puma, 3. Knightsbridge, 4. T O Password (JPN), 5. Forever Young (JPN), 6. Golden Tempo, 7. Napoleon Solo",
    "win_payout": 5.94,
    "place_payout": 4.16,
    "show_payout": 2.94,
    "payouts_by_horse": [
        {"program_number": "2", "horse_name": "Sovereignty", "jockey": "Junior Alvarado", "win": 5.94, "place": 4.16, "show": 2.94, "finish_position": 1},
        {"program_number": "4", "horse_name": "The Puma", "jockey": "Javier Castellano", "win": null, "place": 11.22, "show": 6.1, "finish_position": 2}
    ],
    "exotic_payouts": "{\"pick_3\": 110.46, \"pick_4\": 158.45, \"pick_5\": 452.61, \"pick_6\": 5058.59, \"daily_double\": 7.05, \"exacta\": 31.3, \"superfecta\": 131.71, \"super_high_five\": 3485.57, \"trifecta\": 72.65}",
    "exotic_payouts_by_type": {
        "pick_3": {"raw_label": "$3 Pick 3", "wager_amount": 3.0, "payoff": 110.46, "winning_numbers": "2-2-2 (3 correct)"}
    },
    "race_cancelled": false,
    "stakes_id": "4198",
    "entry_url": "https://www.equibase.com/static/entry/KEE103126USA-EQB.html",
    "result_url": "https://www.equibase.com/static/chart/summary/KEE103126USA-EQB.html"
}
```

A race-day change record:

```json
{
    "record_type": "late_change",
    "change_id": "BEL-2026-10-31-16",
    "track_code": "BEL",
    "track_name": "Belmont Park",
    "race_date": "2026-10-31",
    "race_id": "BEL-2026-10-31-R7",
    "race_number": 7,
    "program_number": "8",
    "horse_name": "Cuando",
    "change_type": "scratch_reason",
    "old_value": "Reason Unavailable",
    "new_value": "PrivVet-Illness",
    "reason": "PrivVet-Illness",
    "time_posted": "9:30 AM ET",
    "time_posted_at": "2026-10-31T13:30:00Z"
}
```

A horse history record (premium record), with one past start and one workout shown:

```json
{
    "record_type": "horse_history",
    "horse_refno": "11442038",
    "horse_name": "T O Password",
    "state_bred": "JPN",
    "sex": "H",
    "color": "B",
    "foaled": "2021-05-20",
    "sire": "Copano Rickey (JPN)",
    "dam": "T O Rachel (JPN)",
    "dam_sire": "King Kamehameha (JPN)",
    "breeder": "Yanagawa Bokujo",
    "last_jockey": "Kazushi Kimura",
    "last_trainer": "Daisuke Takayanagi",
    "last_owner": "Tomoya Ozasa",
    "career_starts": 13,
    "career_wins": 5,
    "career_seconds": 1,
    "career_thirds": 1,
    "career_earnings_usd": 1208627,
    "past_starts": [
        {"race_id": "KEE-2026-10-31-R12", "track_name": "Keeneland", "race_date": "2026-10-31", "race_number": 12, "race_type": "Longines Breeders' Cup Classic (Gr. 1)", "finish_position": 4, "speed_figure": 114}
    ],
    "workouts": [
        {"track_code": "KEE", "track_name": "Keeneland", "date": "2026-10-27", "surface": "Dirt", "distance": "5F", "time": "1:03.80", "note": "Breezing", "rank": "3/5"}
    ],
    "profile_url": "https://www.equibase.com/profiles/Results.cfm?type=Horse&refno=11442038&registry=T"
}
```

### Use Equibase Horse Racing Scraper from Python or JavaScript

Install the client with `pip install apify-client` or `npm install apify-client`, and get your API token from [Apify Console](https://console.apify.com/settings/integrations).

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<APIFY_TOKEN>")
run = client.actor("parsebird/equibase-horse-racing-scraper").call(run_input={
    "raceDate": "10/30/2026",
    "dataMode": "results",
    "maxItems": 500,
})

for race in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(race["race_id"], race["winner_horse"], race["win_payout"], race["exotic_payouts"])
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<APIFY_TOKEN>' });
const run = await client.actor('parsebird/equibase-horse-racing-scraper').call({
    dataMode: 'late_changes',
    trackCodes: ['GP', 'SA'],
    maxItems: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items
    .filter((c) => c.change_type === 'scratch')
    .forEach((c) => console.log(c.track_code, c.race_number, c.program_number, c.horse_name, c.reason));
```

### Use cases

- **Handicapping and betting models**: build datasets of fields, morning lines, results and payouts to test angles by track, surface, distance, trainer or jockey.
- **Payout research**: compare exotic payoffs (exacta, trifecta, superfecta, Pick 4, Pick 5) across tracks and race types.
- **Scratch and change alerts**: [schedule](https://docs.apify.com/platform/schedules) the race-day changes mode every few minutes on race days and push new scratches, jockey switches and surface changes to Slack or email through [integrations](https://docs.apify.com/platform/integrations).
- **Owner, trainer and breeder tracking**: follow which connections are entering and winning, and at what claiming levels.
- **Horse research**: pull each runner's career, Speed Figures and recent workouts before a race.
- **Racing media and apps**: feed race cards and results into websites, newsletters, dashboards or spreadsheets.

### How it works

1. The Actor reads Equibase's entries and results index pages to find every track racing on your date.
2. For each track it reads the race card and the results summary chart and joins them race by race.
3. For today's date, it also reads the track's race-day changes page for track conditions, and the cancellations list for every date.
4. With **Add horse histories** on, it reads each runner's Equibase profile and workout pages.
5. Records are saved as they are built. If Apify moves the run to another server, it continues without saving the same record twice.

In our tests, all 137 races run on October 30, 2026 across 15 tracks came back in under 20 seconds.

### How much does it cost to scrape Equibase?

Equibase Horse Racing Scraper uses pay-per-event pricing. Compute and proxy costs are included in the event price, so they aren't billed separately.

| Event | Free | Bronze | Silver | Gold |
|-------|------|--------|--------|------|
| Record (one race or one race-day change) | $0.99 / 1,000 | $0.89 / 1,000 | $0.79 / 1,000 | **$0.69 / 1,000** |
| Premium record (one horse history) | $1.69 / 1,000 | $1.49 / 1,000 | $1.29 / 1,000 | **$1.09 / 1,000** |

At Free plan prices, a full day of about 140 races costs about $0.14. Adding horse histories for 1,000 runners adds $1.69. To control spending, set **Max records** and **Max horse histories**. The run also stops when it reaches the maximum cost per run you set in Apify Console.

### Is it legal to scrape Equibase?

Equibase Horse Racing Scraper only collects race information that Equibase publishes on its free, public pages: entries, results summary charts, race-day changes and horse profiles. It doesn't log in and doesn't access Equibase's paid products, such as full PDF charts or past performances. Equibase's data is copyrighted and its [terms of use](https://www.equibase.com/about/terms.cfm) limit how it may be used, especially commercially. Check that your use complies with those terms and consult a lawyer if you're unsure. For more background, read Apify's article [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

### Other sports and betting scrapers from ParseBird

| Actor | What it does |
|-------|--------------|
| [Sports Betting Odds Scraper](https://apify.com/parsebird/sports-betting-odds-scraper) | Moneyline, spread and totals from sportsbooks for NFL, NBA, MLB, NHL, soccer and UFC |
| [Action Network Scraper & API](https://apify.com/parsebird/action-network-scraper) | Sportsbook odds, public betting splits, expert picks and line movement from Action Network |
| [Sports Injury Reports API](https://apify.com/parsebird/sports-injury-reports-api) | NFL, NBA, WNBA, MLB and NHL injury reports with status and expected return |
| [FlashScore Scraper & API](https://apify.com/parsebird/flashscore-scraper) | Live and scheduled scores for football, basketball, tennis and more from FlashScore |
| [SofaScore Scraper](https://apify.com/parsebird/sofascore-scraper) | Live scores, fixtures, lineups, statistics and standings from SofaScore |
| [MLB Stats Scraper](https://apify.com/parsebird/mlb-stats-scraper) | Teams, rosters, schedules, standings and player stats from MLB's Stats API |
| [UFC Scraper](https://apify.com/parsebird/ufc-scraper) | Fighter profiles, event fight cards and division rankings from UFC.com |
| [Kalshi Scraper](https://apify.com/parsebird/kalshi-scraper) | Prediction market events, prices and volume from Kalshi |

### FAQ

**Do I need an Equibase account or API key?**
No. The Actor reads the same free pages Equibase shows to every visitor.

**Which dates can I scrape?**
Equibase's free pages keep results for about the last 30 days and race cards for the coming days as they are drawn, usually up to a week ahead. Older pages are removed by Equibase. When you ask for a date outside that range, the run log and status message tell you which dates are available.

**Why are the results empty for today?**
Results appear on Equibase as each race is run. Run the Actor after the last race, or use `entries` mode for today's cards.

**Which tracks are covered?**
Every track on Equibase's entries and results pages for your date, which covers Thoroughbred racing in the United States, Canada and Puerto Rico, plus the Quarter Horse races that run on those cards (`breed` tells them apart). Track codes follow Equibase, such as `SA` Santa Anita, `GP` Gulfstream Park, `KEE` Keeneland, `CD` Churchill Downs, `BEL` Belmont Park, `SAR` Saratoga and `WO` Woodbine.

**How do I get race-day changes for a past date?**
You can't. Equibase only publishes the changes page for the current race day, and early in the morning it can still show the previous day's changes until the new day's page is posted. To keep a history of changes, [schedule](https://docs.apify.com/platform/schedules) runs during race days.

**Are beaten lengths, fractional times and comments included?**
No. Those are only in Equibase's full PDF charts, which aren't part of the free results pages. The Actor returns the order of finish, winning time and payouts from the results summary.

**Why is `show_payout` sometimes `null`?**
Small fields often have no show betting. In four-horse races, for example, Equibase posts win and place prices only. A few exotic payoffs, such as some Super High Five pools, are published as $0.00, and the Actor keeps them as published.

**How does the "Fillies and mares only" filter work?**
It keeps a race only if every runner on the card is a filly or mare. The sex comes from the race card, so it works for dates whose entries are still on Equibase, which is roughly the last 10 days and the coming week.

**Do I need a proxy?**
No. The Actor runs without a proxy by default. If Equibase keeps refusing access from your runs, add an Apify proxy in the Advanced section.

**Can I run it on a schedule or from my own code?**
Yes. Use [Apify schedules](https://docs.apify.com/platform/schedules) for daily runs, the [Apify API](https://apify.com/parsebird/equibase-horse-racing-scraper/api) or the Python and JavaScript clients shown above, and [integrations](https://apify.com/integrations) to send results to Google Sheets, Slack, Make, Zapier or n8n.

**Something doesn't work or a field is missing. What should I do?**
Open an issue on the Actor's [Issues tab](https://apify.com/parsebird/equibase-horse-racing-scraper/issues) with your input and run ID, and we'll look into it.

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/equibase-horse-racing-scraper/changelog.md

# Actor input Schema

## `raceDate` (type: `string`):

Date to scrape, as MM/DD/YYYY or YYYY-MM-DD. Leave empty for today (US Eastern time); if no track races today, the next race day is used. Equibase's free pages cover results for about the last 30 days and entries for the next few days.

## `dataMode` (type: `string`):

Entries = race cards (runners, jockeys, trainers, morning line). Results = finish order and payouts for races already run. Both = cards with results attached where available. Race-day changes = today's scratches, jockey, weight, course and distance changes, rail settings and track conditions, one record per change.

## `trackCodes` (type: `array`):

Optional. Equibase track codes to keep, such as SA (Santa Anita), GP (Gulfstream Park), KEE (Keeneland), CD (Churchill Downs), BEL (Belmont Park), SAR (Saratoga) or WO (Woodbine). Leave empty to get every track racing that day.

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

Maximum number of race records to save (one race = one record; in race-day changes mode, one change = one record). A full day across all tracks is often more than 100 races, so raise this to 500 to get the whole day.

## `raceTypes` (type: `array`):

Optional. Keep only races whose type or name contains one of these words: 'claiming' keeps Claiming, Maiden Claiming and Optional Claiming races, 'maiden' keeps every maiden race, 'stakes' keeps stakes races, 'grade' keeps graded stakes.

## `filliesMaresOnly` (type: `boolean`):

Keep only races where every runner is a filly or mare. Uses the sex listed on the race card, so it works for dates that still have entries on Equibase.

## `includeHorseHistory` (type: `boolean`):

Adds one horse_history record for each horse running in the saved races: profile (pedigree, breeder, career record and earnings), every career start with its Equibase Speed Figure, and workouts from the last 60 days. Each horse history is billed as a premium record.

## `maxHorseProfiles` (type: `integer`):

Maximum number of horse_history records per run. Horses are taken in card order, so the first races' runners come first.

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

Optional proxy. The Actor works without one; add a proxy only if Equibase keeps refusing access from your runs.

## Actor input object example

```json
{
  "dataMode": "both",
  "trackCodes": [],
  "maxItems": 20,
  "raceTypes": [],
  "filliesMaresOnly": false,
  "includeHorseHistory": false,
  "maxHorseProfiles": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `dataset` (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 = {
    "dataMode": "both",
    "maxItems": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/equibase-horse-racing-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 = {
    "dataMode": "both",
    "maxItems": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/equibase-horse-racing-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 '{
  "dataMode": "both",
  "maxItems": 20
}' |
apify call parsebird/equibase-horse-racing-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/equibase-horse-racing-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/SRdKydPGhAxMByYzq/builds/3q1d7Jd9tnMgyVgak/openapi.json
