# Sportsbook Odds Comparison: Pinnacle, FanDuel and DraftKings (`mrdoe/us-sportsbook-odds-comparison`) Actor

Live comparison of Pinnacle, FanDuel and DraftKings: for every match and market see each book's price, the best price and who offers it, the average, each book's margin and whether the best prices create an arbitrage. Fetches fresh odds automatically - no manual setup.

- **URL**: https://apify.com/mrdoe/us-sportsbook-odds-comparison.md
- **Developed by:** [MrDoe](https://apify.com/mrdoe) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

![US Sportsbook Odds Comparison: Best Price per Match - Click Start and get Pinnacle, FanDuel and DraftKings compared live - best price, average, margin and arbitrage, no setup required.](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/us-sportsbook-odds-comparison--hero.png)

### What does US Sportsbook Odds Comparison: Best Price per Match do?

US Sportsbook Odds Comparison runs this account's own Pinnacle, FanDuel and DraftKings Actors live, matches the same game across all three even when team names differ slightly, then for each market and line returns every bookmaker's price, the best price for each outcome and which bookmaker offers it, the average price, each bookmaker's margin, the combined margin of the best prices and a flag when those best prices guarantee a profit. It covers moneyline and total markets, defaulting to NBA.

### Why use US Sportsbook Odds Comparison: Best Price per Match?

- Zero setup: click Start, get a live three-book comparison back.
- Line shopping across Pinnacle, FanDuel and DraftKings in one table.
- Fuzzy team matching across three different data shapes.
- Margin per bookmaker shows who charges the most.
- Arbitrage flag when the best prices genuinely beat the market.

### What makes this different

Odds comparison sites are closed and show only what they choose. This Actor runs the actual bookmaker scrapers live on every call, every time, and hands you the raw per-book comparison as structured data you can filter, store or alert on - not a locked dashboard.

### How it works

![US Sportsbook Odds Comparison: Best Price per Match workflow: your input, collection, output](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/us-sportsbook-odds-comparison--how-it-works.png)

1. **Your input** — press Start with no input - it fetches fresh Pinnacle, FanDuel and DraftKings odds automatically.
2. **The Actor collects it** — it matches the same game across all three books and compares each market.
3. **Your output** — you get one comparison row per match and market, with every book's price.

### What data can you extract?

The dataset has 10 fields per row:

| Field | Type | Description |
|---|---|---|
| `event` | object | Home, away, sport, league and start time. |
| `market` | string | moneyline or total. |
| `line` | number | Total line, null for moneyline. |
| `bookmakers` | number | Bookmakers pricing this market. |
| `best` | object | Best odds and bookmaker per selection. |
| `average` | object | Average odds per selection. |
| `bestPriceMarginPercent` | number | Combined margin of the best prices in percent. |
| `arbitrage` | boolean | True when the best prices guarantee a profit. |
| `books` | array | Each bookmaker's odds, margin and link. |
| `demo` | boolean | True for the built-in sample. |

### How to use US Sportsbook Odds Comparison: Best Price per Match

![US Sportsbook Odds Comparison: Best Price per Match input form](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/us-sportsbook-odds-comparison--input.png)

1. Open the Actor and go to the **Input** tab.
2. Press Start - live fetch is on by default and needs no configuration. To target a different sport, set **Sports to fetch live** (e.g. NFL, MLB, NHL); to use your own saved odds instead, turn off **Fetch live odds now** and add datasets.
3. Optionally set filters and a **Max results** limit.
4. Click **Start**. A default run finishes in under a minute.
5. Open the **Output** tab, then download the dataset or connect it to your tools.

### Input Parameters

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `fetchLiveOdds` | boolean | No | `true` | Runs this repo's own Pinnacle, FanDuel and DraftKings Actors right now and compares their fresh odds, in addition to any datasets below. Each is a separate Actor run on your account, billed and timed as its own run. Turn off to only use the datasets below. |
| `liveBookmakers` | array | No | `[]` | Which of pinnacle, fanduel, draftkings to fetch. Leave empty for all three. |
| `liveSports` | array | No | `[]` | Sport/league to pass to each bookmaker Actor, e.g. NBA, NFL, MLB, NHL. Leave empty for NBA. |
| `liveMaxMatchesPerBook` | integer | No | `20` | Caps how many matches each bookmaker Actor fetches live. |
| `oddsDataset1` | string | No | — | Dataset from a bookmaker odds Actor run (Pinnacle, FanDuel or DraftKings). Add one per bookmaker, on top of or instead of live fetch. Leave all empty to rely on live fetch. |
| `oddsDataset2` | string | No | — | Another dataset of the same kind. |
| `oddsDataset3` | string | No | — | Another dataset of the same kind. |
| `oddsDataset4` | string | No | — | Another dataset of the same kind. |
| `markets` | array | No | `[]` | moneyline and/or total. Leave empty for both. |
| `minBooks` | integer | No | `2` | Only compare markets priced by at least this many bookmakers. |
| `onlyArbitrage` | boolean | No | `false` | Return only markets where the best prices across books guarantee a profit. |
| `maxStartDiffHours` | number | No | `3` | Listings count as the same match when their start times are within this many hours. |
| `maxResults` | integer | No | `5` | Maximum number of comparisons returned. Default is 5 for a quick test; set 0 to return everything available. |

### Output Data

![US Sportsbook Odds Comparison: Best Price per Match dataset table](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/us-sportsbook-odds-comparison--output.png)

`best` gives the highest price and bookmaker for each selection; `average` is the mean price. `bestPriceMarginPercent` is the combined margin of the best prices: below zero means an arbitrage, flagged in `arbitrage`. `books` lists every bookmaker's price and margin.

![US Sportsbook Odds Comparison: Best Price per Match field map of one record](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/us-sportsbook-odds-comparison--fields.png)

A real dataset item:

```json
{
  "event": {
    "home": "Atlanta Hawks",
    "away": "Cleveland Cavaliers",
    "sport": "Basketball",
    "league": "NBA",
    "startTime": "2026-10-30T00:10:00.000Z"
  },
  "market": "moneyline",
  "line": null,
  "bookmakers": 3,
  "best": {
    "home": {
      "bookmaker": "FanDuel",
      "odds": 1.926
    },
    "away": {
      "bookmaker": "Pinnacle",
      "odds": 1.98
    }
  },
  "average": {
    "home": 1.912,
    "away": 1.935
  },
  "bestPriceMarginPercent": 2.43,
  "arbitrage": false,
  "books": [
    {
      "bookmaker": "FanDuel",
      "odds": {
        "home": 1.926,
        "away": 1.926
      },
      "marginPercent": 3.84,
      "url": "https://sportsbook.fanduel.com/basketball/cleveland-cavaliers-atlanta-hawks-36245923"
    },
    {
      "bookmaker": "DraftKings",
      "odds": {
        "home": 1.9,
        "away": 1.9
      },
      "marginPercent": 5.26,
      "url": "https://sportsbook.draftkings.com/event/cle-cavaliers-atl-hawks/34910285"
    },
    {
      "bookmaker": "Pinnacle",
      "odds": {
        "home": 1.909,
        "away": 1.98
      },
      "marginPercent": 2.89,
      "url": "https://www.pinnacle.com/en/basketball/nba/atlanta-hawks-vs-cleveland-cavaliers/1639313823/"
    }
  ],
  "demo": false
}
```

### Usage Examples

#### Default live NBA comparison

```json
{
  "maxResults": 0
}
```

#### Live NFL comparison

```json
{
  "liveSports": [
    "NFL"
  ],
  "maxResults": 0
}
```

#### Arbitrage only

```json
{
  "onlyArbitrage": true,
  "maxResults": 0
}
```

### Tips for Best Results

- Default is 5 results for a fast test. Set the max to 0 to return everything available.

### Known Limitations

- Comparison is only as fresh as the moment the live fetch runs; prices move within minutes.
- Only moneyline and total markets are compared.
- Pinnacle and FanDuel filter by sport, not league; sports outside the built-in NBA preset may need a higher 'Max matches per bookmaker' to find overlap, which adds a modest extra cost.
- Team matching is fuzzy; unusual name differences can leave a match unpaired.
- Each live-fetch run also triggers three separate, separately-billed sub-Actor runs on your own account.

### Integrations

Run it from the Apify API, on a schedule, or from a webhook. Send results straight to Google Sheets, Make, Zapier, Slack or your own database with Apify's built-in integrations.

### Export Formats

Download the dataset as JSON, CSV, Excel, XML, HTML table or RSS from the **Output** tab or the API.

### Frequently Asked Questions

#### Does it need an account or API key?

No. Live fetch needs no account or API key for any of the three books.

#### Am I charged for failed results?

No. You are only charged for results that are written to the dataset.

#### Do I need an account or login?

No. Live fetch needs no account or API key for any of the three books.

#### Am I charged for failed runs or empty results?

You are only charged for results that are actually written to the dataset.

#### Can I run it on a schedule?

Yes. Create a Task with your input and add a schedule in Apify Console. With monitor mode on, each scheduled run returns only what changed since the previous one.

### Support

Questions or a missing field? Open an issue from the **Issues** tab on this Actor's page and it will be looked at.

### Legal / Responsible Use

You are responsible for how you use these results, including compliance with bookmaker terms and the gambling laws that apply to you. This Actor is analysis only and does not place bets. Gambling is age-restricted; if you or someone you know has a problem, seek support such as BeGambleAware or 1-800-GAMBLER.

# Actor input Schema

## `fetchLiveOdds` (type: `boolean`):

Runs this repo's own Pinnacle, FanDuel and DraftKings Actors right now and compares their fresh odds, in addition to any datasets below. Each is a separate Actor run on your account, billed and timed as its own run. Turn off to only use the datasets below.

## `liveBookmakers` (type: `array`):

Which of pinnacle, fanduel, draftkings to fetch. Leave empty for all three.

## `liveSports` (type: `array`):

Sport/league to pass to each bookmaker Actor, e.g. NBA, NFL, MLB, NHL. Leave empty for NBA.

## `liveMaxMatchesPerBook` (type: `integer`):

Caps how many matches each bookmaker Actor fetches live.

## `oddsDataset1` (type: `string`):

Dataset from a bookmaker odds Actor run (Pinnacle, FanDuel or DraftKings). Add one per bookmaker, on top of or instead of live fetch. Leave all empty to rely on live fetch.

## `oddsDataset2` (type: `string`):

Another dataset of the same kind.

## `oddsDataset3` (type: `string`):

Another dataset of the same kind.

## `oddsDataset4` (type: `string`):

Another dataset of the same kind.

## `markets` (type: `array`):

moneyline and/or total. Leave empty for both.

## `minBooks` (type: `integer`):

Only compare markets priced by at least this many bookmakers.

## `onlyArbitrage` (type: `boolean`):

Return only markets where the best prices across books guarantee a profit.

## `maxStartDiffHours` (type: `number`):

Listings count as the same match when their start times are within this many hours.

## `maxResults` (type: `integer`):

Maximum number of comparisons returned. Default is 5 for a quick test; set 0 to return everything available.

## Actor input object example

```json
{
  "fetchLiveOdds": true,
  "liveBookmakers": [],
  "liveSports": [],
  "liveMaxMatchesPerBook": 20,
  "markets": [],
  "minBooks": 2,
  "onlyArbitrage": false,
  "maxStartDiffHours": 3,
  "maxResults": 5
}
```

# 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 = {
    "maxResults": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrdoe/us-sportsbook-odds-comparison").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 = { "maxResults": 5 }

# Run the Actor and wait for it to finish
run = client.actor("mrdoe/us-sportsbook-odds-comparison").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 '{
  "maxResults": 5
}' |
apify call mrdoe/us-sportsbook-odds-comparison --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mrdoe/us-sportsbook-odds-comparison"
        }
    }
}
```

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/qsBoc0f5m9Yi1qZVd/builds/VIL5uoL9mkP1lqiiP/openapi.json
