NEWS


hoopR 3.1.0

Development release on top of the CRAN-shipped 3.0.0 (commit b76100b3). Headline change is a 58-wrapper ESPN endpoint expansion that brings hoopR's ESPN coverage to parity with wehoop — athlete coverage, team detail, event detail, league catalog, news, calendar, injuries, plus draft / freeagents / transactions for the NBA. Also includes bug fixes for endpoint behavior that drifted after CRAN submission, the package-wide @return documentation upgrade, and a proxy-support restoration that addresses a regression introduced by the 3.0.0 httrhttr2 migration.

ESPN endpoint naming convention (game_/player_)

The 3.1.0 ESPN wrappers are renamed to the shared sportsdataverse taxonomy used by cfbfastR (and mirrored in wehoop): event_competitor* → game_team*, event_competition → game, event_* → game_*, and athlete_* → player_* (60 functions). These wrappers are new in this dev cycle and were never on CRAN, so the rename is applied directly (no deprecation shims). The web-common-v3 /athletes/{id}/stats wrapper becomes *_player_stats_v3 (kept alongside the core-v2 *_player_stats, a different endpoint).

New data loaders

13 new load_*() loaders bring NBA and MBB dataset coverage toward parity with the wehoop load_wnba_*() / load_wbb_*() families, reading the corresponding espn_nba_* / espn_mens_college_basketball_* release tags on sportsdataverse-data:

Player/team season-stats loaders return long-format frames (averages / totals / miscellaneous categories). Draft is NBA-only. All accept a seasons vector (min 2002, draft min 2003) and the same dbConnection / tablename dots used by the update_*_db() helpers.

New exported functions

58 new ESPN wrappers added across 8 domains (29 per league × 2 leagues

Athlete coverage (×8 per league)

| Function | Endpoint family | Description | |---|---|---| | espn_mbb_athlete_info() / espn_nba_athlete_info() | site-v2 | Athlete bio / team / position / status / college / draft info. | | espn_mbb_athlete_overview() / espn_nba_athlete_overview() | web-common-v3 | Season overview + last-5-games + news + rotowire notes. | | espn_mbb_athlete_stats() / espn_nba_athlete_stats() | web-common-v3 | Per-category stats as a named list (averages / totals). | | espn_mbb_athlete_gamelog() / espn_nba_athlete_gamelog() | web-common-v3 | Game-by-game log. | | espn_mbb_athlete_splits() / espn_nba_athlete_splits() | web-common-v3 | Long-format home / away / opponent splits. | | espn_mbb_athlete_eventlog() / espn_nba_athlete_eventlog() | core-v2 | Per-event log. statistics.$ref URLs returned as statistics_ref character column (not auto-resolved). | | espn_mbb_athlete_awards() / espn_nba_athlete_awards() | core-v2 | Awards (sparse / often empty); empty payload returns a canonical-shape empty tibble. | | espn_mbb_athlete_statisticslog() / espn_nba_athlete_statisticslog() | core-v2 | Per-season statistics log. |

Team detail (×5 per league)

| Function | Description | |---|---| | espn_mbb_team() / espn_nba_team() | Single-team info as a named list (Info, Record, NextEvent, StandingSummary, Coaches). | | espn_mbb_team_roster() / espn_nba_team_roster() | Roster (one row per athlete with position, height, weight, headshot). | | espn_mbb_team_schedule() / espn_nba_team_schedule() | Schedule (one row per event with opponent, venue, broadcast, result). | | espn_mbb_team_leaders() / espn_nba_team_leaders() | Statistical leaders in long format per category-rank-athlete. | | espn_mbb_team_news() / espn_nba_team_news() | Team-scoped news feed. |

Event detail (×4 per league)

| Function | Description | |---|---| | espn_mbb_event_odds() / espn_nba_event_odds() | Game-level odds (one row per provider). | | espn_mbb_event_probabilities() / espn_nba_event_probabilities() | Paginated play-level win probabilities (page loop capped at 50 pages; respects limit). | | espn_mbb_event_officials() / espn_nba_event_officials() | Per-game officials. | | espn_mbb_event_broadcasts() / espn_nba_event_broadcasts() | Broadcast outlets. |

League catalog (×6 per league)

| Function | Description | |---|---| | espn_mbb_leaders() / espn_nba_leaders() | League leaders (web-common-v3 statistics/byathlete). | | espn_mbb_venues() / espn_nba_venues() | Venue catalog. | | espn_mbb_coaches() / espn_nba_coaches() | Coach roster. | | espn_mbb_athletes_index() / espn_nba_athletes_index() | Paginated athlete index with progress messages. | | espn_mbb_seasons() / espn_nba_seasons() | Season list. | | espn_mbb_season_info() / espn_nba_season_info() | Single-season info. |

News + calendar (×2 per league)

| Function | Description | |---|---| | espn_mbb_news() / espn_nba_news() | League-level news feed (site-v2 /news). | | espn_mbb_calendar() / espn_nba_calendar() | Scoreboard calendar blocks (site-v2 /scoreboard?dates={season}). |

Injuries (×2 per league)

| Function | Description | |---|---| | espn_mbb_injuries() / espn_nba_injuries() | League-wide injury feed (site-v2 /injuries). | | espn_mbb_team_injuries() / espn_nba_team_injuries() | Team-scoped injury feed (site-v2 /teams/{id}/injuries). |

MBB injury data is typically sparse on ESPN; both variants return an empty tibble (rather than erroring) when no injuries are reported.

NBA-only ESPN endpoints

| Function | Description | |---|---| | espn_nba_draft() | Paginates core-v2 /seasons/{year}/draft (up to 20 pages); flat tibble of picks. | | espn_nba_freeagents() | Wraps core-v2 /seasons/{year}/freeagents; returns an empty tibble outside the off-season free-agent window. | | espn_nba_transactions() | Wraps site-v2 /transactions?season={year}&limit={limit} with null-safe to_team_id for release transactions. | | espn_nba_conferences() | NBA-side analog of espn_mbb_conferences(), against the NBA scoreboard-conferences endpoint. |

Tier 1 core-v2 expansion (crawler-driven)

22 new wrappers across 9 resource families, surfaced by an internal $ref-following crawler that mapped the reachable basketball API surface (21,962 fetches, 1,570 unique templates across all 4 basketball leagues). Each wrapper is a thin shim over a shared .espn_basketball_*() helper. WNBA + WBB siblings ship in wehoop's matching release.

| Function | Description | |---|---| | espn_nba_team_season_profile() / espn_mbb_team_season_profile() | Era-correct team identity in a specific season plus $ref URLs for deeper resources (record, statistics, leaders, coaches, etc.). Historical depth back to 1947 (NBA) / 1939 (MBB). | | espn_nba_franchise() / espn_mbb_franchise() | Franchise-level metadata. IDs are stable across relocations and rebrands. | | espn_nba_franchises() / espn_mbb_franchises() | Index of franchise IDs in the league. | | espn_nba_athlete_contracts() | Index of contract seasons recorded for an NBA athlete (NBA-only — WNBA athletes return empty). | | espn_nba_athlete_contract() | Salary, cap-rule flags, Bird status, and trade protections for one (athlete × season). | | espn_nba_season_awards() / espn_mbb_season_awards() | Index of award IDs given out in a season. | | espn_nba_award() / espn_mbb_award() | Award detail with winners (one row per winner; multi-recipient awards like All-NBA return 5 rows). | | espn_nba_futures() / espn_mbb_futures() | Per-season futures betting board in long format (one row per market × team × sportsbook). | | espn_nba_tournaments() / espn_mbb_tournaments() | Index of league-tracked tournaments. | | espn_nba_tournament() / espn_mbb_tournament() | Single tournament metadata + seasons-list $ref. | | espn_nba_tournament_seasons() / espn_mbb_tournament_seasons() | Seasons in which a given tournament was held. | | espn_nba_team_record() / espn_mbb_team_record() | Long-format record breakdown for one team in one season-type (Overall / Home / Road / vs Conference / etc.). | | espn_nba_coach() / espn_mbb_coach() | Single-coach biography, current team / college refs, and counts of career-record + per-season coaching entries. | | espn_nba_powerindex() / espn_mbb_powerindex() | Per-season Basketball Power Index and related metrics, long format (one row per team × stat). |

Tier 2A core-v2 expansion — season metadata

10 new wrappers across 5 resource families covering season-level metadata: season types, the per-(season × season-type) leaderboards, and (mostly college-only) season rankings. Backed by a shared R/espn_basketball_season_meta_helpers.R. WNBA + WBB siblings ship in wehoop's matching release.

| Function | Description | |---|---| | espn_nba_season_types() / espn_mbb_season_types() | Index of season-type IDs that exist for one season (1 = preseason, 2 = regular, 3 = postseason, 4 = off-season). | | espn_nba_season_type() / espn_mbb_season_type() | Single season-type detail (start / end dates, has-groups / has-standings / has-legs flags, $ref URLs to deeper resources). | | espn_nba_season_leaders() / espn_mbb_season_leaders() | Per-(season × season-type) leaderboards in long format (one row per category × rank). 14–15 categories × 25 leaders ≈ 350 rows. | | espn_nba_season_rankings() / espn_mbb_season_rankings() | Index of season-level rankings recorded for a season (NBA / WNBA return zero; MBB / WBB return AP Top 25 + Coaches Poll). | | espn_nba_season_ranking() / espn_mbb_season_ranking() | Per-week snapshot index for one ranking source — each row resolves to a per-week ranked-teams endpoint. |

Tier 2A core-v2 expansion — weeks + per-week rankings

8 new wrappers across 4 resource families covering the week structure of a season. Backed by a shared R/espn_basketball_week_helpers.R. WNBA + WBB siblings ship in wehoop's matching release.

| Function | Description | |---|---| | espn_nba_season_weeks() / espn_mbb_season_weeks() | Index of weeks within one (season × season-type). Typical: ~20 weeks for regular season. NBA / WNBA also have weeks; rankings only populate for MBB / WBB. | | espn_nba_season_week() / espn_mbb_season_week() | Single-week metadata (number, start / end dates, text label, $ref to the per-week rankings endpoint). | | espn_nba_week_rankings() / espn_mbb_week_rankings() | Index of ranking sources for one week (NBA returns zero; MBB returns AP + Coaches). | | espn_nba_week_ranking() / espn_mbb_week_ranking() | The ranked teams (typically 25 rows) for one (season-type × week × source). Includes current / previous rank, points, first-place votes, trend, record summary, team $ref. |

Tier 2A core-v2 expansion — groups (conferences and divisions)

8 new wrappers across 4 resource families covering the per-season group hierarchy (conferences, divisions, and member teams). Backed by a shared R/espn_basketball_group_helpers.R. WNBA + WBB siblings ship in wehoop's matching release.

| Function | Description | |---|---| | espn_nba_season_groups() / espn_mbb_season_groups() | Index of group IDs (conferences / divisions) for one (season × season-type). | | espn_nba_season_group() / espn_mbb_season_group() | Single-group metadata (name, abbreviation, midsize / short name, is_conference flag) plus $ref URLs to parent, children, member teams, and standings. | | espn_nba_season_group_children() / espn_mbb_season_group_children() | Index of child groups (e.g. divisions inside a conference, or conferences inside the NCAA Division I umbrella group). | | espn_nba_season_group_teams() / espn_mbb_season_group_teams() | Index of team IDs that belong to the group for that (season × season-type). |

Tier 2A core-v2 expansion — team deep + coach-in-season

7 new wrappers across 4 resource families covering deeper per-team and per-coach core-v2 endpoints. Backed by a shared R/espn_basketball_team_deep_helpers.R. WNBA + WBB siblings (where applicable) ship in wehoop's matching release.

| Function | Description | |---|---| | espn_nba_team_odds_records() / espn_mbb_team_odds_records() | Long-format odds-records breakdown (Money Line / ATS / O/U × Overall / Home / Road × W/L/Push). Sparse — many (team × season-type) combinations return empty. Default season_type = 0 (all-types aggregate, where ESPN actually populates). | | espn_nba_team_depthchart() | NBA-only long-format depth chart (one row per position × rank × athlete). | | espn_nba_team_season_roster() / espn_mbb_team_season_roster() | Per-season roster (core-v2 seasons/{y}/teams/{id}/athletes). Distinct from the existing site-v2 espn_*_team_roster(): era-correct, available back to the league's earliest season. | | espn_nba_coach_season() / espn_mbb_coach_season() | Single-coach metadata for one (coach × season). Includes name, birth info, and $refs to person / college / team. Sparse coverage — many combinations 404. |

Tier 2A core-v2 expansion — athlete career + draft pick

5 new wrappers across 3 resource families covering career-level athlete endpoints and the single-draft-pick lookup. Backed by R/espn_basketball_athlete_career_helpers.R and R/espn_basketball_draft_helpers.R.

| Function | Description | |---|---| | espn_nba_athlete_seasons() / espn_mbb_athlete_seasons() | List of seasons an athlete appeared in. | | espn_nba_athlete_career_stats() / espn_mbb_athlete_career_stats() | Long-format career stats. Default stat_type = 0L fetches the standard "All Splits" / regular-season view; pass a vector like c(0L, 1L, 2L) to bind multiple types (postseason / career aggregate) via a stat_type_id column. Coverage of types 1 and 2 is sparse — many athletes only populate type 0. | | espn_nba_draft_pick() | Single NBA draft-pick detail (defaults to most-recent NBA season, round 1, pick 1). MBB has no draft endpoint, so this wrapper is NBA-only on the hoopR side. |

Tier 2B core-v2 expansion — athlete event log + draft completion

5 new wrappers across 2 resource families. Extends the athlete and draft endpoint coverage with the remaining per-season core-v2 endpoints.

| Function | Description | |---|---| | espn_nba_athlete_eventlog_v2() / espn_mbb_athlete_eventlog_v2() | Per-season event log from core-v2 (seasons/{y}/athletes/{id}/eventlog). One row per (event × team) appearance with played flag + event/competition $refs. Distinct from the existing espn_*_athlete_eventlog() which hits the web-common-v3 gamelog endpoint with stats per game. | | espn_nba_draft_rounds() | Round-level summary for one NBA draft year (one row per round with pick count + completion status). | | espn_nba_draft_athletes() | Index of every athlete in a given NBA draft year (~102 entries: 60 picks + undrafted invitees). | | espn_nba_draft_status() | Single-row snapshot of one draft year's current state. |

Tier 2B core-v2 expansion — event meta endpoints

8 new wrappers across 4 resource families. Each wraps events/{eid}/competitions/{cid}/... and is added to both NBA and MBB shim files (16 new public functions across both leagues per package = 8 each).

| Function | Description | |---|---| | espn_nba_event_situation() / espn_mbb_event_situation() | Live game situation: timeouts, fouls, fouls-to-give, bonus state, last-play $ref. Single-row tibble. | | espn_nba_event_predictor() / espn_mbb_event_predictor() | Pre-game predictor statistics in long format (one row per team × stat). Stats include matchup quality, predicted score, win pct, team-predicted MoV. Returns empty for events without predictor data. | | espn_nba_event_powerindex() / espn_mbb_event_powerindex() | Per-event power-index $ref index. Coverage is sparse — most events return zero items. | | espn_nba_event_propbets() / espn_mbb_event_propbets() | Per-(event × provider) prop-bet markets in long format. One row per (athlete × prop type) with american / decimal / fraction odds + current target line. Auto-paginates. |

Tier 2B core-v2 expansion — event competitor sub-resources

5 new resource families under events/{eid}/competitions/{cid}/competitors/{team_id}/, each shimmed for NBA and MBB (10 new public functions per package). Pair the team_id with the event_id from espn_*_schedule() (or any boxscore.teams[].id).

| Function | Description | |---|---| | espn_nba_event_competitor_linescores() / espn_mbb_event_competitor_linescores() | Per-quarter scoring for one team in one event. One row per period (regulation + overtime). | | espn_nba_event_competitor_leaders() / espn_mbb_event_competitor_leaders() | Top performers per team in long format: one row per (category × athlete rank). Categories typically include points, rebounds, assists, and rating. | | espn_nba_event_competitor_roster() / espn_mbb_event_competitor_roster() | Game-day roster index for one team. Returns athlete ids + core-v2 $ref URLs for deferred dereferencing. | | espn_nba_event_competitor_statistics() / espn_mbb_event_competitor_statistics() | Full team-game statistics in long format (one row per category × stat) with both numeric values and display strings. | | espn_nba_event_competitor_records() / espn_mbb_event_competitor_records() | Team records as of the event: overall / home / away / conference / division breakdowns. |

Tier 2F core-v2 expansion — typed-detail companions

5 new resource families completing index/detail pairs for existing wrappers. NBA-only or 3-league coverage where the underlying ESPN endpoint isn't symmetric:

| Function | Description | |---|---| | espn_nba_event_official_detail() / espn_mbb_event_official_detail() | Per-official details (name, position, order) for one event. Note: the URL segment is the crew order (1-indexed) not the ESPN stable official_id — the wrapper takes order = to match event_officials()$order. | | espn_nba_team_record_detail() / espn_mbb_team_record_detail() | Per-record stat array in long format. Use team_record() to enumerate record_id values (overall / home / away / conference / per-opponent). Returns 21 rows × 15 cols for one NBA record. | | espn_nba_coach_record() / espn_mbb_coach_record() / espn_wbb_coach_record() | Coach career record by type in long format. Types: 0 = Total, 1 = Pre Season, 2 = Regular Season, 3 = Post Season. | | espn_nba_tournament_season() / espn_mbb_tournament_season() | Single tournament-year detail (id, displayName, numberOfRounds, bracketology $ref). | | espn_nba_draft_athlete_detail() | Rich single-row drafted-player record: height/weight, position, pick (overall/round/team), athlete $ref. |

Tier 2E.2 core-v2 expansion — team-season stats + quick lookups

3 new resource families across NBA + MBB (5 new exports — season_draft is NBA-only). Surfaces the full team-season stat sheet (with league rank per stat), a quick-lookup wrapper for a single team's final score in one event, and the draft-year top-level metadata.

| Function | Description | |---|---| | espn_nba_team_season_statistics() / espn_mbb_team_season_statistics() | Full team-season-type stat sheet in long format (one row per category × stat). Each row carries rank + rank_display_value for league ranking per stat. Smoke-tested: 109 rows × 13 cols for one NBA team. | | espn_nba_event_competitor_score() / espn_mbb_event_competitor_score() | Single-row final score for one team in one event: value, display_value, winner flag, source metadata. | | espn_nba_season_draft() | Draft-year top-level metadata: year, number_of_rounds, display_name, plus sub-refs to athletes/rounds/status. |

Tier 2E.1 core-v2 expansion — event-scoped player + play deep dives

4 new resource families covering per-game player stats, starter/DNP metadata, single-play detail, and on-court personnel (8 new public functions per package).

| Function | Description | |---|---| | espn_nba_event_player_box() / espn_mbb_event_player_box() | Per-game box score for one athlete in long format (one row per category × stat). Same shape as event_competitor_statistics() but scoped to a single athlete-in-event. Smoke-tested: 99 rows × 12 cols for one NBA athlete. | | espn_nba_event_competitor_roster_entry() / espn_mbb_event_competitor_roster_entry() | Per-athlete game-day roster row: starter flag, did_not_play + reason, ejected, period of entry, for_player_id if a substitution. | | espn_nba_event_play() / espn_mbb_event_play() | Rich single-play detail: sequence, period, clock, type, text, scoring/shooting flags, score, team $ref, shot coordinates. | | espn_nba_event_play_personnel() / espn_mbb_event_play_personnel() | Players on court at a specific play in long format. Coverage is sparse — many plays return zero rows; wrapper returns a typed empty tibble. |

Tier 2D core-v2 expansion — position dictionary

2 new resource families for the league-specific position dictionary (4 new public functions). Position ids are not shared across the basketball family — id 1 resolves to Point Guard in NBA and Center in MBB. These wrappers make the dictionary explicit so users can disambiguate position $ref URLs in athlete records.

| Function | Description | |---|---| | espn_nba_positions() / espn_mbb_positions() | League position dictionary index. One row per position with id + canonical $ref. | | espn_nba_position() / espn_mbb_position() | Single-position detail: id, name, displayName, abbreviation, leaf flag, parent $ref. |

Behavior changes to existing functions

Bug fixes

| Function | Fix | |---|---| | nba_schedule() | Migrated off the retired stats.nba.com/stats/scheduleleaguev2 endpoint (returns Connection was reset across multiple client environments; issues #184 and #187) to the public CDN at cdn.nba.com/static/json/staticData/scheduleLeagueV2.json. Same leagueSchedule.gameDates[].games[] payload, no authentication or special headers, stays current with the live season. G-League schedules now come from the _2-suffixed variant on the same CDN. For historical seasons (CDN only serves the current season) the function emits a message() directing users at load_nba_schedule(seasons = ...). Also initializes games <- NULL before tryCatch (issue #184). Verified 2026-05-16: returns 1,398 NBA games × 52 cols for 2025-26. | | nba_leaguegamelog() | Reordered query-string parameter ordering to put LeagueID first. As of 2026 the NBA Stats API rejects the alphabetical ordering (Counter, DateFrom, DateTo, Direction, LeagueID, ...) with a Cloudflare HTML error page; LeagueID-first matches the nba.com client and parses successfully. Verified 2026-05-16: returns 2,460 NBA rows with SEASON_ID=22025. Parallel fix to the WNBA equivalent in wehoop. | | ncaa_mbb_NET_rankings() | Hardened against NCAA.com column drift. The function now uses dplyr::rename(dplyr::any_of(...)) so renamed / added columns (e.g. new Quad 1..4 headers) no longer break the documented schema; existing consumers keep working and new columns ride along untouched. | | ESPN wrappers | Moved .retry_request() and check_status() inside tryCatch so transient HTTP errors surface as cli_alert_danger() + empty fallback rather than escaping the function. Affects every espn_nba_* / espn_mbb_* wrapper. | | ncaa_mbb_teams() | No longer returns NA ids. stats.ncaa.org migrated team links from the legacy /team/{team_id}/{season_id} pair to a single modern /teams/{season_team_id} resource, so the previous str_extract("(\\d+)/(\\d+)") matched nothing. The function now extracts ids from whichever url shape is present (legacy rows populate team_id/season_id; modern rows populate the new season_team_id column), so the id columns are never all-NA when the site flips formats. |

Documentation improvements

@return column descriptions on every exported function

Every @return markdown table across the 39 R source files is upgraded from two columns (col_name | types) to three columns (col_name | types | description). 6,039 total table rows touched; every result set on every function now ships a per-column description in ?<function> help, the pkgdown reference, and the rendered man pages.

Coverage — frequency-weighted, what ?fn readers actually see — 58.4% of the 6,039 @return table rows now carry a hand-quality description (curated + ESPN-API + mined). The remaining 41.6% are heuristic-fallback rows; the heuristic generator's snake_case expansion + suffix rules cover most of those acceptably, and the long tail is dominated by single-occurrence columns from low-traffic NBA Stats endpoints.

Description sources (precedence order, first match wins):

  1. tools/docs/column_descriptions_curated.csv — 619 hand-authored entries covering high-traffic columns and basketball / ESPN domain conventions.
  2. tools/docs/column_descriptions_api.csv — 188 ESPN-authored descriptions mined live from 14 endpoints per league across both nba and mens-college-basketball, covering 9 endpoint families: core-v2 athlete statistics (per-season, post-season, career), core-v2 team statistics, core-v2 statisticslog, core-v2 leaders, web-v3 athlete stats / splits / gamelog / overview, and web-v3 statistics/byathlete leaderboards. Three response shapes are recognized: nested categories with stats objects, parallel arrays under categories, and top-level parallel-array shapes (splits / gamelog).
  3. Mined \item{...}{...} lines from existing \describe{} blocks.
  4. Heuristic patterns driven by column-name suffixes (*_id, *_pct, *_made, *_attempted, *_per_36, etc.) with basketball-friendly noun substitution.

New tooling under tools/docs/ (.Rbuildignore'd via the existing ^tools$ rule):

| File | Purpose | |---|---| | build_column_descriptions.R | One-shot dictionary builder. | | column_descriptions_curated.csv | Hand-edit surface; overrides API / mined / heuristic outputs. | | column_descriptions_api.csv | ESPN-API-mined descriptions, regenerated by mine_api_descriptions.R. | | column_descriptions.csv | Generated dictionary (1,956 rows; 619 curated, 168 ESPN-API, 5 mined, 0 parameter-overlap, 1,164 heuristic). | | mine_api_descriptions.R | Driver that probes the ESPN endpoints which self-document their stat columns. | | audit_column_descriptions.R | Coverage / leverage diagnostic. | | markdown_man_table_helper.R | Programmatic helpers (load_column_descriptions(), make_return_table_md(), roxygenize_return(), augment_return_tables_in_file(), augment_all_r_files(), mine_espn_api_descriptions(url)). | | espn_endpoints_catalog.md | Basketball-scoped ESPN endpoint reference used to scope the miner. |

The sweep is idempotent and offline (no API calls needed for the augmentation itself; existing |col_name|types| tables in each @return block are the parse input).

Internals

HTTP layer — proxy support restored

When the package migrated from httr to httr2 in 3.0.0, the legacy httr::use_proxy() plumbing was dropped and request_with_proxy() quietly stopped honoring proxies (its ... was preserved purely for source compatibility). Both request_with_proxy() and the lower-level .retry_request() now accept a proxy = argument:

Resolution order in .retry_request(): explicit proxy = arg → getOption("hoopR.proxy") → libcurl env vars. The ... thread works for NBA Stats wrappers (which forward into request_with_proxy()); ESPN / KenPom / NBA G-League wrappers call .retry_request() directly without ..., so use options(hoopR.proxy = ...) at the top of the session to cover those without per-function plumbing.

Error-handling consolidation

| Helper | Role | |---|---| | .report_api_error(e, hint, args) | Standardized tryCatch error handler — emits a cli_alert_danger() with hint text plus the captured arg list, then returns an empty fallback. | | .report_api_warning(w, args) | Companion warning handler. | | .interp_braces() | Internal helper for safely interpolating {var} syntax in cli alerts when the variable might contain braces of its own. | | .capture_args() | Helper used at the top of arg-less wrappers (i.e. those whose only formal is ...) so the error/warning reporters still see the call args. Equivalent to mget(setdiff(names(formals()), "...")) for wrappers with formals. |

Every tryCatch(expr = ...) block in ESPN, NBA Stats, and KenPom wrappers now uses these helpers instead of hand-rolled cli::cli_alert_danger("{Sys.time()}: ...") strings. Behavior is the same; the message includes the captured args, which makes failed-call debugging much faster.

Dependency cleanup

Tooling

Test infrastructure

Release / CRAN preparation

hoopR 3.0.0 (2026-03-24)

New exported functions

NBA Play-by-Play V3

| Function / change | Description | |---|---| | nba_playbyplayv3() | Dedicated wrapper for the NBA Stats PlayByPlayV3 endpoint. | | nba_pbp() default flip | Now defaults to version = "v3" (was "v2"). Pass version = "v2" for the previous behavior. | | nba_pbps() default flip | Same default flip applies. | | nba_pbp() p parameter | Now optional (default NULL) — previously required even when not using progress tracking. |

Internal V3→V2 compatibility pipeline backs nba_pbp() so callers keep V2-compatible columns while gaining V3-only columns (x_legacy, y_legacy, shot_distance, shot_result, is_field_goal, points_total, shot_value):

| Helper (internal) | Role | |---|---| | .v3_to_v2_format() | Converts V3 play-by-play data to V2-compatible column format with mapped event types and player resolution. | | .build_player_roster() | Retrieves player roster from nba_boxscoretraditionalv3() for name-to-ID resolution during V3-to-V2 conversion. | | .players_on_court_v3() | Rewritten — uses nba_gamerotation() stint data with interval mapping for robust on-court determination (replaces the previous substitution-parsing approach). |

Removed stringr::str_match import from NAMESPACE — V3 clock parsing now uses base R regex functions.

NBA Boxscore Summary V3

| Function | Description | |---|---| | nba_boxscoresummaryv3() | Returns a named list of 9 data frames: GameSummary, GameInfo, ArenaInfo, Officials, LineScore, InactivePlayers, LastFiveMeetings, OtherStats, AvailableVideo. |

New NBA Stats API endpoint wrappers

| Function | Description | |---|---| | nba_commonteamyears() | Team IDs with their active year ranges. | | nba_dunkscoreleaders() | Dunk tracking data with biomechanics, scores, and style metrics. | | nba_gravityleaders() | Gravity scores — how much defensive attention each player draws. | | nba_iststandings() | In-Season Tournament (NBA Cup) standings. | | nba_scheduleleaguev2int() | International schedule data with broadcaster information. | | nba_teamandplayersvsplayers() | Team and player lineup comparison stats (5 datasets). | | nba_videoeventsasset() | Video event asset data for a given game event. |

ESPN & G-League functions

| Function | Description | |---|---| | espn_nba_team_current_roster() | Current NBA team roster from ESPN. | | espn_mbb_team_current_roster() | Current MBB team roster from ESPN. | | nbagl_live_pbp() | Live G-League play-by-play. | | nbagl_live_boxscore() | Live G-League box score. |

Behavior changes to existing functions

Bug fixes

| Function | Fix | |---|---| | nba_iststandings() | Nested games column now properly flattened. | | nba_dunkscoreleaders() | HTTP 400 error caused by empty-string parameters now resolved. | | nbagl_pbp() | Avoids on-court enrichment dependency failures for G-League game IDs by using the stable core play-by-play path. | | kp_box() | Referee link extraction updated — CSS selectors now match current KenPom HTML structure (div.refline with href-based filtering). | | kp_team_history() | CSS selector updated to table#player-table; team name assignment now uses the display name instead of the URL slug. | | kp_kpoy() example | Year bumped from 2021 to 2026 for current-season relevance. |

Return-value initialization sweep. Fixed df_list not initialized before tryCatch in 147 NBA Stats API wrapper functions, preventing crashes on API errors. Same pattern applied to:

Other fixes:

Deprecations

Calling any of these now errors with a structured lifecycleDeprecatedError that names a replacement. All deprecations were prompted by unstable / partial / empty endpoint responses observed in production.

| Deprecated function | Replacement | Reason | |---|---|---| | nba_boxscorefourfactorsv2() | nba_boxscorefourfactorsv3() | Unstable/partial V2 responses | | nba_boxscoremiscv2() | nba_boxscoremiscv3() | Unstable/partial V2 responses | | nba_boxscorescoringv2() | nba_boxscorescoringv3() | Unstable/partial V2 responses | | nba_boxscoreusagev2() | nba_boxscoreusagev3() | Unstable/partial V2 responses | | nba_boxscoreplayertrackv2() | nba_boxscoreplayertrackv3() | Unstable/partial V2 responses | | nba_boxscorehustlev2() | nba_hustlestatsboxscore() | Unstable/partial V2 responses | | nba_homepageleaders() | nba_leagueleaders() | Unstable/empty responses | | nba_homepagev2() | nba_leagueleaders() | Unstable/empty responses | | nba_leaderstiles() | nba_leagueleaders() | Unstable/empty responses | | nba_teamgamestreakfinder() | nba_teamgamelogs() | Unstable/empty responses | | nba_teamhistoricalleaders() | nba_franchiseleaders() | Unstable/empty responses | | nba_videodetails() | nba_videodetailsasset() | Unstable/empty responses | | nba_winprobabilitypbp() | nba_playbyplayv3() | Unstable/empty responses | | nba_playercareerbycollege() | nba_playercareerbycollegerollup() / nba_leaguedashplayerbiostats() | Unstable/empty responses | | nba_playernextngames() | nba_playerprofilev2() | Unstable/empty responses | | nba_scoreboard() | nba_scoreboardv3() | Unstable/empty responses | | nba_scoreboardv2() | nba_scoreboardv3() | Unstable/partial responses |

Internals

HTTP backend migration (httr → httr2)

Breaking change: httr is replaced with httr2 as the HTTP backend for every API call across the package, and httr is removed from Imports. Migration map:

| Aspect | Before (2.1.0 and earlier) | After (3.0.0) | |---|---|---| | HTTP client backend | httr | httr2 | | httr package availability | Auto-imported with hoopR | Removed from Importslibrary(httr) yourself if your downstream code still needs it | | request_with_proxy() body | rvest::session() + httr::config() arguments | httr2::request() + retry pipeline | | All ESPN / NBA Stats / NBA G-League / NCAA / KenPom HTTP calls | Mixed direct backend calls | Routed through shared internal helpers (.retry_request(), .resp_text()) backed by httr2 | | check_status() internal | httr::status_code() | httr2::resp_status() | | KenPom session authentication | rvest::session() with httr cookies | httr2 cookie-jar via login() / .kp_get_page() / .kp_request() helpers | | libcurl >= 8.x / curl R >= 7.0.0 segfaults | Triggered | Resolved (httr2 does not have the affected code path) |

Note: proxy plumbing on request_with_proxy() was quietly dropped during this migration. The restoration shipped in 3.1.0 — see above.

Messaging migration (usethis → cli)

| Old call | New call | |---|---| | usethis::ui_stop() | cli::cli_abort() | | usethis::ui_oops() | cli::cli_alert_danger() | | usethis::ui_todo() | cli::cli_ul() | | usethis::ui_info() | cli::cli_alert_info() | | usethis::ui_value() | {.val} inline markup | | usethis::ui_path() | {.file} inline markup | | usethis::ui_code() | {.code} inline markup |

Stability and test robustness

Dependency changes

Dependency status before / after the release. Users with strict dependency pinning or downstream packages that re-export hoopR functionality should review this table.

| Dependency | Before (2.1.0) | After (3.0.0) | Why | |---|---|---|---| | httr | Imports | Removed | Replaced by httr2 (see HTTP migration above) | | httr2 | — | Imports | New HTTP backend | | usethis | Imports | Suggests | Messaging migration to cli; retained only for usethis::edit_r_environ() doc references | | furrr | Imports | Suggests | Optional parallel features only; not required for core functionality | | future | Imports | Suggests | Same as furrr — optional parallel features | | lifecycle | — | Imports | Required for the new lifecycle::deprecate_stop() deprecation pattern | | qs | Imports | Removed | No longer used by any code path |

CI, build, and contribution improvements

Social branding (Twitter → X)

hoopR 2.1.0 (2023-11-25)

hoopR 2.0.0

NBA Stats API Live Endpoints

NBA Boxscore V3 (and V3-styled) Endpoints Added

Other NBA Stats API functions added

Other Functions Added

Proxy Capability Added and Other Notes

hoopR 1.9.1

hoopR 1.9.0

hoopR 1.8.1

hoopR 1.8.0 (2022-06-17)

hoopR 1.7.0

hoopR 1.6.0

hoopR 1.5.0 (2021-11-10)

hoopR 1.4.5

hoopR 1.4.4

hoopR 1.4.3

hoopR 1.4.2

hoopR 1.4.1

hoopR 1.4.0

hoopR 1.3.1

hoopR 1.3.0

Add Full Coverage for NBA Stats API

Adding roughly 127 functions

| Function | File Location | |--- |--- | | nba_alltimeleadersgrids | R/nba_stats_leaders.R | | nba_assistleaders | R/nba_stats_leaders.R | | nba_assisttracker | R/nba_stats_leaders.R | | nba_boxscoreadvancedv2 | R/nba_stats_boxscore.R | | nba_boxscoredefensive | R/nba_stats_boxscore.R | | nba_boxscorefourfactorsv2 | R/nba_stats_boxscore.R | | nba_boxscorematchups | R/nba_stats_boxscore.R | | nba_boxscoremiscv2 | R/nba_stats_boxscore.R | | nba_boxscoreplayertrackv2 | R/nba_stats_boxscore.R | | nba_boxscorescoringv2 | R/nba_stats_boxscore.R | | nba_boxscoresimilarityscore | R/nba_stats_boxscore.R | | nba_boxscoresummaryv2 | R/nba_stats_boxscore.R | | nba_boxscoretraditionalv2 | R/nba_stats_boxscore.R | | nba_boxscoreusagev2 | R/nba_stats_boxscore.R | | nba_commonallplayers | R/nba_stats_roster.R | | nba_commonplayerinfo | R/nba_stats_roster.R | | nba_commonplayoffseries | R/nba_stats_roster.R | | nba_commonteamroster | R/nba_stats_roster.R | | nba_cumestatsplayer | R/nba_stats_cume.R | | nba_cumestatsplayergames | R/nba_stats_cume.R | | nba_cumestatsteam | R/nba_stats_cume.R | | nba_cumestatsteamgames | R/nba_stats_cume.R | | nba_defensehub | R/nba_stats_leaders.R | | nba_draftboard | R/nba_stats_draft.R | | nba_draftcombinedrillresults | R/nba_stats_draft.R | | nba_draftcombinenonstationaryshooting | R/nba_stats_draft.R | | nba_draftcombineplayeranthro | R/nba_stats_draft.R | | nba_draftcombinespotshooting | R/nba_stats_draft.R | | nba_draftcombinestats | R/nba_stats_draft.R | | nba_fantasywidget | R/nba_stats_lineups.R | | nba_franchisehistory | R/nba_stats_franchise.R | | nba_franchiseleaders | R/nba_stats_franchise.R | | nba_franchiseplayers | R/nba_stats_franchise.R | | nba_glalumboxscoresimilarityscore | R/nba_stats_boxscore.R | | nba_homepageleaders | R/nba_stats_leaders.R | | nba_homepagev2 | R/nba_stats_leaders.R | | nba_hustlestatsboxscore | R/nba_stats_boxscore.R | | nba_leaderstiles | R/nba_stats_leaders.R | | nba_leaguedashlineups | R/nba_stats_lineups.R | | nba_leaguedashoppptshot | R/nba_stats_league_dash.R | | nba_leaguedashplayerbiostats | R/nba_stats_league_dash.R | | nba_leaguedashplayerclutch | R/nba_stats_league_dash.R | | nba_leaguedashplayerptshot | R/nba_stats_league_dash.R | | nba_leaguedashplayershotlocations | R/nba_stats_league_dash.R | | nba_leaguedashplayerstats | R/nba_stats_league_dash.R | | nba_leaguedashptdefend | R/nba_stats_league_dash.R | | nba_leaguedashptstats | R/nba_stats_league_dash.R | | nba_leaguedashptteamdefend | R/nba_stats_league_dash.R | | nba_leaguedashteamclutch | R/nba_stats_league_dash.R | | nba_leaguedashteamptshot | R/nba_stats_league_dash.R | | nba_leaguedashteamshotlocations | R/nba_stats_league_dash.R | | nba_leaguedashteamstats | R/nba_stats_league_dash.R | | nba_leaguegamefinder | R/nba_stats_league.R | | nba_leaguegamelog | R/nba_stats_league.R | | nba_leaguehustlestatsplayer | R/nba_stats_hustle.R | | nba_leaguehustlestatsplayerleaders | R/nba_stats_hustle.R | | nba_leaguehustlestatsteam | R/nba_stats_hustle.R | | nba_leaguehustlestatsteamleaders | R/nba_stats_hustle.R | | nba_leagueleaders | R/nba_stats_leaders.R | | nba_leaguelineupviz | R/nba_stats_lineups.R | | nba_leagueplayerondetails | R/nba_stats_lineups.R | | nba_leagueseasonmatchups | R/nba_stats_lineups.R | | nba_leaguestandings | R/nba_stats_league.R | | nba_leaguestandingsv3 | R/nba_stats_league.R | | nba_matchupsrollup | R/nba_stats_lineups.R | | nba_pbp | R/nba_stats_pbp.R | | nba_playerawards | R/nba_stats_player.R | | nba_playercareerbycollege | R/nba_stats_player.R | | nba_playercareerbycollegerollup | R/nba_stats_player.R | | nba_playercareerstats | R/nba_stats_player.R | | nba_playercompare | R/nba_stats_player.R | | nba_playerdashboardbyclutch | R/nba_stats_player_dash.R | | nba_playerdashboardbygamesplits | R/nba_stats_player_dash.R | | nba_playerdashboardbygeneralsplits | R/nba_stats_player_dash.R | | nba_playerdashboardbylastngames | R/nba_stats_player_dash.R | | nba_playerdashboardbyopponent | R/nba_stats_player_dash.R | | nba_playerdashboardbyshootingsplits | R/nba_stats_player_dash.R | | nba_playerdashboardbyteamperformance | R/nba_stats_player_dash.R | | nba_playerdashboardbyyearoveryear | R/nba_stats_player_dash.R | | nba_playerdashptpass | R/nba_stats_player_dash.R | | nba_playerdashptreb | R/nba_stats_player_dash.R | | nba_playerdashptshotdefend | R/nba_stats_player_dash.R | | nba_playerdashptshots | R/nba_stats_player_dash.R | | nba_playerestimatedmetrics | R/nba_stats_player.R | | nba_playerfantasyprofile | R/nba_stats_player.R | | nba_playerfantasyprofilebargraph | R/nba_stats_player.R | | nba_playergamelog | R/nba_stats_player.R | | nba_playergamelogs | R/nba_stats_player.R | | nba_playergamestreakfinder | R/nba_stats_player.R | | nba_playernextngames | R/nba_stats_player.R | | nba_playerprofilev2 | R/nba_stats_player.R | | nba_playervsplayer | R/nba_stats_player.R | | nba_playoffpicture | R/nba_stats_league.R | | nba_schedule | R/nba_stats_pbp.R | | nba_scoreboard | R/nba_stats_scoreboard.R | | nba_scoreboardv2 | R/nba_stats_scoreboard.R | | nba_shotchartdetail | R/nba_stats_shotchart.R | | nba_shotchartleaguewide | R/nba_stats_shotchart.R | | nba_teamdashboardbyclutch | R/nba_stats_team_dash.R | | nba_teamdashboardbygamesplits | R/nba_stats_team_dash.R | | nba_teamdashboardbygeneralsplits | R/nba_stats_team_dash.R | | nba_teamdashboardbylastngames | R/nba_stats_team_dash.R | | nba_teamdashboardbyopponent | R/nba_stats_team_dash.R | | nba_teamdashboardbyshootingsplits | R/nba_stats_team_dash.R | | nba_teamdashboardbyteamperformance | R/nba_stats_team_dash.R | | nba_teamdashboardbyyearoveryear | R/nba_stats_team_dash.R | | nba_teamdashlineups | R/nba_stats_team_dash.R | | nba_teamdashptpass | R/nba_stats_team_dash.R | | nba_teamdashptreb | R/nba_stats_team_dash.R | | nba_teamdashptshots | R/nba_stats_team_dash.R | | nba_teamdetails | R/nba_stats_team.R | | nba_teamestimatedmetrics | R/nba_stats_team.R | | nba_teamgamelog | R/nba_stats_team.R | | nba_teamgamelogs | R/nba_stats_team.R | | nba_teamgamestreakfinder | R/nba_stats_team.R | | nba_teamhistoricalleaders | R/nba_stats_team.R | | nba_teaminfocommon | R/nba_stats_team.R | | nba_teamplayerdashboard | R/nba_stats_team.R | | nba_teamplayeronoffdetails | R/nba_stats_team.R | | nba_teamplayeronoffsummary | R/nba_stats_team.R | | nba_teamvsplayer | R/nba_stats_team.R | | nba_teamyearbyyearstats | R/nba_stats_team.R | | nba_videodetails | R/nba_stats_video.R | | nba_videoevents | R/nba_stats_video.R | | nba_videostatus | R/nba_stats_video.R | | nba_winprobabilitypbp | R/nba_stats_scoreboard.R |

hoopR 1.2.0

Add schedule loaders

hoopR 1.1.0

Add team box score loaders

Add player box score loaders

hoopR 1.0.5

Standings functions

hoopR 1.0.4

Add retry

hoopR 1.0.2-3

Quick fix for update db functions

hoopR 1.0.1-4

Dependency pruning

This update is a non-user facing change to package dependencies to shrink the list of dependencies.

hoopR 1.0.0

Package renamed to hoopR

To reflect that the package is no longer just a men's college basketball and KenPom package, but also an NBA package.

Clean names and team returns

Loading capabilities added to the package

hoopR 0.4

hoopR 0.3.0

Dependencies

Test coverage

Function Naming Convention Change

hoopR 0.2.0-3

hoopR 0.1.0

hoopR 0.0.0.9

Initial Commits, remaining tasks: