# Sports Betting Odds History & ATS Results Scraper (`artsiom_k/sports-odds-history-scraper`) Actor

Historical opening and closing odds per sportsbook (spread, moneyline, total) with consensus picks from SportsBookReview, plus 20 seasons of final scores, closing lines and ATS / over-under results from Covers. NFL, NBA, MLB, NHL, WNBA, college football and basketball.

- **URL**: https://apify.com/artsiom_k/sports-odds-history-scraper.md
- **Developed by:** [Artsiom Kunitsyn](https://apify.com/artsiom_k) (community)
- **Categories:** Other, E-commerce
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 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.
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

## Sports Betting Odds History & ATS Results Scraper

Historical sports betting data for backtesting, modeling and research, in two flavors:

- **Odds per sportsbook** from SportsBookReview: the **opening and closing** point spread, moneyline and total at
  BetMGM, bet365, DraftKings, FanDuel, Fanatics, BetRivers, Caesars and Hard Rock Bet, plus consensus pick
  percentages, final scores and venues. NBA, MLB, NHL, WNBA and college basketball go back to **2021**, day by day.
  NFL and college football cover every week of the current season, including lookahead lines.
- **Results with closing lines** from Covers: one row per game with the final score, the **closing spread** (moneylines
  for MLB and NHL), the **closing total**, and **who covered** (ATS) and whether it went **over or under**, for every
  season since **2006-07**. NFL, NBA, MLB, NHL, WNBA, college football and college basketball.

Most odds scrapers only show today's lines. This one is built for history: pick a date range or a range of seasons and
get every game in it.

### What you get

#### `entityType: "odds"` (one row per game and sportsbook)

| Field | Example |
|---|---|
| `game_date`, `start_time`, `league`, `status` | `2025-01-15`, `2025-01-16T00:00:00+00:00`, `nba`, `Final OT` |
| `home_team`, `away_team`, `home_score`, `away_score` | `Philadelphia 76ers`, `New York Knicks`, `119`, `125` |
| `sportsbook`, `sportsbook_name` | `betmgm`, `BetMGM` |
| `spread_home_open` / `_close`, with home and away odds | `6.5` / `5.5`, `-110` |
| `moneyline_home_open` / `_close`, `moneyline_away_open` / `_close` | `+200` / `+170`, `-250` / `-210` |
| `total_open` / `_close`, with over and under odds | `217.5` / `220.5`, `-110` |
| `consensus_spread_home_pct`, `consensus_over_pct` ... | `32.9`, `60.5` |
| `home_starter`, `away_starter` (MLB starting pitchers) | `Sawyer Gipson-Long` |
| `venue`, `city`, `state`, `week` (football), college poll ranks | |

"Close" is the last line before the game finished; for a game that hasn't started it is the current line.
Use **Finished games only** to keep just settled games.

#### `entityType: "results"` (one row per game)

| Field | Example |
|---|---|
| `game_date`, `season`, `season_type`, `week_label` | `2024-02-11`, `2023-2024`, `postseason`, `Super Bowl` |
| `home_team`, `away_team`, `home_score`, `away_score`, `result_note` | `Kansas City Chiefs`, `San Francisco 49ers`, `25`, `22`, `OT` |
| `closing_spread_home` (football, basketball) | `2.5` |
| `closing_moneyline_home`, `closing_moneyline_away` (MLB, NHL) | `-135`, `+118` |
| `closing_total` | `46.5` |
| `ats_result` (home / away / push), `ou_result` (over / under / push) | `home`, `over` |
| `home_starter`, `away_starter` (MLB pitchers, NHL goalies) | `J. Swayman` |
| `neutral_site`, `matchup_url`, team slugs | |

Each game appears once, merged from both teams' records.

### How to use it

- **Last two days of odds, every league** (the default): just run it.
- **A full NBA season of closing lines at every book**: `entityType: "odds"`, leagues `NBA`, `dateFrom: 2024-10-22`,
  `dateTo: 2025-04-13`, clear **Max results**.
- **This NFL season so far**: leagues `NFL`, `weekFrom: 1`.
- **20 years of NFL ATS history**: `entityType: "results"`, leagues `NFL`, `seasonFrom: 2006`, clear **Max results**.
- **One team**: `entityType: "results"`, `teams: ["duke-blue-devils"]` (the Covers team slug from the team's page URL).

Seasons are given by their starting year: `2024` is the 2024-25 NBA, NHL, NFL and college season, and the 2024 MLB and
WNBA season.

### Input

| Field | What it does |
|---|---|
| `entityType` | `odds` (SportsBookReview) or `results` (Covers). |
| `leagues` | Any of NFL, NCAA Football, NBA, NCAA Basketball, MLB, NHL, WNBA. |
| `dateFrom`, `dateTo` | Odds for daily leagues. Empty = yesterday and today. |
| `weekFrom`, `weekTo` | Odds for NFL/college football, current season. Empty = the current week. |
| `sportsbooks` | Odds: only these books. |
| `finalOnly` | Odds: only finished games. |
| `seasonFrom`, `seasonTo` | Results: season range (2006 onward). Empty = the latest season with games. |
| `teams` | Results: only these teams. |
| `maxItems` | Row cap, 50 by default. Clear it for everything. |
| `mode` | Odds: `auto` returns only new and changed rows on repeat runs (with `maxItems` cleared). |
| `concurrency` | Pages fetched in parallel (default 8). |
| `impersonate` | Browser fingerprint (default `chrome`). Change only if requests start failing. |
| `proxyConfiguration` | Off by default; not needed. |

### Good to know

- **Odds history starts in 2021.** SportsBookReview lists older games but without odds. For older seasons use
  `results`, which has the closing spread and total back to 2006.
- **No line movement.** You get the opening and the closing line per book, not every move in between.
- **Football odds are current-season only** on SportsBookReview; football history comes from `results`.
- **Covers' closing lines are its own consensus close**, one number per game, not a specific sportsbook.
- Soccer isn't included: SportsBookReview's soccer pages don't load.
- No proxy needed. Runs are fast: a full season of one league takes seconds to a few minutes.

### FAQ

**How far back does it go?** Odds per sportsbook: about 2021 for NBA, MLB, NHL, WNBA and college basketball. Results
with closing lines: 2006-07 for every league.

**Why are some sportsbooks missing on a game?** A book that didn't price that game has no row.

**Can I run it every day?** Yes. Schedule it with the default input to collect each day's closing lines; with
`maxItems` cleared, `mode: auto` returns only new and changed rows.

### Related sports data scrapers

- [Action Network Scraper](https://apify.com/artsiom_k/actionnetwork-scraper) — current odds from every major US sportsbook, public betting splits, line movement, props, injuries and futures.
- [TennisExplorer Scraper](https://apify.com/artsiom_k/tennisexplorer-scraper) — tennis results, bookmaker odds per match, match statistics and point-by-point.
- [Smarkets Betting Exchange Scraper](https://apify.com/artsiom_k/smarkets-scraper) — betting exchange back and lay odds, matched volume, results and traded-price history.
- [PGA TOUR Scraper](https://apify.com/artsiom_k/pgatour-scraper) — golf results back to the 1950s, hole-by-hole scorecards, FanDuel odds history, tee times and player stats.
- [Kalshi & Polymarket Scraper](https://apify.com/artsiom_k/prediction-markets-scraper) — prediction market odds, settled results and price history for sports, politics, economics and crypto.
- [SofaScore Scraper](https://apify.com/artsiom_k/sofascore-scraper) — results, team statistics, lineups with player ratings, incidents and odds for football, basketball, hockey, tennis and 17 more sports.
- [Flashscore Scraper](https://apify.com/artsiom_k/flashscore-scraper) — results, statistics, lineups, incidents and opening/closing odds from ~20 bookmakers for 17 sports.

# Actor input Schema

## `entityType` (type: `string`):

"odds": one row per game and sportsbook with the opening and closing spread, moneyline and total plus consensus pick percentages. Daily leagues (NBA, college basketball, MLB, NHL, WNBA) go back to about 2021; NFL and college football cover every week of the current season. "results": one row per game with the final score, closing spread (moneylines for MLB/NHL), closing total and who covered, for any season since 2006-07.

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

Leagues to pull. Out-of-season leagues return nothing.

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

odds only, daily leagues: first game date (YYYY-MM-DD). Leave both dates empty for yesterday and today. Odds exist from about 2021.

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

odds only, daily leagues: last game date (YYYY-MM-DD). Defaults to today when only dateFrom is set.

## `weekFrom` (type: `integer`):

odds only: first week of the current NFL/college football season. Leave empty for the current week only. With only this set, the run goes up to the current week.

## `weekTo` (type: `integer`):

odds only: last week of the current season (lookahead lines exist for future weeks).

## `sportsbooks` (type: `array`):

odds only: limit rows to these sportsbooks. Leave empty for all.

## `finalOnly` (type: `boolean`):

odds only: skip games that haven't finished, so every closing line is final.

## `seasonFrom` (type: `integer`):

results only: first season by its starting year (2024 = the 2024-25 season; MLB/WNBA: the 2024 season). Data starts with 2006. Leave both seasons empty for the latest season.

## `seasonTo` (type: `integer`):

results only: last season by its starting year. Defaults to the latest when only seasonFrom is set.

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

results only: limit to these teams, by their Covers slug (e.g. kansas-city-chiefs, duke-blue-devils). Leave empty for every team.

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

Stop after this many rows. Defaults to 50 for a quick preview; clear it (null) for everything in the chosen range.

## `mode` (type: `string`):

odds only. "auto": with maxItems cleared, later runs return only new rows and rows whose score, status or closing lines changed; a capped run always returns rows. "full": every row. "incremental": only new/changed. Results rows are final and always returned.

## `concurrency` (type: `integer`):

Pages fetched in parallel.

## `impersonate` (type: `string`):

curl_cffi browser fingerprint. Defaults to "chrome"; change only if requests start failing.

## `proxyConfiguration` (type: `object`):

Not needed: both sites answered every request from Apify's infrastructure without a proxy in testing.

## Actor input object example

```json
{
  "entityType": "odds",
  "leagues": [
    "nfl",
    "ncaaf",
    "nba",
    "ncaab",
    "mlb",
    "nhl",
    "wnba"
  ],
  "finalOnly": false,
  "maxItems": 50,
  "mode": "auto",
  "concurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("artsiom_k/sports-odds-history-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("artsiom_k/sports-odds-history-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 '{}' |
apify call artsiom_k/sports-odds-history-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,artsiom_k/sports-odds-history-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/8Qt3lyJF3trgeCmPe/builds/ngVPlR9s5e1A9a5XF/openapi.json
