Strava is the largest activity network in sport, and it is the platform in this series that publishes the least to a logged-out client. On 28 September 2026 we fetched it twenty-one times through residential exits in the United States, Germany and Italy. A public segment page returned 117 words: the segment name, sport and location in the title, and a sign-in prompt in the body, the same from every country and with or without a browser. The club page is the one public surface with data: 7,284,511 members and twenty dated posts in 963,234 bytes over plain HTTP. Everything else on Strava is behind OAuth, and the terms say so in one sentence.
On this keyword, "proxy" means the heatmap
Search for Strava proxies and Google returns code, not vendors. Ranks one and four are GitHub repositories called strava-heatmap-proxy, small servers that stream Global Heatmap tiles into mapping tools that cannot log in; rank three is a mapping forum discussing them, and rank two is a Strava community event literally named "Test Proxy" with 247 participants. Further down: an r/Strava thread on alternatives after the API restrictions, one VPN video and a Strava press release about privacy. The autocomplete box is empty for the head term.
The intent that exists is under "strava api", which completes fifteen ways and reads like a support queue: key, access, cost, changes, "subscriber only", limits. And under "strava scraper", where "strava club scraper" is the first suggestion and "can you export data from strava" is the third. This post answers those with numbers: what the public web hands a proxied client, what the club page carries, what the API allows, and where Strava draws the line.
A segment page is 117 words and a sign-in prompt, from any country
We audited strava.com/segments/229781, Hawk Hill in the Marin Headlands, one of the most ridden climbs on the platform, from three countries, each time as a pure HTTP client and as a full browser.
| Exit | Plain HTTP words | Title | h1 |
|---|---|---|---|
| United States | 117 | Hawk Hill | Strava Ride Segment in Marin Headlands (GGNRA), California | Log in to see "Hawk Hill" |
| Germany | 113 | Hawk Hill | Strava Radfahren Segment in Marin Headlands (GGNRA), Vereinigte Staaten von Amerika | Anmelden, um „Hawk Hill“ zu sehen |
| Italy | 123 | Hawk Hill | Strava Ciclismo Segmento in Marin Headlands (GGNRA), Stati Uniti d'America | Accedi per vedere "Hawk Hill" |
The plain response is 615,374 bytes and it contains exactly what a search engine needs and nothing else: the segment name, the sport and the place in the title, a robots: noindex meta tag, an Organization JSON-LD block for Strava itself, and a body that asks you to log in. Strava localises the title and the h1 off the exit IP alone, with no Accept-Language header sent, which is why the three word counts differ by ten: the German chrome is shorter than the Italian.
Rendering does not open it. From the US the browser returned the same 117 words. From Germany and Italy the audit counted 1,805 and 2,116 words in the rendered DOM, so we looked at what they were: the visible text from Italy was the same sign-in prompt, in 1,383,075 bytes and 6.1 seconds. The extra words are the localised chrome and the consent and menu markup that European visitors get; the leaderboard, the elevation profile and the efforts never appear. The pro athlete page behaves the same way: /pros/1671 returned 615,442 bytes with the athlete’s name, team and photo in a Person JSON-LD block and a sign-in prompt for a body. A non-existent id, /athletes/1, returns Strava’s own 404 page, "Sorry, this one stays red".
The club page is the one public surface with data in it
strava.com/clubs/strava, the platform’s own club, is a different animal. Over plain HTTP from the US it returned 963,234 bytes and 1,089 words with real content: the club name, location (San Francisco, California), website, description, a member count of 7,284,511, and twenty dated posts with their first lines, from January to September 2026, including product announcements and the Strava Metro academic programme. No login, no cookie.
The country matters here for the label and the weight, not the data. From Germany the same page came back as "7.284.511 Mitglieder" in 1,337,550 bytes; from Italy as "7.284.511 membri" in 1,317,053 bytes. The localised bundles are 37% heavier than the US one, and the thousands separator flips to a full stop, which is the parser trap we keep meeting in this series: a naive integer parse of "7.284.511" returns 7. The posts themselves stayed in English from all three exits; only the interface moved.
Rendering the club page is the expense to strike out. The browser moved 2,161,313 bytes in 10.5 seconds and returned the same 1,089 words. That is 2.2 times the bandwidth for nothing, and it is the pattern on both public surfaces: on Strava the plain HTTP view is the maximum a logged-out client gets, and the browser only adds weight.
The API needs OAuth, and it documents its own ceiling
Every read on the Strava API is authenticated. A call to /api/v3/segments/229781 with no token answered in 107 bytes of JSON with an Authorization Error naming the access_token field. With a token, the rate-limit page states the numbers plainly, and they are per application, not per IP:
Overall: 200 requests per 15 minutes, 2,000 per day
Non-upload: 100 requests per 15 minutes, 1,000 per day (every read endpoint)
Windows reset at :00, :15, :30, :45; the daily limit at midnight UTC
Headers: X-RateLimit-Limit / X-RateLimit-Usage (15-minute, daily)
X-ReadRateLimit-Limit / X-ReadRateLimit-Usage
Over the limit: 429 with a JSON body; short-term overages still count toward the daily total
Two more numbers decide what an application can be. A newly created app has an athlete capacity of one, which Strava calls Single Player Mode: it can read its own creator’s data and nobody else’s. The self-service upgrade raises that to ten athletes, with reads at 200 per 15 minutes and 2,000 a day. Anything larger is a request to Strava. And the API Agreement adds the clause that settles most "strava data scraper" projects before they start: data related to other users, even if it is publicly viewable on the platform, may not be displayed or disclosed in your application.
Because the limits are per application and per token rather than per address, a proxy pool does nothing for API throughput on Strava. It changes where a request comes from, not which application made it. That is worth saying because on Mastodon and Discord the limit is per IP and a pool is exactly what buys concurrency; here it is not.
What robots.txt and the terms say
strava.com/robots.txt is 1,510 bytes. Four AI crawlers, ClaudeBot, Google-Extended, GPTBot and Meta-ExternalAgent, are refused everywhere. Everyone else is allowed in with 47 path exclusions, and the list is a map of where the data lives: activity analysis, heart rate, laps, power and pace views, athlete follows, segments, training logs and trophy cases, club members, leaderboards and discussions, segment comparisons, route exports, the API itself and the dashboard. One path is explicitly allowed: /training-plans/*. The sitemap index it points to lists 1,889 pro athlete URLs and separate athlete and verified-athlete sitemaps, all regenerated on the day we measured, so the public shells of those pages are meant to be indexed even though their bodies are not public.
The Terms of Service are the line, and it is one sentence in section 19: automated access to or collection of data from the Services, by any means including data mining, robots, screen scraping, scripts, browser extensions and crawlers, is prohibited, and the prohibition applies whether or not you are logged into a Strava account. There is no reading of that clause that permits a crawl of athlete or activity pages, with or without a proxy, and we will not help build one. What the platform does offer is an API with the athlete’s consent for the athlete’s own data, Strava Metro as a free aggregate data service for planners, and a Metro programme for academic researchers.
What a gigabyte buys, and what it does not
Nothing in twenty-one fetches looked at the address: every public page answered a rotating residential exit with a 200 on the first attempt from three countries. The cost driver is bytes, and the arithmetic below uses residential proxies on the Basic line at $0.80/GB, counting a gigabyte as 10^9 bytes.
| Request | Bytes | Requests per GB | Cost per request |
|---|---|---|---|
| Segment page, plain HTTP (title only) | 615,374 | 1,625 | $0.00049 |
| Segment page, rendered (same prompt) | 1,383,075 | 723 | $0.00111 |
| Club page, plain HTTP, US | 963,234 | 1,038 | $0.00077 |
| Club page, plain HTTP, Germany | 1,337,550 | 748 | $0.00107 |
| Club page, rendered | 2,161,313 | 463 | $0.00173 |
| API call without a token | 107 | 9,345,794 | $0.0000001 |
The only job those rows price is club and brand monitoring: 10,000 club pages a month are 9.6 GB and about $7.71 over plain HTTP from a US exit, $17.29 rendered for the same words. A segment sweep prices at $0.00049 a page and returns the segment’s name and place, which is a lookup table, not a dataset. Budget by what a request yields, and on Strava the yield outside the club page is a title.
The setting that works on Strava
- Network: residential proxies, Basic line, $0.80/GB, rotating. The public pages met no address-level obstacle from three countries, and the API limits are per application, so the pool buys throughput on club pages and nothing on the API. Mobile at $2.30/GB and ISP at $2.50/IP per month buy nothing we could measure here.
- Fetch mode:
engine: tls, plain HTTP, never rendered. The club page returns 7,284,511 members and twenty posts in 963,234 bytes; the segment and pro pages return the name, sport, place and a Person block in about 615,000 bytes; rendering returns the same words for 2.2 times the bytes. - Country: pin the United States unless you need the localised labels. The club page is 963,234 bytes from the US and 1,337,550 from Germany, and a German exit writes the member count as "7.284.511". Mixing exits inside a job mixes number formats.
- When the proxy is not enough: there is no Strava collector in our catalogue, and the only public data surface does not need one. The web scraping API without rendering returns each club page as clean Markdown or JSON from $0.0002 per page, retries and rotation included, and failed requests are never billed. For athlete and activity data, the route is the Strava API with the athlete’s consent, inside its documented limits; for aggregate movement data, Strava Metro.
- Free tier: every account gets $2 of free API usage per month, which is 10,000 club pages through the scraping API before you pay anything.
Read club pages over plain HTTP for club and brand monitoring, take segment and pro names from the titles, and stop there: the terms prohibit automated collection of anything else, logged in or not, and no proxy changes that. That is the whole configuration. For the platform in this series where a public profile carried everything in the head, see Snapchat; for the one where a per-IP API limit made the pool the whole point, see Mastodon.