the-odds-api 0.2.0

A Rust SDK for The Odds API - sports odds and scores
Documentation

the-odds-api-rs

A Rust SDK for The Odds API, providing access to sports betting odds, scores, and related data from bookmakers worldwide.

Features

  • Full coverage of The Odds API v4 endpoints
  • Strongly-typed request parameters and responses
  • Builder pattern for flexible request configuration
  • Async/await support with reqwest
  • API usage tracking via response headers
  • Comprehensive error handling

Installation

cargo add the_odds_api

Or add to your Cargo.toml:

[dependencies]
the_odds_api = "0.1"
tokio = { version = "1", features = ["full"] }

Quick Start

use the_odds_api::{TheOddsApiClient, Region, Market};

#[tokio::main]
async fn main() -> the_odds_api::Result<()> {
    let client = TheOddsApiClient::new("your-api-key");

    // Get all in-season sports
    let sports = client.get_sports().await?;
    println!("Found {} sports", sports.data.len());

    // Get NFL odds from US bookmakers
    let odds = client
        .get_odds("americanfootball_nfl")
        .regions(&[Region::Us])
        .markets(&[Market::H2h, Market::Spreads])
        .send()
        .await?;

    // Check API usage
    println!("Requests remaining: {:?}", odds.usage.requests_remaining);

    Ok(())
}

API Endpoints

Sports

Get all available sports. Free - does not count against quota.

// Get in-season sports only
let sports = client.get_sports().await?;

// Get all sports including out-of-season
let all_sports = client.get_all_sports().await?;

Events

Get events for a sport without odds. Free - does not count against quota.

let events = client
    .get_events("americanfootball_nfl")
    .commence_time_from(start_time)
    .commence_time_to(end_time)
    .send()
    .await?;

Options:

  • date_format(DateFormat) - Response date format (ISO or Unix)
  • event_ids(ids) - Filter by specific event IDs
  • commence_time_from(DateTime) - Filter events starting after this time
  • commence_time_to(DateTime) - Filter events starting before this time

Odds

Get odds for a sport. Quota cost: markets x regions

let odds = client
    .get_odds("americanfootball_nfl")
    .regions(&[Region::Us, Region::Uk])
    .markets(&[Market::H2h, Market::Spreads, Market::Totals])
    .odds_format(OddsFormat::American)
    .bookmakers(["draftkings", "fanduel"])
    .include_links(true)
    .send()
    .await?;

Options:

  • regions(&[Region]) - Required. Bookmaker regions (Us, Us2, Uk, Au, Eu)
  • markets(&[Market]) - Market types (H2h, Spreads, Totals, Outrights)
  • odds_format(OddsFormat) - Decimal or American
  • date_format(DateFormat) - ISO or Unix
  • event_ids(ids) - Filter by event IDs
  • bookmakers(keys) - Filter by bookmaker keys
  • commence_time_from/to(DateTime) - Time range filter
  • include_links(bool) - Include deep links to bookmaker pages
  • include_sids(bool) - Include site IDs
  • include_bet_limits(bool) - Include betting limits

Scores

Get live and completed scores. Quota cost: 1 (or 2 with days_from)

// Live/upcoming scores
let scores = client
    .get_scores("americanfootball_nfl")
    .send()
    .await?;

// Include completed games from past 3 days
let scores = client
    .get_scores("americanfootball_nfl")
    .days_from(3)
    .send()
    .await?;

Options:

  • days_from(u8) - Include games from past 1-3 days (costs 2 instead of 1)
  • date_format(DateFormat) - ISO or Unix
  • event_ids(ids) - Filter by event IDs

Event Odds

Get detailed odds for a single event, including player props. Quota cost: markets x regions

let event_odds = client
    .get_event_odds("americanfootball_nfl", "event_id_here")
    .regions(&[Region::Us])
    .markets(&[Market::H2h])
    .custom_market("player_pass_tds")  // Player props
    .include_multipliers(true)  // DFS multipliers
    .send()
    .await?;

Options:

  • regions(&[Region]) - Required. Bookmaker regions
  • markets(&[Market]) - Standard market types
  • custom_market(key) - Add player prop or alternate markets by key
  • odds_format(OddsFormat) - Decimal or American
  • bookmakers(keys) - Filter by bookmaker keys
  • include_links(bool) - Deep links
  • include_sids(bool) - Site IDs
  • include_multipliers(bool) - DFS multipliers

Event Markets

Discover available markets for an event. Quota cost: 1

let markets = client
    .get_event_markets("americanfootball_nfl", "event_id_here")
    .regions(&[Region::Us])
    .send()
    .await?;

// Returns list of available market keys per bookmaker
for bookmaker in markets.data.bookmakers {
    println!("{}: {:?}", bookmaker.title, bookmaker.markets);
}

Participants

Get all teams/players for a sport. Quota cost: 1

let participants = client
    .get_participants("americanfootball_nfl")
    .await?;

Historical Odds

Get odds snapshot at a specific point in time. Quota cost: 10 x markets x regions

use chrono::{TimeZone, Utc};

let historical = client
    .get_historical_odds("americanfootball_nfl")
    .date(Utc.with_ymd_and_hms(2024, 1, 15, 12, 0, 0).unwrap())
    .regions(&[Region::Us])
    .markets(&[Market::H2h])
    .send()
    .await?;

// Navigate through time
println!("Snapshot: {}", historical.data.timestamp);
println!("Previous: {:?}", historical.data.previous_timestamp);
println!("Next: {:?}", historical.data.next_timestamp);

Historical Events

Get events that existed at a specific point in time. Quota cost: 1

let historical_events = client
    .get_historical_events("americanfootball_nfl")
    .date(snapshot_time)
    .send()
    .await?;

Historical Event Odds

Get historical odds for a specific event. Quota cost: markets x regions

let historical_event = client
    .get_historical_event_odds("americanfootball_nfl", "event_id")
    .date(snapshot_time)
    .regions(&[Region::Us])
    .markets(&[Market::Spreads])
    .send()
    .await?;

Types

Regions

pub enum Region {
    Us,   // United States
    Us2,  // United States (secondary)
    Uk,   // United Kingdom
    Au,   // Australia
    Eu,   // Europe
}

Markets

pub enum Market {
    H2h,       // Head to head (moneyline)
    Spreads,   // Point spreads
    Totals,    // Over/under
    Outrights, // Futures
    H2hLay,    // Draw no bet
    Custom(String), // Player props, alternates
}

Odds Format

pub enum OddsFormat {
    Decimal,  // 2.50
    American, // +150, -200
}

Configuration

Custom Client

use the_odds_api::TheOddsApiClient;

// Use IPv6 endpoint
let client = TheOddsApiClient::builder("your-api-key")
    .use_ipv6()
    .build();

// Custom base URL
let client = TheOddsApiClient::builder("your-api-key")
    .base_url("https://custom-endpoint.example.com")
    .build();

// Custom reqwest client
let http_client = reqwest::Client::builder()
    .timeout(std::time::Duration::from_secs(30))
    .build()?;

let client = TheOddsApiClient::builder("your-api-key")
    .client(http_client)
    .build();

API Usage Tracking

Every response includes usage information from the API headers:

let response = client.get_odds("americanfootball_nfl")
    .regions(&[Region::Us])
    .send()
    .await?;

println!("Requests remaining: {:?}", response.usage.requests_remaining);
println!("Requests used: {:?}", response.usage.requests_used);
println!("Last request cost: {:?}", response.usage.requests_last);

Error Handling

use the_odds_api::Error;

match client.get_odds("invalid_sport").regions(&[Region::Us]).send().await {
    Ok(odds) => { /* handle success */ }
    Err(Error::Unauthorized) => {
        println!("Invalid API key");
    }
    Err(Error::RateLimited { requests_remaining }) => {
        println!("Rate limited. Remaining: {:?}", requests_remaining);
    }
    Err(Error::Api { status, message }) => {
        println!("API error {}: {}", status, message);
    }
    Err(Error::MissingParameter(param)) => {
        println!("Missing required parameter: {}", param);
    }
    Err(e) => {
        println!("Other error: {}", e);
    }
}

License

MIT