Strava Data Scraper - Clubs, Athletes & Challenges avatar

Strava Data Scraper - Clubs, Athletes & Challenges

Pricing

from $1.60 / 1,000 strava records

Go to Apify Store
Strava Data Scraper - Clubs, Athletes & Challenges

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

Abot API

Maintained by Community

Actor 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.

FieldExample
recordIdclub:1234567
kindclub, athlete or challenge
nameRiverside Runners
urlhttps://www.strava.com/clubs/1234567
descriptionA friendly community running club
sportTypeRunning
clubTypes["CasualClub"]
city / state / country / countryCodeSpringfield / Illinois / United States / US
memberCount128
verified / inviteOnly / leaderboardEnabled / postsDefaultViewclub settings booleans
websitehttps://example.org
avatarUrl / coverPhotoUrl / displayIconclub imagery and icon token
memberPreviews / badgeType / profileVisibilitySettingfirst members with id, name, badge; Premium; Everyone
challengeId / slug / shortName / subtitle1234567 / october-10k-challenge / October 10K / Lace 'em up
sportrun, ride, swim, walk, hike, workout
goal / dimension / activityType10000.0 / avg_pace_min_distance / streak
dateStart / dateEnd2026-10-01 / 2026-10-31
participantsCount / followersInChallenge244063 / null
qualifyingActivities["Badminton", "Basketball"]
organizingClub / joined / endedthe club that runs the challenge; join state
overviewText / rewardsText / rulesText / additionalInfoTextthe challenge page's section texts
changeTypeNEW, UPDATED, UNCHANGED, REAPPEARED, EXPIRED

Every record also keeps the raw source payload in raw for auditability.

How to Use

Quick start

  1. Challenges (default): just run it. Every current challenge in the gallery, with detail pages read for participant counts and qualifying activities.
  2. Clubs / Athletes: switch the mode and paste links (strava.com/clubs/..., strava.com/athletes/...) or bare ids.
  3. 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 ApifyClient
client = 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.

ParameterTypeDefaultDescription
mcpConnectorsarray[]Connector IDs to push results into after the run.
notionParentPageUrlstring``When pushing into a Notion connector, the parent page to write under.
maxNotifyListingsnumber50Cap on records sent to MCP connectors per run.

Input Parameters

ParameterTypeDefaultDescription
modeselectchallengesChallenges (all current challenges), Clubs (from links), Athletes (from links), Discover (public directory walk).
challengeSportsmulti-selectallWhich sport sections of the challenge gallery to collect.
fetchChallengeDetailscheckboxtrueAdds participant count, qualifying activities and description per challenge.
linkslistone example of each shapeClub or athlete links (full URLs with ids or slugs, or bare ids/slugs); the default carries one example of every supported shape.
discoverCountnumber20How many clubs to collect from the public directory, in directory order.
discoverOffsetnumber0Skip this many directory entries first (continue long walks in later runs).
maxItemsnumber20Maximum records to push.
proxyConfigurationproxyresidentialA residential connection is the reliable default.
resumeFromRunIdstring(empty)Skip records already collected in an earlier run.
incrementalModecheckboxfalseOnly NEW/CHANGED rows on re-runs; disappeared records become EXPIRED.
stateKeystring(empty)Name the incremental baseline yourself to share it across runs.
emitUnchangedcheckboxfalsePush every record each run, flagged UNCHANGED.
emitExpiredcheckboxfalsePush records that disappeared from a complete scan, flagged EXPIRED.
ignoreFieldsForChangeslist(empty)Extra fields that should never mark a record as changed.
mcpConnectorslist(empty)Connector IDs to push results into after the run.
notionParentPageUrlstring(empty)When pushing into a Notion connector, the parent page to write under.
maxNotifyListingsnumber50Cap 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.

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...

👉 Browse all abotapi scrapers

💬 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.