fpl-solver / docs /refresh_headers.md
AnayShukla's picture
updates
2bf5989
|
Raw History Blame Contribute Delete
2.2 kB

Fotmob API access

As of 2026-08-20, fotmob's data API needs no credentials. There is nothing to refresh. If fotmob_session.py reports a failure, it is almost certainly an endpoint change, not an auth problem β€” read the failure detail it prints.

History

Fotmob used to gate /api/* behind an x-mas header and a Cloudflare Turnstile challenge, proven by two cookies: turnstile_verified and g_state. This doc previously told you to copy those two cookies into .env every few weeks.

That gate is gone. Browsers no longer set turnstile_verified at all, and g_state turned out to be a Google Sign-In cookie unrelated to fotmob's API. Verified 2026-08-20: /api/data/leagues, /api/data/fixtures, /api/data/matchDetails, /api/data/teams, and /api/data/allLeagues all return 200 JSON with no cookies whatsoever.

The u:location cookie is still sent, but it is a location preference (pins responses to IST/India formatting), not a credential.

FOTMOB_TURNSTILE_TOKEN and FOTMOB_G_STATE are no longer read by any code and can be deleted from .env.

Health check

.venv\Scripts\python.exe fotmob_session.py
  • [OK] Fotmob API reachable (no credentials required). β€” all good.
  • [FAIL] HTTP 404 ... β€” the endpoint moved. Update _HEALTH_URL in fotmob_session.py, and check whether scrape_luigi.py's fixtures / matchDetails paths moved too.
  • [FAIL] HTTP 401/403 ... β€” fotmob re-introduced an auth gate. Open https://www.fotmob.com/ in Chrome, DevTools (F12) β†’ Network tab, click any /api/data/... request, and compare its Request Headers against build_headers(). Whatever is new is what you need to replicate.
  • [FAIL] got HTML instead of JSON β€” served a page rather than the API; same fix as 404.

A note on diagnosing this

The previous version of check_alive() returned status_code == 200 and the caller logged "cookies STALE" for any failure. It spent weeks reporting a credential problem for what was actually a dead health-check endpoint (/api/data/tls, now 404). The current check_status() returns the real reason β€” trust what it says over any assumption that cookies expired.