# Sports Odds Scraper — NFL, NBA, MLB, NHL + Prediction Markets (`galterapp/sports-odds-scraper`) Actor

Scrape today's sportsbook lines (spread, total, moneyline, vig-free win probability) for NFL, NBA, MLB, NHL, college and soccer from ESPN's public scoreboard, side by side with Polymarket and Kalshi win probabilities for the same games. Public APIs, no login, JSON rows.

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

## Pricing

from $10.00 / 1,000 result rows

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Sports Odds Scraper — NFL, NBA, MLB, NHL & soccer lines with prediction-market probabilities

Get today's **sports odds as JSON** in one run: for every game on the slate, the sportsbook **spread, total and
moneylines** (from ESPN's public scoreboard feed), a **vig-free win probability**, live status and score — and,
uniquely, the **Polymarket and Kalshi win probabilities for the same game** with the gap versus the book. No login,
no API keys, no sportsbook scraping that breaks every week.

![Sports odds board](https://files.catbox.moe/jyobj7.png)

### What can you do with sports odds data?

- **Build an odds board or model input** — one row per game, 14 leagues (NFL, NCAAF, NBA, WNBA, NCAAB, MLB, NHL, MLS, Premier League, Champions League, La Liga, Bundesliga, Serie A, Ligue 1).
- **Spot where prediction markets disagree with the book** — `polymarket_vs_book_pts` / `kalshi_vs_book_pts` in probability points; `OUTPUT.largest_edges` lists the biggest.
- **Track lines over time** — schedule the Actor hourly on game days and diff `spread` / `over_under`.
- **Feed dashboards, sheets, alerts and AI agents** — stable schema, MCP-ready.

### How to scrape NFL odds (quick start)

Defaults return the current slate for NFL, NBA, MLB and NHL with prediction markets attached.

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("galterapp/sports-odds-scraper").call(run_input={"leagues": ["nfl"], "dates": ["20260913"]})
for g in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(g["short_name"], g["line"], g["over_under"], g["book_prob_home"], g["polymarket_prob_home"])
```

```javascript
const { ApifyClient } = require('apify-client');
const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('galterapp/sports-odds-scraper').call({ leagues: ['nba', 'nhl'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

```bash
curl -X POST "https://api.apify.com/v2/acts/galterapp~sports-odds-scraper/run-sync-get-dataset-items?token=<YOUR_API_TOKEN>" \
  -H "content-type: application/json" -d '{"leagues":["mlb"]}'
```

### Sample row

```json
{"league":"nfl","game_id":"401772510","short_name":"KC @ BUF","start_time":"2026-09-13T20:25Z","status":"Scheduled",
 "home_team":"Buffalo Bills","away_team":"Kansas City Chiefs","book":"ESPN BET","line":"BUF -2.5","spread":-2.5,
 "over_under":47.5,"home_moneyline":-135,"away_moneyline":115,"book_prob_home":0.553,"book_vig_pct":4.0,
 "polymarket_prob_home":0.57,"kalshi_prob_home":0.56,"polymarket_vs_book_pts":1.7,"kalshi_vs_book_pts":0.7,
 "polymarket_url":"https://polymarket.com/event/nfl-kc-buf-2026-09-13","ts":1788400000}
```

### Input

| Field | Default | Meaning |
|---|---|---|
| `leagues` | nfl, nba, mlb, nhl | any of the 14 supported leagues |
| `dates` | current slate | list of `YYYYMMDD` |
| `includePredictionMarkets` | true | attach Polymarket/Kalshi home-win probabilities |
| `maxResults` | 200 | rows returned (and paid for) |

### How the numbers are computed

- `book_prob_home` = home moneyline probability ÷ (home + away probabilities) — the vig is removed; `book_vig_pct` is the overround.
- Prediction-market probabilities come from the most liquid game market whose text names both teams and closes within 3 days of kickoff; `*_vs_book_pts` = market − book, in points.
- Off-season leagues return no games (not an error). Lines appear when ESPN publishes them, typically 1–6 days before kickoff.

### Notes

- Public JSON endpoints only (ESPN scoreboard, Polymarket Gamma, Kalshi trade API). Nothing stored, no accounts.
- Not betting advice. Availability of the venues depends on your jurisdiction.
- Pricing: pay per game row. A full four-league day is typically 15–40 rows.

# Actor input Schema

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

Which leagues to pull.

## `dates` (type: `array`):

Game dates to fetch, e.g. \["20260907", "20260908"]. Empty = today's/current slate.

## `includePredictionMarkets` (type: `boolean`):

Match each game to its Polymarket and Kalshi game markets and add their implied home-win probability and the gap vs the sportsbook.

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

Cap on rows returned (and paid for).

## Actor input object example

```json
{
  "leagues": [
    "nfl",
    "nba",
    "mlb",
    "nhl"
  ],
  "dates": [],
  "includePredictionMarkets": true,
  "maxResults": 200
}
```

# Actor output Schema

## `games` (type: `string`):

Dataset items: league, teams, start\_time, status, scores, book, line, spread, over\_under, moneylines, book\_prob\_home, polymarket\_prob\_home, kalshi\_prob\_home, \*\_vs\_book\_pts, URLs.

## `summary` (type: `string`):

Counts, first 25 games with lines and probabilities, and largest\_edges\[] (prediction market vs sportsbook).

# 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"
    ],
    "dates": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("galterapp/sports-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 = {
    "leagues": [
        "nfl",
        "nba",
        "mlb",
        "nhl",
    ],
    "dates": [],
}

# Run the Actor and wait for it to finish
run = client.actor("galterapp/sports-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 '{
  "leagues": [
    "nfl",
    "nba",
    "mlb",
    "nhl"
  ],
  "dates": []
}' |
apify call galterapp/sports-odds-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,galterapp/sports-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/POFjb3ouhnw4PBVTh/builds/qR8jdkE10KBecmWF2/openapi.json
