Skip to content

Getting Data in Batches

This following information only applies to the /events/, /teams, and /players endpoints. Other endpoints will always return all of the results which match your query. However, there may be hundreds or even thousands of results to these endpoints, so they must be fetched in batches.

How It Works

  1. Make a request. Each request has a limit on the number of items returned.
  2. If there are more items to show, you’ll get a nextCursor in the response.
  3. Repeat the query but put the value from last request’s nextCursor in the cursor parameter.
  4. Repeat this until you no longer receive a nextCursor in the response in order to get all of the results.

The cursor Parameter

This tells the API where to pick up from. If you received a response from the API and there are more items to show, you’ll get a nextCursor at the top level of the response. Use this value in the cursor parameter of your next request to pick up where you left off.

Notes on using cursor:

  • Always use the value from the last response’s nextCursor property. Don’t try to reverse-engineer the cursor value yourself
  • Don’t change any query parameters between cursor requests. This will cause the cursor to not function properly.
  • Don’t try to reverse-engineer the cursor value yourself. Just use the value from the last response’s nextCursor property instead.
  • In some cases, the API may return a nextCursor when in fact there are no more items to show. So if you include a cursor parameter and get 404 (no results) back, that just means you’ve reached the end of the results.

The limit Parameter

The limit parameter determines the max number of items to return in each request. It has a default value which can be overridden.

  • If you don’t specify a limit parameter, then a limit of 10 will be used.
  • If you specify a limit above 300, then you’ll receive an error.
  • Otherwise, the limit applied is the smaller value between the limit parameter you supplied and the max-limit for the endpoint.
  • If you’re making a request to the /players or /teams endpoints, the max-limit is 250
  • If you’re making a request to the /events endpoint, the max-limit varies from 25-100 depending on the query. Factors affecting this include:
    • If the query filters for specific fields (ex: oddIDs)
    • If the query is for upcoming or past events
    • If the query includes alt lines

Example

Let’s take the following example, where we want to grab all unfinalized NBA events:

js
const allEvents = [];
let nextCursor = null;
let hasMore = true;
while (hasMore) {
  try {
    const response = await axios.get("https://api.sportsgameodds.com/v2/events", {
      params: {
        leagueID: "NBA",
        finalized: false,
        limit: 100,
        cursor: nextCursor,
      },
      headers: {
        "x-api-key": YOUR_API_KEY,
      },
    });
    allEvents.push(...response.data.data);
    nextCursor = response.data.nextCursor;
    hasMore = Boolean(nextCursor);
  } catch (error) {
    hasMore = false;
  }
}

console.log(`Found ${allEvents.length} events`);
allEvents.forEach((event) => console.log(event.eventID));

return allEvents;
python
import requests

all_events = []
next_cursor = None
has_more = True

while has_more:
    try:
        response = requests.get(
            "https://api.sportsgameodds.com/v2/events",
            params={
                "leagueID": "NBA",
                "finalized": "false",
                "limit": 100,
                "cursor": next_cursor
            },
            headers={"x-api-key": YOUR_API_KEY}
        )
        response.raise_for_status()
        data = response.json()

        all_events.extend(data.get("data", []))
        next_cursor = data.get("nextCursor")
        has_more = next_cursor is not None
    except requests.RequestException:
        has_more = False

print(f"Found {len(all_events)} events")
for event in all_events:
    print(event["eventID"])

return all_events
ruby
require "net/http"
require "json"
require "uri"

def fetch_all_events(api_key)
  all_events = []
  next_cursor = nil
  has_more = true

  while has_more
    begin
      uri = URI("https://api.sportsgameodds.com/v2/events")
      params = {
        leagueID: "NBA",
        finalized: false,
        limit: 100,
        cursor: next_cursor
      }.compact
      uri.query = URI.encode_www_form(params)

      req = Net::HTTP::Get.new(uri)
      req["x-api-key"] = api_key

      res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
        http.request(req)
      end

      data = JSON.parse(res.body)
      all_events.concat(data["data"] || [])
      next_cursor = data["nextCursor"]
      has_more = !next_cursor.nil? && !next_cursor.empty?
    rescue StandardError
      has_more = false
    end
  end

  puts "Found #{all_events.length} events"
  all_events.each { |event| puts event["eventID"] }

  all_events
end
php
$allEvents = [];
$nextCursor = null;
$hasMore = true;

while ($hasMore) {
    try {
        $params = [
            'leagueID' => 'NBA',
            'finalized' => 'false',
            'limit' => 100,
        ];
        if ($nextCursor !== null) {
            $params['cursor'] = $nextCursor;
        }

        $ch = curl_init("https://api.sportsgameodds.com/v2/events?" . http_build_query($params));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "x-api-key: " . YOUR_API_KEY
        ]);

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode !== 200) {
            throw new Exception("HTTP Error: " . $httpCode);
        }

        $data = json_decode($response, true);
        $events = $data['data'] ?? [];
        $allEvents = array_merge($allEvents, $events);
        $nextCursor = $data['nextCursor'] ?? null;
        $hasMore = $nextCursor !== null;
    } catch (Exception $e) {
        $hasMore = false;
    }
}

echo "Found " . count($allEvents) . " events\n";
foreach ($allEvents as $event) {
    echo $event['eventID'] . "\n";
}

return $allEvents;
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

List<JsonObject> allEvents = new ArrayList<>();
String nextCursor = null;
boolean hasMore = true;
HttpClient client = HttpClient.newHttpClient();

while (hasMore) {
    try {
        String url = String.format(
            "https://api.sportsgameodds.com/v2/events?leagueID=NBA&finalized=false&limit=100%s",
            nextCursor != null ? "&cursor=" + nextCursor : ""
        );

        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(url))
            .header("x-api-key", YOUR_API_KEY)
            .GET()
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        JsonObject data = JsonParser.parseString(response.body()).getAsJsonObject();

        data.getAsJsonArray("data").forEach(event ->
            allEvents.add(event.getAsJsonObject())
        );

        nextCursor = data.has("nextCursor") && !data.get("nextCursor").isJsonNull()
            ? data.get("nextCursor").getAsString()
            : null;
        hasMore = nextCursor != null;
    } catch (Exception e) {
        hasMore = false;
    }
}

System.out.println("Found " + allEvents.size() + " events");
allEvents.forEach(event ->
    System.out.println(event.get("eventID").getAsString())
);

return allEvents;