Skip to main content
TheRundown API provides several endpoints for accessing historical odds data. You can retrieve full price history for charting, compare opening and closing lines, and filter by time range.

Endpoints Overview

EndpointDescription
GET /api/v2/events/{eventID}/markets/historyFull price history across all markets for an event
GET /api/v2/events/{eventID}/markets/{marketID}/historyPrice history for a specific market (ideal for charting)
GET /api/v2/events/{eventID}/openersOpening lines when a market first appeared
GET /api/v2/events/{eventID}/closingClosing lines at game time

Full Market History

Use the full history endpoint to get every recorded price change for an event across all markets and sportsbooks.
curl "https://therundown.io/api/v2/events/{eventID}/markets/history?\
key=YOUR_API_KEY&affiliate_ids=19,23"

Query Parameters

ParameterTypeDescription
affiliate_idsstringComma-separated sportsbook IDs to include
market_idsstringComma-separated market IDs to filter
fromstringStart time in RFC 3339 format (e.g., 2026-02-10T00:00:00Z)
tostringEnd time in RFC 3339 format (e.g., 2026-02-12T23:59:59Z)

Example Response

{
  "event_id": "abc123",
  "history": [
    {
      "market_id": 2,
      "market_name": "Point Spread",
      "participant_name": "Boston Celtics",
      "affiliate_id": 19,
      "line": -3.5,
      "price": -110,
      "timestamp": "2026-02-10T14:30:00Z"
    },
    {
      "market_id": 2,
      "market_name": "Point Spread",
      "participant_name": "Boston Celtics",
      "affiliate_id": 19,
      "line": -4.0,
      "price": -110,
      "timestamp": "2026-02-11T09:15:00Z"
    }
  ]
}

Single Market History (Chart Data)

For building a line movement chart, fetch history for a specific market. This returns a time series ideal for plotting.
# Spread history (market_id=2) for a specific event
curl "https://therundown.io/api/v2/events/{eventID}/markets/2/history?\
key=YOUR_API_KEY&affiliate_ids=19"
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://therundown.io/api/v2"
EVENT_ID = "abc123"

# Fetch spread history from DraftKings
response = requests.get(
    f"{BASE_URL}/events/{EVENT_ID}/markets/2/history",
    params={
        "key": API_KEY,
        "affiliate_ids": "19",
    }
)

history = response.json()["history"]

print("Timestamp                  | Line   | Price")
print("-" * 50)
for entry in history:
    print(f"{entry['timestamp']}  | {entry['line']:>6} | {entry['price']}")

Filtering by Time Range

Use from and to parameters in RFC 3339 format to scope history to a specific window. This is useful for showing line movement in the last 24 hours or during a specific period.
# History from the last 24 hours
curl "https://therundown.io/api/v2/events/{eventID}/markets/2/history?\
key=YOUR_API_KEY&affiliate_ids=19\
&from=2026-02-11T00:00:00Z\
&to=2026-02-12T00:00:00Z"
from datetime import datetime, timedelta, timezone

now = datetime.now(timezone.utc)
yesterday = now - timedelta(days=1)

response = requests.get(
    f"{BASE_URL}/events/{EVENT_ID}/markets/2/history",
    params={
        "key": API_KEY,
        "affiliate_ids": "19",
        "from": yesterday.strftime("%Y-%m-%dT%H:%M:%SZ"),
        "to": now.strftime("%Y-%m-%dT%H:%M:%SZ"),
    }
)

history = response.json()["history"]
print(f"Found {len(history)} price changes in the last 24 hours")

Opening Lines

The openers endpoint returns the first price posted by each sportsbook for each market. This is useful for comparing how lines have moved since they opened.
curl "https://therundown.io/api/v2/events/{eventID}/openers?\
key=YOUR_API_KEY&market_ids=1,2,3&affiliate_ids=19,23"
response = requests.get(
    f"{BASE_URL}/events/{EVENT_ID}/openers",
    params={
        "key": API_KEY,
        "market_ids": "1,2,3",
        "affiliate_ids": "19,23",
    }
)

openers = response.json()
for market in openers.get("markets", []):
    print(f"\n{market['name']} (opened)")
    for participant in market["participants"]:
        for line in participant["lines"]:
            for aff_id, price in line["prices"].items():
                print(f"  {participant['name']}: {price['price']} @ {aff_id}")

Closing Lines

The closing endpoint returns the final price posted before game time. Closing lines are widely considered the most efficient odds and are useful for evaluating betting performance.
curl "https://therundown.io/api/v2/events/{eventID}/closing?\
key=YOUR_API_KEY&market_ids=1,2,3&affiliate_ids=19,23"
response = requests.get(
    f"{BASE_URL}/events/{EVENT_ID}/closing",
    params={
        "key": API_KEY,
        "market_ids": "1,2,3",
        "affiliate_ids": "19,23",
    }
)

closing = response.json()
for market in closing.get("markets", []):
    print(f"\n{market['name']} (closing)")
    for participant in market["participants"]:
        for line in participant["lines"]:
            for aff_id, price in line["prices"].items():
                print(f"  {participant['name']}: {price['price']} @ {aff_id}")

Building a Line Movement Chart

Here is a complete example that fetches spread history and formats the data for a charting library.
import requests
from datetime import datetime, timezone

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://therundown.io/api/v2"
EVENT_ID = "abc123"
AFFILIATE_IDS = ["19", "23"]  # DraftKings, FanDuel
BOOKS = {"19": "DraftKings", "23": "FanDuel"}

# Fetch spread history for multiple books
response = requests.get(
    f"{BASE_URL}/events/{EVENT_ID}/markets/2/history",
    params={
        "key": API_KEY,
        "affiliate_ids": ",".join(AFFILIATE_IDS),
    }
)
history = response.json()["history"]

# Group by sportsbook for charting
series = {}
for entry in history:
    aff_id = str(entry["affiliate_id"])
    book_name = BOOKS.get(aff_id, aff_id)

    if book_name not in series:
        series[book_name] = {"timestamps": [], "lines": [], "prices": []}

    series[book_name]["timestamps"].append(entry["timestamp"])
    series[book_name]["lines"].append(entry["line"])
    series[book_name]["prices"].append(entry["price"])

# Print chart data
for book, data in series.items():
    print(f"\n{book} Spread Movement:")
    for ts, line, price in zip(data["timestamps"], data["lines"], data["prices"]):
        print(f"  {ts}: {line} ({price})")

# To use with matplotlib:
# import matplotlib.pyplot as plt
# import matplotlib.dates as mdates
#
# fig, ax = plt.subplots(figsize=(12, 6))
# for book, data in series.items():
#     dates = [datetime.fromisoformat(ts.replace("Z", "+00:00")) for ts in data["timestamps"]]
#     ax.step(dates, data["lines"], where="post", label=book)
# ax.set_xlabel("Time")
# ax.set_ylabel("Spread")
# ax.legend()
# ax.invert_yaxis()
# plt.title("Spread Line Movement")
# plt.show()

Comparing Openers to Current Lines

A common use case is showing how far a line has moved from its opener. Fetch both the opener and current odds, then compute the difference.
import requests
from datetime import date

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://therundown.io/api/v2"
EVENT_ID = "abc123"

# Fetch opener and current data in parallel (or sequentially)
opener_resp = requests.get(
    f"{BASE_URL}/events/{EVENT_ID}/openers",
    params={"key": API_KEY, "market_ids": "2", "affiliate_ids": "19"}
)

current_resp = requests.get(
    f"{BASE_URL}/events/{EVENT_ID}",
    params={"key": API_KEY, "market_ids": "2", "affiliate_ids": "19"}
)

# Extract spread values and compare
opener_data = opener_resp.json()
current_data = current_resp.json()

print("Opening vs Current Spread:")
# Parse and compare the spread line values from each response

Next Steps