fix(espn): send an identifying User-Agent so ESPN stops returning 403 - #436
Conversation
Around 11:00 EDT on 2026-08-04 ESPN's site.api began rejecting the agents
this repo sends. Every scoreboard that goes through the shared data
sources returned `403 Client Error: Forbidden` — standings, game
summaries and scoreboards alike. A device that had been running fine
logged 287 ESPN errors in a day.
The filter is not the familiar one. Probing site.api across agents and
libraries, using requests as the plugins do:
bare 'LEDMatrix/1.0' 403 (with or without Accept)
browser string 403 (no header rescues it)
'LEDMatrix/1.0 (+https://github.com/...)' 200
requests / urllib / curl defaults 200
So it rejects browser-style strings outright and bare custom tokens, and
accepts honest client tokens or an agent that identifies the client and
links to it. The instinct to "just send a browser User-Agent" is now
exactly backwards — that is the one thing guaranteed to stay blocked.
Both call sites here sent a bare token: `LEDMatrix/1.0` in the sports
data sources and `LEDMatrix-Common/1.0` in the API helper. The Accept
header the data sources already sent does not save it. Both now send an
agent carrying the project URL, which also gives ESPN someone to contact
rather than an anonymous token to rate-limit.
Verified on a live device: ESPN errors went from a steady stream to zero
across a restart, with live MLB games fetching again.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe request header helpers now send project-identifying ChangesRequest header identification
Estimated code review effort: 1 (Trivial) | ~5 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 0 |
| Duplication | 0 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Around 11:00 EDT on 2026-08-04, ESPN's
site.apibegan rejecting the User-Agent strings this repo sends. Every scoreboard that goes through the shared data sources returned403 Client Error: Forbidden— standings, game summaries and scoreboards alike. A device that had been running fine logged 287 ESPN errors in a day.The filter is the opposite of the usual one
Probed
site.apiacross agents and libraries, usingrequestsas the plugins do:LEDMatrix/1.0Accept)LEDMatrix-Common/1.0LEDMatrix/1.0 (+https://github.com/ChuckBuilds/LEDMatrix)requests/urllib/curldefaultsESPN rejects browser-style strings outright and bare custom tokens, while accepting honest client tokens or an agent that identifies the client and links to it. The reflex fix — "send a browser User-Agent" — is now the one change guaranteed to stay blocked.
Confirmed independently: ha-teamtracker#355 hit the same wall and switched from a browser agent to
curl/8.20.0(merged 2026-08-05).The library matters too, which is worth recording. Under
urllib, a bare token plus anAcceptheader still returned 200; underrequestsit does not. The data sources here were already sendingAccept: application/jsonand were still refused.The change
Two call sites sent a bare token:
src/base_classes/data_sources.py—LEDMatrix/1.0, the agent behind the failing standings and summary callssrc/common/api_helper.py—LEDMatrix-Common/1.0Both now send an agent carrying the project URL. That form is accepted with or without
Accept, on/scoreboard,/standingsand/summary, and it gives ESPN a client to identify and contact rather than an anonymous token to rate-limit — which seems the likelier way to stay working than blending in as curl.LEDMatrix-Plugin-Manager/1.0is left alone: it talks to the GitHub API, not ESPN.Verification
On a live 512x64 device, across a service restart:
mlb_live=True, MLB=4 live)Companion PR
The plugins monorepo carries the same bug in 24 files across 14 plugins and needs to land too, otherwise plugins that bundle their own
data_sources.pystay broken: ChuckBuilds/ledmatrix-plugins#254.🤖 Generated with Claude Code
https://claude.ai/code/session_01Udr6MfaFLUPhX5Fgo67Jf5
Summary by CodeRabbit