### Clone and install oddsapiR locally Source: https://oddsapir.sportsdataverse.org/index.html Clone the repository and install locally using pak or devtools. ```bash git clone https://github.com/sportsdataverse/oddsapiR cd oddsapiR Rscript -e "pak::local_install()" # or: Rscript -e "devtools::install()" ``` -------------------------------- ### Install oddsapiR with pak and load libraries Source: https://oddsapir.sportsdataverse.org/articles/oddsapiR.html Install oddsapiR and its suggested dependencies using the pak package, then load dplyr, knitr, and gt for the vignette examples. ```r # You can install using the pak package using the following code: if (!requireNamespace('pak', quietly = TRUE)){ install.packages('pak') } pak::pak("sportsdataverse/oddsapiR", dependencies = TRUE, update = TRUE) pak::pak("jthomasmock/gtExtras", dependencies = TRUE, update = TRUE) pak::pak(c("dplyr", "knitr", "gt")) library(dplyr) library(knitr) library(gt) ``` -------------------------------- ### Install oddsapiR using pak Source: https://oddsapir.sportsdataverse.org/index.html Recommended installation method using the pak package. Installs the latest development version from GitHub. ```r if (!requireNamespace('pak', quietly = TRUE)){ install.packages('pak') } pak::pak("sportsdataverse/oddsapiR") ``` -------------------------------- ### Install oddsapiR using devtools Source: https://oddsapir.sportsdataverse.org/index.html Alternative installation method using the devtools package. Installs from GitHub using install_github. ```r if (!requireNamespace('devtools', quietly = TRUE)){ install.packages('devtools') } devtools::install_github(repo = "sportsdataverse/oddsapiR") ``` -------------------------------- ### Install development dependencies with pak or devtools Source: https://oddsapir.sportsdataverse.org/CONTRIBUTING.html Install the development dependencies for oddsapiR. The recommended method uses pak, but devtools is also supported. ```r # recommended: install.packages("pak") pak::local_install_dev_deps() # or with devtools: install.packages("devtools") devtools::install_dev_deps() ``` -------------------------------- ### Example: toa_sports() and toa_quota() with output Source: https://oddsapir.sportsdataverse.org/reference/toa_quota.html Example usage showing toa_sports() to make an API call and then toa_quota() to inspect the usage quota. The output displays the tibble with quota information and the sports coverage data. ```r # \donttest{ try(toa_sports()) #> ── Sports coverage data from the-odds-api.com ──────── oddsapiR 1.0.1 ── #> ℹ Data updated: 2026-10-09 05:38:12 UTC #> ℹ Odds API quota: 208904 used, 4791096 remaining (last call cost 0) #> # A tibble: 180 × 6 #> key group title description active has_outrights #> #> 1 americanfootball_cfl Amer… CFL Canadian F… TRUE FALSE #> 2 americanfootball_ncaaf Amer… NCAAF US College… TRUE FALSE #> 3 americanfootball_ncaaf_… Amer… NCAA… US College… TRUE TRUE #> 4 americanfootball_ncaaf_… Amer… NCAA… US College… TRUE FALSE #> 5 americanfootball_nfl Amer… NFL US Football TRUE FALSE #> 6 americanfootball_nfl_pr… Amer… NFL … US Football FALSE FALSE #> 7 americanfootball_nfl_su… Amer… NFL … Super Bowl… TRUE TRUE #> 8 americanfootball_ufl Amer… UFL United Foo… FALSE FALSE #> 9 aussierules_afl Auss… AFL Aussie Foo… FALSE FALSE #> 10 aussierules_aflw Auss… AFL … Aussie Foo… TRUE FALSE #> # ℹ 170 more rows try(toa_quota()) #> # A tibble: 1 × 3 #> requests_remaining requests_used requests_last #> #> 1 4791096 208904 0 # } ``` -------------------------------- ### Install oddsapiR development version from GitHub Source: https://oddsapir.sportsdataverse.org/index.html Installs the development version of oddsapiR directly from GitHub. ```R remotes::install_github("sportsdataverse/oddsapiR") ``` -------------------------------- ### Build & Development Commands Source: https://oddsapir.sportsdataverse.org/CLAUDE.html Commands for regenerating documentation, running tests, checking the package, building the README and pkgdown site, and installing locally. Requires ODDS_API_KEY for live tests. ```bash # Regenerate roxygen documentation + NAMESPACE devtools::document() # Run all tests (live; needs ODDS_API_KEY set) devtools::test() # Run a specific test file testthat::test_file("tests/testthat/test-toa_event_odds.R") # Full R CMD check devtools::check() # Re-render README from README.Rmd devtools::build_readme() # Build pkgdown site locally pkgdown::build_site() # Install locally (prefer pak) pak::local_install() ``` -------------------------------- ### Odds API Output Example Source: https://oddsapir.sportsdataverse.org/articles/oddsapiR.html Example output from an odds API call showing the home team, away team, outcomes name, bookmaker, and outcomes price for a basketball game. ```r # home_team away_team outcomes_name bookmaker outcomes_price # Los Angeles Lakers Boston Celtics Los Angeles Lakers DraftKings 2.05 # Los Angeles Lakers Boston Celtics Boston Celtics FanDuel 1.87 ``` -------------------------------- ### Example with output of toa_sports() Source: https://oddsapir.sportsdataverse.org/reference/toa_sports.html Example call wrapped in try() to handle errors, showing the printed output including a tibble of 180 sports. The output includes the data update timestamp and quota usage information. ```r # \donttest{ try(toa_sports(all_sports = TRUE)) #> ── Sports coverage data from the-odds-api.com ──────── oddsapiR 1.0.1 ── #> ℹ Data updated: 2026-10-09 05:38:13 UTC #> ℹ Odds API quota: 208904 used, 4791096 remaining (last call cost 0) #> # A tibble: 180 × 6 #> key group title description active has_outrights #> #> 1 americanfootball_cfl Amer… CFL Canadian F… TRUE FALSE #> 2 americanfootball_ncaaf Amer… NCAAF US College… TRUE FALSE #> 3 americanfootball_ncaaf_… Amer… NCAA… US College… TRUE TRUE #> 4 americanfootball_ncaaf_… Amer… NCAA… US College… TRUE FALSE #> 5 americanfootball_nfl Amer… NFL US Football TRUE FALSE #> 6 americanfootball_nfl_pr… Amer… NFL … US Football FALSE FALSE #> 7 americanfootball_nfl_su… Amer… NFL … Super Bowl… TRUE TRUE #> 8 americanfootball_ufl Amer… UFL United Foo… FALSE FALSE #> 9 aussierules_afl Auss… AFL Aussie Foo… FALSE FALSE #> 10 aussierules_aflw Auss… AFL … Aussie Foo… TRUE FALSE #> # ℹ 170 more rows # } ``` -------------------------------- ### Install oddsapiR from CRAN Source: https://oddsapir.sportsdataverse.org/index.html Installs the stable CRAN version of the oddsapiR package. ```R install.packages("oddsapiR") ``` -------------------------------- ### toa_requests() usage example Source: https://oddsapir.sportsdataverse.org/reference/toa_requests.html Calls toa_requests() to retrieve API key usage. The example is wrapped in try() and \donttest{} to avoid errors during testing. The output shows the usage data and a tibble with requests_remaining and requests_used. ```R # \donttest{ try(toa_requests()) #> ── API Key Usage data from the-odds-api.com ────────── oddsapiR 1.0.1 ── #> ℹ Data updated: 2026-10-09 05:38:12 UTC #> ℹ Odds API quota: 208904 used, 4791096 remaining (last call cost 0) #> # A tibble: 1 × 2 #> requests_remaining requests_used #> #> 1 4791096 208904 # } ``` -------------------------------- ### Worked example: pulling moneyline odds Source: https://oddsapir.sportsdataverse.org/articles/oddsapiR.html Minimal workflow: check quota, pull NBA moneyline odds, inspect, and find best lines. ```r library(oddsapiR) library(dplyr) # 1. Verify a key exists and check starting budget check_toa_key() toa_requests() # requests_remaining = 500, requests_used = 0 # 2. Pull moneyline (h2h) odds for the NBA from US books nba_h2h <- toa_sports_odds( sport_key = "basketball_nba", regions = "us", markets = "h2h", odds_format = "decimal", date_format = "iso" ) # 3. Inspect: one row per (event x bookmaker x outcome) glimpse(nba_h2h) # Rows: ~120 # Columns: id, sport_key, sport_title, commence_time, home_team, away_team, # bookmaker_key, bookmaker, bookmaker_last_update, # market_key, market_last_update, outcomes_name, outcomes_price # 4. Find the best moneyline price for each team across all books best_lines <- nba_h2h %>% group_by(home_team, away_team, outcomes_name) %>% slice_max(outcomes_price, n = 1) %>% select(home_team, away_team, outcomes_name, bookmaker, outcomes_price) best_lines ``` -------------------------------- ### Check API key and budget with check_toa_key() and toa_requests() Source: https://oddsapir.sportsdataverse.org/articles/building-an-odds-pipeline.html Verify the API key is set with check_toa_key(), which errors loudly if missing. Then check the remaining credit budget with toa_requests() before starting to pull data. ```r check_toa_key() ``` ```r budget_before <- toa_requests() budget_before # # A tibble: 1 x 2 # requests_remaining requests_used # # 480 20 ``` -------------------------------- ### Example: toa_sports_events() with basketball_nba Source: https://oddsapir.sportsdataverse.org/reference/toa_sports_events.html Example call to toa_sports_events() for the NBA, wrapped in try() to handle errors. The output shows a tibble with 46 rows and 6 columns, including event id, sport key, sport title, commence time, home team, and away team. The output also displays the Odds API quota usage and data update timestamp. ```r # \donttest{ try(toa_sports_events(sport_key = 'basketball_nba')) #> ── Sports Events data from the-odds-api.com ────────── oddsapiR 1.0.1 ── #> ℹ Data updated: 2026-10-09 05:38:13 UTC #> ℹ Odds API quota: 208904 used, 4791096 remaining (last call cost 0) #> # A tibble: 46 × 6 #> id sport_key sport_title commence_time home_team away_team #> #> 1 26b036ff107f… basketba… NBA 2026-10-20T1… Detroit … Boston C… #> 2 2b042ddad3d3… basketba… NBA 2026-10-20T2… New York… Philadel… #> 3 bccd283de569… basketba… NBA 2026-10-21T0… San Anto… Oklahoma… #> 4 164cc0396837… basketba… NBA 2026-10-21T2… Washingt… Milwauke… #> 5 85e6e4e2404e… basketba… NBA 2026-10-21T2… Orlando … Atlanta … #> 6 47cc511bb5ce… basketba… NBA 2026-10-21T2… Brooklyn… Charlott… #> 7 60431a347fea… basketba… NBA 2026-10-21T2… Toronto … Chicago … #> 8 93cdd8e4ade5… basketba… NBA 2026-10-21T2… Miami He… Minnesot… #> 9 fd33c09c84ab… basketba… NBA 2026-10-22T0… New Orle… Indiana … #> 10 e6769c813dd6… basketba… NBA 2026-10-22T0… Memphis … Utah Jazz #> # ℹ 36 more rows # } ``` -------------------------------- ### toa_function wrapper example using toa_api_call and tryCatch Source: https://oddsapir.sportsdataverse.org/CLAUDE.html Shows the standard structure for an endpoint wrapper: builds a base URL and query list, initializes the return variable before tryCatch, calls toa_api_call, and returns the result unconditionally. Uses cli alerts for errors and warnings. ```r toa_function <- function(sport_key, regions = 'us', markets = 'h2h', date_format = 'iso'){ base_url <- glue::glue('https://api.the-odds-api.com/v4/sports/{sport_key}/odds') query_params <- list( apiKey = as.character(toa_key()), regions = regions, markets = markets, dateFormat = date_format ) odds <- data.frame() # initialize return var BEFORE tryCatch (see below) tryCatch( expr = { odds <- toa_api_call(base_url, query = query_params) %>% # ... parse ... make_toa_data("Sports Odds data from the-odds-api.com", Sys.time()) }, error = function(e) { cli::cli_alert_danger("{Sys.time()}: Invalid arguments or no data available for {sport_key}!") cli::cli_alert_danger("Error:\n{e}") }, warning = function(w) { cli::cli_alert_warning("{Sys.time()}: Warning:\n{w}") }, finally = {} ) return(odds) } ``` -------------------------------- ### toa_event_markets() example with error output Source: https://oddsapir.sportsdataverse.org/reference/toa_event_markets.html Example call to toa_event_markets() with a basketball_nba sport_key and a specific event_id. The output shows an error when no markets data is available: the function returns a 0x0 data frame and emits an error about renaming a non-existent column. ```r # \donttest{ try(toa_event_markets(sport_key = 'basketball_nba', event_id = '48db9c3293a52baab881d95d38f37a98', regions = 'us')) #> ✖ 2026-10-09 05:38:11.033617: Invalid arguments or no markets data available for event 48db9c3293a52baab881d95d38f37a98! #> ✖ Error: #> Error in `dplyr::rename()`: #> ! Can't rename columns that don't exist. #> ✖ Column `key` doesn't exist. #> data frame with 0 columns and 0 rows # } ``` -------------------------------- ### Call toa_sports_scores() to retrieve NBA scores Source: https://oddsapir.sportsdataverse.org/reference/toa_sports_scores.html Example usage of toa_sports_scores() with sport_key='basketball_nba', days_from=NULL, and date_format='iso'. The output shows a tibble with 46 rows and 9 columns, including game IDs, sport keys, commence times, completion status, and team names. The example is wrapped in try() and \donttest{} to avoid errors during package checks. ```r # \donttest{ try(toa_sports_scores(sport_key = 'basketball_nba', days_from = NULL, date_format = 'iso')) #> ── Sports scores data from the-odds-api.com ────────── oddsapiR 1.0.1 ── #> ℹ Data updated: 2026-10-09 05:38:16 UTC #> ℹ Odds API quota: 208918 used, 4791082 remaining (last call cost 1) #> # A tibble: 46 × 9 #> id sport_key sport_title commence_time completed home_team #> #> 1 26b036ff107f… basketba… NBA 2026-10-20T1… FALSE Detroit … #> 2 2b042ddad3d3… basketba… NBA 2026-10-20T2… FALSE New York… #> 3 bccd283de569… basketba… NBA 2026-10-21T0… FALSE San Anto… #> 4 164cc0396837… basketba… NBA 2026-10-21T2… FALSE Washingt… #> 5 85e6e4e2404e… basketba… NBA 2026-10-21T2… FALSE Orlando … #> 6 47cc511bb5ce… basketba… NBA 2026-10-21T2… FALSE Brooklyn… #> 7 60431a347fea… basketba… NBA 2026-10-21T2… FALSE Toronto … #> 8 93cdd8e4ade5… basketba… NBA 2026-10-21T2… FALSE Miami He… #> 9 fd33c09c84ab… basketba… NBA 2026-10-22T0… FALSE New Orle… #> 10 e6769c813dd6… basketba… NBA 2026-10-22T0… FALSE Memphis … #> # ℹ 36 more rows #> # ℹ 3 more variables: away_team , scores , last_update # } ``` -------------------------------- ### toa_requests() - Fetch quota from the API directly Source: https://oddsapir.sportsdataverse.org/articles/oddsapiR.html Hits the free /v4/sports endpoint specifically to read the current quota balance from the response headers. Use this at the start of a session to check your budget before pulling odds. ```R toa_requests() ``` -------------------------------- ### Discover active sports with toa_sports() and filter(active) Source: https://oddsapir.sportsdataverse.org/articles/building-an-odds-pipeline.html List all sports covered by the API with toa_sports(all_sports = TRUE), then filter to active == TRUE to get sports currently in season. The output shows the key, group, and title columns. ```r all_sports <- toa_sports(all_sports = TRUE) # Sports currently in season in_season <- all_sports %>% filter(active) %>% select(key, group, title) in_season # key group title # basketball_nba Basketball NBA # americanfootball_nfl American Football NFL # soccer_epl Soccer EPL # icehockey_nhl Ice Hockey NHL ``` -------------------------------- ### List upcoming NBA events with toa_sports_events() Source: https://oddsapir.sportsdataverse.org/articles/building-an-odds-pipeline.html Lists in-play and pre-match events for the NBA without odds using `toa_sports_events()`. The `id` column in the result is the `event_id` used by `toa_event_odds()` and `toa_event_markets()`. This example sets a 24-hour window from the current UTC time. ```r # Events for the next 24 hours now <- format(Sys.time(), "%Y-%m-%dT%H:%M:%SZ", tz = "UTC") tomorrow <- format(Sys.time() + 86400, "%Y-%m-%dT%H:%M:%SZ", tz = "UTC") nba_events <- toa_sports_events( sport_key = "basketball_nba", date_format = "iso", commence_time_from = now, commence_time_to = tomorrow ) nba_events ``` -------------------------------- ### toa_sports_participants usage example Source: https://oddsapir.sportsdataverse.org/reference/toa_sports_participants.html Example call to toa_sports_participants with sport_key = 'basketball_nba'. The output shows a tibble with participant IDs and names, and notes the Odds API quota usage. ```R # \donttest{ try(toa_sports_participants(sport_key = 'basketball_nba')) #> ── Sports Participants data from the-odds-api.com ──── oddsapiR 1.0.1 ── #> ℹ Data updated: 2026-10-09 05:38:15 UTC #> ℹ Odds API quota: 208917 used, 4791083 remaining (last call cost 1) #> # A tibble: 32 × 3 #> sport_key id full_name #> #> 1 basketball_nba par_01hqmkq6fceknv7cwebesgrx03 Atlanta Hawks #> 2 basketball_nba par_01hqmkq6fdf1pvq7jgdd7hdmpf Boston Celtics #> 3 basketball_nba par_01hqmkq6fefp3r8597cv3wj3cr Brooklyn Nets #> 4 basketball_nba par_01hqmkq6fffqq9gze9hqf1fwn6 Charlotte Hornets #> 5 basketball_nba par_01hqmkq6fgf7krk5evvjfy9mr1 Chicago Bulls #> 6 basketball_nba par_01hqmkq6fhec0t7bezwtzqv0fq Cleveland Cavaliers #> 7 basketball_nba par_01hqmkq6fje5rrsbnbx97seg30 Dallas Mavericks #> 8 basketball_nba par_01hqmkq6fkf9r8wh7303b8hy40 Denver Nuggets #> 9 basketball_nba par_01hqmkq6fmfyjsnjtexnh7vdwm Detroit Pistons #> 10 basketball_nba par_01hqmkq6fne7nsfvf365y98r0h Golden State Warriors #> # ℹ 22 more rows # } ``` -------------------------------- ### Add ODDS_API_KEY to .Renviron Source: https://oddsapir.sportsdataverse.org/reference/register_toa.html Paste this line into your .Renviron file (opened via usethis::edit_r_environ()) to save the key persistently. Do not include quotations. ```r ODDS_API_KEY = XXXX-YOUR-API-KEY-HERE-XXXXX ``` -------------------------------- ### Retrieve historical event odds with toa_event_odds_history() Source: https://oddsapir.sportsdataverse.org/reference/toa_event_odds_history.html Example call to toa_event_odds_history() for NBA basketball, specifying event ID, date, regions, markets, and formats. The output is a tibble with 20 rows and 16 columns, including timestamp, sport_key, and outcome details. The example is wrapped in \donttest{} to avoid CRAN test issues. ```r # \donttest{ try(toa_event_odds_history(sport_key = 'basketball_nba', event_id = '93af4b300a4c0dded909234ea32e9abd', date = '2024-01-15T12:15:00Z', regions = 'us', markets = 'h2h', odds_format = 'decimal', date_format = 'iso')) #> ── Historical Event Odds data from the-odds-api.com ── oddsapiR 1.0.1 ── #> ℹ Data updated: 2026-10-09 05:38:12 UTC #> ℹ Odds API quota: 208904 used, 4791096 remaining (last call cost 10) #> # A tibble: 20 × 16 #> timestamp previous_timestamp next_timestamp id sport_key #> #> 1 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 2 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 3 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 4 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 5 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 6 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 7 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 8 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 9 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 10 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 11 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 12 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 13 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 14 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 15 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 16 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 17 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 18 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 19 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> 20 2024-01-15T12:10:3… 2024-01-15T12:05:… 2024-01-15T12… 93af… basketba… #> # ℹ 11 more variables: sport_title , commence_time , #> # home_team , away_team , bookmaker_key , #> # bookmaker , bookmaker_last_update , market_key , #> # market_last_update , outcomes_name , outcomes_price ``` -------------------------------- ### devtools workflow commands for oddsapiR development Source: https://oddsapir.sportsdataverse.org/CONTRIBUTING.html Run these devtools commands in sequence during development: load_all() to load the package, document() to regenerate man/ and NAMESPACE after roxygen changes, test() to run the test suite (requires ODDS_API_KEY), build_readme() to re-render README.md from README.Rmd, and check() for a full R CMD check before opening a PR. ```R devtools::load_all() # load the package devtools::document() # regenerate man/ + NAMESPACE after changing roxygen devtools::test() # run the test suite (needs ODDS_API_KEY) devtools::build_readme() # re-render README.md from README.Rmd devtools::check() # full R CMD check before opening a PR ``` -------------------------------- ### Usage of toa_sports_odds_history() Source: https://oddsapir.sportsdataverse.org/reference/toa_sports_odds_history.html Shows the function signature with all arguments and defaults. Use this to call the function with a sport_key and date to get historical odds. ```r toa_sports_odds_history( sport_key, date, regions = "us", markets = "spreads", odds_format = "decimal", date_format = "iso", event_ids = NULL, bookmakers = NULL ) ``` -------------------------------- ### Fetch detailed props for a single game with toa_event_markets() and toa_event_odds() Source: https://oddsapir.sportsdataverse.org/articles/building-an-odds-pipeline.html First, discover available markets for a game using toa_event_markets() (costs 1 credit). Then fetch odds for a specific market (player_points) with toa_event_odds(), costing 1 market x 1 region = 1 credit. The output shows the distinct bookmaker-market combinations and the first 10 player-points props with decimal odds. ```r game_id <- "48db9c3293a52baab881d95d38f37a98" # from toa_sports_events() # Discover available markets for this game (1 credit) available_markets <- toa_event_markets( sport_key = "basketball_nba", event_id = game_id, regions = "us" ) available_markets %>% distinct(bookmaker, market_key) %>% arrange(bookmaker, market_key) # bookmaker market_key # DraftKings h2h # DraftKings player_points # DraftKings player_rebounds # DraftKings spreads # DraftKings totals # FanDuel h2h # FanDuel player_points # ... ``` ```r # Fetch player-points props (cost: 1 market x 1 region = 1 credit) player_pts <- toa_event_odds( sport_key = "basketball_nba", event_id = game_id, regions = "us", markets = "player_points", odds_format = "decimal", date_format = "iso" ) player_pts %>% select(bookmaker, outcomes_name, outcomes_description, outcomes_price, outcomes_point) %>% head(10) # bookmaker outcomes_name outcomes_description outcomes_price outcomes_point # DraftKings Over LeBron James 1.91 25.5 # DraftKings Under LeBron James 1.91 25.5 # FanDuel Over LeBron James 1.87 25.5 # FanDuel Under LeBron James 1.95 25.5 ``` -------------------------------- ### Build 6-snapshot series with toa_event_odds_history Source: https://oddsapir.sportsdataverse.org/articles/building-an-odds-pipeline.html Builds a 6-snapshot series for a specific event using toa_event_odds_history, pausing 0.5 seconds between calls to respect rate limits. Stops early if a snapshot returns zero rows. The output shows the resulting line movement for DraftKings spreads, with timestamps and point changes. ```R event_id <- "93af4b300a4c0dded909234ea32e9abd" start_date <- "2024-01-13T12:00:00Z" n_snapshots <- 6 snapshots <- list() current_date <- start_date for (i in seq_len(n_snapshots)) { snap <- toa_event_odds_history( sport_key = "basketball_nba", event_id = event_id, date = current_date, regions = "us", markets = "spreads", odds_format = "decimal", date_format = "iso" ) if (nrow(snap) == 0) break snapshots[[i]] <- snap current_date <- snap$next_timestamp[[1]] # Be kind to the API rate limit Sys.sleep(0.5) } line_movement <- bind_rows(snapshots) %>% filter(market_key == "spreads", bookmaker_key == "draftkings") %>% select(timestamp, home_team, away_team, outcomes_name, outcomes_price, outcomes_point) line_movement ``` ```text # timestamp home_team away_team outcomes_name price point # 2024-01-13T12:00:00Z Los Angeles Lakers Boston Celtics Los Angeles Lakers 1.91 -4.5 # 2024-01-13T17:00:00Z Los Angeles Lakers Boston Celtics Los Angeles Lakers 1.91 -5.0 # 2024-01-14T00:00:00Z Los Angeles Lakers Boston Celtics Los Angeles Lakers 1.95 -5.5 # ... ``` -------------------------------- ### toa_sports_odds Source: https://oddsapir.sportsdataverse.org/reference/toa_sports_odds.html Get the featured-market odds for a sport which The Odds API covers. Returns a list of upcoming and live games with featured bookmaker odds for the specified markets and regions. ```APIDOC ## toa_sports_odds ### Description Get the featured-market odds for a sport which The Odds API covers. Returns a list of upcoming and live games with featured bookmaker odds for the specified markets and regions. For player props and other additional markets, use `toa_event_odds()` instead. ### Usage ```r toa_sports_odds( sport_key, regions = "us", markets = "spreads", odds_format = "decimal", date_format = "iso" ) ``` ### Arguments - **sport_key** (string, required): The `sport_key` to look up odds for. See `toa_sports()` for a full lookup of `sport_key` values. - **regions** (string, required): The region(s) to pull bookmakers from. Multiple can be specified if comma delimited. Options include: `us`, `us2`, `uk`, `eu`, `au`. - **markets** (string, optional): The featured markets to return. Multiple can be specified if comma delimited. Options include: `h2h` (moneyline), `spreads` (points handicaps), `totals` (over/under), `outrights` (futures, select sports only). - **odds_format** (string, optional): Format in which to return odds. Options are `decimal` (default) or `american`. - **date_format** (string, optional): Format of returned timestamps. Options are `iso` (default) or `unix`. ### Value A long-format tibble with one row per bookmaker market outcome: | col_name | types | description | |---|---|---| | id | character | Unique event id. | | sport_key | character | Sport key, e.g. `basketball_nba`. | | sport_title | character | Human-readable sport title, e.g. `NBA`. | | commence_time | character | Game start time (ISO 8601 string or unix seconds). | | home_team | character | Home team name. | | away_team | character | Away team name. | | bookmaker_key | character | Bookmaker slug, e.g. `draftkings`. | | bookmaker | character | Bookmaker display title, e.g. `DraftKings`. | | bookmaker_last_update | character | When this bookmaker's odds were last updated. | | market_key | character | Market key, e.g. `spreads`. | | market_last_update | character | When this market's odds were last updated. | | outcomes_name | character | Outcome label (team name, `Over`/`Under`, etc.). | | outcomes_price | numeric | The price/odds for the outcome. | | outcomes_point | numeric | The handicap/total line, when applicable. | ### Usage Quota Cost `[number of markets] x [number of regions]`. ### See Also `toa_event_odds()` for a single event's odds (including player props and alternate lines), `toa_event_markets()` to list a game's available market keys, and `toa_sports()` to find `sport_key` values. Part of the SportsDataverse. ### Examples ```r # Example usage (not provided in source) ``` ``` -------------------------------- ### Store snapshots to SQLite with DBI and RSQLite Source: https://oddsapir.sportsdataverse.org/articles/building-an-odds-pipeline.html Sets up a SQLite archive with DBI and RSQLite, creating an odds_snapshots table keyed by pulled_at. The pull_and_store function fetches odds via toa_sports_odds, appends rows, and reports success; it returns early if no rows are returned. Close the connection with dbDisconnect when done. ```R # --- one-time setup --- con <- dbConnect(RSQLite::SQLite(), "odds_archive.sqlite") # Create the table if it doesn't exist yet dbExecute(con, " CREATE TABLE IF NOT EXISTS odds_snapshots ( pulled_at TEXT, snapshot_ts TEXT, event_id TEXT, sport_key TEXT, sport_title TEXT, commence_time TEXT, home_team TEXT, away_team TEXT, bookmaker_key TEXT, bookmaker TEXT, market_key TEXT, outcomes_name TEXT, outcomes_price REAL, outcomes_point REAL ) ") # --- called on each scheduled pull --- pull_and_store <- function(sport_key, regions = "us", markets = "h2h,spreads") { pulled_at <- format(Sys.time(), "%Y-%m-%dT%H:%M:%SZ", tz = "UTC") raw <- toa_sports_odds( sport_key = sport_key, regions = regions, markets = markets, odds_format = "decimal", date_format = "iso" ) if (nrow(raw) == 0) return(invisible(NULL)) to_store <- raw %>% mutate(pulled_at = pulled_at) %>% select( pulled_at, snapshot_ts = bookmaker_last_update, event_id = id, sport_key, sport_title, commence_time, home_team, away_team, bookmaker_key, bookmaker, market_key, outcomes_name, outcomes_price, # outcomes_point may be NA for h2h outcomes_point = dplyr::any_of("outcomes_point") ) dbAppendTable(con, "odds_snapshots", to_store) cli::cli_alert_success("Stored {nrow(to_store)} rows at {pulled_at}.") } # Run the pull pull_and_store("basketball_nba") # When done for the session, close the connection dbDisconnect(con) ``` -------------------------------- ### View bundled sport keys with head() Source: https://oddsapir.sportsdataverse.org/articles/building-an-odds-pipeline.html Displays the first 10 rows of the bundled `toa_sports_keys` dataset, which maps sport keys to metadata without a network call. The `key` column is the `sport_key` argument for downstream functions. ```r head(oddsapiR::toa_sports_keys, 10) #> ── Sports coverage data from the-odds-api.com ──────── oddsapiR 1.0.1 ── #> ℹ Data updated: 2022-06-17 05:54:44 UTC #> # A tibble: 10 × 5 #> key group title description has_outrights #> #> 1 americanfootball_ncaaf Amer… NCAAF US College… FALSE #> 2 americanfootball_nfl Amer… NFL US Football FALSE #> 3 americanfootball_nfl_super_bow… Amer… NFL … Super Bowl… TRUE #> 4 aussierules_afl Auss… AFL Aussie Foo… FALSE #> 5 baseball_mlb Base… MLB Major Leag… FALSE #> 6 baseball_mlb_world_series_winn… Base… MLB … World Seri… TRUE #> 7 basketball_euroleague Bask… Bask… Basketball… FALSE #> 8 basketball_nba Bask… NBA US Basketb… FALSE #> 9 basketball_nba_championship_wi… Bask… NBA … Championsh… TRUE #> 10 basketball_ncaab Bask… NCAAB US College… FALSE ``` -------------------------------- ### toa_event_odds_history Source: https://oddsapir.sportsdataverse.org/reference/toa_event_odds_history.html Get bookmaker odds for a single event as they appeared at a point in time. Accepts any available market key and returns odds at the snapshot closest to (and at or before) the requested date. ```APIDOC ## toa_event_odds_history ### Description Get bookmaker odds for a single event as they appeared at a point in time. Accepts any available market key (including player props and alternate lines) and returns the odds at the snapshot closest to (and at or before) the requested `date`. ### Usage ```r toa_event_odds_history( sport_key, event_id, date, regions = "us", markets = "h2h", odds_format = "decimal", date_format = "iso", bookmakers = NULL ) ``` ### Parameters - **sport_key** (character) - Required - The sport key for the event. - **event_id** (character) - Required - The historical event ID. - **date** (character) - Required - The date/time for the historical snapshot. - **regions** (character) - Optional - Regions for which to return odds. Default is "us". - **markets** (character) - Optional - Markets to return odds for. Default is "h2h". - **odds_format** (character) - Optional - Format for odds. Default is "decimal". - **date_format** (character) - Optional - Format for dates. Default is "iso". - **bookmakers** (character) - Optional - Filter by bookmakers. ### Response Returns a data frame with historical odds data, including columns `timestamp`, `previous_timestamp`, and `next_timestamp` for paging through snapshots. ### Notes - Historical odds for additional markets are available from 2023-05-03 at 5-minute intervals; featured markets reach back to June 2020 on paid plans. - Usage quota cost: `[number of unique markets returned] x [number of regions]` (standard rate, not the 10x historical multiplier). Snapshots with no data do not count against the quota. ``` -------------------------------- ### Load the package for interactive development Source: https://oddsapir.sportsdataverse.org/CONTRIBUTING.html Load the oddsapiR package in an R session for interactive development. ```r devtools::load_all() ```