# Sports Betting Odds Scraper - Spreads, Totals, Moneylines & ATS (`datawright/sports-betting-odds-scraper`) Actor

Spreads, totals and moneylines (opening vs current) for NFL, NBA, NHL, MLB, college and 15 soccer leagues, plus closing lines with ATS and over/under results and graded NFL player props. Flat rows for betting models and line tracking.

- **URL**: https://apify.com/datawright/sports-betting-odds-scraper.md
- **Developed by:** [Datawright](https://apify.com/datawright) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 row of data

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

## Sports Betting Odds Scraper - Spreads, Totals, Moneylines, Line Movement & ATS Results

Betting lines for **23 leagues** - NFL, NBA, NHL, MLB, WNBA, college football and basketball and 15 soccer competitions: **opening and current spread, total and moneyline** (plus the draw in soccer) for upcoming games, and **closing lines graded against the final score** - did the favourite cover (**ATS**), did the game go **over or under**. NFL player props from DraftKings, graded over/under, are included too.

**Leagues:** NBA, WNBA, NCAA Men's Basketball, NCAA Women's Basketball, NFL, College Football, NHL, MLB, Premier League, EFL Championship, LaLiga, Serie A, Bundesliga, Ligue 1, Eredivisie, Primeira Liga, Scottish Premiership, UEFA Champions League, UEFA Europa League, MLS, Liga MX, Brasileirao, A-League Men.

Built for **betting models, line-movement tracking, ATS research and odds dashboards**, spreadsheets and AI agents. No API key, no browser, no login - fast and cheap.

### What you get

| Data type | One row per | Highlights |
|---|---|---|
| **Team game logs** | team per game | Team stats, spread, moneyline (+ draw), total, **ATS result**, **O/U result** |
| **Player props** | prop line | DraftKings prop line (opening + current + movement), the actual stat and **over/under/hit/miss** result |
| **Schedule & scores** | game | Status, score, venue, TV, records, **opening vs current spread/total/moneyline** |

Every row is flat (no nested JSON), so it drops straight into Excel, Google Sheets, pandas or a database.

### Player props: lines *and* results

Most prop tools only give you today's lines. This one also grades them: for every finished game you get the DraftKings line (opening and closing), the player's actual stat, the margin and the result (**over / under / push**, or **hit / miss** for milestones and TD scorers, double-doubles, goalscorer props, cards). Pull a season to get prop **hit rates** per player, per market or per matchup - and pull upcoming games to get this week's lines.

```json
{
  "league": "nfl",
  "dataType": "playerProps",
  "season": "2026",
  "players": [
    "Josh Allen"
  ]
}
```

### How to use

1. Pick a **league**, then **what data** you want.
2. Choose a **season** (e.g. `2026`) or a **date range** - or leave both empty for the most recent games.
3. Optionally filter by **teams** and **players**.
4. Run, then download as JSON, CSV or Excel, or pull it via the API.

#### Examples

This week's NFL lines (opening vs current):

```json
{
  "league": "nfl",
  "dataType": "games",
  "daysAhead": 7
}
```

A full NBA season of closing lines with ATS and over/under results per team:

```json
{
  "league": "nba",
  "dataType": "teamGameLogs",
  "season": "2025-26"
}
```

Premier League match odds incl. the draw:

```json
{
  "league": "epl",
  "dataType": "games",
  "daysAhead": 7
}
```

Track line movement - schedule this every few hours and compare opening vs current:

```json
{
  "league": "nfl",
  "dataType": "games",
  "daysAhead": 3
}
```

### Sample output (game with betting lines)

```json
{
  "league": "NFL",
  "season": "2026",
  "seasonType": "regular",
  "week": 4,
  "gameId": "401872965",
  "gameDate": "2026-10-04T13:30Z",
  "gameDateET": "2026-10-04",
  "name": "Indianapolis Colts at Washington Commanders",
  "status": "STATUS_SCHEDULED",
  "statusDetail": "10/4 - 9:30 AM EDT",
  "completed": false,
  "homeTeamId": "28",
  "homeTeam": "WSH",
  "homeTeamName": "Washington Commanders",
  "homeScore": 0,
  "homeRecord": "1-2",
  "awayTeamId": "11",
  "awayTeam": "IND",
  "awayTeamName": "Indianapolis Colts",
  "awayScore": 0,
  "awayRecord": "1-2",
  "winner": null,
  "venue": "Tottenham Hotspur Stadium",
  "city": "London",
  "neutralSite": true,
  "attendance": 0,
  "broadcasts": "NFL Net",
  "oddsProvider": "Draft Kings",
  "oddsDetails": "IND -3",
  "homeSpread": 3,
  "homeSpreadOpen": -1.5,
  "total": 47.5,
  "totalOpen": 48.5,
  "homeMoneyline": 136,
  "awayMoneyline": -162,
  "drawMoneyline": null,
  "homeMoneylineOpen": -110,
  "awayMoneylineOpen": -110
}
```

### Pricing

Pay only for rows you get - see the **Pricing** tab. Player-prop rows are priced lower because each game has hundreds of them. Use *Max rows* or the run's maximum cost to cap spending, and *Only new games* on schedules so you never pay twice for the same game.

### Automate it

- **Schedule** a daily run (Schedules → Create) with *Only new games* enabled to keep a database or spreadsheet current.
- Connect to **Google Sheets, Zapier, Make, n8n** or webhooks from the Integrations tab.
- Call it from code with the Apify API or from AI agents via the Apify MCP server.

### FAQ

**How fresh is the data?** Box scores are available minutes after a game ends; schedules and lines are fetched live on every run.

**Which betting lines are included?** The primary sportsbook line published on ESPN (usually DraftKings): closing spread, moneyline (plus the draw for soccer) and total on game logs, and opening vs current lines on the schedule.

**What if there are no games right now?** With no dates set, the actor returns the most recent game day (or, for schedules, the next one) instead of an empty result.

**Can I get historical seasons?** Yes - set *Season* to any past season ESPN has box scores for. Soccer seasons are written like "2025-26" (MLS and Brasileirao use a single year).

### Disclaimer

This actor is not affiliated with, endorsed by or connected to ESPN, DraftKings or any league. It collects publicly available factual sports statistics. It only reads publicly accessible data and grants you no rights in it: you are responsible for making sure your use complies with the data source's terms of use and applicable laws (including copyright, database and privacy laws).

# Actor input Schema

## `league` (type: `string`):

Which league or competition to pull.

## `dataType` (type: `string`):

Player game logs = one row per player per game (box-score line). Team game logs include the closing line with ATS and over/under results. Player props = sportsbook prop lines (opening + current) graded against what actually happened.

## `season` (type: `string`):

Whole-season pull, e.g. "2026". Leave empty and set dates instead (or neither for the most recent games).

## `dateFrom` (type: `string`):

YYYY-MM-DD (US Eastern game date). Overrides season.

## `dateTo` (type: `string`):

YYYY-MM-DD, inclusive. Defaults to today.

## `daysBack` (type: `integer`):

Used when no season or dates are given: finished games from the last N days (falls back to the most recent game day if there were none).

## `daysAhead` (type: `integer`):

For schedules and player props: how many upcoming days to include.

## `seasonTypes` (type: `array`):

Which parts of the season to include (ignored for soccer).

## `teams` (type: `array`):

Team abbreviations to keep, e.g. KC, LAL. Empty = all teams.

## `players` (type: `array`):

Player names (partial match) or ESPN player IDs, e.g. Josh Allen. Empty = all players.

## `propMarkets` (type: `string`):

Which player prop markets to include. Milestones and TD scorers, double-doubles, goalscorer props, cards are graded hit/miss; period props are listed but not graded.

## `includeOdds` (type: `boolean`):

Adds the closing spread, moneyline (and draw for soccer) and total to game-log rows.

## `onlyNewGames` (type: `boolean`):

Skip games this account already received from a previous run - ideal for a daily schedule so you only pay for new rows.

## `stateStoreName` (type: `string`):

Named key-value store used by "Only new games". Use different names for independent schedules.

## `maxItems` (type: `integer`):

Stop after this many rows (0 = no limit). Pre-set to 200 so a first try stays cheap - raise it or set 0 for full pulls.

## `maxConcurrency` (type: `integer`):

Parallel requests.

## Actor input object example

```json
{
  "league": "nfl",
  "dataType": "games",
  "daysBack": 3,
  "daysAhead": 7,
  "seasonTypes": [
    "regular",
    "playin",
    "postseason"
  ],
  "propMarkets": "main",
  "includeOdds": true,
  "onlyNewGames": false,
  "maxItems": 200,
  "maxConcurrency": 6
}
```

# 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 = {
    "league": "nfl",
    "dataType": "games",
    "maxItems": 200
};

// Run the Actor and wait for it to finish
const run = await client.actor("datawright/sports-betting-odds-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 = {
    "league": "nfl",
    "dataType": "games",
    "maxItems": 200,
}

# Run the Actor and wait for it to finish
run = client.actor("datawright/sports-betting-odds-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 '{
  "league": "nfl",
  "dataType": "games",
  "maxItems": 200
}' |
apify call datawright/sports-betting-odds-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datawright/sports-betting-odds-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/3appKJoSf1URdXtzB/builds/LCzlgG7dVDZ6Zeco4/openapi.json
