BlogSportsbook data

FanDuel API Data and Matching Markets Across Books

A search for a FanDuel API usually comes from someone who wants FanDuel's sportsbook prices, props especially, in a program so they can compare them with other books. Whether FanDuel itself offers developers an official or partner API, and on what terms, is something only FanDuel can confirm. The other route is a service that reads the book's public prices and returns them with other books in one format.

ZippyOddsAPI is that kind of service, and it's independent: no sportsbook, FanDuel included, is affiliated with it, endorses it or partners with it. When FanDuel is feeding, its prices sit in the same response as every other book's, matched to the same games and outcomes. Getting the prices is the easy half. Comparing them correctly is the harder half, and that's what most of this guide is about.

What only FanDuel can tell you

Before you build on any route to FanDuel's prices, look on the operator's own site for a developer or partner page, and for FanDuel API documentation published by FanDuel itself. Code samples and posts elsewhere can be out of date or simply wrong.

Then read the operator's terms for what they say about automated access, storing prices, showing them to others and commercial use. If you use an aggregator, read its terms too. None of that is something a third party can answer for you.

Same-game parlays don't compare like straight bets

Same-game parlays are a large part of US sportsbook menus, FanDuel's included, and developers often want to compare those prices across books. That comparison is harder than it looks.

Take two legs in one game, each priced at -110 as a straight bet. If the legs were independent, the parlay would pay the two decimal prices multiplied together:

  • -110 in decimal is 1 + 100 / 110 = 1.9091.
  • 1.9091 × 1.9091 = 3.6446, which is about +264.

But legs in the same game are often related. A quarterback's passing yards and his top receiver's receiving yards tend to rise together. A book that thinks the legs move together will price the parlay shorter than +264, and each book has its own view of how much. Two books can quote the same two legs at different parlay prices while having identical straight prices.

So a same-game parlay price is a book's model of the correlation, not just its leg prices. ZippyOddsAPI's market catalog has no parlay market: it returns the straight price of each leg. That's the part that compares cleanly across books. If you're estimating whether a book's parlay is generous, start from the fair price of each leg and then your own estimate of how they're related.

Matching one market across books

A straight price is comparable across books only when all of these agree:

Must matchWhy
EventThe same game, not one with similar team names.
Market keyPoints, not points plus rebounds plus assists.
PeriodFull game, not first half.
PlayerThe same player, however each book spells the name.
Line and sideOver 24.5 is not over 25.5.

In ZippyOddsAPI an outcome's id (it starts with sel_) is the same at every book for the same side and point in the same market. So the match is done for you: group prices by outcome id and you have every book's price for exactly the same bet. Here's FanDuel's points props set against the best price elsewhere, in decimal odds:

from collections import defaultdict

quotes = defaultdict(list)
for event in body["data"]:
    for book in event["bookmakers"]:
        for market in book["markets"]:
            for o in market["outcomes"]:
                if o["price"] is not None:
                    quotes[o["id"]].append((o["price"], book["id"], market["player"]["name"], o["side"], o["point"]))

for outcome_id, rows in quotes.items():
    fanduel = [r for r in rows if r[1] == "fanduel"]
    if fanduel:
        best = max(rows)
        print(fanduel[0][2:], "FanDuel", fanduel[0][0], "best", best[0], "at", best[1])

body is the JSON from /v1/props?league=nba&markets=player_points&format=decimal&include_dfs=false. Leaving pick'em apps out matters here, because their outcomes have price: null and pay by entry instead. When lines differ, say FanDuel at 24.5 and another book at 25.5, the outcomes have different ids. That's correct: they're different bets, and comparing them needs a model of how likely the half point is.

Why FanDuel's props carry weight

ZippyOddsAPI builds fair prices from reference books with their margins removed. The docs list FanDuel as a reference on player markets only, at a weight below the sharpest books, and as one of the references behind pick'em pricing. On other markets its prices are scored but don't help set the fair line. Settings like these can change, so the docs are the place to check the current table.

Its own prices are never scored against itself. A FanDuel prop is compared with a fair price from other books, which is how the +EV board avoids a book agreeing with its own number.

Checking that FanDuel is feeding

The coverage page shows every book's state. A book in the registry isn't a promise of prices: only a feeding state means its prices are on the board and recent. Each FanDuel entry in a response also has updated_at, the time its prices were read, so you can drop anything too old for your use.

Where to go next

Exchanges price differently from sportsbooks, with backers and layers instead of a house margin, and the Betfair API guide covers that side. The Pinnacle API guide explains why a sharp book is the usual reference for a fair price, and the sportsbook API guide covers reading any book's prices in code. The ZippyOddsAPI docs cover every parameter used above and how to get a key.