PointsBet API: How to Access PointsBet Odds Without Official API

PointsBet API - OddsPapi API Blog
How To Guides July 17, 2026

Searching for a “PointsBet API” so you can pull PointsBet odds into a model, a line-shopping tool, or a dashboard? There isn’t a public one. PointsBet, like every major sportsbook, keeps its pricing endpoints private and locked behind its own apps. The good news: you do not need PointsBet to open a developer portal. You can read live PointsBet odds today through an aggregator that already carries them, alongside Pinnacle, the prediction markets, and 350+ other books, on a free tier.

This guide shows you how, in Python, using OddsPapi. Every number and code block below was tested live against the 2026 FIFA World Cup feed.

Why PointsBet Has No Public Odds API

PointsBet is an Australian-founded sportsbook (launched 2017), best known for its “PointsBetting” spread-style product where your win or loss scales with the margin of victory. Its US business was acquired by Fanatics in 2023; the brand still operates in Australia and Canada. The slug you will see in the data below, pointsbet.com.au, is the Australian sportsbook.

None of those entities publish a documented odds API. Sportsbooks have no commercial reason to hand competitors and arbitrageurs a clean feed of their prices. What exists instead are private, undocumented endpoints behind their web and mobile apps, which change without notice, sit behind Cloudflare and geo-blocks, and will get your IP banned the moment you scrape them at any useful rate.

So you have three options. Two of them are bad.

Scraping vs. Enterprise vs. OddsPapi

Approach What it actually means Verdict
Scrape PointsBet directly Reverse-engineer private app endpoints, rotate proxies, fight Cloudflare and geo-blocks, rebuild every time they ship a release. Brittle, against ToS, bans your IP.
Enterprise data feed Sportradar / Genius-tier contracts. Real coverage, but sales calls, minimums, and four- to five-figure monthly invoices. Overkill unless you are an operator.
OddsPapi One REST API that already aggregates PointsBet plus 350+ books. Query by sport, fixture, and bookmaker. Free tier, no scraping. The developer option.

OddsPapi is the third option: enterprise-grade coverage (372 bookmakers across 69 sports as of this writing, including sharps like Pinnacle and SBOBet and prediction markets like Polymarket and Kalshi) at a developer-friendly price, with a free tier and free historical data.

What PointsBet Data Is Available Through OddsPapi

PointsBet is live in the feed under the slug pointsbet.com.au. On the 2026 World Cup slate it showed up on every fixture we sampled (10 of 10), carrying 36 to 49 markets per match. That is well beyond a moneyline-only book. On the Argentina vs. Austria group-stage fixture, PointsBet priced:

  • Full Time Result (1X2), Double Chance, Draw No Bet, Half Time / Full Time
  • Both Teams To Score (full match, first half, second half)
  • Correct Score, Winning Margin, First Goal, Odd/Even
  • Clean Sheet and “to win both halves / either half” team markets
  • Corners (1X2, handicap, over/under)

One honest caveat: PointsBet did not ship the headline full-time Over/Under 2.5 goals line in this payload (it carried second-half totals and corner totals instead). That is exactly why you line-shop: pull PointsBet for the markets it prices well, and let the other 350+ books fill the gaps. We will do that below.

Step 1: Authenticate

Authentication is a single query parameter. There are no OAuth dances, no headers, no signing. Grab a free key and you are in.

import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.oddspapi.io/v4"

# Auth is a query parameter, NOT a header
r = requests.get(f"{BASE_URL}/sports", params={"apiKey": API_KEY})
print(r.status_code)  # 200

Step 2: Find Fixtures With PointsBet Odds

Soccer is sportId=10. Pull a date range (the window is capped at 10 days), then keep only fixtures that have odds. Here we filter to the World Cup tournament.

params = {
    "apiKey": API_KEY,
    "sportId": 10,
    "from": "2026-06-22",
    "to": "2026-07-02",
}
fixtures = requests.get(f"{BASE_URL}/fixtures", params=params).json()

world_cup = [
    f for f in fixtures
    if f.get("hasOdds") and "world cup" in str(f.get("tournamentName", "")).lower()
]

for f in world_cup[:5]:
    print(f["fixtureId"], f["participant1Name"], "vs", f["participant2Name"])

# id1000001666457022 Argentina vs Austria
# id1000001666457010 France vs Iraq
# ...

Only fixtures with hasOdds: true return a pricing payload. The terminology note for US devs: OddsPapi calls a league a tournament, a game a fixture, and a team a participant.

Step 3: Pull PointsBet Odds for a Fixture

Hit /odds with a fixtureId. The response nests prices under bookmakerOdds[slug]["markets"][marketId]["outcomes"][outcomeId]["players"]["0"]. For the live endpoint, players["0"] is a dict with the current price.

fixture_id = "id1000001666457022"  # Argentina vs Austria

odds = requests.get(f"{BASE_URL}/odds", params={
    "apiKey": API_KEY,
    "fixtureId": fixture_id,
}).json()

pb = odds["bookmakerOdds"]["pointsbet.com.au"]

# Market 101 = Full Time Result (1X2). Outcomes: 101=Home, 102=Draw, 103=Away
ftr = pb["markets"]["101"]["outcomes"]
for outcome_id, label in [("101", "Argentina"), ("102", "Draw"), ("103", "Austria")]:
    price = ftr[outcome_id]["players"]["0"]["price"]
    print(f"{label}: {price}")

# Argentina: 1.42
# Draw: 4.3
# Austria: 7.5

The feed pre-converts every price to decimal (price), American (priceAmerican, a string), and fractional (priceFractional, a string), so you never write your own odds converter.

A pitfall worth knowing: the bookmakers filter

You can narrow /odds to specific books with a bookmakers comma list. But there is a sharp edge: if you include a slug that is not on that fixture, the entire response comes back empty, not just that one book. We confirmed it live:

# Both present -> works
get_books("pinnacle,pointsbet.com.au")   # ['pinnacle', 'pointsbet.com.au']

# One slug absent on this fixture -> whole response zeroes out
get_books("pointsbet.com.au,betway")     # []

So either omit the filter and parse the full payload, or filter only by slugs you have already confirmed are on the fixture. The model names need to match the feed exactly too: PointsBet is pointsbet.com.au, not pointsbet.

PointsBet vs. Pinnacle: The 7% Vig Gap

PointsBet is a soft, recreational-facing book. Pinnacle is the sharpest mainstream book on the planet. The price difference is not subtle. Here is the same 1X2 market, same fixture, both books:

Outcome PointsBet Pinnacle
Argentina 1.42 1.487
Draw 4.30 4.50
Austria 7.50 8.00
Overround (vig) 7.01% 1.97%

PointsBet is worse on all three outcomes, and its built-in margin is 3.5x heavier than Pinnacle’s. To find the market’s fair probabilities, de-vig the sharp line (strip Pinnacle’s overround proportionally):

def devig_proportional(decimal_odds):
    inv = [1 / o for o in decimal_odds]
    total = sum(inv)               # = 1 + overround
    return [i / total for i in inv]  # fair probabilities

pin = [1.487, 4.5, 8.0]            # Argentina / Draw / Austria
fair = devig_proportional(pin)
# Argentina 65.9% (fair 1.516)
# Draw      21.8% (fair 4.589)
# Austria   12.3% (fair 8.158)

Against a fair Argentina price of 1.516, PointsBet’s 1.42 is charging you 6%+ in margin on the favorite. This is why no one should bet a soft book blind, and why pairing PointsBet with a sharp anchor is the whole point. (For the math three ways, see our no-vig odds guide and the vig calculator.)

Line Shopping: PointsBet vs the Field

The real unlock of an aggregator is comparing PointsBet against every other book in one call. Walk every bookmaker on the fixture and keep the best decimal price per outcome, filtering on active so you never compare against a suspended line.

def best_price(bookmaker_odds, market_id, outcome_id):
    best, best_book = None, None
    for slug, data in bookmaker_odds.items():
        try:
            o = data["markets"][market_id]["outcomes"][outcome_id]
            p = o["players"]["0"]
            if not o.get("active", True):
                continue
            if best is None or p["price"] > best:
                best, best_book = p["price"], slug
        except (KeyError, TypeError):
            continue
    return best, best_book

books = odds["bookmakerOdds"]
for oid, label in [("101", "Argentina"), ("102", "Draw"), ("103", "Austria")]:
    price, book = best_price(books, "101", oid)
    print(f"{label}: best {price} @ {book}")

# Argentina: best 1.505 @ circasports   (PointsBet 1.42)
# Draw:      best 4.762 @ kalshi        (PointsBet 4.30)
# Austria:   best 8.333 @ kalshi        (PointsBet 7.50)

On all three outcomes the best available price across the field beats PointsBet, by roughly 6% on Argentina and 11% on both the draw and Austria. That is not a value or +EV claim, just the best price on offer. But it shows the cost of betting one soft book in isolation, and it is exactly the workflow our line shopping tutorial generalizes across the full catalog. A standard sanity check: outliers like a single book quoting far above the pack can be stale or boosted, so cross-check before trusting them.

Native Markets: Beyond the Moneyline

PointsBet ships structured props natively, so you do not have to reconstruct them. Both Teams To Score on the same fixture, for example:

# Market 104 = Both Teams To Score. Outcomes: 104=Yes, 105=No
btts = pb["markets"]["104"]["outcomes"]
print("Yes:", btts["104"]["players"]["0"]["price"])  # 2.05
print("No:",  btts["105"]["players"]["0"]["price"])  # 1.69

Market and outcome IDs are integers; pull human-readable names from /markets?sportId=10 and build your own lookup dict rather than hardcoding the catalog (soccer alone has tens of thousands of market-line variants):

cat = requests.get(f"{BASE_URL}/markets",
                   params={"apiKey": API_KEY, "sportId": 10}).json()
market_names = {m["marketId"]: m["marketName"] for m in cat}

Free Historical PointsBet Odds

Backtesting is where most aggregators put up a paywall. OddsPapi gives historical price history away on the free tier. The historical endpoint has a different shape from the live one: the top key is bookmakers (not bookmakerOdds), and players["0"] is a list of snapshots, not a single dict. Max three books per call.

hist = requests.get(f"{BASE_URL}/historical-odds", params={
    "apiKey": API_KEY,
    "fixtureId": fixture_id,
    "bookmakers": "pointsbet.com.au,pinnacle",   # max 3
}).json()

snaps = hist["bookmakers"]["pointsbet.com.au"]["markets"]["101"]["outcomes"]["101"]["players"]["0"]
for snap in snaps:
    print(snap["createdAt"], snap["price"])

That timeline is how you measure line movement and closing line value: store the opening PointsBet price, compare it to the close, and you have a CLV audit with no extra cost.

PointsBet vs. Pinnacle: Why You Need Both

Use PointsBet for… Use Pinnacle (and the field) for…
The price you can actually bet (if you have an account) The fair probability anchor (de-vigged)
Recreational and prop market depth Sharp, low-margin lines for value detection
One book’s view of a market Best available price across 350+ books

PointsBet alone tells you almost nothing about whether a price is good. PointsBet next to Pinnacle and the rest of the field tells you everything.

Frequently Asked Questions

Does PointsBet have an official API?

No. PointsBet does not publish a documented public odds API. Its pricing lives behind private app endpoints. To read PointsBet odds programmatically, use an aggregator like OddsPapi that already carries the feed.

What is the PointsBet slug in OddsPapi?

It is pointsbet.com.au (the Australian sportsbook). Use that exact string in the bookmakers filter; pointsbet on its own will not match.

Is scraping PointsBet legal?

Scraping violates PointsBet’s terms of service and will get your IP blocked. Reading the prices through a licensed aggregator avoids the ToS, the Cloudflare fights, and the maintenance burden entirely.

How many markets does PointsBet cover?

On the World Cup fixtures we tested, PointsBet priced 36 to 49 markets each, including 1X2, double chance, draw no bet, both teams to score, correct score, half time/full time, winning margin, and corners. The exact set varies by fixture and sport.

Is PointsBet odds data free on OddsPapi?

Yes. PointsBet live and historical odds are available on the OddsPapi free tier, alongside 350+ other bookmakers.

Stop Hunting for a PointsBet API That Does Not Exist

There is no PointsBet developer portal coming. But you do not need one. With a free OddsPapi key you can read live and historical PointsBet odds in Python today, line-shop them against Pinnacle and 350+ books, and build whatever model, scanner, or dashboard you came here for, without scraping a single page.

Get your free API key and pull your first PointsBet price in the next five minutes.

Related: DraftKings API access, World Cup Odds API, and the consensus odds calculator.