<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SportsAPIs.dev</title>
    <description>The latest articles on DEV Community by SportsAPIs.dev (@sportsapis).</description>
    <link>https://dev.to/sportsapis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4187486%2Fafd65981-b12d-4f9d-b374-2019e66f325c.png</url>
      <title>DEV Community: SportsAPIs.dev</title>
      <link>https://dev.to/sportsapis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sportsapis"/>
    <language>en</language>
    <item>
      <title>Live Sports Odds APIs: WebSocket vs REST, Latency and In-Play Feeds</title>
      <dc:creator>SportsAPIs.dev</dc:creator>
      <pubDate>Thu, 15 Oct 2026 21:28:24 +0000</pubDate>
      <link>https://dev.to/sportsapis/live-sports-odds-apis-websocket-vs-rest-latency-and-in-play-feeds-3n0k</link>
      <guid>https://dev.to/sportsapis/live-sports-odds-apis-websocket-vs-rest-latency-and-in-play-feeds-3n0k</guid>
      <description>&lt;p&gt;&lt;em&gt;This post first appeared on &lt;a href="https://sportsapis.dev/live-sports-odds-api" rel="noopener noreferrer"&gt;SportsAPIs.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Live Sports Odds API?
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;live sports odds API&lt;/strong&gt; (also called in-play or in-game betting API) provides real-time betting odds that update continuously while games are in progress. Unlike pregame odds that remain relatively stable until game time, live odds change dynamically based on score, time remaining, momentum shifts, injuries, and other in-game events.&lt;/p&gt;

&lt;p&gt;Live betting is the fastest-growing segment of sports wagering, accounting for over 50% of handle at many sportsbooks. Bettors love the excitement of reacting to game flow, and odds APIs enable developers to build applications that capitalize on this trend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Live Odds APIs Are Different
&lt;/h3&gt;

&lt;p&gt;Live sports odds APIs require fundamentally different infrastructure than pregame odds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time updates:&lt;/strong&gt; Odds change every few seconds, requiring WebSocket connections or aggressive polling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low latency:&lt;/strong&gt; Milliseconds matter for arbitrage and value betting opportunities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher costs:&lt;/strong&gt; Real-time data feeds from sportsbooks are expensive to license and maintain&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex markets:&lt;/strong&gt; In-play markets include next-to-score, next-quarter winner, and dynamic player props&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reliability requirements:&lt;/strong&gt; Downtime during games = lost revenue for betting apps&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're building a live betting application, arbitrage tool, or real-time &lt;a href="https://jedibets.com" rel="noopener noreferrer"&gt;odds comparison site&lt;/a&gt;, a dedicated live sports odds API is essential.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebSocket vs REST: What's the Difference?
&lt;/h2&gt;

&lt;p&gt;Understanding the technology behind live odds delivery is crucial for choosing the right API:&lt;/p&gt;

&lt;h3&gt;
  
  
  REST API (Polling)
&lt;/h3&gt;

&lt;p&gt;Traditional HTTP requests where your application repeatedly asks "what are the current odds?" at regular intervals.&lt;/p&gt;

&lt;h4&gt;
  
  
  Advantages:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Simpler to implement (standard HTTP requests)&lt;/li&gt;
&lt;li&gt;Works with any programming language&lt;/li&gt;
&lt;li&gt;Easier debugging and testing&lt;/li&gt;
&lt;li&gt;Stateless (no persistent connections)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Limitations:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Higher latency (5-60 second delays typical)&lt;/li&gt;
&lt;li&gt;Wastes API calls polling for unchanged data&lt;/li&gt;
&lt;li&gt;Inefficient bandwidth usage&lt;/li&gt;
&lt;li&gt;Not suitable for time-sensitive arbitrage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example polling code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Poll for odds every 10 seconds&lt;/span&gt;
&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;odds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://api.example.com/live-odds&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;updateDisplay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;odds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 10-second delay between updates&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  WebSocket API (Streaming)
&lt;/h3&gt;

&lt;p&gt;Persistent two-way connection where the server pushes odds updates to you instantly when they change.&lt;/p&gt;

&lt;h4&gt;
  
  
  Advantages:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Sub-second latency (often &amp;lt;500ms)&lt;/li&gt;
&lt;li&gt;Only receive updates when odds actually change&lt;/li&gt;
&lt;li&gt;Efficient bandwidth (push model)&lt;/li&gt;
&lt;li&gt;Perfect for arbitrage and live betting&lt;/li&gt;
&lt;li&gt;Lower API costs (pay for connection, not per-request)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Limitations:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;More complex implementation&lt;/li&gt;
&lt;li&gt;Requires WebSocket library support&lt;/li&gt;
&lt;li&gt;Connection management (reconnects, heartbeats)&lt;/li&gt;
&lt;li&gt;Typically higher monthly cost than REST&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example WebSocket code:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WebSocket connection for real-time odds&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wss://api.example.com/live-odds&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oddsUpdate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;updateDisplay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oddsUpdate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Instant updates when odds change&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;reconnect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Handle disconnections&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Which Should You Choose?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Use WebSocket for:&lt;/strong&gt; Live betting apps, arbitrage tools, real-time odds comparison, time-sensitive applications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use REST polling for:&lt;/strong&gt; Budget projects, infrequent updates (hourly), pregame-focused apps, MVPs/prototypes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Many providers offer both options. Start with REST to build your app, then upgrade to WebSocket when you need real-time performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Latency in Live Odds APIs
&lt;/h2&gt;

&lt;p&gt;Latency (the delay between a real-world event and seeing updated odds) is critical for live betting applications. Here's what affects latency:&lt;/p&gt;

&lt;h3&gt;
  
  
  Sources of Latency
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sportsbook data delay:&lt;/strong&gt; Time for sportsbooks to update their own systems (1-5 seconds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API provider processing:&lt;/strong&gt; Time to normalize and distribute data (0.1-2 seconds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network transmission:&lt;/strong&gt; Data traveling over the internet (0.05-0.5 seconds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your application processing:&lt;/strong&gt; Parsing and displaying data (0.01-0.2 seconds)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Total latency:&lt;/strong&gt; Typically ranges from 2-10 seconds for live odds, though premium WebSocket APIs can achieve sub-second from sportsbook to your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Latency Matters
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arbitrage:&lt;/strong&gt; Opportunities often last only 5-30 seconds. High latency = missed opportunities&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User experience:&lt;/strong&gt; Outdated odds frustrate users and reduce trust&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market efficiency:&lt;/strong&gt; Sharp bettors need current odds to identify value&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Risk management:&lt;/strong&gt; Delayed odds can lead to accepting changed lines&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Much Latency Can Your App Tolerate?
&lt;/h3&gt;

&lt;p&gt;Not every live app needs a WebSocket. Match the feed to the job:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;th&gt;Latency you can live with&lt;/th&gt;
&lt;th&gt;Feed that fits&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Live betting / in-play wagering&lt;/td&gt;
&lt;td&gt;Under 500ms, ideally under 200ms&lt;/td&gt;
&lt;td&gt;WebSocket on a premium plan&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Odds comparison and arbitrage&lt;/td&gt;
&lt;td&gt;1-5 seconds&lt;/td&gt;
&lt;td&gt;WebSocket, or REST polled every 5-10 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Live score tracking&lt;/td&gt;
&lt;td&gt;5-30 seconds&lt;/td&gt;
&lt;td&gt;REST polled every 10-30 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fantasy and DFS scoring&lt;/td&gt;
&lt;td&gt;30-60 seconds&lt;/td&gt;
&lt;td&gt;REST polled every 30-60 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Score widgets on news sites&lt;/td&gt;
&lt;td&gt;1-5 minutes&lt;/td&gt;
&lt;td&gt;REST with caching&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Latency Benchmarks by Feed Type
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Premium WebSocket APIs:&lt;/strong&gt; 0.5-2 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REST with fast polling:&lt;/strong&gt; 5-15 seconds (at 10s intervals)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standard REST polling:&lt;/strong&gt; 30-60 seconds (budget implementations)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Test latency during free trials to ensure it meets your needs. Request sample WebSocket feeds or monitor timestamps in API responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Can You Build with Live Odds APIs?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Live Betting Applications
&lt;/h3&gt;

&lt;p&gt;Build iOS/Android apps or web platforms that display in-play betting markets with real-time odds updates. Show live scores alongside current betting lines for maximum engagement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required:&lt;/strong&gt; WebSocket API, low latency (&amp;lt;3s), reliable uptime&lt;/p&gt;

&lt;h3&gt;
  
  
  Arbitrage Bots
&lt;/h3&gt;

&lt;p&gt;Automated systems that detect price discrepancies across sportsbooks and alert users to risk-free profit opportunities. Live arbitrage is highly time-sensitive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required:&lt;/strong&gt; Sub-second updates, wide sportsbook coverage, WebSocket&lt;/p&gt;

&lt;h3&gt;
  
  
  Live Odds Comparison Sites
&lt;/h3&gt;

&lt;p&gt;Real-time &lt;a href="https://jedibets.com" rel="noopener noreferrer"&gt;odds comparison platforms&lt;/a&gt; showing which sportsbook offers the best live lines for in-progress games. Refresh automatically as odds change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required:&lt;/strong&gt; WebSocket or fast polling, multiple sportsbooks&lt;/p&gt;

&lt;h3&gt;
  
  
  Positive EV Alerts
&lt;/h3&gt;

&lt;p&gt;Systems that compare your predictive models to live market odds to identify bets with positive expected value in real-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required:&lt;/strong&gt; Fast updates, historical odds for model training&lt;/p&gt;

&lt;h3&gt;
  
  
  Live Line Movement Trackers
&lt;/h3&gt;

&lt;p&gt;Visualize how odds change throughout a game. Track line movements to understand sharp money, public betting, and market reactions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required:&lt;/strong&gt; Historical live odds, frequent updates&lt;/p&gt;

&lt;h3&gt;
  
  
  Discord/Telegram Live Alerts
&lt;/h3&gt;

&lt;p&gt;Bots that push notifications to communities when favorable live betting opportunities arise based on custom criteria.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required:&lt;/strong&gt; WebSocket for speed, custom filtering logic&lt;/p&gt;

&lt;h3&gt;
  
  
  Live Betting Analytics
&lt;/h3&gt;

&lt;p&gt;Tools that analyze in-play betting patterns, calculate live win probabilities, and compare to market odds to find inefficiencies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required:&lt;/strong&gt; Live odds + live stats/scores, fast updates&lt;/p&gt;

&lt;h3&gt;
  
  
  Hedge Calculators
&lt;/h3&gt;

&lt;p&gt;Real-time hedge calculators that show optimal live bets to lock in profit or minimize loss on existing pregame wagers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required:&lt;/strong&gt; Live odds, user bet tracking&lt;/p&gt;

&lt;h2&gt;
  
  
  Live Scores vs Live Odds APIs
&lt;/h2&gt;

&lt;p&gt;People search for "real-time sports API" and mean one of two different products. A live scores feed tells you what happened in the game. A live odds feed tells you what the sportsbooks think will happen next. They run at different speeds and cost different amounts.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Live scores API&lt;/th&gt;
&lt;th&gt;Live odds API&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Data&lt;/td&gt;
&lt;td&gt;Score, period, game clock, play-by-play, live player stats&lt;/td&gt;
&lt;td&gt;In-play moneylines, spreads, totals, live props, line movement across books&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical latency&lt;/td&gt;
&lt;td&gt;1-30 seconds&lt;/td&gt;
&lt;td&gt;Under 2 seconds on good feeds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built for&lt;/td&gt;
&lt;td&gt;Score apps, news widgets, fantasy scoring, push alerts&lt;/td&gt;
&lt;td&gt;Live betting, in-play comparison, live arbitrage, CLV tracking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If your app shows both (a touchdown lands and the new line appears next to it), you need them in sync. Some providers bundle scores and odds in one feed; others make you join two. The SportsAPIs.dev directory marks which providers cover each, and the free &lt;a href="https://sportsapis.dev/espn-api" rel="noopener noreferrer"&gt;ESPN endpoints&lt;/a&gt; are a fair start for scores alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Integrate a Live Sports Odds API
&lt;/h2&gt;

&lt;p&gt;Integrating live odds requires different considerations than pregame data:&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Choose WebSocket vs REST
&lt;/h3&gt;

&lt;p&gt;For true real-time applications, prioritize APIs offering WebSocket support. For less time-sensitive use cases, REST with aggressive polling (every 5-10 seconds) may suffice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Implement Connection Management
&lt;/h3&gt;

&lt;p&gt;WebSocket connections require robust error handling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// WebSocket connection with auto-reconnect&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;reconnectInterval&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ws&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;WebSocket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wss://api.example.com/live&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onopen&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Connected to live odds feed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Subscribe to specific games/markets&lt;/span&gt;
    &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscribe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;sports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;basketball_nba&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;americanfootball_nfl&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;processOddsUpdate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;WebSocket error:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Disconnected, reconnecting...&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reconnectInterval&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Optimize Display Updates
&lt;/h3&gt;

&lt;p&gt;Don't update your UI on every single odds change. Batch updates to prevent flickering:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;pendingUpdates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;pendingUpdates&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;game_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Batch update UI every 500ms&lt;/span&gt;
&lt;span class="nf"&gt;setInterval&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pendingUpdates&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;updateGameOdds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;pendingUpdates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Handle Rate Limits
&lt;/h3&gt;

&lt;p&gt;Even WebSocket APIs may limit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Number of concurrent connections&lt;/li&gt;
&lt;li&gt;Number of subscribed games/markets&lt;/li&gt;
&lt;li&gt;Messages per second&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Subscribe only to games/markets you're actively displaying to users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Monitor Latency
&lt;/h3&gt;

&lt;p&gt;Track timestamps in API responses to measure end-to-end latency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;ws&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onmessage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;receiveTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;latency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;receiveTime&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;apiTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Latency: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;latency&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;ms`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;monitorLatency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;latency&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Alert if latency spikes&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Implement Fallbacks
&lt;/h3&gt;

&lt;p&gt;Have a backup plan if WebSocket connections fail:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fall back to REST polling if WebSocket disconnects repeatedly&lt;/li&gt;
&lt;li&gt;Cache last-known odds to display during brief outages&lt;/li&gt;
&lt;li&gt;Show users a "Live odds temporarily unavailable" message&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Live Odds API Pricing
&lt;/h2&gt;

&lt;p&gt;Live sports odds APIs cost more than pregame-only APIs due to infrastructure requirements:&lt;/p&gt;

&lt;h3&gt;
  
  
  Typical Pricing Tiers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free trials:&lt;/strong&gt; 7-14 days from various providers to test latency and features&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Entry-level:&lt;/strong&gt; $100-300/month for REST polling access with limited sportsbooks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Professional:&lt;/strong&gt; $300-800/month for WebSocket access, multiple sports, comprehensive coverage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enterprise:&lt;/strong&gt; $1000+/month for dedicated connections, SLA guarantees, premium support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cost Factors
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Update frequency:&lt;/strong&gt; WebSocket costs more than REST polling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sportsbook count:&lt;/strong&gt; More books = higher licensing costs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sports coverage:&lt;/strong&gt; Niche sports may cost extra&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request volume:&lt;/strong&gt; Some charge per message/update&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Features:&lt;/strong&gt; Player props and SGP odds increase cost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with free trials to validate your concept before committing to expensive plans.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a live sports odds API?
&lt;/h3&gt;

&lt;p&gt;A live sports odds API provides real-time betting odds that update continuously during games. Unlike pregame odds that are static until game time, live odds (also called in-play or in-game odds) change based on score, time remaining, and in-game events. These APIs use WebSocket connections or rapid polling to deliver sub-second to 10-second updates to betting applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Which API has the fastest live odds updates?
&lt;/h3&gt;

&lt;p&gt;Several providers are known for sub-second live odds via WebSocket connections. Update speed depends on both the sportsbook's data feed and the API provider's infrastructure. WebSocket APIs consistently outperform REST polling, delivering updates in under 2 seconds vs 5-60 seconds for polling.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much do live odds APIs cost?
&lt;/h3&gt;

&lt;p&gt;Live sports odds APIs typically cost $200-1000+/month depending on update frequency, sportsbook coverage, and request volumes. This is significantly higher than pregame-only APIs ($20-100/month) due to infrastructure requirements for real-time data. Entry-level live odds start around $100-300/month, while professional WebSocket access costs $300-800/month. Most providers offer free trials to test latency and reliability.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between WebSocket and REST for live odds?
&lt;/h3&gt;

&lt;p&gt;REST APIs require you to repeatedly poll for updates (every 5-60 seconds), causing delays and wasting requests when odds haven't changed. WebSocket APIs maintain a persistent connection where the server pushes updates to you instantly when odds change, achieving sub-second latency. WebSockets are essential for live betting apps, arbitrage detection, and real-time odds comparison, though they cost more than REST-only access.&lt;/p&gt;

&lt;h3&gt;
  
  
  What sports offer live odds through APIs?
&lt;/h3&gt;

&lt;p&gt;Most major sports offer live in-play betting: NFL, NBA, MLB, NHL, NCAAF, NCAAB, Soccer (Premier League, Champions League, MLS), Tennis, MMA/UFC, Cricket, Rugby, and Esports. Live odds availability and market depth vary by sport: high-scoring sports like basketball have more frequent updates than baseball or soccer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I get live player props through an API?
&lt;/h3&gt;

&lt;p&gt;Yes, some APIs provide live player props during games (points, rebounds, strikeouts, etc.). However, live player props are typically premium features requiring higher-tier paid plans. Not all sportsbooks offer live player props, so coverage varies by provider. This &lt;a href="https://sportsapis.dev/player-props-api" rel="noopener noreferrer"&gt;guide to player props APIs&lt;/a&gt; covers the details.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I test live odds API latency?
&lt;/h3&gt;

&lt;p&gt;Use free trials to test real-world latency. Connect during live games and compare the API's odds timestamps to your system clock. Measure the delay between a game event (score change) and updated odds appearing in your app. Expect 1-10 second total latency depending on the API. WebSocket connections should show sub-3-second latency, while REST polling typically shows 10-60 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are free live odds APIs available?
&lt;/h3&gt;

&lt;p&gt;Very few APIs offer truly free live odds due to high infrastructure costs. Some providers offer limited free tiers (e.g., 500 requests/month) which technically allows live odds via polling, but this is insufficient for real-time applications (you'd exhaust it in hours). Your best option is free trials (typically 7-14 days) to build and test your live betting app before committing to paid plans.&lt;/p&gt;

&lt;h3&gt;
  
  
  What latency is acceptable for arbitrage betting?
&lt;/h3&gt;

&lt;p&gt;For live arbitrage, you need sub-3-second latency. Arbitrage opportunities in live betting typically last only 5-30 seconds before odds adjust. If your API has 10+ second latency, most opportunities will disappear before you can capitalize. WebSocket APIs are recommended for arbitrage detection with their sub-second update speeds.&lt;/p&gt;

&lt;p&gt;Compare live odds providers by WebSocket support, latency and sportsbook coverage in the &lt;a href="https://sportsapis.dev/" rel="noopener noreferrer"&gt;SportsAPIs.dev directory&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>sports</category>
      <category>javascript</category>
      <category>websocket</category>
    </item>
    <item>
      <title>ESPN API: Free Sports Data for Scores, Stats and News</title>
      <dc:creator>SportsAPIs.dev</dc:creator>
      <pubDate>Thu, 15 Oct 2026 21:18:47 +0000</pubDate>
      <link>https://dev.to/sportsapis/espn-api-free-sports-data-for-scores-stats-and-news-4n2i</link>
      <guid>https://dev.to/sportsapis/espn-api-free-sports-data-for-scores-stats-and-news-4n2i</guid>
      <description>&lt;p&gt;&lt;em&gt;This post first appeared on &lt;a href="https://sportsapis.dev/espn-api" rel="noopener noreferrer"&gt;SportsAPIs.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the ESPN API?
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;ESPN API&lt;/strong&gt; refers to a collection of undocumented endpoints that developers have discovered by reverse-engineering ESPN's web and mobile applications. While ESPN doesn't offer an official public API, these hidden endpoints provide free access to a wealth of sports data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time Scores:&lt;/strong&gt; Live scoreboards across all major sports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team &amp;amp; Player Stats:&lt;/strong&gt; Comprehensive statistics and performance data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;News &amp;amp; Headlines:&lt;/strong&gt; Latest sports news articles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Standings &amp;amp; Rankings:&lt;/strong&gt; League standings and power rankings&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Game Summaries:&lt;/strong&gt; Play-by-play data, box scores, and game details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Schedules:&lt;/strong&gt; Upcoming games and event calendars&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free Access:&lt;/strong&gt; No subscription or payment required&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Authentication:&lt;/strong&gt; No API key or token needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JSON Responses:&lt;/strong&gt; Clean, structured data format&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comprehensive Coverage:&lt;/strong&gt; All major US sports plus international soccer&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  API Base URLs
&lt;/h2&gt;

&lt;p&gt;ESPN's hidden API uses several base domains, each serving different types of data:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Domain&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;site.api.espn.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;General site data - scores, news, teams, standings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sports.core.api.espn.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Core sports data - athletes, detailed stats, odds, venues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;site.web.api.espn.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Web-specific APIs - search, game summaries, athlete overviews&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;fantasy.espn.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Fantasy sports data (may require authentication for private leagues)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cdn.espn.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Content delivery - optimized for speed and caching&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Supported Sports &amp;amp; Leagues
&lt;/h2&gt;

&lt;p&gt;The ESPN API covers a wide range of sports and leagues. Here are the most commonly used:&lt;/p&gt;

&lt;h4&gt;
  
  
  Football
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;NFL (&lt;code&gt;football/nfl&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;College Football (&lt;code&gt;football/college-football&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Basketball
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;NBA (&lt;code&gt;basketball/nba&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;WNBA (&lt;code&gt;basketball/wnba&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Men's CBB (&lt;code&gt;basketball/mens-college-basketball&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Women's CBB (&lt;code&gt;basketball/womens-college-basketball&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Baseball
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;MLB (&lt;code&gt;baseball/mlb&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;College Baseball (&lt;code&gt;baseball/college-baseball&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Hockey
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;NHL (&lt;code&gt;hockey/nhl&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Soccer
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;MLS (&lt;code&gt;soccer/usa.1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Premier League (&lt;code&gt;soccer/eng.1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;La Liga (&lt;code&gt;soccer/esp.1&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;And many more...&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Other Sports
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Golf&lt;/li&gt;
&lt;li&gt;Tennis&lt;/li&gt;
&lt;li&gt;MMA/UFC&lt;/li&gt;
&lt;li&gt;Racing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Endpoints
&lt;/h2&gt;

&lt;p&gt;Most endpoints follow a consistent pattern: &lt;code&gt;/apis/site/v2/sports/{sport}/{league}/{endpoint}&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Endpoint&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Live scores and game status&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sports/football/nfl/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/news&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Latest news articles&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sports/basketball/nba/news&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/teams&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All teams in a league&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sports/baseball/mlb/teams&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/teams/{id}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specific team details&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sports/football/nfl/teams/12&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/summary&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Game details with box score&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sports/basketball/nba/summary?event=401234567&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/standings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;League standings&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sports/hockey/nhl/standings&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/rankings&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Power rankings (college)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/sports/football/college-football/rankings&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Common Query Parameters
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dates&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One day (YYYYMMDD) or a whole month (YYYYMM). Ranges return HTTP 400, see date filters&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?dates=20251201&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;limit&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Maximum number of results&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?limit=50&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;season&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specific season year&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?season=2025&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;seasontype&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Season type (1=preseason, 2=regular, 3=postseason)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?seasontype=2&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;week&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Specific week (football)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;?week=10&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;groups&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Conference/division filter&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;?groups=80&lt;/code&gt; (FBS)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  ESPN Game Summary Endpoint (summary?event=)
&lt;/h2&gt;

&lt;p&gt;The summary endpoint returns everything ESPN has on one game: box score, play-by-play, win probability, betting lines, injuries and news. It is the ESPN endpoint developers search for most, and it has the least documentation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/{sport}/{league}/summary?event={eventId}
https://site.web.api.espn.com/apis/site/v2/sports/{sport}/{league}/summary?event={eventId}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both hosts returned the same JSON for the same game in our tests. Pick either one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where the event ID comes from
&lt;/h3&gt;

&lt;p&gt;Every scoreboard response has an &lt;code&gt;events&lt;/code&gt; array, and each event has an &lt;code&gt;id&lt;/code&gt;. That id is your &lt;code&gt;event&lt;/code&gt; value. For example, &lt;code&gt;basketball/nba/scoreboard?dates=20250605&lt;/code&gt; returns Game 1 of the 2025 NBA Finals (Pacers at Thunder) with id &lt;code&gt;401766122&lt;/code&gt;, so the summary URL is &lt;code&gt;basketball/nba/summary?event=401766122&lt;/code&gt;. A missing or wrong ID returns HTTP 400.&lt;/p&gt;

&lt;h3&gt;
  
  
  What the summary response contains
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Key&lt;/th&gt;
&lt;th&gt;What it holds&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;header&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Teams, score, date, status and which side is home&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;boxscore&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Team stats (&lt;code&gt;teams&lt;/code&gt;) and player stat lines (&lt;code&gt;players&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;plays&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Play-by-play. Our NBA Finals test game had 503 plays, each with an &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;text&lt;/code&gt;, &lt;code&gt;period&lt;/code&gt; and &lt;code&gt;clock&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;winprobability&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Home win probability after every play (see below)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;leaders&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Top performer per stat category for each team&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;odds&lt;/code&gt;, &lt;code&gt;pickcenter&lt;/code&gt;, &lt;code&gt;againstTheSpread&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Betting lines and against-the-spread records. Often empty for finished games: both were empty for our NBA test game&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;injuries&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Injury report for both teams&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;gameInfo&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Venue, attendance and officials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;standings&lt;/code&gt;, &lt;code&gt;seasonseries&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;League table and the season head-to-head&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;news&lt;/code&gt;, &lt;code&gt;article&lt;/code&gt;, &lt;code&gt;videos&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Recap and highlight content&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Other sports use the same path with their own sport and league. Football responses add &lt;code&gt;drives&lt;/code&gt; and &lt;code&gt;scoringPlays&lt;/code&gt;. Soccer responses add &lt;code&gt;keyEvents&lt;/code&gt; (a match timeline), &lt;code&gt;commentary&lt;/code&gt; and &lt;code&gt;rosters&lt;/code&gt;. A 2026 World Cup match looks like &lt;code&gt;soccer/fifa.world/summary?event=760506&lt;/code&gt; (Portugal vs Spain).&lt;/p&gt;

&lt;h2&gt;
  
  
  ESPN Win Probability Data
&lt;/h2&gt;

&lt;p&gt;ESPN publishes a win probability for every play, and there are two ways to get it. Use the summary endpoint unless you have a reason not to.&lt;/p&gt;

&lt;h3&gt;
  
  
  From the summary endpoint
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;winprobability&lt;/code&gt; array has one row per play:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"homeWinPercentage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.665&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"tiePercentage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"playId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"4017661224"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Values are fractions, not percents. The away side's chance is &lt;code&gt;1 - homeWinPercentage - tiePercentage&lt;/code&gt;. To see which play moved the number, match &lt;code&gt;playId&lt;/code&gt; to the &lt;code&gt;id&lt;/code&gt; of an entry in &lt;code&gt;plays&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;event_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;401766122&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;  &lt;span class="c1"&gt;# 2025 NBA Finals, Game 1
&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://site.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;plays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;plays&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;winprobability&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:]:&lt;/span&gt;
    &lt;span class="n"&gt;play&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;plays&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;playId&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;clock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;clock&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;displayValue&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;homeWinPercentage&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  Q&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;period&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="si"&gt;{}&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;number&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;clock&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;  &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;play&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;text&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  From the core API
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://sports.core.api.espn.com/v2/sports/basketball/leagues/nba/events/{eventId}/competitions/{eventId}/probabilities
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For NBA games the competition ID is the same as the event ID. This version is paginated (&lt;code&gt;?limit=&lt;/code&gt; and &lt;code&gt;?page=&lt;/code&gt;) and each item is a &lt;code&gt;$ref&lt;/code&gt; link, so every play costs one more request. The records do carry extra fields: &lt;code&gt;awayWinPercentage&lt;/code&gt;, &lt;code&gt;spreadCoverProbHome&lt;/code&gt; and &lt;code&gt;totalOverProb&lt;/code&gt;. The spread and total fields were all 0 in our test, so the summary array gives you the same useful numbers in one call.&lt;/p&gt;

&lt;h2&gt;
  
  
  ESPN Scoreboard URLs by League
&lt;/h2&gt;

&lt;p&gt;Every URL below returned HTTP 200 when we tested it. With no &lt;code&gt;dates&lt;/code&gt; parameter you get today's games, or the current week for football.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;League&lt;/th&gt;
&lt;th&gt;Scoreboard URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NBA&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/basketball/nba/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NFL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;College football&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/football/college-football/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MLB&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NHL&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/hockey/nhl/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Premier League&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/soccer/eng.1/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;La Liga&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/soccer/esp.1/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FIFA World Cup&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/soccer/fifa.world/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Every soccer league&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/soccer/all/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PGA Tour&lt;/td&gt;
&lt;td&gt;&lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/golf/pga/scoreboard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Cricket is the odd one out. It takes a numeric league ID in place of a slug: &lt;code&gt;cricket/8048/scoreboard&lt;/code&gt; returned a match, while &lt;code&gt;cricket/scoreboard&lt;/code&gt; returned 404.&lt;/p&gt;

&lt;h3&gt;
  
  
  Date filters
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Format&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;What we got back&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;YYYYMMDD&lt;/td&gt;
&lt;td&gt;&lt;code&gt;basketball/nba/scoreboard?dates=20250605&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One day: Game 1 of the 2025 NBA Finals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YYYYMM&lt;/td&gt;
&lt;td&gt;&lt;code&gt;basketball/nba/scoreboard?dates=202506&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A whole month: all 7 games of the 2025 NBA Finals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YYYYMM&lt;/td&gt;
&lt;td&gt;&lt;code&gt;soccer/fifa.world/scoreboard?dates=202606&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;79 World Cup matches from June 2026&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Season + week&lt;/td&gt;
&lt;td&gt;&lt;code&gt;football/nfl/scoreboard?dates=2025&amp;amp;seasontype=2&amp;amp;week=1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Week 1 of the 2025 NFL regular season (16 games)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;YYYYMMDD-YYYYMMDD&lt;/td&gt;
&lt;td&gt;&lt;code&gt;basketball/nba/scoreboard?dates=20250601-20250630&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP 400. Ranges failed for every league we tried&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Need a range? Request it month by month and filter the dates yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;p&gt;Here are practical examples for fetching data from the ESPN API:&lt;/p&gt;

&lt;h3&gt;
  
  
  Get NFL Scores
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fetch today's NFL scores&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;game&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;game&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;# Fetch today's NFL scores
&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;game&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;events&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;game&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;description&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fetch today's NFL scores&lt;/span&gt;
curl &lt;span class="s1"&gt;'https://site.api.espn.com/apis/site/v2/sports/football/nfl/scoreboard'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get NBA Game Summary
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fetch detailed game data (replace eventId with actual game ID)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eventId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;401584793&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://site.web.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;eventId&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Boxscore:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;boxscore&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Play-by-play:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;plays&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="c1"&gt;# Fetch detailed game data
&lt;/span&gt;&lt;span class="n"&gt;event_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;401584793&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;
&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;https://site.web.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;event_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;

&lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Boxscore:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;boxscore&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Play-by-play:&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;plays&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Get Scores for Specific Date
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Fetch MLB scores for a specific date&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;20251001&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// YYYYMMDD format&lt;/span&gt;
&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`https://site.api.espn.com/apis/site/v2/sports/baseball/mlb/scoreboard?dates=&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ESPN API 403 and 400 Errors
&lt;/h2&gt;

&lt;h3&gt;
  
  
  403 Forbidden
&lt;/h3&gt;

&lt;p&gt;ESPN serves these endpoints through a CDN that blocks some scripted traffic. In our tests, a script that sent a copied Chrome &lt;code&gt;User-Agent&lt;/code&gt; header got 403 on every request. The same URLs returned 200 with the default headers of curl, Python &lt;code&gt;requests&lt;/code&gt; and Node &lt;code&gt;fetch&lt;/code&gt;. If your script sets a browser User-Agent, delete that header first.&lt;/p&gt;

&lt;p&gt;If the 403 continues after that, slow down and cache what you fetch. ESPN publishes no rate limit, so there is no safe number to aim for.&lt;/p&gt;

&lt;h3&gt;
  
  
  400 Bad Request
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No valid event ID:&lt;/strong&gt; &lt;code&gt;summary&lt;/code&gt; needs &lt;code&gt;?event=&lt;/code&gt; with an id from a scoreboard response&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A date range:&lt;/strong&gt; &lt;code&gt;?dates=20250601-20250630&lt;/code&gt; fails. Use one day or one month&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  200 with an empty events array
&lt;/h3&gt;

&lt;p&gt;That means no games on that date, not a broken endpoint. Try a date you know had games.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limitations &amp;amp; Considerations
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Important: Unofficial API
&lt;/h4&gt;

&lt;p&gt;The ESPN API is &lt;strong&gt;not officially supported&lt;/strong&gt;. Keep these limitations in mind:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No Official Documentation:&lt;/strong&gt; These endpoints are undocumented and discovered through reverse engineering&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Stability Guarantee:&lt;/strong&gt; ESPN can modify or remove endpoints at any time without notice&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unknown Rate Limits:&lt;/strong&gt; There's no published information about rate limiting or usage quotas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Support:&lt;/strong&gt; ESPN does not provide developer support for these endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terms of Service:&lt;/strong&gt; Heavy automated usage may violate ESPN's terms of service&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Recommendations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;For Hobby Projects:&lt;/strong&gt; The ESPN API works great for personal projects, learning, and experimentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For Production Apps:&lt;/strong&gt; Consider official &lt;a href="https://sportsapis.dev/sports-data-api" rel="noopener noreferrer"&gt;sports data providers&lt;/a&gt; for applications requiring guaranteed uptime and support&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error Handling:&lt;/strong&gt; Implement robust error handling since endpoints may change unexpectedly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching:&lt;/strong&gt; Cache responses to reduce API calls and improve reliability&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Community Resources
&lt;/h2&gt;

&lt;p&gt;These community-maintained resources provide additional documentation and tools for working with the ESPN API:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/pseudo-r/Public-ESPN-API" rel="noopener noreferrer"&gt;ESPN API GitHub Repository&lt;/a&gt;: Comprehensive community documentation with endpoint references and examples&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gist.github.com/akeaswaran/b48b02f1c94f873c6655e7129910fc3b" rel="noopener noreferrer"&gt;ESPN Hidden API Gist&lt;/a&gt;: Original endpoint discovery documentation with URL patterns for multiple sports&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://scrapecreators.com/blog/espn-api-free-sports-data" rel="noopener noreferrer"&gt;ESPN API Tutorial&lt;/a&gt;: Step-by-step guide on accessing ESPN's free sports data endpoints&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://zuplo.com/learning-center/espn-hidden-api-guide" rel="noopener noreferrer"&gt;ESPN Hidden API Guide&lt;/a&gt;: Getting started guide with best practices and common use cases&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.gpwa.org/forum/espns-hidden-api-scores-stats-json-endpoints-251149.html" rel="noopener noreferrer"&gt;GPWA Forum Discussion&lt;/a&gt;: Community forum thread with additional endpoint discoveries and tips&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Does ESPN have a free API?
&lt;/h3&gt;

&lt;p&gt;ESPN does not offer an official public API, but developers have discovered undocumented endpoints that provide free access to scores, stats, news, and standings data. These hidden APIs require no authentication or API key, making them accessible for personal projects and experimentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is the ESPN API official?
&lt;/h3&gt;

&lt;p&gt;No. The ESPN API endpoints discussed here are unofficial and undocumented. They were discovered by reverse-engineering ESPN's web and mobile applications. ESPN does not provide official API documentation, support, or any service level agreements for these endpoints.&lt;/p&gt;

&lt;h3&gt;
  
  
  What sports does the ESPN API cover?
&lt;/h3&gt;

&lt;p&gt;The ESPN API covers NFL, NBA, MLB, NHL, WNBA, college football, men's and women's college basketball, college baseball, MLS, international soccer leagues (Premier League, La Liga, Bundesliga, Serie A, etc.), golf, tennis, MMA/UFC, racing, and many other sports.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need an API key for the ESPN API?
&lt;/h3&gt;

&lt;p&gt;No. The ESPN hidden API endpoints are publicly accessible and do not require authentication, API keys, or tokens. You can make simple HTTP GET requests to retrieve data. However, private fantasy league data may require authentication cookies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is the ESPN API reliable for production use?
&lt;/h3&gt;

&lt;p&gt;The ESPN API is not recommended for production applications that require guaranteed stability and uptime. Since these are unofficial endpoints, ESPN can modify or remove them at any time without notice. For production applications, consider using official sports data providers that offer documentation, support, and SLAs.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I get NBA scores from the ESPN API?
&lt;/h3&gt;

&lt;p&gt;To get NBA scores, make a GET request to: &lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/basketball/nba/scoreboard&lt;/code&gt;. The response includes all games for the current day with scores, team info, and game status. Add &lt;code&gt;?dates=YYYYMMDD&lt;/code&gt; to get scores for a specific date.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is the difference between site.api.espn.com and site.web.api.espn.com?
&lt;/h3&gt;

&lt;p&gt;For the game summary endpoint, nothing that matters. Both hosts returned the same JSON for the same event in our tests. &lt;code&gt;site.web.api.espn.com&lt;/code&gt; also serves some web-only data, such as search and athlete overviews.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I get win probability from the ESPN API?
&lt;/h3&gt;

&lt;p&gt;Call the summary endpoint for a game, for example &lt;code&gt;https://site.api.espn.com/apis/site/v2/sports/basketball/nba/summary?event=401766122&lt;/code&gt;, and read the &lt;code&gt;winprobability&lt;/code&gt; array. Each row has &lt;code&gt;homeWinPercentage&lt;/code&gt;, &lt;code&gt;tiePercentage&lt;/code&gt; and a &lt;code&gt;playId&lt;/code&gt; that matches a play in the &lt;code&gt;plays&lt;/code&gt; array. The full example is in the win probability section above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does the ESPN API return 403 Forbidden?
&lt;/h3&gt;

&lt;p&gt;In our tests, ESPN returned 403 when a script sent a copied browser &lt;code&gt;User-Agent&lt;/code&gt; header. Remove that header and let your HTTP client send its default. The same requests then returned 200. The 403 and 400 errors section above has more.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does the ESPN API have a rate limit?
&lt;/h3&gt;

&lt;p&gt;ESPN does not publish one. We did not hit a limit during our tests, but heavy traffic can get blocked without warning. Cache responses and do not poll faster than your app needs.&lt;/p&gt;

&lt;p&gt;If you outgrow the hidden endpoints, compare the official providers side by side in the &lt;a href="https://sportsapis.dev/" rel="noopener noreferrer"&gt;SportsAPIs.dev directory&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>sports</category>
      <category>javascript</category>
      <category>python</category>
    </item>
    <item>
      <title>Historical Odds APIs: Pinnacle and Bet365 Closing Lines for Backtesting</title>
      <dc:creator>SportsAPIs.dev</dc:creator>
      <pubDate>Thu, 15 Oct 2026 21:18:30 +0000</pubDate>
      <link>https://dev.to/sportsapis/historical-odds-apis-pinnacle-and-bet365-closing-lines-for-backtesting-chn</link>
      <guid>https://dev.to/sportsapis/historical-odds-apis-pinnacle-and-bet365-closing-lines-for-backtesting-chn</guid>
      <description>&lt;p&gt;&lt;em&gt;This post first appeared on &lt;a href="https://sportsapis.dev/historical-odds" rel="noopener noreferrer"&gt;SportsAPIs.dev&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Historical Odds Data Matters
&lt;/h2&gt;

&lt;p&gt;Historical odds data is essential for serious sports bettors and analytics professionals. Unlike current odds which show today's lines, &lt;strong&gt;historical odds APIs&lt;/strong&gt; provide access to past betting lines, enabling critical analysis:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backtesting Betting Models:&lt;/strong&gt; Test your betting strategies against years of real odds data to validate performance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closing Line Value (CLV):&lt;/strong&gt; Compare your bet prices to closing lines to measure betting skill&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Line Movement Analysis:&lt;/strong&gt; Study how odds change from opening to closing to identify sharp money&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sportsbook Comparison:&lt;/strong&gt; Analyze which bookmakers historically offer the best prices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Market Efficiency Studies:&lt;/strong&gt; Research betting market behavior and predictive accuracy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gold standard for historical odds is &lt;strong&gt;sharp sportsbook closing lines&lt;/strong&gt;, lines from books that accept professional bettors and maintain high limits, making their odds highly efficient and widely used as industry benchmarks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding Historical Odds Providers
&lt;/h2&gt;

&lt;p&gt;When evaluating historical odds providers, consider these key factors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Historical Depth:&lt;/strong&gt; How far back does the data go? (90 days to 10+ years)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharp Closing Lines:&lt;/strong&gt; Does it include closing lines from sharp sportsbooks?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sportsbook Coverage:&lt;/strong&gt; Which bookmakers are included?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Format:&lt;/strong&gt; API access vs. bulk CSV downloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update Frequency:&lt;/strong&gt; How often is historical data updated?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sharp Closing Lines &amp;amp; Why They Matter
&lt;/h2&gt;

&lt;p&gt;Sharp sportsbooks, those that accept professional bettors and maintain high limits, produce the most efficient closing lines in the market. These lines are critical for historical analysis because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Market Efficiency:&lt;/strong&gt; Sharp books accept professional action, making their lines reflect true market consensus&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Limits:&lt;/strong&gt; Large bet limits mean odds aren't easily moved by small wagers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Closing Line Value (CLV):&lt;/strong&gt; Beating the closing line at a sharp book is the industry benchmark for measuring betting skill&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Account Limits:&lt;/strong&gt; Sharp books don't ban winners, ensuring honest and efficient prices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Comparing sharp book closing lines against recreational sportsbook lines reveals historical +EV opportunities and helps validate model accuracy. Recreational books cater to casual bettors and often offer worse prices. The gap between sharp and recreational lines is where profitable bettors find consistent edges.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Historical Closing Line Data Includes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Opening lines&lt;/li&gt;
&lt;li&gt;Closing lines (most important for CLV analysis)&lt;/li&gt;
&lt;li&gt;Line movements with timestamps&lt;/li&gt;
&lt;li&gt;Moneyline, spread, totals&lt;/li&gt;
&lt;li&gt;Major sports: NFL, NBA, MLB, NHL, Soccer, Tennis&lt;/li&gt;
&lt;li&gt;Game results for settlement validation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Use Cases for Historical Odds Data
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Backtesting Betting Models
&lt;/h3&gt;

&lt;p&gt;The primary use case. Test your predictive models against historical odds to see if they would have been profitable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load historical odds for NBA from 2020 to today&lt;/li&gt;
&lt;li&gt;Run your model predictions for each game&lt;/li&gt;
&lt;li&gt;Compare model predictions to actual odds available&lt;/li&gt;
&lt;li&gt;Calculate ROI if you had bet based on model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pitfall to Avoid:&lt;/strong&gt; Don't backtest against opening lines only: you need to know what odds were available when your model would have actually made the bet.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Closing Line Value Analysis
&lt;/h3&gt;

&lt;p&gt;Measure your betting performance by comparing your bet prices to closing lines:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track all your bets with the odds you got&lt;/li&gt;
&lt;li&gt;Compare to Pinnacle closing line&lt;/li&gt;
&lt;li&gt;Calculate CLV% for each bet&lt;/li&gt;
&lt;li&gt;Positive CLV = beating the market (good!)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; You bet Lakers -5.5 at -110. Pinnacle closes at -6.5. You beat closing by 1 point (positive CLV).&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Line Movement Studies
&lt;/h3&gt;

&lt;p&gt;Analyze how odds move from opening to closing to identify sharp action:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Track opening vs. closing line differences&lt;/li&gt;
&lt;li&gt;Identify "steam moves" (rapid line changes)&lt;/li&gt;
&lt;li&gt;Correlate line moves with bet timing&lt;/li&gt;
&lt;li&gt;Find patterns in sharp betting&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Arbitrage Backtesting
&lt;/h3&gt;

&lt;p&gt;Find historical arbitrage opportunities to validate arb strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compare odds across multiple books historically&lt;/li&gt;
&lt;li&gt;Identify when arb opportunities existed&lt;/li&gt;
&lt;li&gt;Calculate historical arb profitability&lt;/li&gt;
&lt;li&gt;Determine which sportsbook pairs create most arbs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. Market Efficiency Research
&lt;/h3&gt;

&lt;p&gt;Academic and professional analysis of betting market behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Test efficient market hypothesis in sports betting&lt;/li&gt;
&lt;li&gt;Analyze favorite-longshot bias&lt;/li&gt;
&lt;li&gt;Study home field advantage pricing over time&lt;/li&gt;
&lt;li&gt;Quantify market reaction to news/injuries&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6. Sportsbook Comparison
&lt;/h3&gt;

&lt;p&gt;Determine which sportsbooks historically offer the best value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compare average odds across books for specific bet types&lt;/li&gt;
&lt;li&gt;Identify books that consistently offer better prices&lt;/li&gt;
&lt;li&gt;Find books with soft lines in specific sports/markets&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Historical Data Availability by Sport
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Sport&lt;/th&gt;
&lt;th&gt;Typical Historical Depth&lt;/th&gt;
&lt;th&gt;Pinnacle Available&lt;/th&gt;
&lt;th&gt;Data Quality&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NFL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5-10 years&lt;/td&gt;
&lt;td&gt;✅ Excellent&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;Most complete data available&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NBA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5-10 years&lt;/td&gt;
&lt;td&gt;✅ Excellent&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;Includes player props historical&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MLB&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;5-10 years&lt;/td&gt;
&lt;td&gt;✅ Excellent&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;Most extensive dataset&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;NHL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3-7 years&lt;/td&gt;
&lt;td&gt;✅ Good&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;Good coverage, fewer props&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Soccer&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3-7 years&lt;/td&gt;
&lt;td&gt;✅ Good&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;Varies by league&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;College Sports&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2-5 years&lt;/td&gt;
&lt;td&gt;❓ Limited&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;Less consistent coverage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MMA/Boxing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;2-5 years&lt;/td&gt;
&lt;td&gt;✅ Good&lt;/td&gt;
&lt;td&gt;⭐⭐⭐&lt;/td&gt;
&lt;td&gt;Major events well-covered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tennis&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;3-5 years&lt;/td&gt;
&lt;td&gt;✅ Good&lt;/td&gt;
&lt;td&gt;⭐⭐⭐⭐&lt;/td&gt;
&lt;td&gt;Grand Slams excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Historical Odds Pricing
&lt;/h2&gt;

&lt;p&gt;Historical odds data is typically more expensive than current odds because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Storage Costs:&lt;/strong&gt; Years of data requires significant database infrastructure&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acquisition Difficulty:&lt;/strong&gt; Historical data often comes from scraping over many years&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Licensing:&lt;/strong&gt; Some providers pay for official historical data rights&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Higher Value:&lt;/strong&gt; Critical for professional bettors willing to pay premium prices&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Typical Pricing Models
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Per-Sport Licensing:&lt;/strong&gt; $200-500/month per sport for multi-year history&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Historical Add-On:&lt;/strong&gt; $100-300/month added to current odds subscription&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bulk Data Dumps:&lt;/strong&gt; One-time purchase of CSV/JSON historical files ($500-2000)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Access:&lt;/strong&gt; Query historical odds via API (higher monthly fees)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Free Options:&lt;/strong&gt; Some providers offer 30-90 days of historical data in their lower-tier paid plans (starting ~$50/month). For longer history (years of data), expect $200+/month.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently Asked Questions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Where can I get free historical odds data?
&lt;/h3&gt;

&lt;p&gt;Free historical odds data is very limited. Some providers include limited historical data (past 30-90 days) in their free tiers. Sports-Reference.com offers basic closing lines for major sports going back years (free with registration). For comprehensive historical databases with Pinnacle/Bet365, you'll need paid access.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Closing Line Value (CLV)?
&lt;/h3&gt;

&lt;p&gt;Closing Line Value measures the difference between the odds you bet at and the closing odds (final odds before game starts). If you consistently bet at better prices than closing, you're beating the market. Example: You bet Lakers -5 (-110), line closes at -6 (-110). You gained 1 point of CLV. Pinnacle closing lines are the gold standard for CLV calculation.&lt;/p&gt;

&lt;h3&gt;
  
  
  How far back does historical Pinnacle data go?
&lt;/h3&gt;

&lt;p&gt;Most third-party providers offer Pinnacle historical data from 2018-present. Some specialized providers have older data, but pre-2018 data is harder to find. Pinnacle itself closed its public API in July 2025.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I backtest betting strategies with historical odds?
&lt;/h3&gt;

&lt;p&gt;Yes, this is the primary use of historical odds APIs. To properly backtest: (1) Get historical odds data with timestamps, (2) Run your model's predictions for past games, (3) Determine which odds would have been available when your model made each prediction, (4) Calculate P&amp;amp;L assuming you bet those odds. Never backtest using only opening or closing lines: use the actual odds available at decision time.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between opening and closing lines?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Opening lines&lt;/strong&gt; are the first odds posted by sportsbooks (often Sunday night for NFL). &lt;strong&gt;Closing lines&lt;/strong&gt; are the final odds right before the game starts. Closing lines are more accurate because they incorporate all betting action, sharp money, and late information. For backtesting, closing lines are more important.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do historical odds APIs include player props?
&lt;/h3&gt;

&lt;p&gt;Some do, but historical player props data is much more limited than game odds. A few providers include historical player props for NBA, NFL, and MLB going back 2-3 seasons. Expect to pay premium prices ($300+/month) for comprehensive historical props databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why are Pinnacle lines considered the "sharpest"?
&lt;/h3&gt;

&lt;p&gt;Pinnacle accepts professional bettors (unlike most sportsbooks that limit or ban winners), has very high betting limits, and uses sophisticated pricing models. This means Pinnacle's lines reflect true market consensus from sharp bettors. Other books often copy Pinnacle's lines because they're so accurate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I download historical odds as CSV files?
&lt;/h3&gt;

&lt;p&gt;Some providers offer bulk historical data downloads in CSV or JSON format. This is often cheaper than API access if you only need a one-time historical dataset. Expect to pay $500-2000 for multi-year, multi-sport CSV dumps.&lt;/p&gt;

&lt;p&gt;Compare the providers side by side in the &lt;a href="https://sportsapis.dev/" rel="noopener noreferrer"&gt;SportsAPIs.dev directory&lt;/a&gt;. For lines on the closed Pinnacle API, see the &lt;a href="https://sportsapis.dev/pinnacle-api" rel="noopener noreferrer"&gt;Pinnacle API guide&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>api</category>
      <category>sports</category>
      <category>datascience</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
