# Changelog of Basketball Reference Scraper (`normdata/basketball-reference-scraper`) Actor

- **URL**: https://apify.com/normdata/basketball-reference-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/normdata/basketball-reference-scraper.md

## Changelog

### 2026-09-13 (2)

- A real Apify run took 36s for a single season-leaderboard page fetch that completes in under 1s
  locally. Confirmed gzip compression is working correctly either way (not the cause) - real
  network-latency variance to the source. Bumped the per-request timeout from 30s to 45s so a
  genuinely slow-but-successful response isn't cut off and retried, which would only make it worse.

### 2026-09-13

- Full field audit: ran every mode and every season stat type live, collected the real, complete
  set of every top-level field the Actor actually produces, and diffed it against the dataset
  schema until the two matched exactly (0 missing, 0 stale). Found and fixed along the way:
  - Season/team-mode rows carried the player's name as raw, un-mapped `name_display` - now mapped
    to the same `player_name` used everywhere else, not left inconsistent.
  - All-NBA/All-Defense/All-Rookie award rows have their own real fields (`all_nba_team`,
    `all_defense_team`, `all_rookie_team`, `first_team_votes`/`second_team_votes`/
    `third_team_votes`) - not previously in the dataset schema at all.
  - Player mode's own link field was named `url`; every other mode's is `player_url` - renamed for
    consistency.
- Rebuilt the dataset schema's "Overview" table to include every one of the ~148 real fields this
  Actor can produce, grouped and ordered by category (identity/bio, per-game, season totals,
  per-36, per-100-poss, advanced, draft, awards, nested arrays) instead of a smaller curated subset.

### 2026-09-12

- Initial release: `player` (career stats by name/ID via Basketball-Reference's own search),
  `season` (full leaderboard by year + stat type, with team/minGames/minMinutesPerGame filters),
  `team` (roster + stats for one team-season), `draft` (one draft class with career totals), and
  `awards` (MVP/ROY/DPOY/SMOY/MIP/Clutch POY/All-NBA/All-Defense/All-Rookie/COY voting) - no API
  key, no login, no browser.
- Real bugs found and fixed via live testing before shipping:
  - Basketball-Reference appends a non-player "League Average" summary row to every season
    leaderboard - excluded (confirmed live via its real `norank` row class, not guessed).
  - The raw field `g` genuinely means different things on different tables - a draft class's
    career games total vs. a Coach of the Year row's that-season team games - handled correctly on
    each rather than one blanket rename.
  - Player-mode lookups were sequential (2 real page fetches per name); switched to concurrency 5,
    verified directly: 10 real players dropped from 26s to 10s with no failures.
  - A bad team/year/draft-year/awards-year now surfaces a clear "check the code/year" message
    instead of a raw HTTP-404 string.
  - **A real mislabeling bug, found only by testing `totals`/`per_minute`/`per_poss` season stat
    types (not just the `per_game` one tested first):** the raw fields `pts`/`trb`/`ast` mean
    "this single season's total" on a season-leaderboard `totals` row, but "career total through
    today" on a draft-class row - the same collision class as the earlier `g` fix, just not caught
    for these three at the same time. A Boston player's real 2023-24 season totals (1,987 points)
    were showing up labeled `career_points`, which is wrong. Fixed: the generic mapping now uses
    context-neutral names (`points`, `total_rebounds`, `assists`), and only `draft` mode - which
    knows for certain it's looking at career totals - renames them to `career_*` itself.
  - Added the real field names `totals`, `per_minute` (per-36), and `per_poss` (per-100-poss.)
    stat types actually use - previously unmapped and left as raw, un-coerced strings.
- Verified at scale: a full season leaderboard (735 real 2023-24 players, after excluding the
  summary row) in ~25s from a single page fetch; a team roster correctly joined 19/19 players with
  their per-game stats; a 60-pick draft class and a full awards page (160 rows across 10
  categories) both verified against real, checkable values (pick 1 = Anthony Edwards/MIN; 2024 MVP
  \= Jokić/DEN with a 0.935 award share).
- Free-plan runs are locked to a fixed 10-row sample.
