Strava Data Scraper - Clubs, Athletes & Challenges
Pricing
from $1.60 / 1,000 strava records
Strava Data Scraper - Clubs, Athletes & Challenges
Scrape public Strava data: clubs (members, location, sport, settings), athlete profiles and every current challenge (goals, dates, participants, qualifying activities). Club directory discovery, monitoring (NEW, UPDATED, EXPIRED), incremental runs, resume, MCP export.
Pricing
from $1.60 / 1,000 strava records
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Strava Data Scraper
Collect public Strava data: every current challenge, club profiles with member previews, and athlete profiles - in one structured dataset with change tracking for scheduled monitoring.
Why This Scraper?
- All three public surfaces in one actor. Challenges (goals, dates, participants, qualifying activities), clubs (member counts, locations, sport types, settings), and athlete profiles (name, badge, country) come out of the same run engine with the same record shape.
- Four collection modes. Pull the full current challenge gallery with nothing but defaults, paste club/athlete links, or walk the public club directory (hundreds of thousands of club ids) from any offset.
- Richer club data than the directory page shows. Each club record carries the description, sport type, club types, exact member count, invite-only and leaderboard settings, website, imagery, and the first member previews with their badge tiers.
- Built for monitoring. Incremental mode classifies every record NEW, UPDATED, UNCHANGED or EXPIRED across scheduled runs, participant counts and member previews never flag phantom changes, and every run can resume from an earlier run.
- Structured and honest. Every record carries the stable fields documented below, with imagery URLs and change tracking, and no placeholder rows.
Use Cases
- Who: Sports-market analysts tracking which challenges brands sponsor each month and how big their audiences get.
- Who: Community managers benchmarking running and cycling clubs by size, location, sport and open-vs-invite settings.
- Who: Researchers studying athlete visibility: badge tiers (free vs subscribed) and public location distributions.
- Who: Sellers of training services building a directory of clubs to partner with, filtered by sport and country.
Data You Get
Sample shape: values are illustrative placeholders, not from a live record.
| Field | Example |
|---|---|
recordId | club:1234567 |
kind | club, athlete or challenge |
name | Riverside Runners |
url | https://www.strava.com/clubs/1234567 |
description | A friendly community running club |
sportType | Running |
clubTypes | ["CasualClub"] |
city / state / country / countryCode | Springfield / Illinois / United States / US |
memberCount | 128 |
verified / inviteOnly / leaderboardEnabled / postsDefaultView | club settings booleans |
website | https://example.org |
avatarUrl / coverPhotoUrl / displayIcon | club imagery and icon token |
memberPreviews / badgeType / profileVisibilitySetting | first members with id, name, badge; Premium; Everyone |
challengeId / slug / shortName / subtitle | 1234567 / october-10k-challenge / October 10K / Lace 'em up |
sport | run, ride, swim, walk, hike, workout |
goal / dimension / activityType | 10000.0 / avg_pace_min_distance / streak |
dateStart / dateEnd | 2026-10-01 / 2026-10-31 |
participantsCount / followersInChallenge | 244063 / null |
qualifyingActivities | ["Badminton", "Basketball"] |
organizingClub / joined / ended | the club that runs the challenge; join state |
overviewText / rewardsText / rulesText / additionalInfoText | the challenge page's section texts |
changeType | NEW, UPDATED, UNCHANGED, REAPPEARED, EXPIRED |
Every record also keeps the raw source payload in raw for auditability.
How to Use
Quick start
- Challenges (default): just run it. Every current challenge in the gallery, with detail pages read for participant counts and qualifying activities.
- Clubs / Athletes: switch the mode and paste links (
strava.com/clubs/...,strava.com/athletes/...) or bare ids. - Discover: walk the public club directory from a starting offset to build a club list at scale.
All current challenges (the default run):
{"mode": "challenges","challengeSports": ["run", "ride", "swim", "walk", "hike", "workout"],"fetchChallengeDetails": true,"maxItems": 30}
A club and athlete watchlist:
{"mode": "clubs","links": ["https://www.strava.com/clubs/1234567", "987654"],"maxItems": 10}
Discover clubs from the public directory:
{"mode": "discover","discoverCount": 50,"discoverOffset": 0,"maxItems": 50,"incrementalMode": true,"stateKey": "club-directory-walk"}
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("abotapi/strava-public-data-scraper").call(run_input={"mode": "challenges","challengeSports": ["run", "ride"],"maxItems": 50,})for item in client.dataset(run["defaultDatasetId"]).iterate_dataset_items():print(item["recordId"], item["name"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('abotapi/strava-public-data-scraper').call({mode: 'challenges',challengeSports: ['run', 'ride'],maxItems: 50,});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const item of items) console.log(item.recordId, item.name);
Resume and recurring updates
Turn Incremental mode on and schedule the actor: each run pushes only NEW or CHANGED records, a complete scan marks disappeared records EXPIRED, and Resume from run skips anything an earlier run already collected. Challenge participant counts and club member previews never flag phantom changes.
Send results into your apps (MCP connectors)
Point the run at an MCP connector you have authorized under Apify, Settings, API & Integrations, and each collected record is pushed to it after the run: Notion as a rich page per record, other connectors as a best-effort write. Leave the field empty to skip the export entirely; it never changes the dataset output.
| Parameter | Type | Default | Description |
|---|---|---|---|
mcpConnectors | array | [] | Connector IDs to push results into after the run. |
notionParentPageUrl | string | `` | When pushing into a Notion connector, the parent page to write under. |
maxNotifyListings | number | 50 | Cap on records sent to MCP connectors per run. |
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | select | challenges | Challenges (all current challenges), Clubs (from links), Athletes (from links), Discover (public directory walk). |
challengeSports | multi-select | all | Which sport sections of the challenge gallery to collect. |
fetchChallengeDetails | checkbox | true | Adds participant count, qualifying activities and description per challenge. |
links | list | one example of each shape | Club or athlete links (full URLs with ids or slugs, or bare ids/slugs); the default carries one example of every supported shape. |
discoverCount | number | 20 | How many clubs to collect from the public directory, in directory order. |
discoverOffset | number | 0 | Skip this many directory entries first (continue long walks in later runs). |
maxItems | number | 20 | Maximum records to push. |
proxyConfiguration | proxy | residential | A residential connection is the reliable default. |
resumeFromRunId | string | (empty) | Skip records already collected in an earlier run. |
incrementalMode | checkbox | false | Only NEW/CHANGED rows on re-runs; disappeared records become EXPIRED. |
stateKey | string | (empty) | Name the incremental baseline yourself to share it across runs. |
emitUnchanged | checkbox | false | Push every record each run, flagged UNCHANGED. |
emitExpired | checkbox | false | Push records that disappeared from a complete scan, flagged EXPIRED. |
ignoreFieldsForChanges | list | (empty) | Extra fields that should never mark a record as changed. |
mcpConnectors | list | (empty) | Connector IDs to push results into after the run. |
notionParentPageUrl | string | (empty) | When pushing into a Notion connector, the parent page to write under. |
maxNotifyListings | number | 50 | Cap on records sent to MCP connectors per run. |
Output Example
Sample shape: values are illustrative placeholders, not from a live record.
A club record as it lands in the dataset:
{"recordId": "club:1234567","kind": "club","clubId": "1234567","name": "Riverside Runners","url": "https://www.strava.com/clubs/1234567","description": "A friendly community running club","sportType": "Running","clubTypes": ["CasualClub"],"city": "Springfield","state": "Illinois","country": "United States","countryCode": "US","memberCount": 128,"verified": false,"inviteOnly": false,"leaderboardEnabled": true,"website": "https://example.org","avatarUrl": "https://example.com/avatar.jpg","coverPhotoUrl": "https://example.com/cover.jpg","memberPreviews": [{"athleteId": "7654321","firstName": "Jordan","lastName": "Smith","badgeType": "Premium","profileImageUrl": "https://example.com/jordan.jpg"}],"changeType": "NEW","changedFields": ["clubId", "name", "url"],"firstSeenAt": "2026-10-24T10:00:00+00:00","lastSeenAt": "2026-10-24T10:00:00+00:00"}
The dataset ships Output tabs: Records (all kinds), Clubs, Athletes, Challenges, and Changes (incremental mode).
Plan Requirement
This Actor charges per record collected plus a small surcharge for each challenge detail page read. Check the pricing tab for current per-event prices. Runs are typically a few cents: the default 20-item run reads one index call plus one detail page per challenge.
FAQ
How much does it cost?
You pay the per-record event for each club, athlete or challenge record plus the detail surcharge for each challenge detail page read, and Apify compute for the run. A default 20-challenge run reads 1 index call plus 20 detail pages.
Is it legal to scrape Strava?
This actor reads Strava's public pages at modest request rates and documents its scope honestly. You remain responsible for how you use the data and for complying with Strava's terms and applicable law in your jurisdiction.
Can I get only new or changed records on a schedule?
Yes, that is what incremental mode is for. Turn it on and schedule the actor; each run pushes only NEW or CHANGED records (or everything, with "Also emit unchanged records"), and a complete scan marks disappeared records EXPIRED.
Why did my run fail instead of returning an empty dataset?
The site occasionally refuses individual proxy exits; the actor rotates to a fresh exit automatically. If every exit is refused (rare), the run fails loudly rather than returning empty results, so just run it again.
Can I use it with AI agents or MCP?
Yes. The output is structured JSON with stable field names, works with the Apify MCP server, and can be pushed straight into Notion or other apps through MCP connectors.
🔗 Want more sports data?
Pair this actor with these related scrapers from the same team:
| 🥦 Lidl.es Products, Weekly Offers, Prices & Reviews Scraper Scrape Lidl.es grocery and non-food products across weekly offers, tools, home, garden... | ⚽ SofaScore Scraper ⚽ Live Scores, Stats, Players & Odds Pull structured sports data from SofaScore across football, basketball, tennis, and 20+... |
| ⚽ JioHotstar Scraper Scrape the JioHotstar catalog by content type or URL. Extract shows, movies, episodes... | ⚽ FotMob Scraper ⚽ Match Details, Stats, Lineups & Players Pull structured football data from FotMob: match details with scores, team stats, events... |
| ⚽ BookMyShow Scraper Scrape BookMyShow movies and live events by city, category or URL. Extract genres... | ⚽ Sportsbook Odds Scraper (1xBet, Melbet, Linebet, Paripulse) Collect live and prematch betting odds from 1xBet, Melbet, Linebet and Paripulse. Give it... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.