Most people who search for a PrizePicks API want one thing: the app's current player lines (player, stat, line, and which way you can pick) inside their own program, so they can compare them with sportsbook prices or track how they move. Whether PrizePicks offers that to outside developers, and on what terms, is something only PrizePicks can tell you. Check its own site, help pages and terms rather than a forum thread or an old GitHub repo.
What you can plan for is the shape of the data and the arithmetic that makes it useful. A pick'em line on its own says very little. It becomes a number you can act on only once you know the fair chance of each side and the chance you need to break even on the entry. That's the part this guide works through.
What a pick'em line is, as data
PrizePicks is a pick'em fantasy app. You choose more or less than a posted stat line on several players, and the entry pays a multiple of the stake if every pick (or enough of them, on some entry types) hits. For a developer, that has a few consequences:
- There's often no price per pick. A sportsbook quotes -110 on each side. A pick'em line usually quotes only the line, and the payout lives at the entry level.
- Lines can come in types. An app can mark some lines as easier or harder than its standard line, with a different payout. Treat each type as its own market, even at the same number.
- Names have to match. "J. Example" on one app and "Jordan Example" at a sportsbook must resolve to one player before you compare anything. A wrong match invents an edge.
So the useful record is wider than the line: player, team, stat, line, side, line type, when it was read, and the payout rule it sits under.
The break-even arithmetic
On an entry where every pick must hit, the chance each pick needs is the n-th root of one over the payout multiple. For a hypothetical 2-pick entry paying 3 times the stake:
def per_pick_break_even(multiple: float, picks: int) -> float:
if multiple <= 1 or picks < 1:
raise ValueError("need a multiple above 1 and at least one pick")
return (1.0 / multiple) ** (1.0 / picks)
print(round(per_pick_break_even(3.0, 2), 4)) # 0.5774
Each pick has to hit 57.74% of the time just to break even. Check it the other way: 0.5774 x 0.5774 = 0.3334, and 1 / 3 = 0.3333. In American odds that's about -137 per pick, which is why a pick'em line that looks like a coin flip is usually a poor bet. Payout tables belong to the app and change, so read the current ones from the app itself.
Now the fair side. If sharp sportsbooks price the over at -150 and the under at +130, the implied chances are 150 / 250 = 60.00% and 100 / 230 = 43.48%. They sum to 103.48%, so divide each by 1.0348: the fair over is about 57.98%. Against a 57.74% break-even, that's an edge of about 0.24 points, which is small enough that a stale price on either side wipes it out. A real edge still loses most entries, so size any stake from money you can afford to lose.
How ZippyOddsAPI handles pick'em lines
ZippyOddsAPI is independent and not affiliated with PrizePicks. Pick'em lines show up in the /v1/dfs endpoint, and a line is scored against sharp books only when it comes from the app's own feed. PrizePicks lines are currently read from a public publisher's copy, so they are labelled raw-only: each row comes back with no fair chance and says why. The book id prizepicks appears in the documented example, but a book in an example isn't a promise that it's feeding: the coverage page shows what is live now.
curl -s "https://zippyoddsapi.com/v1/dfs?league=nba&books=prizepicks" \
-H "Authorization: Bearer $ZIPPYODDS_KEY"
Each row is one side of one full-game line. The fields that matter most:
| Field | What it holds |
|---|---|
line, side, variant | The line, over or under, and the app's line type |
fairProbability | The fair chance from sharp books, or null |
threshold | The chance this pick needs to break even, or null if unknown |
edge | Fair chance minus threshold, as a fraction |
basis | Where the threshold came from: power_table, per_pick_multiplier or none |
reason | Why there's no fair chance: no_sharp_books, low_confidence or books_disagree, or for a raw-only app, the app's own reason in words |
observedAt | When the line was read, in epoch milliseconds |
Three details save debugging time. /v1/dfs uses camelCase names and fractions, unlike /v1/ev, which uses snake_case and percents. observedAt is a number, not an ISO string. And a row with an edge too large to believe comes back with plausible: false, sorted after believable ones, so filter on it before you show anything.
The method behind fairProbability (which books, how they're weighted, and how lines are interpolated when no sharp book has the exact number) is set out in the ZippyOddsAPI docs, along with the payout tables used and how keys are issued.
Before you build on any source
Whatever you end up reading pick'em lines from, decide these early:
- Can you show the data to other people, or only use it yourself? That's a terms question for the source.
- How old can a line be before you stop scoring it? A line that moved five minutes ago is a different bet.
- What happens when names don't match? Dropping the row is safer than guessing.
Underdog raises the same questions with a different payout structure, covered in our guide to Underdog Fantasy API options. For the sportsbook side of the comparison, see what a DraftKings API search turns up and the wider guide to choosing a sportsbook API. ZippyOddsAPI returns sportsbook and pick'em prices in the same schema, which is what makes that comparison a join rather than a project.