Changes in version 2.3.0 This release adds a 65-function ESPN college-football API layer, expanding cfbfastR's ESPN surface from 8 wrappers to 73. The new wrappers expose ESPN's core-v2 endpoints in ESPN's own ID space — complementary to the CollegeFootballData (cfbd_*) wrappers, and the natural join partners for espn_cfb_pbp() / espn_cfb_scoreboard(). Every wrapper was verified live against the 2023, 2024, and 2025 seasons. Naming alignment with the sportsdataverse convention (this dev cycle, never on CRAN): espn_cfb_player_statistics() is renamed to espn_cfb_player_career_stats() (the core-v2 /athletes/{id}/statistics career view, matching hoopR/wehoop/sportsdataverse-py). New espn_cfb_player_stats_v3() wraps the comprehensive web-common-v3 /athletes/{id}/stats payload (all categories, long format) — the _v3 companion to espn_cfb_player_stats() (core-v2 season statistics). New ESPN wrappers — football-specific metrics - espn_cfb_powerindex() — ESPN's College Football Power Index (FPI): every predictive metric and efficiency component, in long format. - espn_cfb_qbr() — Total Quarterback Rating (QBR) and the full set of clutch-weighted EPA components, one row per qualified passer. - espn_cfb_futures() — the season betting-futures board (national championship, conference, and award markets) with each sportsbook's American odds. - espn_cfb_recruits() — ESPN's recruiting board for a class, one row per recruit with grade, position/state/region rank, committed school, and hometown. New ESPN wrappers — players - espn_cfb_players(), espn_cfb_player(), espn_cfb_player_eventlog(), espn_cfb_player_gamelog(), espn_cfb_player_statistics(), espn_cfb_player_splits(), espn_cfb_player_overview(), and espn_cfb_player_seasons() — player index, biographical detail, per-game logs, season statistics, and split breakdowns. The season-level wrappers resolve athlete_id to human-readable name/position columns via an athlete_detail argument. New ESPN wrappers — teams - espn_cfb_teams(), espn_cfb_team(), espn_cfb_team_roster(), espn_cfb_team_schedule(), espn_cfb_team_record(), and espn_cfb_team_leaders() — team index, team-in-season detail, roster, schedule, records, and statistical leaders. - espn_cfb_team_ats(), espn_cfb_team_powerindex(), espn_cfb_team_events(), espn_cfb_team_ranks(), espn_cfb_team_awards(), and espn_cfb_team_coaches() — team against-the-spread records, single-team power index, season event log, poll-rank history, player awards, and coaching staff. New ESPN wrappers — game detail - espn_cfb_game_teams(), espn_cfb_game_team_linescores(), espn_cfb_game_team_leaders(), espn_cfb_game_team_roster(), espn_cfb_game_team_statistics(), and espn_cfb_game_team_records() — per-game team breakdowns. - espn_cfb_game_odds(), espn_cfb_game_broadcasts(), espn_cfb_game_predictor(), espn_cfb_game_probabilities(), espn_cfb_game_powerindex(), and espn_cfb_game_pbp() — per-game odds, broadcasts, pre-game predictor, live win-probability, matchup power index, and play-by-play. - espn_cfb_game_drives(), espn_cfb_game_drive_plays(), espn_cfb_game_play(), espn_cfb_game_leaders(), espn_cfb_game_situation(), espn_cfb_game_status(), espn_cfb_game_player_statistics(), and espn_cfb_game_player_box() — drive log, drive-scoped plays, single-play detail, game statistical leaders, situation, status, and per-player game box lines. - The play-level wrappers (espn_cfb_game_pbp(), espn_cfb_game_drive_plays(), espn_cfb_game_play()) extract every field ESPN returns for a play and expose its nested child collections through opt-in parameters: participants ("none"/"wide"/"long") and participants_list surface per-play athlete involvement (passer, rusher, tackler, …), and team_participants / team_participants_list surface the offense/defense team participants — "wide" modes pivot to one row per play, the *_list flags keep the raw detail as a list-column. - espn_cfb_game_team_records(detail = TRUE) unpacks each record's full statistic breakdown; espn_cfb_game_odds(line_history = TRUE) returns the open/close/current line-movement history. Roster and player-stats wrappers join ESPN position-catalog detail when position_detail = TRUE. - espn_cfb_game_drives() gains a plays argument — "list" nests each drive's plays (full play-by-play schema, with the participant pass-through options) as a list-column, "expand" returns the flat one-row-per-play table with drive_* context columns. The new espn_cfb_unnest_plays() performs the same drives-to-play-by-play transform on an already-fetched nested frame. - The game wrappers join human-readable team detail when team_detail = TRUE (default): every team-id column (team_id, home_team_id, start_team_id, leader_team_id, …) gains sibling *_name, *_abbreviation, *_location, *_display_name, *_color, *_logo_href, … columns from the ESPN team catalog. espn_cfb_game_teams(format = "wide") collapses the two competitor rows into a single per-game row with home_* / away_* columns for direct joining onto one-row-per-game tables. - espn_cfb_pbp_v2() — a core-v2-sourced successor to espn_cfb_pbp(): assembles play-by-play in one structured request (vs. the legacy site-v2 summary parse) and, with epa_wpa = TRUE, runs cfbfastR's full EPA/WPA model pipeline — producing EPA/WPA columns identical to the legacy modeled feed. New ESPN wrappers — catalogs and season metadata - espn_cfb_seasons(), espn_cfb_season_info(), espn_cfb_season_types(), espn_cfb_season_weeks(), espn_cfb_groups(), and espn_cfb_standings() — season structure, conferences, and standings. - espn_cfb_coaches(), espn_cfb_coach(), espn_cfb_venues(), espn_cfb_positions(), espn_cfb_awards(), espn_cfb_rankings(), and espn_cfb_week_rankings() — league catalogs and poll rankings. - espn_cfb_coach_record(), espn_cfb_franchises(), espn_cfb_franchise(), espn_cfb_venue(), espn_cfb_position(), and espn_cfb_award() — coach season win/loss records, the league franchise catalog, and single-record venue / position / award detail. New CollegeFootballData wrappers - cfbd_betting_ats() — season against-the-spread (ATS) summary records by team, wrapping the CollegeFootballData /teams/ats endpoint. - cfbd_stats_game_havoc() — per-game havoc statistics (total / front-seven / defensive-back havoc events and rates, offense and defense), wrapping the CollegeFootballData /stats/game/havoc endpoint. - cfbd_pbp_data_v2() is a new public function: a modular successor to cfbd_pbp_data() that runs the same EPA/WPA pipeline through a single shared engine (.run_epa_wpa()) and a canonical play-type taxonomy (.pbp_play_types()). The legacy cfbd_pbp_data() is unchanged. - espn_cfb_pbp_v2() now sources play-by-play and meta through the shared engine, requests participants = "wide" and team_participants = "wide" from espn_cfb_game_drives(), and adds the meta columns home_team_name, home_team_color, home_team_alternate_color, home_team_rank (and away_*) via the new .espn_pbp_game_meta() bridge. Output is a strict superset of legacy espn_cfb_pbp() on the meta columns. Bug fixes - espn_cfb_pbp() now builds its request URL with the ?event= query separator (previously concatenated as summaryevent=, which returned HTTP 404 for every game) and initializes its return frame before the tryCatch so an upstream failure no longer throws object 'plays_df' not found. - cfbd_pbp_data_v2() and espn_cfb_pbp_v2() preserve character id_play precision through the EPA/WPA pipeline. The legacy shared helper used unquoted numeric literals in two ifelse calls (a historical id_play swap for one game), which silently coerced character id_play to numeric and then lost precision past 2^53 — breaking the play-id join-back in espn_cfb_pbp_v2(). The modular .pbp_clean_pbp_dat() quotes those literals so id_play stays character; the legacy clean_pbp_dat() is unchanged. Internal changes - httr -> httr2 migration. cfbfastR's HTTP layer now uses the modern httr2 package (>= 1.0.0) instead of the legacy httr. End users running existing wrapper calls (cfbd_*, espn_cfb_*) should see no behavioural change -- the migration is internal. Custom code that calls get_req() or check_status() directly must update from httr::content(res, as = "text") to httr2::resp_body_string(res) and from httr::status_code(res) to httr2::resp_status(res). - Proxy support. get_req() now resolves a proxy in the order: explicit proxy argument -> getOption("cfbfastR.proxy") -> http_proxy / https_proxy env vars. The proxy value accepts either a URL string or a named list with url / port / username / password / auth for authenticated proxies. - Dependency footprint trimmed. lubridate, progressr, memoise, cachem, and magrittr have moved out of Imports (21 -> 16). lubridate is gone entirely -- its two ymd_hm() |> with_tz() calls in espn_cfb_schedule.R are now base-R as.POSIXct(format = "%Y-%m-%dT%H:%M", tz = "UTC") + attr(., "tzone"). progressr, memoise, and cachem moved to Suggests and the helpers degrade gracefully when missing: load_cfb_pbp() / cfbd_pbp_data() / pbp_epa_wpa_engine() run without a progress bar when progressr is absent; ESPN catalog wrappers run uncached when memoise / cachem are absent (espn_cfb_clear_cache() becomes a no-op). Drops the Imports count below the >20 R CMD check NOTE threshold. - Native pipe migration. All 1,419 %>% chains in R/, plus 137 across vignettes/ and tests/, were converted to the base-R native pipe |>. magrittr is no longer an Imports; downstream consumers that load cfbfastR purely for its functions don't get %>% re-exported anymore. User-visible impact is minimal -- the public API is unchanged and dplyr (which is in Imports) still re-exports %>% for users who want to keep writing it. Two non-mechanical fixes were needed during the sweep: three |> [[("url") chains in cfbd_betting.R and cfbd_coaches.R (rejected as RHS in R 4.1's |>) became |> purrr::pluck("url"); seven |> tibble::tibble(col = .data$.) constructs were a magrittr quirk that silently duplicated the LHS into both a . and the named column -- rewritten to tibble::tibble(col = ), which drops the redundant . column. - Test-time CFBD throttle. A new tests/testthat/setup-cfbd-throttle.R adds a 1-second sleep before every CFBD request made by devtools::test() / R CMD check. It works by monkey-patching cfbfastR:::get_req() for the duration of the test session (restored via withr::defer(., teardown_env())) -- the package code is unchanged, so interactive and production calls pay no penalty. Tunable via options(cfbfastR.test_request_delay = N) (default 1; set to 0 for unthrottled local runs). Resolves the cascading HTTP 429 skip-if-empty results that were turning otherwise-green test runs into "all green, mostly skipped." withr joins Suggests to declare the test-side dependency cleanly (it was already a transitive dep of testthat). Changes in version 2.2.0 - Fixes a bug in validate_week() utility function where some inputs were not being handled correctly (i.e. week 16). Fixes trickle down to cfbd_pbp_data() and other functions. - Default value for season_type parameter in cfbd_game_info() and cfbd_play_stats_player() function changed from "regular" to "both" to align with other functions in the package. Changes in version 2.1.0 - Fixes a bug in cfbd_pbp_data() where play-by-play data for some games were not as expected. - Improves add_yardage() where plays with missing yardage values were not being handled correctly. Changes in version 2.0.0 (2025-09-09) Breaking Changes to Loading Functions - All load_cfb_*() functions now use sportsdataverse-data releases or the CollegeFootballData.com API as their underlying data source to remain in compliance with CFBD API terms and conditions (See Note below). - Updated load_cfb_pbp() dataset to include various team- and game-level ID's and flags that were not being included, like home_team_id, away_team_id, season_type, venue_id, some drive_* columns, a half-dozen player stat columns, etc. Essentially, all the leg-work users have undoubtedly had to do while using these datasets is mostly just included now. The downside: this means end users need to check their pipelines which build off these datasets to ensure behavior is as expected and all your joins are doing what is intended. Now upgraded to the CFBD v2 API Special thanks are in order for our newest contributor, Brad Hill (@bradisbrad) for providing most of the v2 upgrade via his first PR to cfbfastR!! 🙌🏽 👑 🥇 Your contributions are most appreciated by the community. Note: The free-tier API key for the CFBD v2 API has a strict 1k calls/month limit, so plan your workflows accordingly! If you receive errors mentioning r Request failed [429], you have most likely run out of API calls for the month in your membership tier. - Added all new cfbd_*() functions accommodated by the new College Football Data API v2. This includes the following functions: - Added cfbd_metrics_fg_ep() function to access the new field goal expected points added metric from the API. - Added cfbd_metrics_wepa_team_season() function to access the new opponent adjusted team season predicted points added metric from the API. - Added cfbd_metrics_wepa_players_passing() function to access the new opponent adjusted players passing predicted points added metric from the API. - Added cfbd_metrics_wepa_players_rushing() function to access the new opponent adjusted players rushing predicted points added metric from the API. - Added cfbd_metrics_wepa_players_kicking() function to access the new Points Added Above Replacement (PAAR) ratings for kickers from the API. - Added cfbd_ratings_fpi() function to access the new FPI ratings from the API. - Added cfbd_live_scoreboard() function to access live scoreboard data from the API. - Added cfbd_live_plays() function to access live play-by-play data from the API. - Added cfbd_api_key_info() function to get information about your API key, including your Patreon level and usage limits. - Minor changes to the existing cfbd_*() functions under the hood to accommodate the new API v2 structure. Please see below for a list of all updated functions: - Updated cfbd_betting_lines() function - Updated cfbd_coaches() function - Updated cfbd_conferences() function - Updated cfbd_drives() function - Updated cfbd_calendar() function - Updated cfbd_game_box_advanced() function - Updated cfbd_game_info() function - Updated cfbd_game_media() function - Updated cfbd_game_player_stats() function - Updated cfbd_game_records() function - Updated cfbd_game_team_stats() function - Updated cfbd_metrics_ppa_games() function - Updated cfbd_metrics_ppa_players_games() function - Updated cfbd_metrics_ppa_players_season() function - Updated cfbd_metrics_ppa_predicted() function - Updated cfbd_metrics_ppa_teams() function - Updated cfbd_metrics_wp() function - Updated cfbd_metrics_wp_pregame() function - Updated cfbd_pbp_data() function - Updated cfbd_play_stats_player() function - Updated cfbd_play_stats_types() function - Updated cfbd_play_types() function - Updated cfbd_plays() function - Updated cfbd_player_info() function - Updated cfbd_player_returning() function - Updated cfbd_player_usage() function - Updated cfbd_rankings() function - Updated cfbd_ratings_sp() function - Updated cfbd_ratings_sp_conference() function - Updated cfbd_ratings_srs() function - Updated cfbd_recruiting_player() function - Updated cfbd_recruiting_position() function - Updated cfbd_recruiting_team() function - Updated cfbd_stats_categories() function - Updated cfbd_stats_game_advanced() function - Updated cfbd_stats_season_advanced() function - Updated cfbd_stats_season_player() function - Updated cfbd_stats_season_team() function - Updated cfbd_team_info() function - Updated cfbd_team_matchup() function - Updated cfbd_team_matchup_records() function - Updated cfbd_team_roster() function - Updated cfbd_team_talent() function - Updated cfbd_venues() function - Fixed the following functions and/or documentation: - Documentation cfbd_team_info() addressing #97 - Ensuring cfbd_stats_game_advanced() returns an empty data frame when there are no results - Documentation cfbd_game_team_stats() updated to reflect all parameter requirement scenarios. - Fixed athlete_id parameter cfbd_player_usage() so that it works as users would expect. There was an API query-parameter mismatch - Fixed athlete_id parameter for cfbd_play_stats_player() function and added more thorough documentation. - Fixed returned position to correct value (instead of NA) from cfbd_stats_season_player() - Added more thorough season_type parameter documentation across many functions - Changed behavior of cfbd_pbp_data() to substitute 3 timeouts per half when the data is missing from the API. Changes in version 1.9.5 - fixed breaking bug related to stringi v1.8 update in cfbd_play_pbp_data() EPA and WPA processing - Minor documentation and test updates Changes in version 1.9.4 - Improve date parsing for espn_cfb_scoreboard() and espn_cfb_schedule() functions while adding lubridate dependency - Made a minor tweak to the returns of the espn_ratings_fpi() function Changes in version 1.9.3 - Add division parameter to the following functions: - cfbd_game_info() - cfbd_plays() - cfbd_drives() - cfbd_game_media() - cfbd_game_team_stats() Changes in version 1.9.2 - espn_cfb_player_stats() function added. Changes in version 1.9.1 - Improved drive_pts logic in play-by-play data. - Fixed an issue that occasionally made the cfbd_game_team_stats() function return data in a long format - Minor documentation and test updates Changes in version 1.9.0 (2022-06-13) Added functions to access ESPN API: - espn_cfb_calendar() - espn_cfb_schedule() - Added EPA and WPA processing to espn_cfb_pbp() - espn_cfb_team_stats() Added functions to pull data from the data repo: - load_cfb_rosters() - load_cfb_schedules() - load_cfb_teams() - Removes furrr, future dependencies, adds Rcpp, RcppParallel, and purrr dependencies Changes in version 1.8.0 - All functions now default to return tibbles. - Added S3 method to print outputs with data info and retrieval timestamps. Thank you to Tan Ho (@tanho36) for the idea. Changes in version 1.7.1 - Added espn_ratings_fpi() to exports. Changes in version 1.7.0 - Added cfbd_recruiting_transfer_portal(). Changes in version 1.6.7 - Fixed bug in cfbd_game_team_stats() with _allowed columns duplicating team stats instead of showing opponent stats. - Updated tests and documentation for cfbd_game_team_stats(). Changes in version 1.6.6 - Updated function cfbd_pbp_data() to account for additional timeout cases (namely, kickoffs/extra point attempts). Changes in version 1.6.5 - Updated tests and documentation for cfbd_betting_lines() - API call in espn_ratings_fpi() now requires headers in httr request Changes in version 1.6.4 (2021-10-27) - Changed options to revert to old options on exit of function. - Removed check_github functions. Changes in version 1.6.3 - Switched package urls in DESCRIPTION again. Changes in version 1.6.2 - Switched package urls in README and DESCRIPTION files to https:// Changes in version 1.6.1 - Removed source urls from many package documentation entries. - Updated a test to skip on CRAN Changes in version 1.6.0 - Added cfbd_ratings_elo() function - Fixed a bug in update_cfb_db() where the function failed when trying to load recent games from the data repo. (#35) - Added the option cfbfastR.dbdirectory that allows to set the database directory in update_cfb_db() globally. Changes in version 1.5.2 - Remove verbose parameter Changes in version 1.5.1 Minor release - Removed calculated columns from cfbd_stats_season_team() that were not behaving correctly - Fixed bug where only_fbs input in cfbd_team_info() was ignored. It is now possible to get the team info for all the colleges in the API instead of only FBS schools. - Removed default year from cfbd_metrics_ppa_teams. cfbd_metrics_ppa_teams and cfbd_metrics_ppa_players_season now require one of team or year to be specified Changes in version 1.5.0 Added espn_cfb_scoreboard() Added espn_cfb_pbp() Changes in version 1.4.0 Added cfbd_game_weather() Changes in version 1.3.3 Hotfix cfbd_game_player_stats() Changes in version 1.3.2 Added ID linking to cfbd_recruiting_players() Changes in version 1.3.0-1 Added three NFL draft functions: - cfbd_draft_teams() - Get list of NFL teams - cfbd_draft_positions() - Get list of NFL positions for mapping to collegiate - cfbd_draft_picks() - Get list of NFL Draft picks Changes in version 1.2.1 Minor release - Added headshot_url to outputs of cfbd_team_roster() - Renamed returns in cfbd_game_box_advanced(): - rushing_line_yd_avg to plural rushing_line_yds_avg - rushing_second_lvl_yd_avg to plural rushing_second_lvl_yds_avg - rushing_open_field_yd_avg to plural rushing_open_field_yds_avg - Completed documentation for all returns except cfbd_pbp_data() - Continued work on intro vignette Changes in version 1.2.0-1 Add significant documentation to the package - Added mini-vignettes pertaining to CFB Data functionality: - cfbd_betting, - cfbd_games, - cfbd_plays, - cfbd_recruiting, - cfbd_stats, - cfbd_teams - Introductory vignette stub added ESPN/CFBD metrics function variable return standardization - Change id variable to team_id in espn_ratings_fpi() - Changed espn_game_id variable to game_id in espn_metrics_wp(), corrected the away_win_percentage calculation and added tie_percentage to the returns. - Change id variable to athlete_id in cfbd_metrics_ppa_players_season() Changes in version 1.1.0 Add loading from Data Repository functionality - Added load_cfb_pbp() and update_cfb_db() functions. Pretty much cherry-picking the nflfastR methodology of loading data from the cfbfastR-data repository. Add support for parallel processing and progress updates - Added furrr, future, and progressr dependencies to the package to allow for parallel processing of the play-by-play data with progress updates if desired. Changes in version 1.0.0 Function Naming Convention Change - All functions sourced from the College Football Data API will start with cfbd_ as opposed to cfb_ (as in cfbscrapR). One additional cfbd_ function has been added that corresponds to the result when cfbd_pbp_data() has the parameter epa_wpa=FALSE. It has now been separated into its own function for clarity cfbd_plays(). The parameter and functionality still exists in cfbd_pbp_data() but we expect this function will still exist but made obsolete in favor of a function more closely matching nflfastR's naming conventions. - Similarly, data and metrics sourced from ESPN will begin with espn_ as opposed to cfb_. In particular, the two functions are now espn_ratings_fpi() and espn_metrics_wp() - Data generated from any of the cfbfastR methods will use cfb_ College Football Data API Keys The CollegeFootballData API now requires an API key, here's a quick run-down: - To get an API key, follow the directions here: College Football Data Key Registration. - Using the key: You can save the key for consistent usage by adding CFBD_API_KEY=XXXX-YOUR-API-KEY-HERE-XXXXX to your .Renviron file (easily accessed via usethis::edit_r_environ()). Run usethis::edit_r_environ(), a new script will pop open named .Renviron, THEN paste the following in the new script that pops up (without quotations) CFBD_API_KEY = XXXX-YOUR-API-KEY-HERE-XXXXX Save the script and restart your RStudio session, by clicking Session (in between Plots and Build) and click Restart R (n.b. there also exists the shortcut Ctrl + Shift + F10 to restart your session). If set correctly, from then on you should be able to use any of the cfbd_ functions without any other changes. - For less consistent usage: At the beginning of every session or within an R environment, save your API key as the environment variable CFBD_API_KEY (with quotations) using a command like the following. Sys.setenv(CFBD_API_KEY = "XXXX-YOUR-API-KEY-HERE-XXXXX") - Added API Key methods. If you forget to set your environment variable, functions will give you a warning and ask for one.