# PrizePicks & Sleeper Props API: Goblins, Demons, Line Moves (`epicscrapers/prizepicks-props-scraper`) Actor

Feed your pick'em bot, optimizer or model: every PrizePicks and Sleeper Picks player prop in one schema. Goblin and demon ladders, payout multipliers, pick counts, last-10 hit rates. Line IDs survive line moves, so scheduled runs build your line history. API, webhooks or Sheets. No login.

- **URL**: https://apify.com/epicscrapers/prizepicks-props-scraper.md
- **Developed by:** [Epic Scrapers](https://apify.com/epicscrapers) (community)
- **Categories:** Developer tools, Automation, Integrations
- **Stats:** 3 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / 1,000 prop line saveds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### PrizePicks & Sleeper Props API: the data feed behind your pick'em tool

Building a Discord bot, a prop optimizer, a picks newsletter or your own model? This Actor gives you the data
layer: every **PrizePicks** player prop (standard, **goblin and demon ladders**, promos) and every **Sleeper
Picks** line (over/under **payout multipliers**, pick counts, **last-10 results and hit rate**) as clean JSON,
in one schema, with IDs that survive line moves.

You don't have to deal with DataDome, US-only geo-blocking, residential proxies, JSON:API joins or Sleeper's ID
lookups. Call it from your code, schedule it every morning or every hour, and read the dataset. No PrizePicks or
Sleeper account needed.

![PrizePicks and Sleeper player props as an API: 20,050 lines from every league in 47 seconds, with goblin, standard and demon lines, payout multipliers and hit rates](https://api.apify.com/v2/key-value-stores/WjOh8lICHONsBs2Ui/records/hero.png)

#### Built for people who ship prop tools

- **Discord and Telegram bots:** post the day's goblins, the biggest line moves or free squares as soon as they appear.
- **Pick'em optimizers and +EV finders:** full goblin/demon ladders grouped by `marketKey`, next to Sleeper multipliers for the same player and stat.
- **Models and dashboards:** a timestamped snapshot every run (`scrapedAt`) and a stable `projectionId`, so your database gets a line history neither app publishes.
- **Picks newsletters and sheets:** send each run to Google Sheets, Airtable or a webhook with no code.

### Why this feed

| What you'd build yourself                                                          | What you get here                                                                               |
| ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| PrizePicks blocks non-US IPs and datacenters, and its app API sits behind DataDome | US residential proxy included in the price. Runs from anywhere.                                 |
| JSON:API with players, games, teams and stats in separate lists                    | One flat row per line: player, team, opponent, stat, line, line type, game time.                |
| Sleeper lines only have IDs                                                        | Names, teams, opponents and game times joined in from Sleeper's player and score endpoints.     |
| Two apps, two naming schemes                                                       | One schema, the same league names (NFL, NBA, MLB, NHL, CFB, UCL, CS2…) for both sources.        |
| Line IDs you have to reverse-engineer                                              | `projectionId` stays the same when the line moves; `marketKey` groups a goblin/demon ladder.    |
| Hit rates you compute from box scores                                              | `recentResults`, `recentAverage` and `recentHitRate` against today's line on every Sleeper row. |

### Use it as an API

#### Copy to your AI assistant

Paste this into ChatGPT, Claude, Cursor or any coding assistant to start building on the feed:

```
epicscrapers/prizepicks-props-scraper on Apify: PrizePicks and Sleeper Picks player props in one schema.
Call: ApifyClient("TOKEN").actor("epicscrapers/prizepicks-props-scraper").call(run_input={...}), then read
client.dataset(run["defaultDatasetId"]).iterate_items(). Inputs: sources (["prizepicks","sleeper"]),
leagues (string[], PrizePicks names: NFL, NBA, MLB, NHL, CFB, WNBA, TENNIS, SOCCER, UCL, CS2...; empty = all),
includePeriodBoards (bool), maxResultsPerLeague (int, 0 = full board, default 500), playerNames (string[],
substring, accent-insensitive), statTypes (string[], exact statType or Sleeper statKey), lineTypes
(["standard","goblin","demon"]). One row per line: source, league, playerName, team, opponent, statType,
lineScore, lineType, overMultiplier, underMultiplier, pickCountOver, pickCountUnder, recentResults,
recentHitRate, isPromo, flashSaleLineScore, gameStartTime, status, projectionId (stable across line moves),
marketKey (groups a goblin/demon ladder), scrapedAt (same for the whole run). Fields one app lacks are null.
Pricing: $0.03 per run + $0.05 per 1,000 lines. Token: https://console.apify.com/account/integrations
```

#### Call it from code

Run the Actor and get the rows in one HTTP call (good for boards up to a few thousand lines):

```bash
curl -X POST "https://api.apify.com/v2/acts/epicscrapers~prizepicks-props-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"sources": ["prizepicks", "sleeper"], "leagues": ["NBA"], "maxResultsPerLeague": 0}'
```

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("epicscrapers/prizepicks-props-scraper").call(run_input={
    "leagues": ["NFL", "NHL"],
    "lineTypes": ["goblin"],
    "maxResultsPerLeague": 0,
})
for line in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(line["playerName"], line["statType"], line["lineScore"], line["lineType"])
```

JavaScript:

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_TOKEN>' });
const run = await client
    .actor('epicscrapers/prizepicks-props-scraper')
    .call({ leagues: ['NBA', 'NFL'], maxResultsPerLeague: 0 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### Recipes

#### Track line moves

Schedule the Actor (every morning, or hourly on game days) and store each run. Every row has `scrapedAt` (the
same for the whole run) and a `projectionId` that **stays the same when the line moves**. Join two runs on
`projectionId` and compare `lineScore`. A `projectionId` that disappears was pulled from the board.

![29 lines moved in 14 minutes between two full-board runs, for example Dak Prescott Pass+Rush Yds demon 424.5 to 399.5, matched on projectionId](https://api.apify.com/v2/key-value-stores/WjOh8lICHONsBs2Ui/records/line-moves.png)

#### Rebuild goblin and demon ladders

Goblins and demons come in ladders: the same player, stat and game at several lines. Group by `marketKey` and
sort by `lineScore` to get each ladder with its standard line.

![Sam Darnold Pass Yards ladder on PrizePicks: four goblins from 159.5 to 210.5, the standard line at 218.5 and four demons from 224.5 to 360.5, all with one marketKey](https://api.apify.com/v2/key-value-stores/WjOh8lICHONsBs2Ui/records/ladder.png)

#### Compare PrizePicks with Sleeper

Both sources share one schema and the same league names. Match on `league`, `playerName` and `statType` to see
where the two apps disagree. The apps name some stats differently (PrizePicks `Pass Yards`, Sleeper
`Passing Yards`), so map those in your code.

![NFL lines where PrizePicks and Sleeper disagree, with Sleeper's over and under multipliers and the share of recent games over the Sleeper line](https://api.apify.com/v2/key-value-stores/WjOh8lICHONsBs2Ui/records/compare.png)

#### Flag hit-rate outliers

Every Sleeper row has `recentResults` (last ≤10 games for that stat), `recentAverage` and `recentHitRate`
(share of those games strictly over today's line). Filter to `recentHitRate` ≥ 0.7 or ≤ 0.3 and show them
with `overMultiplier`, `underMultiplier` and the pick counts. The **Hit rates (Sleeper)** view in the Output tab
does this in the Console.

#### Post free squares and flash sales

PrizePicks promo rows have `isPromo: true`, `flashSaleLineScore` (the discounted line), `discountName` (for
example `free_square`) and `discountPercentage`. Filter on `isPromo` and post them to your channel.

### Schedule it and connect the output

![Schedule, then this Actor, then the dataset and a webhook, then your Discord bot, optimizer, model or newsletter](https://api.apify.com/v2/key-value-stores/WjOh8lICHONsBs2Ui/records/flow.png)

1. Save your input as a **task** (Save as new task at the top of the input page).
2. Open the task, then **Schedule**: for example 9:00 every day, or every hour on game days.
3. Connect the output: a **webhook** to your bot or backend on `ACTOR.RUN.SUCCEEDED`, the **Google Sheets**
   integration, Zapier, Make, or read the dataset with the API.

| Cadence                | Good for                                                   |
| ---------------------- | ---------------------------------------------------------- |
| Once or twice a day    | Picks newsletters, daily sheets, model training data       |
| Every 1 to 4 hours     | Line comparison tools, line history databases              |
| Every 10 to 15 minutes | Discord alerts for line moves and new promos (use filters) |

### Input

| Field                                       | What it does                                                                                                                                                                                                                                          |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Sources**                                 | PrizePicks, Sleeper Picks, or both (default).                                                                                                                                                                                                         |
| **Leagues**                                 | League names as PrizePicks uses them: NFL, NBA, MLB, NHL, WNBA, CFB, CBB, TENNIS, SOCCER, UCL, UFC, PGA, CS2, LoL, VAL and more. Not case-sensitive. Empty = every league with a board right now. `SOCCER` also selects all of Sleeper's club soccer. |
| **Include half, quarter and period boards** | Adds PrizePicks' NFL1H, NFL1Q, NHL1P and similar boards for the leagues you picked.                                                                                                                                                                   |
| **Max results per league**                  | Lines saved per league and per source. Default 500 (a cheap first run); **set 0 for the full board**, which is what a feed usually needs. A full NFL board on PrizePicks is about 2,500 lines, most of them goblin and demon ladders.                 |
| **Player names**                            | Part of a name, any case, accents ignored: `ramirez` finds José Ramírez.                                                                                                                                                                              |
| **Stat types**                              | Exact stat as the output shows it (`Points`, `Pass Yards`, `Shots On Goal`) or Sleeper's `statKey` (`passing_yards`).                                                                                                                                 |
| **Line types**                              | Standard, Goblin, Demon. Sleeper lines are all standard.                                                                                                                                                                                              |

Example inputs:

```json
{ "sources": ["prizepicks", "sleeper"], "leagues": ["NBA", "NFL"], "maxResultsPerLeague": 0 }
```

```json
{
    "sources": ["prizepicks"],
    "leagues": ["NFL"],
    "playerNames": ["josh allen", "puka nacua"],
    "lineTypes": ["goblin", "demon"]
}
```

```json
{ "leagues": ["NFL", "NHL"], "includePeriodBoards": true, "maxResultsPerLeague": 0 }
```

### Output

One row per line. Real example from a PrizePicks NBA board (a promo line):

```json
{
    "source": "prizepicks",
    "league": "NBA",
    "playerName": "Anthony Edwards",
    "team": "MIN",
    "teamName": "Timberwolves",
    "opponent": "MIA",
    "position": "G",
    "statType": "Points",
    "lineScore": 27.5,
    "lineType": "standard",
    "flashSaleLineScore": 0.5,
    "isPromo": true,
    "discountName": "free_square",
    "discountPercentage": 98,
    "status": "pre_game",
    "gameStartTime": "2026-10-21T23:40:00.000Z",
    "updatedAt": "2026-10-08T18:05:51.382Z",
    "homeTeam": "MIA",
    "awayTeam": "MIN",
    "period": "Full",
    "trendingCount": 70627,
    "projectionId": "15575749",
    "marketKey": "prizepicks:188017:19:11:NBA_game_ZHHvKkKdvBJF6u8gKONUoWLw",
    "playerImageUrl": "https://static.prizepicks.com/images/players/NBA/Anthony_Edwards_NBA_player_rhlEP3GCAg5LDJD8uChjFU81.webp",
    "scrapedAt": "2026-10-12T22:24:46.985Z"
}
```

And a Sleeper line with multipliers and hit rate:

```json
{
    "source": "sleeper",
    "league": "NHL",
    "playerName": "Shea Theodore",
    "team": "VGK",
    "opponent": "MIN",
    "statType": "Assists",
    "lineScore": 0.5,
    "lineType": "standard",
    "overMultiplier": 2.7,
    "underMultiplier": 1.29,
    "recentAverage": 0.33,
    "recentHitRate": 0.17,
    "gameStartTime": "2026-10-13T00:00:00.000Z",
    "projectionId": "20261012_MIN_VGK:assists_over_under_player_1031"
}
```

| Field                                                                 | Description                                                                  |
| --------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `source`                                                              | `prizepicks` or `sleeper`                                                    |
| `league`                                                              | NFL, NBA, NFL1H, UCL, CS2…                                                   |
| `playerName`, `team`, `teamName`, `position`, `jerseyNumber`          | The player (or both players for combos, `isCombo: true`)                     |
| `opponent`, `homeTeam`, `awayTeam`                                    | The matchup. Empty for combos and season-long props                          |
| `statType`, `statKey`                                                 | Stat as shown in the app, and the app's stat ID or key                       |
| `lineScore`                                                           | The line                                                                     |
| `lineType`                                                            | `standard`, `goblin` or `demon`                                              |
| `overMultiplier`, `underMultiplier`                                   | Sleeper payouts for each side                                                |
| `allowedPicks`                                                        | `over` or `under_or_over` (some PrizePicks lines are more-only)              |
| `flashSaleLineScore`, `isPromo`, `discountName`, `discountPercentage` | PrizePicks promos                                                            |
| `status`                                                              | `pre_game` or `in_progress` (live lines)                                     |
| `gameStartTime`, `boardTime`, `updatedAt`                             | Game start, when the line was posted, when it last changed (UTC)             |
| `period`                                                              | `Full`, or the half, quarter or period of a period board                     |
| `trendingCount`                                                       | PrizePicks pick popularity                                                   |
| `pickCountOver`, `pickCountUnder`, `pickCountTotal`                   | Sleeper picks on each side                                                   |
| `recentResults`, `recentGames`, `recentAverage`, `recentHitRate`      | Sleeper: last results for the stat and the share over today's line           |
| `projectionId`                                                        | Line ID, unchanged when the line moves. Use it to compare runs               |
| `marketKey`                                                           | Same for every rung of a goblin or demon ladder (player, stat, period, game) |
| `playerId`, `gameId`                                                  | The app's player and game IDs                                                |
| `playerImageUrl`                                                      | Headshot (Sleeper: NFL, NBA, NHL, MLB)                                       |
| `scrapedAt`                                                           | When the run started. The same on every row of a run                         |

### Pricing

**$0.03 per run plus $0.05 per 1,000 lines saved**, on every plan. Platform usage and the US residential proxy
PrizePicks needs are included. The run fee is charged per GB of memory; the default 1 GB is plenty.

What real runs cost (Tuesday morning, October 13, 2026, full boards):

| Run                                                                | Lines  | Cost  |
| ------------------------------------------------------------------ | ------ | ----- |
| One player or stat filter (a typical bot poll)                     | <100   | $0.03 |
| NBA, both apps                                                     | ~250   | $0.04 |
| NFL, NBA, MLB and NHL, both apps                                   | ~6,800 | $0.37 |
| Every league on both apps (including 7,800 Champions League lines) | 19,834 | $1.02 |

Monthly cost of common schedules:

| Schedule                                      | Runs / month | Cost  |
| --------------------------------------------- | ------------ | ----- |
| NFL, NBA, MLB and NHL, both apps, once a day  | 30           | ~$11  |
| NBA, both apps, every hour                    | 720          | ~$31  |
| A filtered poll (a few players), every 15 min | 2,880        | ~$90  |
| NFL, NBA, MLB and NHL, both apps, every hour  | 720          | ~$270 |

About two thirds of PrizePicks lines are demons. If your tool doesn't need them, `lineTypes: ["standard",
"goblin"]` cuts the line cost by more than half. For hourly runs, pick only the leagues you need, and set a
spending limit on the task: the Actor reads it at start and stops fetching when it's reached.

### FAQ

**Is there an official PrizePicks API?**
No public one. This Actor reads the same JSON the PrizePicks board loads and gives it to you as an API.

**How fresh is the data?**
Each run fetches the live boards. A run of every league takes about a minute; a single league takes a few
seconds. Schedule it as often as your tool needs.

**Can I get historical lines?**
Neither app publishes past boards. Schedule the Actor and keep the datasets (or push them to your database);
`scrapedAt` and `projectionId` turn them into a line history.

**Do I need a PrizePicks or Sleeper account, or a VPN?**
No. PrizePicks only answers US connections, so the Actor uses US residential IPs for it. You can run it from
anywhere.

**Why are some fields empty?**
Each app returns different data. Multipliers, pick counts and hit rates are Sleeper only; promos, ladders and
trending counts are PrizePicks only. Combos have no single opponent.

**Why did a league return nothing?**
The board is empty when a league has no games soon (for example NBA in the off-season). The log lists leagues
with no board.

**Underdog, Chalkboard or sportsbooks?**
Not yet. Tell us in the Issues tab which one your tool needs.

**Is it legal?**
The Actor collects public line data shown to any visitor of the apps, without logging in. Check the apps' terms
and your local laws on betting before you use or republish the data.

# Actor input Schema

## `sources` (type: `array`):

Pick'em apps to scrape. PrizePicks: standard, goblin and demon lines. Sleeper: Sleeper Picks lines with over and under payout multipliers and pick counts.

## `leagues` (type: `array`):

Leagues as PrizePicks names them, for example NFL, NBA, MLB, NHL, WNBA, CFB, CBB, TENNIS, SOCCER, UCL, UFC, PGA, CS2, LoL. Not case-sensitive. Leave empty for every league that has a board right now.

## `includePeriodBoards` (type: `boolean`):

PrizePicks lists 1st half, 1st quarter and 1st period lines as separate boards (NFL1H, NFL1Q, NHL1P and so on). Turn on to add them for the leagues you picked. You can also type a board such as NFL1H under Leagues.

## `maxResultsPerLeague` (type: `integer`):

Maximum lines saved per league from each source. Set to 0 for the full board. A full NFL board on PrizePicks is about 2,500 lines (most of them goblin and demon ladders); NBA, MLB and NHL boards are usually 200 to 1,700.

## `playerNames` (type: `array`):

Keep only lines for these players. Matches any part of the name and ignores case, so "mahomes" finds Patrick Mahomes. Leave empty for all players.

## `statTypes` (type: `array`):

Keep only these stats, written as the output's statType shows them (for example Points, Rebounds, Pass Yards, Shots On Goal) or as Sleeper's statKey (for example passing_yards). Not case-sensitive. PrizePicks and Sleeper name some stats differently. Leave empty for all stats.

## `lineTypes` (type: `array`):

Standard: the normal line. Goblin: an easier line with a lower payout. Demon: a harder line with a higher payout. Goblins and demons are PrizePicks only; Sleeper lines are standard. Leave empty for all.

## Actor input object example

```json
{
  "sources": [
    "prizepicks",
    "sleeper"
  ],
  "leagues": [
    "NFL",
    "NBA",
    "MLB",
    "NHL"
  ],
  "includePeriodBoards": false,
  "maxResultsPerLeague": 500
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "leagues": [
        "NFL",
        "NBA",
        "MLB",
        "NHL"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("epicscrapers/prizepicks-props-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "leagues": [
        "NFL",
        "NBA",
        "MLB",
        "NHL",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("epicscrapers/prizepicks-props-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "leagues": [
    "NFL",
    "NBA",
    "MLB",
    "NHL"
  ]
}' |
apify call epicscrapers/prizepicks-props-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,epicscrapers/prizepicks-props-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/rzhfCgweE5Zvgty1O/builds/DFAmcF1OgnvcWQHCt/openapi.json
