# Pinnacle Odds API — Sharp Lines, Limits & Fair Odds (`lergassy/pinnacle-odds-api`) Actor

Pinnacle's moneyline, spread and total for every game, with the maximum stake it will accept on each market and the fair probability with the bookmaker's margin removed. Pinnacle is the sharp reference the rest of the market prices against — no API key, no login.

- **URL**: https://apify.com/lergassy/pinnacle-odds-api.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 odds rows

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?

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

**Pinnacle Odds API** returns Pinnacle's moneyline, spread and total for every game it prices, with two numbers almost no other feed carries: the **maximum stake Pinnacle will accept** on that market, and the **fair probability** with the bookmaker's margin removed. No API key, no account, no browser.

![One run of Pinnacle Odds API: moneyline and spread prices with fair probabilities and the stake limit.](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/pinnacle-odds-api/pinnacle-odds-api-output-table.png)

Pinnacle is the sharp reference book. It runs on low margins and high limits and it does not restrict winning customers, so the rest of the market prices against it. Its number, stripped of margin, is the closest thing to a true probability that a betting market produces.

### What is Pinnacle Odds API?

A clean feed of Pinnacle's own board: every game in the leagues you pick, every market on it, both sides priced, with the implied and the fair probability side by side. Two modes: **odds** (one row per game, market and side) and **leagues** (what is covered right now).

### What makes it different

**The limit is data.** Pinnacle publishes the maximum it will accept on each market, and that figure says how much the book itself trusts its own number. A line with a low limit is one Pinnacle is unsure about; a full-limit line is one it will happily take money on. Feeds that only copy prices throw that away.

**Fair probability, not implied.** Both sides of a market always add up to more than 1: the surplus is the margin. Every row carries the raw `impliedProbability`, the `overround`, and the `fairProbability` with the margin split out — a share of 1, summing to 1, which is the number a model should actually consume.

**Every price format.** American, decimal, fractional and Hong Kong on the same row — set `oddsFormat` and read whichever your workflow speaks.

### What data does it return?

| Field | Example |
|---|---|
| `league`, `game`, `startTime`, `status` | nfl · Baltimore Ravens at Indianapolis Colts · … |
| `market`, `line` | moneyline / spread / total · −3.5 |
| `homePrice`, `awayPrice`, `drawPrice` | −165 · +140 · (soccer only) |
| `overPrice`, `underPrice` | −110 · −110 |
| `homeDecimal`, `awayDecimal`, `overDecimal`, `underDecimal` | 1.606 · 2.40 · … |
| `homeImpliedProbability`, `awayImpliedProbability` | 0.67 · 0.3623 — shares of 1, and they sum to more than 1 |
| `homeFairProbability`, `awayFairProbability` | 0.649 · 0.351 — the same two with the margin removed, summing to 1 |
| `overround` | 0.0323 — the book's margin on this market, here 3.2% |
| `limitUsd` | 20,000 — the largest stake Pinnacle will take here |
| `favorite`, `sourceUrl` | Indianapolis Colts · link to the game |

Alternate lines — the full ladder of spreads and totals, not just the main number — come back when you ask for them.

### How much does it cost?

Pay per row, and only for rows you actually get:

| Event | Price |
| --- | --- |
| Odds row | $0.002 |
| Game (nested output) | $0.006 |
| League row | $0.0005 |

**Error rows are never charged.** No browser, no proxy — one public JSON API — so platform usage on top is negligible.

| Job | Cost |
| --- | --- |
| An NFL Sunday, all three markets (≈500 rows) | $1.00 |
| Five leagues, moneyline only, once a day for a month | $6.00 |
| A single game's full ladder of alternate lines | $0.20 |

### How to use it

1. Name your **🏆 Leagues** — `nfl`, `nba`, `mlb`, `nhl`, `epl`, `ncaaf` and the rest.
2. Pick the **📈 Markets**: moneyline, spread, total.
3. Set **📅 Days ahead**, or an explicit date range.
4. Choose **💱 Odds format** — American, decimal, fractional or Hong Kong.
5. Click **Start**, then export as JSON, CSV or Excel, or read the dataset through the API.

![The input form of Pinnacle Odds API: leagues, markets, days ahead and odds format.](https://raw.githubusercontent.com/lergassy/apify-actor-assets/main/pinnacle-odds-api/pinnacle-odds-api-input-form.png)

### ⬇️ Input

```json
{
  "mode": "odds",
  "leagues": ["nfl", "nba"],
  "markets": ["moneyline", "spread", "total"],
  "daysAhead": 7,
  "oddsFormat": "american"
}
```

#### One game with every alternate line

```json
{ "mode": "odds", "leagues": ["nfl"], "includeAlternateLines": true, "maxItems": 500 }
```

#### One row per game instead of one per side

```json
{ "mode": "odds", "leagues": ["epl"], "outputFormat": "nested" }
```

### ⬆️ Output

```json
{
  "type": "odds",
  "league": "nfl",
  "game": "Baltimore Ravens at Indianapolis Colts",
  "startTime": "2026-09-13T17:00Z",
  "market": "moneyline",
  "homeTeam": "Indianapolis Colts",
  "awayTeam": "Baltimore Ravens",
  "homePrice": -203,
  "awayPrice": 176,
  "homeDecimal": 1.493,
  "awayDecimal": 2.76,
  "homeImpliedProbability": 0.67,
  "awayImpliedProbability": 0.3623,
  "homeFairProbability": 0.649,
  "awayFairProbability": 0.351,
  "overround": 0.0323,
  "limitUsd": 20000,
  "favorite": "Indianapolis Colts",
  "sourceUrl": "https://www.pinnacle.com/en/football/nfl/matchups",
  "scrapedAt": "2026-09-09T13:30:00.000Z"
}
```

A request that fails arrives as a `type: "error"` row with the reason, never as a silently short list.

### Use cases

#### A reference price for your model

Fair probabilities from the sharpest book are the benchmark every other price is judged against.

#### Closing line value

Schedule the run and store the line at intervals; the closing number is the standard measure of whether a bet was good.

#### Comparing your book against the market

Put Pinnacle's fair probability next to whatever price you were offered elsewhere and see who is paying more than the risk deserves.

#### Limits as a signal

Track `limitUsd` through the week: limits rising into kick-off means the book has settled on its number.

#### AI agents

An agent asked "what are the real odds on this game" reads `homeFairProbability` straight off the row.

### 🤖 For AI Agents & LLM Apps

Compact reference for agents calling this Actor through the [Apify MCP server](https://mcp.apify.com) or the Apify API (`lergassy/pinnacle-odds-api`).

**Minimal input:**

```json
{ "leagues": ["nfl"], "markets": ["moneyline"], "daysAhead": 3 }
```

**Behaviors an agent should know:**

- **Quote `fairProbability`, not `impliedProbability`.** Both are shares of 1. The implied numbers include the book's margin and sum to more than 1; the fair ones sum to exactly 1. Multiply by 100 before showing a percentage.
- `limitUsd` is how much Pinnacle will accept on that market — a confidence signal, not a price.
- `line` belongs to spreads and totals; a moneyline row has none.
- `drawPrice` exists only where a draw is possible, which in practice means soccer.
- Prices move constantly. Every row carries `scrapedAt`; treat a row as a snapshot, not a standing quote.
- Set `oddsFormat` rather than converting prices yourself.
- The Pinnacle guest API is public: no key, no account, no proxy.

### Pinnacle API without a key

Pinnacle's own guest endpoints serve matchups and prices as JSON, split across two documents that have to be joined by matchup id — and the market list carries the limits that most feeds discard. This Actor does the join, keeps the limits, and returns one stable row shape per league.

### ❓ FAQ

#### Is this betting advice?

No. It reads public odds data and returns it as a table. It places no bets.

#### Why Pinnacle rather than a retail sportsbook?

Because its margin is small and it does not close winning accounts, so its price reflects what the market actually believes rather than what a book can get away with.

#### What is the overround?

The amount by which the two sides of a market exceed 1. It is the book's margin — 0.0323 means 3.2% — and removing it gives the fair probability.

#### Which leagues are covered?

The major US leagues and the main soccer competitions. Run the leagues mode to see the current list.

#### How fresh are the numbers?

Live at the moment of the run. Schedule the Actor if you want a line-movement history.

#### Can I use it with the Apify API or an MCP server?

Yes. It runs from the API and the official clients, and AI agents reach it through the Apify MCP server without extra setup.

### Your feedback

Missing a league or a market? Open an issue on the **Issues** tab — every one gets answered.

### You might also like

| Actor | What it does |
|---|---|
| [Sports Betting Odds API](https://apify.com/lergassy/sports-odds-api) | Several books at once, with arbitrage and value bets |
| [DFS Player Props API](https://apify.com/lergassy/dfs-props-scraper) | PrizePicks and Underdog lines side by side |
| [Sports Injury Report API](https://apify.com/lergassy/sports-injuries-api) | Who is out, questionable or probable |
| [Sports Scores & Schedules API](https://apify.com/lergassy/sports-scores-api) | Live scores and schedules for 33 leagues |

### Also known as

People look for this Actor as a Pinnacle API, Pinnacle odds scraper, sharp odds data, closing line value data, fair odds, no-vig odds and betting limits data.

# Actor input Schema

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

<b>Odds</b> — moneyline, spread and total for every game, per book, with opening lines and movement. <b>Props</b> — player and game props from DraftKings for every game. <b>Futures</b> — championship, division, award and season-win markets. <b>Prediction markets</b> — Kalshi game contracts with traded probabilities. <b>Leagues</b> — every league DraftKings currently prices, with ids.

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

One or more leagues. Odds, props and Kalshi contracts are matched game by game. You can also type any ESPN league path such as <code>soccer/eng.2</code> for the game list (DraftKings and Kalshi prices then depend on whether they carry that league).

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

Games from today up to this many days ahead (ignored when dates are set below). 0 = today only.

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

<code>YYYY-MM-DD</code>, UTC. Optional.

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

<code>YYYY-MM-DD</code>, UTC. Optional; at most 60 days after the start.

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

Odds mode: which game lines to output. Spread is the run line in MLB and the puck line in NHL; soccer moneylines carry a draw price.

## `oddsFormat` (type: `string`):

How the <code>homePrice</code>/<code>awayPrice</code>/<code>overPrice</code>… fields are written. Decimal odds and implied probabilities are always included as separate fields.

## `outputFormat` (type: `string`):

<b>Flat</b> — one row per game × market × book, spreadsheet-friendly. <b>Nested</b> — one row per game with all books inside and the best price per outcome.

## `includeAlternateLines` (type: `boolean`):

Add DraftKings' alternate lines as extra rows (market <code>alternate-spread</code> / <code>alternate-total</code>).

## `includeFinished` (type: `boolean`):

Odds mode: keep games that are already final (closing lines, if a source still carries them). Prediction-markets mode: keep settled contracts.

## `eventIds` (type: `array`):

ESPN event ids (the <code>eventId</code> field of any row, or the number in an ESPN game URL). Leave empty for every game in the date range.

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

Stop after this many rows in the run.

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

How many requests run at once.

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

Not needed: every source answers Apify's own servers directly. Set only if a source starts refusing. <b>Leave it off unless a source starts refusing you:</b> a datacenter proxy is blocked by some books, so switching it on can cost you prices rather than save them. If you do need one, pick Residential.

## Actor input object example

```json
{
  "mode": "odds",
  "leagues": [
    "nfl",
    "nba",
    "mlb",
    "epl"
  ],
  "daysAhead": 7,
  "markets": [
    "moneyline",
    "spread",
    "total"
  ],
  "oddsFormat": "american",
  "outputFormat": "flat",
  "includeAlternateLines": false,
  "includeFinished": false,
  "maxItems": 5000,
  "concurrency": 6,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `rows` (type: `string`):

Odds mode: one row per game × market × book with prices in the chosen format, decimal odds, implied and fair probabilities, opening line and movement (or one nested row per game with best prices). Props/futures: one row per selection. Prediction markets: one row per Kalshi contract.

# 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",
        "epl"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/pinnacle-odds-api").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",
        "epl",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("lergassy/pinnacle-odds-api").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",
    "epl"
  ]
}' |
apify call lergassy/pinnacle-odds-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/pinnacle-odds-api"
        }
    }
}

```

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/FjL0i4DqqRdjF3RkA/builds/fsLqohlfaTOaFUEqZ/openapi.json
