Tab APIform.tab.com.au ↗
Access TAB Australian racing schedules, runner lists, fixed odds, and tote odds for thoroughbred, harness, and greyhound meetings via 2 JSON endpoints.
What is the Tab API?
The form.tab.com.au API provides 2 endpoints covering TAB's Australian racing schedule: list_meetings returns every meeting and race card summary for a given day, and get_race returns the full runner list for a specific race including fixed odds, tote odds, barrier draws, jockey and trainer details, and recent form. No account or betting access is required.
curl -X GET 'https://api.parse.bot/scraper/fe8da069-f426-4e7d-81f2-a4ed9e293638/list_meetings?date=today&race_type=R' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace form-tab-com-au-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: TAB Australian Racing — browse today's meetings, drill into a race."""
from parse_apis.form_tab_com_au_api import TAB, RaceType, RaceNotFound
client = TAB()
# List today's thoroughbred meetings, capped to 5.
for meeting in client.meetings.list(race_type=RaceType.THOROUGHBRED, limit=5):
print(meeting.meeting_name, meeting.venue_code, meeting.track_condition)
# Take the first meeting and drill into its first race.
meeting = client.meetings.list(race_type=RaceType.THOROUGHBRED, limit=1).first()
if meeting is not None:
first_race_num = meeting.race_summaries[0].race_number
try:
race = meeting.races.get(race_number=first_race_num)
except RaceNotFound:
print("Race not found at", meeting.venue_code)
else:
print(race.race_name, f"{race.distance_m}m", race.status)
# Show each runner's fixed-odds win price and jockey.
for runner in race.runners:
print(
f"#{runner.runner_number} {runner.runner_name}",
f"win=${runner.fixed_odds.win:.2f}",
f"jockey={runner.jockey}",
)
print("exercised: meetings.list / meeting.races.get")
Returns every meeting of one racing code (thoroughbred by default) scheduled for the requested day, each with its race card summary (race number, name, class, distance, start time, status, scratchings, and results once declared). One upstream request; the response is not paginated and includes all meetings for the day. `meeting_date` and `venue_code` in each meeting are the inputs for get_race. The date 'today' resolves to the current Australian racing day; `weather_condition`, `track_condition` and `rail_position` may be null for greyhound meetings.
| Param | Type | Description |
|---|---|---|
| date | string | Racing day as 'today' or ISO date YYYY-MM-DD (future days show upcoming cards). |
| race_type | string | Racing code to list. |
| jurisdiction | string | Australian state code TAB uses to shape the offer (NSW and VIC exercised); the meeting schedule itself is national. |
{
"type": "object",
"fields": {
"date": "the date input echoed ('today' or YYYY-MM-DD)",
"total": "integer count of meetings returned",
"meetings": "array of meetings; each has meeting_name, venue_code (key for get_race), meeting_date (YYYY-MM-DD, key for get_race), race_type, location (state), prize_money (string with $), weather_condition, track_condition, rail_position, and races",
"race_type": "racing code of the returned meetings",
"jurisdiction": "state code the request was made for",
"meetings[].races": "array of race summaries: race_number, race_name, class_conditions, distance_m (integer metres), start_time (ISO UTC), status, has_fixed_odds, has_parimutuel, results (empty until declared), scratchings (runner_number, runner_name)"
},
"sample": {
"data": {
"date": "today",
"total": 39,
"meetings": [
{
"races": [
{
"status": "Normal",
"results": [],
"race_name": "WYONG EQUINE CLINIC MIDWAY 4YO&UP MAIDEN",
"distance_m": 1350,
"start_time": "2026-09-04T02:50:00.000Z",
"race_number": 1,
"scratchings": [
{
"runner_name": "AELFWYNN",
"runner_number": 7
}
],
"has_fixed_odds": true,
"has_parimutuel": true,
"class_conditions": "4YO+ MDN"
}
],
"location": "NSW",
"race_type": "R",
"venue_code": "WYO",
"prize_money": "$810000.00",
"meeting_date": "2026-09-04",
"meeting_name": "WYONG",
"rail_position": "True",
"track_condition": "SOFT5",
"weather_condition": "FINE"
}
],
"race_type": "R",
"jurisdiction": "NSW"
},
"status": "success"
}
}About the Tab API
Meetings and Race Cards
The list_meetings endpoint returns every meeting scheduled for a racing day, filtered by race_type (thoroughbred by default) and optionally scoped by Australian state via the jurisdiction parameter (NSW and VIC tested). Each meeting in the meetings array carries venue_code and meeting_date, which are the keys required to query individual races. The nested races array inside each meeting includes race_number, race_name, class_conditions, distance_m in integer metres, start_time in ISO UTC, status, and whether scratchings or results are present. Passing 'today' or an ISO YYYY-MM-DD string to the date parameter lets you look up both current-day and upcoming cards.
Runner Detail and Odds
The get_race endpoint accepts venue_code and race_number (both sourced from list_meetings) and returns the full runner list. Each runner object in the runners array includes runner_name, barrier, jockey, trainer, weight_kg, last_5_starts, and an emergency flag. The fixed_odds sub-object carries win, place, opening_win_price, recent fluctuations, and a betting_status field (e.g. Open, LateScratched). Tote (parimutuel) win odds are also returned alongside the fixed prices. Once a race is run, the results array is populated with placings; before jump it is empty.
Coverage and Scope
The API covers TAB's published schedule for Australian thoroughbred, harness, and greyhound racing. The jurisdiction parameter (NSW, VIC) shapes the offer returned, reflecting the state-based structure TAB uses, though the national meeting schedule is returned in all cases. Race data includes prize money (prize_money as a dollar string), venue location (location), and race distance. No account creation, login, or wagering is involved.
The Tab API is a managed, monitored endpoint for form.tab.com.au — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when form.tab.com.au changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official form.tab.com.au API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Display today's Australian race schedule grouped by venue using
list_meetingswithdate='today' - Build a live odds comparison table by polling
get_raceforfixed_odds.winandfixed_odds.placeacross runners - Track market movement by recording
fixed_odds.opening_win_priceand fluctuation history for each runner - Filter scratched runners from a race card using the
fixed_odds.betting_statusfield (e.g.LateScratched) - Show form summaries to punters by surfacing
last_5_starts,jockey,trainer, andweight_kgper runner - Build a results feed by checking the
resultsarray after a race'sstart_timehas passed - Scope a meeting lookup to a specific jurisdiction and race type using the
jurisdictionandrace_typeparameters
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does TAB have an official developer API for racing data?+
What does `get_race` return for a race that hasn't been run yet versus one that's finished?+
results array is empty and fixed_odds.betting_status reflects the current market state (e.g. Open). After the race is resolved, results is populated with placings and runners may show a LateScratched or similar status. The start_time field (ISO UTC) is the reference point for determining whether a race has started.Does the API cover historical racing results beyond today's card?+
date parameter accepts past ISO dates, but depth of historical result data depends on what TAB's platform retains. Extended historical archives — full past-season results, long-form speed maps, or sectional times — are not currently part of the response schema. You can fork this API on Parse and revise it to add endpoints targeting historical result pages if that data becomes accessible.Are exotic market odds (exacta, quinella, trifecta) included in the response?+
get_race endpoint returns fixed odds and tote odds for win and place markets per runner. Exotic pool prices are not part of the current response shape. You can fork this API on Parse and revise it to add an endpoint covering exotic market data.Is the `list_meetings` response paginated?+
list_meetings returns all meetings for the requested day in a single response. The total field gives the integer count of meetings returned. There are no pagination parameters or cursor tokens.