# Quickstart - First API Call in 5 Minutes
URL: https://sportsgameodds.com/docs/basics/quickstart

# Quickstart - First API Call in 5 Minutes [#quickstart---first-api-call-in-5-minutes]

A complete, copy-paste tutorial to fetch live odds

## Step 1: Get Your API Key [#step-1-get-your-api-key]

1. Sign up at [sportsgameodds.com/pricing](/pricing)
2. Check your email for your API key
3. Copy your API key - you'll need it in the next step

## Step 2: Make A Request [#step-2-make-a-request]

1. Copy one of the examples below into a file
2. Replace `YOUR_API_KEY` with your actual API key
3. Run it!

<Tabs items="['Browser URL', 'cURL', 'JavaScript', 'Python', 'Ruby', 'PHP', 'Java']">
  <Tab value="Browser URL">
    ```text
    https://api.sportsgameodds.com/v2/events?apiKey=YOUR_API_KEY&leagueID=NBA,NFL,MLB&oddsAvailable=true
    ```
  </Tab>

  <Tab value="cURL">
    ```bash
    curl -X GET "https://api.sportsgameodds.com/v2/events?apiKey=YOUR_API_KEY&leagueID=NBA,NFL,MLB&oddsAvailable=true"
    ```
  </Tab>

  <Tab value="JavaScript">
    ```javascript
    (async () => {
      const response = await fetch("https://api.sportsgameodds.com/v2/events?apiKey=YOUR_API_KEY&leagueID=NBA,NFL,MLB&oddsAvailable=true");

    const output = await response.json();
    console.log(JSON.stringify(output.data, null, 2));
    })();

    ```
  </Tab>

  <Tab value="Python">
    ```python
    import requests
    import json

    response = requests.get(
        'https://api.sportsgameodds.com/v2/events',
        params={'leagueID': 'NBA,NFL,MLB', 'oddsAvailable': 'true', 'apiKey': 'YOUR_API_KEY'}
    )

    output = response.json()
    print(json.dumps(output['data'], indent=2))
    ```
  </Tab>

  <Tab value="Ruby">
    ```ruby
    require 'net/http'
    require 'json'

    uri = URI('https://api.sportsgameodds.com/v2/events')
    uri.query = URI.encode_www_form({
    leagueID: 'NFL,NBA,MLB',
    oddsAvailable: 'true',
    apiKey: 'YOUR_API_KEY'
    })

    response = Net::HTTP.get_response(uri)
    output = JSON.parse(response.body)

    puts JSON.pretty_generate(output['data'])

    ```
  </Tab>

  <Tab value="PHP">
    ```php
    <?php
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, 'https://api.sportsgameodds.com/v2/events?leagueID=NFL,NBA,MLB&oddsAvailable=true&apiKey=YOUR_API_KEY');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

    $response = curl_exec($ch);
    curl_close($ch);

    $output = json_decode($response, true);
    print_r($output['data']);
    ?>
    ```
  </Tab>

  <Tab value="Java">
    ```java
    import java.net.URI;
    import java.net.http.HttpClient;
    import java.net.http.HttpRequest;
    import java.net.http.HttpResponse;

    public class SportsGameOddsAPI {
    public static void main(String[] args) throws Exception {
    String url = "https://api.sportsgameodds.com/v2/events?" +
    "leagueID=NFL,NBA,MLB" +
    "&oddsAvailable=true" +
    "&apiKey=YOUR_API_KEY";

            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .GET()
                .build();

            HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
            System.out.println(response.body());
        }

    }

    ```
  </Tab>
</Tabs>

<Callout type="info">
  If you don't want to write code, paste the "Browser URL" example into your browser
</Callout>

## Step 3: See Live Odds [#step-3-see-live-odds]

You'll get a response like this:

```json
{
  "nextCursor": "n.1763687700000.4lronEc61vA9pcyqoRIa",
  "success": true,
  "data": [
    {
      "eventID": "4lronEc61vA9pcyqoRIa",
      "sportID": "FOOTBALL",
      "leagueID": "NFL",
      "type": "match",
      "teams": {
        "home": {
          "teamID": "HOUSTON_TEXANS_NFL",
          "names": {
            "long": "Houston Texans",
            "medium": "Texans",
            "short": "HOU"
          }
          //.. more team details
        },
        "away": {
          "teamID": "BUFFALO_BILLS_NFL",
          "names": {
            "long": "Buffalo Bills",
            "medium": "Bills",
            "short": "BUF"
          }
          //... more team details
        }
      },
      "status": {
        "started": false,
        "completed": false,
        "cancelled": false,
        "ended": false,
        "live": false,
        "delayed": false,
        "currentPeriodID": "",
        "previousPeriodID": "",
        "displayShort": "",
        "displayLong": "Upcoming",
        "inBreak": false,
        "hardStart": true,
        "periods": {
          "started": [],
          "ended": []
        },
        "oddsPresent": true,
        "oddsAvailable": true,
        "finalized": false,
        "startsAt": "2025-11-21T01:15:00.000Z",
        "previousStartsAt": []
      },
      "info": {
        "seasonWeek": "NFL 25/26"
      },
      "odds": {
        "passing_yards-JOSH_ALLEN_1_NFL-game-ou-over": {
          "oddID": "passing_yards-JOSH_ALLEN_1_NFL-game-ou-over",
          "opposingOddID": "passing_yards-JOSH_ALLEN_1_NFL-game-ou-under",
          "statID": "passing_yards",
          "statEntityID": "JOSH_ALLEN_1_NFL",
          "periodID": "game",
          "betTypeID": "ou",
          "sideID": "over",
          "playerID": "JOSH_ALLEN_1_NFL",
          "started": false,
          "ended": false,
          "cancelled": false,
          "bookOddsAvailable": true,
          "fairOddsAvailable": true,
          "fairOdds": "+100",
          "bookOdds": "-114",
          "fairOverUnder": "231",
          "bookOverUnder": "224.5",
          "openFairOdds": "+100",
          "openBookOdds": "-114",
          "openFairOverUnder": "231",
          "openBookOverUnder": "224.5",
          "scoringSupported": true,
          "byBookmaker": {
            "betmgm": {
              "odds": "-118",
              "overUnder": "224.5",
              "lastUpdatedAt": "2025-11-19T21:12:36.000Z",
              "available": true,
              "deeplink": "https://sports.nj.betmgm.com/en/sports?options=18503696-1407860184--325476953"
            },
            "prizepicks": {
              "odds": "+100",
              "overUnder": "224.5",
              "lastUpdatedAt": "2025-11-19T21:09:53.000Z",
              "available": true,
              "deeplink": "https://app.prizepicks.com/?projections=7878799-o-224.5"
            }
            //... more bookmakers
          },
          "marketName": "Josh Allen Passing Yards Over/Under"
        }
        //... more odds markets
      },
      "links": {
        "bookmakers": {
          "espnbet": "https://espnbet.com/sport/football/organization/united-states/competition/nfl/event/2c83a542-357e-4e78-8efe-58129cb8cd37",
          "draftkings": "https://sportsbook.draftkings.com/event/32225621",
          "nordicbet": "https://www.nordicbet.com/en/sportsbook/american-football/nfl/nfl/houston-texans-buffalo-bills"
          // ...more deeplinks
        }
      },
      "players": {
        "JOSH_ALLEN_1_NFL": {
          "playerID": "JOSH_ALLEN_1_NFL",
          "teamID": "BUFFALO_BILLS_NFL",
          "firstName": "Josh",
          "lastName": "Allen",
          "name": "Josh Allen",
          "nickname": "J.Allen"
        }
        // ... more players
      }
    }
    //... more events
  ]
}
```

### Understand the Response [#understand-the-response]

Let's break down what you just got:

**Event Details:**

* `eventID` - Unique identifier for this game
* `teams.home.name` - Home team: Los Angeles Lakers
* `teams.away.name` - Away team: Boston Celtics
* `startTime` - When the game starts (UTC)

**Odds Data:**
Each odd is keyed by `oddID` which follows this pattern:

```
{statID}-{statEntityID}-{periodID}-{betTypeID}-{sideID}
```

Note: The oddID does NOT include bookmakerID. Each oddID contains odds from ALL available bookmakers nested under the `byBookmaker` object.

**Example:** `points-home-game-sp-home` means:

* `points` - Stat being bet on (team points/score)
* `home` - Entity (home team)
* `game` - For the full game (not just a quarter/half)
* `sp` - This is a point spread bet (betTypeID)
* `home` - Side of the bet (home team)

**The odds show:**

* Each oddID contains odds from multiple bookmakers under `byBookmaker`
* Lakers -5.5 @ -110 from DraftKings, -5.5 @ -112 from FanDuel
* Celtics +5.5 @ -110 from DraftKings, +5.5 @ -108 from FanDuel
* Lakers moneyline -220 from DraftKings, -225 from FanDuel
* All odds values (spread, odds) are **strings**, not numbers

## Done! [#done]

**Congratulations!** You just fetched live odds from the SportsGameOdds API.

## Next Steps [#next-steps]

Now that you've made your first successful call, explore what else you can do:

### Build Something Real [#build-something-real]

Start with these complete, working examples:

* **[Live Odds Tracker](/docs/examples/live-odds-tracker)** - Track line movement in real-time
* **[Arbitrage Calculator](/docs/examples/arbitrage-calculator)** - Find guaranteed profit opportunities
* **[Odds Comparison Dashboard](/docs/examples/odds-comparison-dashboard)** - Compare odds across bookmakers
* **[Player Props Analyzer](/docs/examples/player-props-analyzer)** - Analyze player prop bets
* **[Parlay Builder](/docs/examples/parlay-builder)** - Build parlay bet calculators

### Learn the Basics [#learn-the-basics]

* **[Understanding Odds Data](/docs/data-types/odds)** - Deep dive into the oddID structure
* **[Sports Betting Glossary](/docs/info/glossary)** - Learn all the terminology
* **[Setup](/docs/basics/setup)** - More about how to get started with the API
* **[Rate Limiting](/docs/info/rate-limiting)** - Understand request limits

### Use Our SDK [#use-our-sdk]

Instead of raw HTTP requests, use our official SDKs with built-in pagination, retries, and type safety:

```bash
# TypeScript/JavaScript
npm install sports-odds-api
yarn add sports-odds-api
pnpm add sports-odds-api

# Python
pip install sports-odds-api
poetry add sports-odds-api

# Ruby
gem install sports-odds-api
bundle add sports-odds-api

# Go
go get github.com/SportsGameOdds/sports-odds-api-go
```

[Full SDK Guide →](/docs/sdk)

### Explore All Endpoints [#explore-all-endpoints]

* **[API Reference](/docs/reference)** - Interactive documentation for all endpoints
* **[Data Explorer](/docs/explorer)** - Browse our data schema interactively

## Common Next Questions [#common-next-questions]

<Accordions>
  <Accordion title="How do I get odds from multiple bookmakers?">
    By default, the API returns odds from all available bookmakers. Each bookmaker appears in the oddID:

    ```javascript
    // Filter to specific bookmaker
    fetch("/v2/events?leagueID=NBA&bookmakerID=draftkings");

    // Or get all and filter in code
    Object.entries(event.odds).forEach(([oddID, odd]) => {
      if (odd.bookmakerID === "draftkings") {
        console.log("DraftKings odds:", odd);
      }
    });
    ```

    See [all available bookmakers →](/docs/data-types/bookmakers)
  </Accordion>

  <Accordion title="How do I get live scores?">
    Scores are included automatically in the same response for live games:

    ```javascript
    const response = await fetch("/v2/events?leagueID=NBA&live=true", { headers: { "x-api-key": API_KEY } });

    const data = await response.json();
    data.data.forEach((event) => {
      console.log(`${event.teams.away.name}: ${event.scores.away}`);
      console.log(`${event.teams.home.name}: ${event.scores.home}`);
    });
    ```

    No separate API needed - odds, scores, and stats all in one response!
  </Accordion>

  <Accordion title="How do I get historical data?">
    Use the `startsAfter` and `startsBefore` parameters:

    ```javascript
    // Get all NBA games from December 2024
    fetch("/v2/events?leagueID=NBA&startsAfter=2024-12-01&startsBefore=2024-12-31");
    ```

    Historical data from 2024+ is included in all plans. Extended historical data (2020+) available on Pro/AllStar plans.
  </Accordion>

  <Accordion title="How often should I poll for live odds?">
    **Recommended intervals:**

    * **Pre-match:** Every 5-15 minutes (odds change slowly)
    * **Live:** Every 30-60 seconds (good balance)
    * **Critical moments:** Use real-time streaming (AllStar plan)

    Polling faster than 30 seconds wastes rate limits without meaningful updates.

    See [Best Practices Guide →](/docs/info/best-practices)
  </Accordion>

  <Accordion title="What counts as an &#x22;object&#x22; in pricing?">
    An **object** = 1 event (game). Each event includes ALL odds markets and ALL bookmakers by default.

    **Key difference from other APIs:** You pay per event, not per market or per bookmaker.

    **Example:**

    * 1 NBA game with 100 odds markets across 20 bookmakers = **1 object**
    * 10 NBA games = **10 objects**
    * Same 10 games polled twice = **20 objects** (charged per request)

    This makes SportsGameOdds 60-80% cheaper than competitors who charge per market or per bookmaker.

    Learn more: [Rate Limiting →](/docs/info/rate-limiting)
  </Accordion>
</Accordions>

**Ready to build something amazing?** Pick a recipe and start coding! 🚀