Discover/TAB API
live

TAB APItab.com.au

Retrieve horse racing meetings, race cards, fixed odds, and results from TAB Australia. Covers thoroughbred, harness, and greyhound racing across all states.

Endpoints
5
Updated
2mo ago

What is the TAB API?

The TAB.com.au API exposes 5 endpoints covering Australian racing meetings, race cards, fixed odds, and results. Use get_racing_meetings_by_date to pull all meetings for a given day filtered by jurisdiction, or hit get_next_to_jump_races for a live feed of upcoming races across all venues and race types without specifying any parameters.

Try it
Date in YYYY-MM-DD format. Defaults to today.
State jurisdiction code (NSW, VIC, QLD, etc.)
api.parse.bot/scraper/5137d70d-0c2b-4de4-a5a9-1554bd34c3e9/<endpoint>
Ready to send
Fill in the parameters and hit sign in to send to see live response data here.
Call it over HTTPgrab a free API key at signup
curl -X GET 'https://api.parse.bot/scraper/5137d70d-0c2b-4de4-a5a9-1554bd34c3e9/get_racing_meetings_by_date' \
  -H 'X-API-Key: $PARSE_API_KEY'
Python SDK · recommended

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

"""
TAB Australia API Client
Horse racing data, sports betting odds, and account information from TAB.com.au

Get your API key from: https://parse.bot/settings
"""

import os
import requests
from typing import Optional, Any, Dict, List
from datetime import datetime


class ParseClient:
    """Client for interacting with the TAB Australia API via Parse."""

    def __init__(self, api_key: Optional[str] = None):
        """
        Initialize the Parse API client.

        Args:
            api_key: API key for authentication. If not provided, reads from PARSE_API_KEY env var.
        """
        self.base_url = "https://api.parse.bot"
        self.scraper_id = "38bc6ea2-d123-477f-bf57-9b9312f634d8"
        self.api_key = api_key or os.getenv("PARSE_API_KEY")
        self.session_id: Optional[str] = None
        self.encryption_key: Optional[str] = None

        if not self.api_key:
            raise ValueError("API key must be provided or set as PARSE_API_KEY environment variable")

    def _call(
        self,
        endpoint: str,
        method: str = "POST",
        **params
    ) -> Dict[str, Any]:
        """
        Make an API call to the Parse scraper.

        Args:
            endpoint: The endpoint name (e.g., "get_racing_meetings_by_date")
            method: HTTP method ("GET" or "POST")
            **params: Parameters to pass to the endpoint

        Returns:
            Response data as a dictionary

        Raises:
            requests.exceptions.RequestException: If the API call fails
        """
        url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
        headers = {
            "X-API-Key": self.api_key,
            "Content-Type": "application/json"
        }

        # Add session info if available
        if self.session_id:
            params["sessionId"] = self.session_id
        if self.encryption_key:
            params["encryptionKey"] = self.encryption_key

        try:
            if method == "GET":
                response = requests.get(url, headers=headers, params=params)
            elif method == "POST":
                response = requests.post(url, headers=headers, json=params)
            else:
                raise ValueError(f"Unsupported HTTP method: {method}")

            response.raise_for_status()
            return response.json()
        except requests.exceptions.RequestException as e:
            print(f"API Error calling {endpoint}: {e}")
            raise

    def login(self, username: str, password: str) -> Dict[str, Any]:
        """
        Authenticate a user to obtain a session token.

        Args:
            username: Account username
            password: Account password

        Returns:
            Response containing accessToken and user info
        """
        response = self._call(
            "login",
            method="POST",
            username=username,
            password=password
        )

        # Store session info for subsequent calls
        if "accessToken" in response:
            self.session_id = response.get("accessToken")

        return response

    def get_racing_meetings_by_date(
        self,
        date: Optional[str] = None,
        jurisdiction: str = "NSW"
    ) -> List[Dict[str, Any]]:
        """
        Retrieve all racing meetings for a given date.

        Args:
            date: Date in YYYY-MM-DD format. Defaults to today.
            jurisdiction: State jurisdiction code (NSW, VIC, QLD, etc.)

        Returns:
            List of meeting objects
        """
        params = {"jurisdiction": jurisdiction}
        if date:
            params["date"] = date

        response = self._call(
            "get_racing_meetings_by_date",
            method="GET",
            **params
        )
        return response.get("meetings", [])

    def get_next_to_jump_races(self) -> List[Dict[str, Any]]:
        """
        Retrieve the next races to jump across all venues and race types.

        Returns:
            List of race objects with startTime and raceName
        """
        response = self._call(
            "get_next_to_jump_races",
            method="GET"
        )
        return response.get("races", [])

    def get_race_card(
        self,
        date: str,
        venue_code: str,
        venue: str,
        race_number: int,
        race_type: str
    ) -> Dict[str, Any]:
        """
        Retrieve full race card/details for a specific race.

        Args:
            date: Race date (YYYY-MM-DD)
            venue_code: Venue code
            venue: Venue name slug
            race_number: Race number
            race_type: Race type (thoroughbred, harness, greyhound)

        Returns:
            Race card with raceName and runners list
        """
        return self._call(
            "get_race_card",
            method="GET",
            date=date,
            venue_code=venue_code,
            venue=venue,
            race_number=race_number,
            race_type=race_type
        )

    def get_race_fixed_odds(
        self,
        date: str,
        venue_code: str,
        venue: str,
        race_number: int,
        race_type: str
    ) -> List[Dict[str, Any]]:
        """
        Retrieve current fixed odds for a specific race.

        Args:
            date: Race date (YYYY-MM-DD)
            venue_code: Venue code
            venue: Venue name slug
            race_number: Race number
            race_type: Race type

        Returns:
            List of fixed odds with runnerNumber, winPrice, and placePrice
        """
        response = self._call(
            "get_race_fixed_odds",
            method="GET",
            date=date,
            venue_code=venue_code,
            venue=venue,
            race_number=race_number,
            race_type=race_type
        )
        return response.get("fixedOdds", [])

    def get_race_results(
        self,
        date: str,
        venue_code: str,
        venue: str,
        race_number: int,
        race_type: str
    ) -> Dict[str, Any]:
        """
        Retrieve final results for a completed race.

        Args:
            date: Race date (YYYY-MM-DD)
            venue_code: Venue code
            venue: Venue name slug
            race_number: Race number
            race_type: Race type

        Returns:
            Results with finishing positions and dividends
        """
        return self._call(
            "get_race_results",
            method="GET",
            date=date,
            venue_code=venue_code,
            venue=venue,
            race_number=race_number,
            race_type=race_type
        )

    def get_account_balance(self) -> float:
        """
        Retrieve the authenticated user's account balance.
        Requires prior login.

        Returns:
            Available balance as a float
        """
        response = self._call(
            "get_account_balance",
            method="GET"
        )
        return response.get("availableBalance", 0.0)


if __name__ == "__main__":
    # Initialize client with API key from environment
    client = ParseClient()

    print("=" * 60)
    print("TAB Australia Racing API - Practical Workflow Example")
    print("=" * 60)

    # Step 1: Check upcoming races
    print("\n[1] Getting next races to jump...")
    next_races = client.get_next_to_jump_races()

    if next_races:
        upcoming_race = next_races[0]
        print(f"   Next race: {upcoming_race.get('raceName')} at {upcoming_race.get('startTime')}")

    # Step 2: Get today's meetings
    print("\n[2] Getting today's racing meetings (NSW)...")
    today = datetime.now().strftime("%Y-%m-%d")
    meetings = client.get_racing_meetings_by_date(date=today, jurisdiction="NSW")

    if meetings:
        print(f"   Found {len(meetings)} meetings:")
        for meeting in meetings[:3]:  # Show first 3
            print(f"   - {meeting.get('meetingName')} ({meeting.get('venueCode')})")

        # Step 3: Get race card for first meeting
        if meetings:
            first_meeting = meetings[0]
            venue_code = first_meeting.get("venueCode", "R")
            venue_slug = first_meeting.get("meetingName", "RANDWICK").lower()

            print(f"\n[3] Getting race card for Race 1 at {first_meeting.get('meetingName')}...")
            try:
                race_card = client.get_race_card(
                    date=today,
                    venue_code=venue_code,
                    venue=venue_slug,
                    race_number=1,
                    race_type="R"
                )

                race_name = race_card.get("raceName", "Race 1")
                runners = race_card.get("runners", [])
                print(f"   Race: {race_name}")
                print(f"   Runners ({len(runners)}):")
                for runner in runners[:5]:  # Show first 5 runners
                    print(f"     - #{runner.get('number')}: {runner.get('name')}")

                # Step 4: Get odds for this race
                print(f"\n[4] Getting fixed odds for Race 1...")
                odds = client.get_race_fixed_odds(
                    date=today,
                    venue_code=venue_code,
                    venue=venue_slug,
                    race_number=1,
                    race_type="R"
                )

                print(f"   Found {len(odds)} odds entries:")
                for odd in odds[:3]:  # Show first 3
                    runner_num = odd.get("runnerNumber")
                    win_price = odd.get("winPrice")
                    place_price = odd.get("placePrice")
                    print(f"     - Runner {runner_num}: Win ${win_price:.2f}, Place ${place_price:.2f}")

            except Exception as e:
                print(f"   (Unable to fetch detailed race info: {e})")

    # Step 5: Authentication flow (commented out without valid credentials)
    print("\n[5] Authentication Example (requires valid credentials):")
    print("   To access account balance, login with:")
    print("   >>> client.login(username='your_username', password='your_password')")
    print("   >>> balance = client.get_account_balance()")
    print("   >>> print(f'Account Balance: ${balance:.2f}')")

    print("\n" + "=" * 60)
    print("Workflow completed successfully!")
    print("=" * 60)
All endpoints · 5 totalmissing one? ·

Retrieve all racing meetings for a given date across all race types.

Input
ParamTypeDescription
datestringDate in YYYY-MM-DD format. Defaults to today.
jurisdictionstringState jurisdiction code (NSW, VIC, QLD, etc.)
Response
{
  "type": "object",
  "fields": {
    "meetings": "array"
  },
  "sample": {
    "meetings": [
      {
        "raceType": "R",
        "venueCode": "R",
        "meetingName": "RANDWICK"
      }
    ]
  }
}

About the TAB API

Racing Meetings and Next to Jump

get_racing_meetings_by_date returns a meetings array for any date in YYYY-MM-DD format, optionally filtered by a state jurisdiction code (NSW, VIC, QLD, etc.). Omit the date parameter and it defaults to today. get_next_to_jump_races takes no inputs and returns a races array reflecting the current queue of imminent races across all venues — useful for real-time dashboards or alert systems that need to react to race start times without polling a full meeting list.

Race Cards and Fixed Odds

Both get_race_card and get_race_fixed_odds require four identifying parameters — date, venue (as a name slug), venue_code, and race_number — plus a race_type of thoroughbred, harness, or greyhound. get_race_card returns a runners array and a raceName string, giving you the full field for a specific race. get_race_fixed_odds returns a fixedOdds array reflecting current TAB-listed odds for each runner in that race.

Race Results

get_race_results uses the same five-parameter signature and returns a results array alongside a dividends object once a race is complete. The dividends object covers payout data for the applicable bet types for that race. This endpoint is only meaningful after a race has been run — querying a future race will not return result data.

Coverage Notes

The API covers the three race types TAB supports: thoroughbred, harness, and greyhound racing. All endpoints that target a specific race share a consistent parameter set, so venue and date references are interchangeable across the race card, odds, and results calls for the same event.

Reliability & maintenance

The TAB API is a managed, monitored endpoint for tab.com.au — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when 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 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?+
It's built not to. Every endpoint is health-checked on a schedule with automated test probes. When the source site changes and a check fails, the API is automatically queued for repair and re-verified — that's the self-healing layer. Each API page shows when its endpoints were last verified. And because marketplace APIs are shared, any fix reaches everyone using it.
Is this an official API from the source site?+
No — Parse APIs are independent, managed REST wrappers over publicly available data. That is the point: where a site has no official API (or only a limited one), Parse gives you a maintained, monitored endpoint for that data and keeps it working as the site changes — so you get a stable contract over a source that never promised one.
Can I fix or extend this API myself if I need a new endpoint or field?+
Yes — and you don't have to wait on us. This API was generated by the Parse agent, which stays attached. Describe the change in plain English ("add an endpoint that returns reviews", "fix the price field") in the revise box on the API page or via the revise_api MCP tool, and the agent rebuilds it against the live site in minutes. Contributing the change back to the public API is free.
What happens if I call an endpoint that has an issue?+
Errors are machine-readable: a bad call returns a clean status with the list of available endpoints and a repair hint, so an agent (or you) can recover or trigger a fix instead of failing silently. Confirmed failures feed the automatic repair queue.
Common use cases
  • Build a race-day dashboard that lists all Australian meetings by state using get_racing_meetings_by_date filtered by jurisdiction code
  • Power a 'next to jump' widget on a betting or sports news site using the get_next_to_jump_races endpoint
  • Display full race fields including runner names by fetching the runners array from get_race_card
  • Track current fixed odds movements for a specific race by polling get_race_fixed_odds on a schedule
  • Record historical race outcomes and dividends by querying get_race_results after each race completes
  • Build a multi-race comparison tool for greyhound or harness races by iterating race numbers across a venue
  • Alert users when a monitored runner's odds change by comparing successive fixedOdds array responses
Pricing & limitsSee full pricing →
TierPriceCredits/monthRate limit
Free$0/mo1005 req/min
Hobby$30/mo1,00020 req/min
Developer$100/mo5,000100 req/min

One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.

Frequently asked questions
Does TAB.com.au have an official developer API?+
TAB does not publish a public developer API or documented REST interface for third-party use. This Parse API provides structured access to TAB racing and odds data without requiring any official partnership or account.
What does get_race_fixed_odds return, and how current is the data?+
It returns a fixedOdds array for the specified race, reflecting TAB's current fixed-price odds for each runner. Odds on TAB can change up to race start, so the freshness of the data depends on when you call the endpoint. For live odds tracking, periodic polling is the appropriate approach.
Does the API cover sports betting markets, not just racing?+
The current endpoints cover racing only: meetings, race cards, fixed odds, and results for thoroughbred, harness, and greyhound races. TAB also offers sports betting markets on its site. You can fork this API on Parse and revise it to add an endpoint targeting TAB's sports betting data.
Can I retrieve results and dividends for exotic bets like trifectas or first fours?+
get_race_results returns a dividends object that reflects payout data for the applicable bet types for that race. The specific bet types included in the dividends object depend on what TAB settles for each race. If you need to filter or expand dividend coverage beyond what the current endpoint returns, you can fork the API on Parse and revise the endpoint logic.
Do I need both venue and venue_code to query a specific race?+
Yes. get_race_card, get_race_fixed_odds, and get_race_results all require both the venue slug and the venue_code alongside the date, race_type, and race_number. You can obtain the venue slug and code from the meetings array returned by get_racing_meetings_by_date.
Page content last updated . Spec covers 5 endpoints from tab.com.au.
Related APIs in SportsSee all →
neds.com.au API
Get up-to-date horse racing information from Neds, including upcoming races, event details, and past results. View which races are next to jump and access comprehensive race data all in one place.
racingpost.com API
Access comprehensive horse racing data from Racing Post, including daily racecards, meeting schedules, race results, and detailed horse profiles with form history, stats, and pedigree.
racing.hkjc.com API
Access comprehensive horse racing data from the Hong Kong Jockey Club. Retrieve race results, detailed horse profiles including pedigree and form records, jockey and trainer season rankings, upcoming race meeting fixtures, and horse search by name.
atg.se API
Access comprehensive horse racing data from ATG.se, including race calendars, detailed race information, horse profiles, starting lineups, and results. Retrieve up-to-date information on races, horses, drivers, betting pools, and outcomes.
equibase.com API
Access comprehensive horse racing data from Equibase, including horse profiles, historical race results, track entries, post times, speed figures, and leader statistics for horses, jockeys, trainers, and owners.
oddschecker.com API
Compare betting odds across multiple bookmakers for a wide range of sports, markets, and events on Oddschecker. Retrieve match details, race cards, market outcomes, and bookmaker-by-bookmaker odds to identify the best available prices.
bloodhorse.com API
Get comprehensive horse racing information including race results, stakes entries, horse profiles, and the latest news from BloodHorse.com. Search racing data, view detailed race information, and discover current racing leaders all in one place.
gbgb.org.uk API
Access comprehensive greyhound racing information including race results, meeting details, greyhound profiles and form history, and upcoming open races across all GBGB tracks. Search for specific races and greyhounds, browse available tracks and race classes, and stay updated on upcoming racing events.