# Strava Community Hub Scraper (`maximedupre/strava`) Actor

Search public Strava athletes, clubs, activities, challenges, events, training pages, and Community Hub posts or help articles by keyword. Get structured rows with source links, context, public contact details, and images when available. Filter by location, email, phone, or Community Hub type.

- **URL**: https://apify.com/maximedupre/strava.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 1 total users, 1 monthly users, 85.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.65 / 1,000 public matches

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### 🏃 Find public Strava athletes, clubs, and content

For sports researchers, coaches, marketing teams, and developers, this Actor searches public Strava pages from one shared list of keywords. It returns structured rows for athletes, clubs, activities, challenges, events, training pages, and Community Hub posts or help articles, with source links, context, and public contact details when available. Use the data to study sports communities, find relevant public pages, and review possible public contacts in one dataset.

- Search public pages for broad topics with **[Strava App](https://apify.com/maximedupre/strava/examples/strava-app)** and review matching source links.
- Find public running athletes, clubs, and content with **[Strava Running](https://apify.com/maximedupre/strava/examples/strava-running)** for a focused sports search.
- Look up public Community Hub help pages about pricing with **[Is Strava Free](https://apify.com/maximedupre/strava/examples/is-strava-free)**.
- Search public Community Hub guidance about devices with **[Strava Watch](https://apify.com/maximedupre/strava/examples/strava-watch)**.
- Find public watch compatibility help pages with **[Strava Compatible Watches](https://apify.com/maximedupre/strava/examples/strava-compatible-watches)**.
- Find public Community Hub help pages about account billing with **[Strava Manage Subscription](https://apify.com/maximedupre/strava/examples/strava-manage-subscription)**.

#### 🧾 Structured Strava search rows

The Actor saves the first eligible occurrence of each public source item. If the same item appears again from another keyword, URL, handle, or ID, that later match is ignored, so the row keeps the first saved match context. Optional fields are included only when the source provides them.

#### ▶️ Search public Strava data

1. Add one or more keywords of the same kind to search in one run.
2. Add a location, email domain, phone country, or Community Hub content filter when needed.
3. Set `maxResultsPerKeyword` if you want a smaller distinct result set for each keyword.
4. Start the run and open the dataset from the Output tab.

All keywords in a run use the same optional filters. The Actor does not run several independently configured search batches in one run.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `keywords` | array of strings | Required. Searches public Strava pages with one or more words or phrases. |
| `location` | string | Optional. Narrows public results to a city, region, or country. Leave it blank to search all locations. |
| `emailDomains` | array of strings | Optional. Keeps matches with public email addresses from the listed domains. Leave it blank to include any available public email domain. |
| `phoneCountry` | string | Optional. Keeps matches with public phone numbers from the selected country. Leave it blank to include any available public phone number. |
| `communityContentType` | string | Optional. Chooses `all`, `posts`, or `helpArticles` for Community Hub content. Other supported result types are not changed by this setting. |
| `maxResultsPerKeyword` | integer | Optional. Sets the maximum number of distinct results for each keyword. Leave it empty to return all available results until the source is exhausted. |

**Example input**

This is the public input from successful hosted QA default-input run `irpmm5jPFBljPe8Jm`.

```json
{
  "keywords": [
    "marathon"
  ],
  "communityContentType": "all",
  "maxResultsPerKeyword": 10
}
```

Leaving `maxResultsPerKeyword` empty returns all available results until the source is exhausted. The same rule applies to any other optional filter that is left blank: it does not add a restriction.

#### 🧾 Output

The Output tab opens the default dataset with the structured rows from the run. Optional fields are included only when the source provides them.

**Output link**

| Field | Type | What it does |
| --- | --- | --- |
| `dataset` | link | Opens the structured rows returned by this public Strava search. |

**Output fields**

| Field | Type | What it does |
| --- | --- | --- |
| `resultType` | string | Required. Identifies the source result type, such as `athlete`, `club`, `activity`, `challenge`, `event`, `training`, `communityPost`, or `helpArticle`. |
| `title` | string | Required. Gives the public athlete or club name, or the content title. |
| `bio` | string | Optional. Gives public biography or profile text when available. |
| `excerpt` | string | Optional. Gives a short public content excerpt when available. |
| `authors` | array of strings | Optional. Lists public authors credited for the content. |
| `affiliations` | array of strings | Optional. Lists public clubs, teams, or other source affiliations. |
| `categories` | array of strings | Optional. Lists categories assigned by the source. |
| `location` | string | Optional. Gives the public location shown by the source. |
| `publishedAt` | date-time string | Optional. Gives the source publication date for content when available. |
| `sourceUrl` | URL string | Required. Links directly to the public Strava source page. |
| `contacts` | object | Optional. Holds public contact details and source-provided contact context. |
| `contacts.emails` | array of strings | Optional. Lists public email addresses shown by the source. |
| `contacts.emailDomains` | array of strings | Optional. Lists email domains shown by the source. |
| `contacts.phoneNumbers` | array of strings | Optional. Lists public phone numbers shown by the source. |
| `contacts.phoneCountries` | array of strings | Optional. Lists phone countries shown by the source. |
| `imageUrls` | array of URL strings | Optional. Lists public image URLs belonging to the returned profile, club, or content item when available. |

**Example output row**

This complete row is from successful current-beta run `7fobszjz0Adzf20FT`. It shows a club with source context, a public contact, and item images.

```json
{
  "resultType": "club",
  "title": "Stumprunners",
  "sourceUrl": "https://www.strava.com/clubs/117663",
  "bio": "🌲Running PDX since Nov 27, 2012🌲 📍NW 24th & Thurman 🕘 Every Saturday, 9AM Multiple Distance Options. All Paces. All Abilities. 📧 stumprunners@gmail.com 📱 IG: @stumprunners",
  "excerpt": "Demo Run with Keen this Saturday 8/1",
  "authors": [
    "Stumprunners"
  ],
  "affiliations": [
    "Stumprunners"
  ],
  "categories": [
    "Running",
    "CasualClub",
    "LocalCommunity"
  ],
  "location": "Portland, Oregon, United States",
  "publishedAt": "2026-07-30T06:47:05.000Z",
  "contacts": {
    "emails": [
      "stumprunners@gmail.com"
    ],
    "emailDomains": [
      "gmail.com"
    ]
  },
  "imageUrls": [
    "https://dgalywyr863hv.cloudfront.net/pictures/clubs/117663/2193429/3/large.jpg",
    "https://dgalywyr863hv.cloudfront.net/pictures/clubs/117663/35256834/1/large.jpg"
  ]
}
```

#### 💳 Pricing

**Billable event**

The billable event is one public Strava athlete, club, or content match saved to the dataset. The amount depends on the Apify pricing tier shown for your account. Setup, diagnostic, and no-result behavior are not represented by this event description.

#### 🔌 Integrations

**Dataset access**

Open the dataset in Apify, use the dataset API, or export the returned rows in a supported format.

**Video guide**

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### What happens when the same public item matches more than one keyword?

The first eligible occurrence is saved. A later match for the same source item from another keyword, URL, handle, or ID is ignored, so the row keeps the first match context.

##### Which public Strava sources can appear?

Rows can represent athletes, clubs, activities, challenges, events, training content, Community Hub posts, or help articles when a matching public page is available.

##### Does the Actor access private Strava data?

No. It searches publicly accessible Strava pages only. Account-only and authenticated data are not included.

##### Will every row include an email address or phone number?

No. Contact details are included only when the source exposes them publicly and they match the optional filters. A missing contact does not remove the main public result.

##### How does the per-keyword limit work?

`maxResultsPerKeyword` limits distinct results separately for each submitted keyword. Leave it empty to return all available results until the source is exhausted.

##### Can I narrow the search?

Yes. Use `location` for a geographic filter, `emailDomains` for public email domains, `phoneCountry` for public phone numbers, and `communityContentType` for Community Hub posts or help articles.

##### Can I run different settings for different keywords?

No. One run uses one shared keyword list and one shared set of optional filters. Use separate runs when the searches need different settings.

##### What does `publishedAt` mean?

It is the source publication date for content when the source provides one. It is not a capture-time field.

### 📝 Changelog

**v0.1** (24-09-2026)

- Search a public Strava activity by its numeric ID.
- Find more valid public matches from Strava search results.
- Match phone-country filters when public pages use common country names.
- Continue processing other keywords after a temporary source failure.

**v0.0** (17-09-2026)

- Initial release.

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~strava/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [Influencer Scraper](https://apify.com/maximedupre/influencer-scraper): Find public creator profiles by keyword across TikTok, Instagram, and YouTube.
- [Instagram User Search Scraper](https://apify.com/maximedupre/instagram-user-search-scraper): Find public Instagram accounts by keyword with profile, audience, and public contact data.
- [Facebook Business Page Lead Scraper](https://apify.com/maximedupre/facebook-page-lead-scraper): Find public Facebook Pages with available public contact fields for lead research.
- [Strava Community Hub Scraper - Cheap 🚴](https://apify.com/scrapestorm/strava-community-hub-scraper---cheap): Focus on public Strava Community Hub posts and help articles.
- [Strava Email Scraper – Cheapest 🏃‍♂️🚴‍♀️📧](https://apify.com/contactminerlabs/strava-email-scraper---cheapest): Focus on public email addresses from Strava athlete and club profiles.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `keywords` (type: `array`):

Enter one or more words or phrases to search public Strava athletes, clubs, activities, challenges, events, training content, and Community Hub posts or help articles.

## `location` (type: `string`):

Enter a city, region, or country to narrow public results by location. Leave it blank to search all locations.

## `emailDomains` (type: `array`):

Optionally enter one or more email domains for matches with public email addresses. Leave it blank to include any available public email domain.

## `phoneCountry` (type: `string`):

Optionally enter a country for matches with public phone numbers. Leave it blank to include any available public phone number.

## `communityContentType` (type: `string`):

Choose which Community Hub items to include. This setting does not change athlete, club, activity, challenge, event, or training results.

## `maxResultsPerKeyword` (type: `integer`):

Set the maximum number of distinct results returned for each keyword. Leave it blank to return all available results until the source is exhausted.

## Actor input object example

```json
{
  "keywords": [
    "trail running",
    "cycling club"
  ],
  "location": "London",
  "emailDomains": [
    "example.com"
  ],
  "phoneCountry": "United Kingdom",
  "communityContentType": "posts",
  "maxResultsPerKeyword": 25
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open the structured rows returned by this public Strava search.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": [
        "marathon"
    ],
    "maxResultsPerKeyword": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/strava").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keywords": ["marathon"],
    "maxResultsPerKeyword": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/strava").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": [
    "marathon"
  ],
  "maxResultsPerKeyword": 10
}' |
apify call maximedupre/strava --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/strava"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/muWfxpac8euMryfaK/builds/9gSML9nNTAomT1muT/openapi.json
