Equibase Scraper - Horse Racing Entries, Results & Charts API
Pricing
from $6.23 / 1,000 results
Equibase Scraper - Horse Racing Entries, Results & Charts API
Extract US and Canadian Thoroughbred racing data from Equibase: race entries with jockey, trainer, owner, sire and dam, finished results with win-place-show and exotic payoffs, and horse profiles with career records.
Pricing
from $6.23 / 1,000 results
Rating
0.0
(0)
Developer
ParseForge
Maintained by CommunityActor stats
0
Bookmarked
7
Total users
4
Monthly active users
6 days ago
Last modified
Categories
Share
Equibase Scraper - Horse Racing Entries, Results & Charts API
Scrape North American Thoroughbred racing from Equibase, the official data source of the sport. Get tomorrow's entries with every horse's jockey, trainer, owner, sire, dam and morning line; get yesterday's results with the full order of finish, win-place-show and every exotic payoff; get any horse's career record. 71 fields, no login, no API key. Export to CSV, JSON, Excel, or XML.
Equibase has no free public API, and its data pages sit behind Imperva bot protection that answers a plain HTTP request with HTTP 200 and a block page — which is how a scraper ends up reporting a successful run with an empty dataset. This Actor drives a real browser through the challenge and checks every page by content, never by status code.
| Who uses it | What they scrape Equibase for |
|---|---|
| Handicappers and betting models | Full fields with morning lines, post positions, weights and medication, the morning the entries drop |
| Racing analytics and data products | Results with finish order, final times, and every exotic pool payoff in one schema |
| Bloodstock and breeding research | Sire, dam and dam sire on every entry, plus career earnings and speed figures per horse |
| Racing media and tipping services | Whole cards, every track, ready to publish without manual entry |
| Ownership and syndicate platforms | Owner and breeder on every runner, joined by a stable horse id |
What it does
Pick one of three result types and the Actor returns flat rows.
🏇 Race entries — one row per horse declared: program number, post position, age, sex, medication, assigned weight, jockey, trainer, owner, breeder, sire, dam, dam sire, and the morning line in both fraction and decimal.
🏁 Race results — one row per finisher: finish position, win, place and show payoffs, the winning connections, the final time and going, plus every exotic pool — exacta, trifecta, superfecta, Pick N — attached to the winning row.
📋 Horse profiles — one row per horse: lifetime starts, wins, placings and earnings, best Equibase Speed Figure, season-by-season splits and the complete past-performance list.
Every run also gives you:
- 🗓️ Whole cards or whole meets. Name a track and a date, a date range, or nothing at all to take every track racing that day.
- 📏 Distances normalised to yards. Equibase writes "Five And One Half Furlongs" on entries and "5 1/2 F" on results; both come back as
distanceYards: 1210. - 🟫 Surface on every race. Entries only annotate turf and synthetic, so an unannotated race is reported as Dirt — a rule checked against the results page for the same card and right on all ten races.
- ✂️ Scratches handled properly. A scratched horse is a differently shaped table row on Equibase; it is flagged
isScratched, keeps its name and morning line, and never has another horse's jockey pasted onto it. - 🔗 Stable ids to join on.
horseRefNumber,jockeyIdandtrainerIdcome straight from Equibase and survive name spellings.
Results export to CSV, JSON, Excel, or XML, or stream from the API.
What you can do with Equibase data
📊 Build a handicapping model.
Entries give you the whole field with weights, medication, post positions and the morning line; results give you what actually happened. Join them on horseRefNumber and raceDate.
🎯 Track a trainer or jockey.
Filter every card at every track by trainer or jockey and get their runners, prices and finishes without opening a single page.
🧬 Study a sire's progeny.
Sire, dam and dam sire on every entry make it one filter to pull every runner by a given stallion across the country.
💰 Model payoff structure.
Exotic payoffs with the winning combinations let you measure pool behaviour, favourite-longshot bias, and carryover value.
Why choose this scraper
| What you get | |
|---|---|
| Gets past the bot wall | Equibase's Imperva protection returns HTTP 200 on a block. This Actor drives a real browser through a residential exit and verifies every page by content, so a blocked page is never mistaken for an empty card — and a blocked page is never charged. |
| Three result types | Entries, results and horse profiles, in one Actor and one schema. |
| 71 fields | Everything Equibase publishes on the page, including owner, breeder and full pedigree on every runner. |
| Connections and pedigree per horse | Owner, breeder, sire, dam and dam sire, matched to each runner by program number. Optional, so you only pay for them when you want them. |
| Payoffs, not just finishers | Win, place and show on the finishers that earned them, and every exotic pool on the winning row. |
| Distances you can compute with | distanceYards alongside the prose, so races compare across both of Equibase's spellings. |
| 17 filters that cut the bill | Race number, surface, purse, breed, stakes, claiming, jockey, trainer, owner, horse, sex, age and scratches. Filtered rows are never written and never charged. |
| Predictable bill | One per-row price by default. Connections, pedigree, exotic payoffs and race history are each a checkbox that is off until you tick it, so a run cannot surprise you with charges you did not ask for. |
| Honest empties | A field Equibase does not publish is absent, never a guessed value and never a null. |
| Four export formats | CSV, JSON, Excel, and XML, from the dashboard or the API. |
How it compares
There is one other Equibase Actor in the Store. The competitor column reflects what its own public listing states, not a test run of it.
| Feature | ParseForge | jungle_synthesizer |
|---|---|---|
| Race entries | Yes | Yes |
| Race results and payoffs | Yes, including every exotic pool | Yes, finish order, times, payouts |
| Horse career profiles | Yes | Not stated |
| Owner and breeder per runner | Yes | Not stated |
| Sire, dam and dam sire | Yes | Not stated |
| Scratched horses handled | Flagged, and never column-shifted | Not stated |
| Distance normalised to yards | Yes | Not stated |
| Filter before you pay | 17 filters | Not stated |
| Date range across a meet | Yes, using each track's own calendar | Any date and track |
| Actor start fee | $0.02 per GB | $0.10 |
| Base price per row | $0.007 | $0.001 |
Come here when you need the connections, the pedigree, the exotic payoffs, or scratch handling you can trust.
What an entry looks like
Every runner returns as one flat JSON row. Here is a real record, unedited:
{"rowType": "entry","trackCode": "DMR","trackName": "Del Mar","country": "USA","raceDate": "2026-08-20","raceNumber": 1,"raceName": "Del Mar ALLOWANCE OPTIONAL CLAIMING $80,000","raceType": "ALLOWANCE OPTIONAL CLAIMING","purse": 81000,"distance": "Five Furlongs","distanceYards": 1100,"surface": "Turf","claimingPrice": 80000,"ageRestriction": "Three Year Olds","isStakes": false,"isClaiming": true,"wagers": ["$1 Exacta", "$2 Quinella", "50c Trifecta"],"programNumber": "1","postPosition": 1,"horse": "Dr. My Eyes","horseState": "LA","horseRefNumber": "11306737","horseUrl": "https://www.equibase.com/profiles/Results.cfm?type=Horse&refno=11306737®istry=T&rbt=TB","age": 3,"sex": "C","medication": "L","weight": 121,"jockey": "K Kimura","jockeyId": "164186","trainer": "P D'Amato","trainerId": "277836","morningLineOdds": "3/1","morningLineDecimal": 4,"owner": "Intrepid Thoroughbreds LLC","breeder": "Coteau Grove Farms, LLC","sire": "Maxfield","dam": "You Caught My Eye","damSire": "Can the Man","isScratched": false,"entryUrl": "https://www.equibase.com/static/entry/DMR082026USA-EQB.html","scrapedAt": "2026-08-20T14:05:53.732Z"}
And a result row, with the payoffs on the winner:
{"rowType": "result","trackName": "Del Mar","raceDate": "2026-08-15","raceNumber": 1,"raceType": "Maiden Special Weight","purse": 80000,"distance": "1 M","distanceYards": 1760,"surface": "Dirt","trackCondition": "Fast","postTime": "2:01","finalTime": "1:37.79","finishPosition": 1,"programNumber": "6","horse": "Harmonique","winPayoff": 15.8,"placePayoff": 5.6,"showPayoff": 3.2,"winningOwner": "Thor-Bred Stables LLC","winningTrainer": "Neil D. Drysdale","winningJockey": "Joel Rosario","exoticWagers": [{ "wagerType": "$1 Exacta", "winningNumbers": "6-5", "payoff": 14.5 }]}
Configure the run
| Setting | What it does |
|---|---|
resultType | entries, results, or horses. |
tracks | Equibase codes (DMR, SAR, CD) or full names (Del Mar). Empty takes every track with a card that day. |
date | One race day, YYYY-MM-DD. Defaults to today for entries, and to each track's most recent card for results. |
dateFrom / dateTo | An inclusive range. Days a track did not race are skipped using its own calendar, so they cost nothing. |
maxDays | Ceiling on race days fetched per track. Each day is one page load through the challenge, so this is the main lever on run time. |
country | USA, CAN or PUR. Canadian tracks such as Woodbine need CAN. |
horseUrls | Horse profile URLs or bare reference numbers, for resultType: horses. |
maxItems | Ceiling on rows written. |
includeConnections, includePedigree, includeWagers, includeRaceHistory | Optional data blocks, all off by default. Each adds fields to the row and is billed separately — see Pricing. |
proxyConfiguration | Residential proxy, on by default. Equibase refuses datacenter addresses — see below. |
Narrow the run with filters
Every filter runs before the row is written, so rows you filter out are never charged.
| Filter | What it keeps |
|---|---|
raceNumbers | Only these races on the card. |
surfaces | Dirt, Turf, All Weather, Steeplechase. |
minPurse / maxPurse | Races inside a purse range. |
onlyStakes | Stakes, handicaps, derbies, cups and graded races. |
onlyClaiming | Races where horses can be claimed. |
breeds | Thoroughbred, Quarter Horse and the rest, by Equibase's code. |
horseName | Runners whose name contains your text. |
jockey / trainer / owner | Runners with that connection. Substring match, because Equibase abbreviates first names on entries. |
sexes | Colt, filly, gelding, horse, mare, ridgling. |
minAge / maxAge | Horses inside an age range. |
excludeScratched | Drops horses withdrawn from the card. |
Why it needs a browser and a residential proxy
Equibase's Imperva protection makes two separate demands, and both were measured on 20/08/2026.
It wants the challenge executed. Plain HTTP requests are refused whatever IP they come from: all four Apify proxy groups — none, datacenter, residential and Unblocker — were tried against the same three URLs and all four were blocked identically, always with HTTP 200. Replaying the reese84 cookie that a browser mints does not help either, because Imperva fingerprints the TLS handshake as well. Only a real browser navigation gets through, and only a real navigation: fetch() from inside the page is refused too, because Imperva reads Sec-Fetch-Dest.
It also refuses datacenter addresses. A browser running on an Apify datacenter IP is blocked however long it waits. That is why the residential proxy is on by default — on this site it is not a tuning knob, it is the difference between rows and an empty dataset.
To keep the proxy bill down, images, fonts, media and stylesheets are dropped on the way in. That takes a card from about 9.8 MB of traffic to about 1.8 MB, and the challenge still clears — scripts are never blocked, because the challenge is a script.
Pricing
This Actor is pay per event, and a run left at its defaults has exactly one per-row price. Every optional data block is off by default: if you do not tick it, you do not receive it and you are not charged for it. Nothing is billed for rows a filter rejected, and a page Equibase never let us read is not billed either.
| Event | Price | When it fires |
|---|---|---|
result-item | $0.007 | One row. Covers the race and its conditions, purse, distance and surface, plus the horse, jockey, trainer, weight and odds — or the finish position with win, place and show payoffs. |
race-page | $0.045 | One track-and-day page loaded through the anti-bot challenge, however many races the card holds. |
horse-profile | $0.03 | One horse profile page loaded through the challenge. |
calendar-scan | $0.01 | One track calendar read, so days the track did not race cost nothing. |
apify-actor-start | $0.02 | Once when the run starts, per GB of memory. |
Optional, and off unless you ask for them:
| Event | Price | Switched on by |
|---|---|---|
connections | $0.0012 | includeConnections — owner and breeder on a runner, winning connections on a result. |
pedigree | $0.0012 | includePedigree — sire, dam and dam sire. |
wager-payoffs | $0.002 | includeWagers — exacta, trifecta, superfecta and Pick N payoffs. |
race-history | $0.003 | includeRaceHistory — the full past-performance list on a horse profile. |
A default full card — one page, ninety runners — costs $0.675. Switch on connections and pedigree and the same card is $0.891.
The page and profile events are priced where they are because each one is a real browser navigation through an anti-bot challenge, not an HTTP request.
Free users
Apify free-plan runs are capped at 50 rows per run, because every page costs a full browser load. Everything else works the same: all 71 fields, all 17 filters, all three result types, and every optional block available to tick. Upgrade your Apify plan to lift the cap.
Run it
- Open the Actor in Apify Console, pick a result type, and put a track code in
tracks. - Set
maxItemsto the number of rows you want. - Click Start, then export the dataset as CSV, JSON, Excel, or XML.
Or from the API:
curl -X POST "https://api.apify.com/v2/acts/parseforge~equibase-scraper/runs?token=YOUR_TOKEN" \-H 'Content-Type: application/json' \-d '{"resultType":"entries","tracks":["DMR"],"maxItems":100}'
Use with AI agents (MCP)
The Actor is exposed over Apify's MCP server, so an agent can call it as a tool:
https://mcp.apify.com/sse?actors=parseforge/equibase-scraper
Ask things like "who is running at Del Mar today and what are the morning lines" and the agent fills the input itself.
Troubleshooting
No rows came back.
The most common cause is a date with no card. A track only has entries on days it races — check its calendar, or leave date empty and let the Actor use today for entries and the last published card for results.
"No card published" in the log.
Equibase returns a 404 for a track-and-day with no race. That is the source's real state, and it is not charged.
Why is surface "Dirt" when the page says nothing?
Equibase only annotates turf and synthetic surfaces on entries. An unannotated race runs on the main dirt track. The rule was checked against the results page for the same card, which does state the surface, and it was right on all ten races.
Why does a scratched horse have no jockey?
Equibase collapses the jockey, trainer, weight and medication of a scratched horse into a single dashed cell. The name and the morning line survive, and the row is flagged isScratched. Nothing is invented to fill the gap.
Why is medication or claimingPrice empty?
Not every horse runs on medication and not every race is a claimer. An absent field is a real absence.
Why is the run slow?
Each track-and-day is one browser navigation through a residential exit, and the anti-bot challenge needs a few seconds to clear before the page is readable. Lower maxDays, or name specific tracks instead of taking every card in the country.
The log says pages were blocked.
Imperva blocks per IP. The Actor already retries each page three times, taking a fresh browser session and a new exit IP each time, and a page it never managed to read is not charged. If a whole run is blocked, check that the residential proxy is enabled in the input and run it again.
A field stopped filling.
Equibase changed its page markup. Email us with your run ID so we can update the parser.
FAQ
| Question | Answer |
|---|---|
| Do I need an Equibase account or API key? | No. This reads public Equibase pages, so there is nothing to register or authenticate. |
| Does it cover Canada? | Yes. Set country to CAN for Woodbine and the other Canadian tracks. |
| Does it cover harness racing or Quarter Horses? | Equibase publishes them and they come through the same schema. Use the breeds filter to keep or drop them. |
| Can I get a whole meet in one run? | Yes. Set dateFrom and dateTo and raise maxDays. Days the track did not race are skipped for free. |
| Are live tote odds included? | No. The morning line is, in both fraction and decimal. Equibase's live-odds column mirrors the morning line outside live wagering, so it is not shipped as a field that would always be empty. |
| Can I join entries to results? | Yes. horseRefNumber is on both, and it is Equibase's own permanent id. |
| How many rows per run? | Free plan: 50. Paid: up to 100,000, bounded by how many runners your tracks and dates actually contain. |
| Does it need a proxy? | Yes, residential, and it is on by default. Equibase refuses datacenter addresses even to a real browser. Plain HTTP is refused from every IP, proxied or not. |
| Is this an official Equibase product? | No. It is unofficial and reads only publicly available Equibase pages. |
Related actors
- Sherdog Scraper: MMA fighter records and full event cards.
- DraftKings DFS Scraper: contests and player salaries.
- SofaScore Live Scraper: live scores and match data across sports.
Browse the full ParseForge collection for more scrapers.
🆘 Need help? Email parseforge@protonmail.com with your run ID, your input, and what you expected.
⚠️ Disclaimer. This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by Equibase Company LLC, The Jockey Club, or any racing authority. It collects only publicly available Equibase data. Equibase asserts copyright over its racing data; you are responsible for using it in compliance with Equibase's terms and applicable law, and for obtaining a licence where your use requires one. Race results are public sporting records.
