πŸ“Š betPrices Quickstart

Get real-time odds data from all major sportsbooks in 5 minutes

betPrices Quickstart Guide

betPrices provides real-time odds data from all major US sportsbooks with standardized IDs and unlimited API calls. Perfect for odds comparison sites, analytics platforms, and line shopping tools.

What's Included

See subscription pricing β†’ for current rates.

  • βœ… Unlimited API calls
  • βœ… Real-time odds from 20+ sportsbooks
  • βœ… Standardized team/player/market IDs
  • βœ… Historical odds data
  • βœ… All major leagues (NFL, NBA, MLB, NHL, NCAA, etc.)

Prerequisites

  1. SharpSports account (sign up here)
  2. betPrices subscription (see pricing)
  3. Your API keys (found in dashboard)

5-Minute Quickstart

Step 1: Set Up Your Environment

import requests
import json

# Use your private key for fetching data
API_KEY = "sk_test_your_key_here"  # Use sk_live_ in production

headers = {
    "Authorization": f"Token {API_KEY}",
    "Content-Type": "application/json"
}

base_url = "https://api.sharpsports.io/v1"

Step 2: Get Upcoming Events

Find games to get odds for:

# Get upcoming NFL games
def get_upcoming_events(league="nfl", limit=10):
    response = requests.get(
        f"{base_url}/events",
        headers=headers,
        params={
            "league": league,
            "upcoming": "true",
            "limit": limit
        }
    )

    events = response.json()

    for event in events:
        print(f"{event['id']}: {event['name']} - {event['startTime']}")

    return events

events = get_upcoming_events("nfl")

Step 3: Get Odds for an Event

Fetch current odds from all sportsbooks:

def get_event_odds(event_id):
    # Get all prices for the event
    response = requests.get(
        f"{base_url}/prices",
        headers=headers,
        params={"eventId": event_id}
    )

    return response.json()

# Get odds for the first event
if events:
    event_id = events[0]['id']
    odds = get_event_odds(event_id)
    print(f"Found {len(odds)} prices for event {event_id}")

Step 4: Filter Prices by Market Type

Get prices for specific markets using the proposition parameter:

def get_prices_by_market(event_id, proposition="spread"):
    """Get all prices for a specific market type"""
    response = requests.get(
        f"{base_url}/prices",
        headers=headers,
        params={
            "eventId": event_id,
            "proposition": proposition
        }
    )

    prices = response.json()

    # Group prices by selection (e.g., home team vs away team)
    by_selection = {}
    for price in prices:
        position = price['marketSelection']['position']

        if position not in by_selection:
            by_selection[position] = []

        by_selection[position].append({
            'book': price['book']['abbr'],
            'line': price.get('line'),
            'odds': price['odds']
        })

    # Display grouped prices
    for position, price_list in by_selection.items():
        print(f"\n{proposition.upper()} - {position}")
        for p in price_list[:5]:  # Show first 5 books
            line_str = f"{p['line']:+.1f}" if p['line'] else ""
            print(f"  {p['book'].upper():8} {line_str:6} ({p['odds']:+d})")

    return prices

# Get spread prices for first event
spread_prices = get_prices_by_market(events[0]['id'], "spread")

Step 5: Build an Odds Comparison Table

Create a comprehensive odds comparison display:

def create_odds_table(event_id):
    """Display all major market odds for an event"""
    # Get event details first
    event = requests.get(
        f"{base_url}/events/{event_id}",
        headers=headers
    ).json()

    print(f"\n🏈 {event['name']}")
    print(f"πŸ“… {event['startTime']}")
    print("-" * 50)

    # Get prices for each market type
    propositions = ["spread", "total", "moneyline"]

    for prop in propositions:
        # Fetch prices for this market type
        response = requests.get(
            f"{base_url}/prices",
            headers=headers,
            params={
                "eventId": event_id,
                "proposition": prop
            }
        )

        prices = response.json()

        # Group by position (e.g., home/away)
        by_position = {}
        for price in prices:
            position = price['marketSelection']['position']
            if position not in by_position:
                by_position[position] = []
            by_position[position].append(price)

        # Display results
        print(f"\nπŸ“Š {prop.upper()}")
        for position, price_list in by_position.items():
            print(f"\n{position}:")
            # Show top 5 books
            for price in sorted(price_list, key=lambda p: p['odds'], reverse=True)[:5]:
                book = price['book']['abbr'].upper()
                line = f"{price['line']:+.1f}" if price.get('line') else ""
                odds = f"{price['odds']:+d}"
                print(f"  {book:8} {line:6} ({odds})")

# Create odds table for the first event
if events:
    create_odds_table(events[0]['id'])

Complete Working Example

Here's a full script that finds the best available odds across all sportsbooks:

import requests
from datetime import datetime

class BetPricesClient:
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = "https://api.sharpsports.io/v1"
        self.headers = {
            "Authorization": f"Token {api_key}",
            "Content-Type": "application/json"
        }

    def get_best_lines(self, event_id):
        """Find the best available odds for each side of every market"""
        markets = ["spread", "total", "moneyline"]
        best_lines = {}

        for market in markets:
            # Get all prices for this market type
            response = requests.get(
                f"{self.base_url}/prices",
                headers=self.headers,
                params={
                    "eventId": event_id,
                    "proposition": market
                }
            )

            prices = response.json()

            # Group by position and find best odds
            by_position = {}
            for price in prices:
                position = price['marketSelection']['position']

                if position not in by_position:
                    by_position[position] = price
                elif price['odds'] > by_position[position]['odds']:
                    # Found better odds for this position
                    by_position[position] = price

            # Store best lines
            for position, price in by_position.items():
                key = f"{market}_{position}"
                best_lines[key] = {
                    "book": price['book']['abbr'],
                    "line": price.get('line'),
                    "odds": price['odds']
                }

        return best_lines

# Initialize client
client = BetPricesClient("sk_test_your_key_here")

# Get today's NBA games
response = requests.get(
    f"{client.base_url}/events",
    headers=client.headers,
    params={"league": "nba", "upcoming": "true", "limit": 5}
)

events = response.json()

# Display best lines for each game
for event in events:
    print(f"\nπŸ€ {event['name']}")
    print(f"πŸ“… {datetime.fromisoformat(event['startTime']).strftime('%B %d, %I:%M %p')}")

    best = client.get_best_lines(event['id'])

    # Display best lines
    for market, data in best.items():
        if data['line'] is not None:
            print(f"  {market}: {data['line']:+.1f} ({data['odds']:+d}) @ {data['book'].upper()}")
        else:
            print(f"  {market}: ({data['odds']:+d}) @ {data['book'].upper()}")

Understanding the Data

Standardized IDs

All entities use consistent ID formats:

  • Events: EVNT_ + UUID (example: EVNT_abc123def456789012345678901234)
  • Markets: MKT_ + UUID (example: MKT_xyz789abc012345678901234567890)
  • Market Selections: MRKT_ + UUID (example: MRKT_def456abc789012345678901234567)
  • Teams: TEAM_ + UUID (example: TEAM_lakers)
  • Players: PLYR_ + UUID (example: PLYR_abc123def456789012345678901234)

Price Object Structure

{
  "id": "PRICE_abc123def456789012345678901234",
  "book": {
    "id": "BOOK_abc123def456789012345678901234",
    "abbr": "dk",
    "name": "DraftKings"
  },
  "line": -3.5,
  "odds": -110,
  "isMain": true,
  "timeUpdated": "2024-01-15T10:30:00Z"
}

Market Types (Propositions)

  • spread - Point spread
  • total - Over/Under
  • moneyline - Winner
  • player_points - Player props
  • player_rebounds - Player props
  • player_assists - Player props
  • And 100+ more prop types

Advanced Features

Historic Pricing (Requires historicData Subscription)

πŸ“Š

Requires historicData Product: The historic pricing endpoints below require a separate historicData subscription in addition to betPrices. historicData provides OHLC timeseries data and aggregated price statistics for analyzing line movements.

Track line movement over time with historic pricing:

def get_historic_price_summary(market_selection_id):
    """Get aggregated historic pricing statistics (requires historicData)"""
    response = requests.get(
        f"{base_url}/prices/historic/summary",
        headers=headers,
        params={"marketSelectionId": market_selection_id}
    )

    summary = response.json()

    print(f"Opening Line: {summary['openingLine']}")
    print(f"Current Line: {summary['currentLine']}")
    print(f"Line Movement: {summary['currentLine'] - summary['openingLine']:+.1f}")
    print(f"Average Line: {summary['avgLine']:.1f}")
    print(f"Min/Max: {summary['minLine']:.1f} / {summary['maxLine']:.1f}")

    return summary

def get_price_timeseries(market_selection_id, rollup="1h"):
    """Get OHLC price timeseries for charting (requires historicData)"""
    response = requests.get(
        f"{base_url}/prices/historic/timeseries",
        headers=headers,
        params={
            "marketSelectionId": market_selection_id,
            "rollup": rollup  # Options: 5m, 15m, 1h, 1d
        }
    )

    timeseries = response.json()

    for window in timeseries:
        print(f"{window['timestamp']}: O:{window['open']} H:{window['high']} L:{window['low']} C:{window['close']}")

    return timeseries

# Example usage
mrkt_id = "MRKT_abc123def456789012345678901234"
summary = get_historic_price_summary(mrkt_id)
timeseries = get_price_timeseries(mrkt_id, rollup="1h")

For complete historic pricing documentation, see the historicData Quickstart.

Filtering by Sportsbook

Get odds from specific books only:

def get_odds_for_books(event_id, book_abbrs=["dk", "fd", "mgm"]):
    # Filter prices by book
    all_prices = get_event_odds(event_id)
    filtered = [p for p in all_prices if p['book']['abbr'] in book_abbrs]
    return filtered

Real-time Updates

Poll for odds changes:

import time

def monitor_odds(event_id, interval=30):
    """Monitor odds changes every 30 seconds"""
    last_odds = {}

    while True:
        current_odds = get_event_odds(event_id)

        for price in current_odds:
            key = f"{price['book']['abbr']}_{price['marketSelection']}"

            if key in last_odds:
                if last_odds[key] != price['odds']:
                    print(f"πŸ”„ Line moved: {key} from {last_odds[key]} to {price['odds']}")

            last_odds[key] = price['odds']

        time.sleep(interval)

Rate Limits

betPrices has generous rate limits:

  • 100 requests/second with private key
  • Unlimited daily requests
  • No additional charges for high volume

Next Steps

  1. Explore more markets: Try props, futures, and alternate lines
  2. Build comparisons: Create odds comparison tables
  3. Track movement: Monitor line changes over time
  4. Combine with betPlace: Add deep linking to your odds ($1,750/mo)

Need Help?