# Strava Segment & Club Intel - Public Segment, Climb & Club Data (`seibs.co/strava-segment-intel`) Actor

Public Strava segment + club intelligence the locked-down API no longer hands out: normalized segments (distance, grade, elevation, climb category), aggregate club info, and popular-segments-by-area rollups. Logged-out, public-only, PII-minimized. For coaches and route analytics.

- **URL**: https://apify.com/seibs.co/strava-segment-intel.md
- **Developed by:** [Seibs.co](https://apify.com/seibs.co) (community)
- **Categories:** Business, Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 segment or club records

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Strava Segment & Club Intel

Public Strava **segment** and **club** intelligence the locked-down API no longer hands to third parties - normalized into one schema, with geometry-derived climb metrics and popular-segments-by-area rollups.

In November 2024 Strava tightened its API: new apps default to **one authorized user**, broader access goes through a review/approval form, **AI/aggregation use is banned**, and a developer subscription gates the standard tier. The people that locks out - fitness-app builders, coaches, route/segment-analytics tools, endurance-gear marketers - are exactly who needs this data. This actor delivers the **public** segment/club surface that doesn't require an application: logged-out, public-only, and PII-minimized.

> **Responsible use (read this first).** This actor reads **only logged-out, PUBLIC Strava data**. It does **not** log in, use any athlete credential, or collect individual athletes' names, IDs, photos, leaderboard positions, or any private activity/movement trace. Club output is **aggregate** (member *count* only). Segment geometry is the segment's own public road/trail shape, not a person. Use it for segment/route and **area** analytics, not to profile or track individuals. Respect Strava's Terms and applicable privacy law in your jurisdiction.

---

### What it does

| Mode | Input | Output |
|---|---|---|
| **segment_detail** | `segment_ids` (IDs or URLs) | Normalized segment records - name, sport, location, and **distance / average + max grade / elevation gain-loss / climb category** *derived from Strava's own public geometry stream* - plus automatic **area rollups**. |
| **club_profile** | `club_ids` (IDs or URLs) | **Aggregate** club records - name, sport, location, club type, **member count**, verified flag. No member identities, ever. |
| **area_explore** | `bounds` or `center_lat/lng` + `radius_km` | Best-effort bounding-box discovery. Strava's explore endpoint is auth-gated when logged out, so this **fail-softs** with a documented note unless you supply a warm browser session (`browser_cdp_url`); place-level rollups still run over any `segment_ids` you provide. |

#### Why the metrics are *derived*

Since the Nov-2024 lockdown, the logged-out segment page no longer ships the numeric stats (effort/athlete counts, leaderboards) - those load behind a session. What **is** public is the segment's geometry stream (`/stream/segments/{id}`: the distance, altitude, and lat/lng arrays of the segment's shape). This actor computes distance, grade, elevation gain/loss, and a Strava-style **climb category** from that public geometry, and labels every computed value `metrics_source: "public_stream"` so you never mistake a derived grade for an official one.

Worked example (live-verified): segment **229781 "Hawk Hill"** -> 2,658 m, 5.86% avg grade, +156 m, **Cat 4**. Segment **8109834 "Old La Honda"** -> 5,048 m, 7.7% avg grade, +389 m, **Cat 2**.

---

### Output

Each record carries `record_type`: `segment`, `club`, `area_rollup`, plus a `responsible_use_note` header and any `fetch_error` / `explore_gated` notes. Dataset **views**: `overview` (AI-agent skim), `segments`, `clubs`, `areas`.

```json
{
  "record_type": "segment",
  "segment_id": "229781",
  "name": "Hawk Hill",
  "activity_type": "ride",
  "display_location": "Marin Headlands (GGNRA), California",
  "distance_m": 2658.5, "distance_mi": 1.65,
  "average_grade_pct": 5.86, "max_grade_pct": 9.2,
  "elevation_diff_m": 155.9, "total_elevation_gain_m": 155.9,
  "climb_category": 4, "climb_category_label": "Cat 4",
  "start_latlng": [37.8331, -122.483451],
  "metrics_source": "public_stream",
  "source_url": "https://www.strava.com/segments/229781"
}
````

***

### Pricing (pay-per-event)

| Event | Price | When |
|---|---|---|
| `segment_record` | $0.006 | One normalized segment or aggregate club record |
| `metric_enrichment` | $0.012 | Per segment enriched with geometry-derived metrics |
| `area_rollup` | $0.015 | Per popular-segments-by-area aggregation |
| `scheduled_delta_run` | $0.050 | Per scheduled monitor run (new/changed deltas) |

***

### Anti-bot escalation ladder

Strava's public pages usually answer the cheapest tier from a datacenter IP. On a real block the client escalates automatically:

1. **httpx** over the DATACENTER proxy.
2. **curl\_cffi** with Chrome TLS impersonation over the RESIDENTIAL proxy (defeats JA3/TLS-fingerprint WAFs).
3. **Playwright** (patchright stealth) over RESIDENTIAL / a warm `BROWSER_CDP_URL` session - for JS/Cloudflare challenges and to reach the auth-gated explore endpoint with the operator's *own* session (this actor never handles credentials).
4. **Fail-soft** - a documented note, run still finishes SUCCEEDED.

Set `BROWSER_CDP_URL` to point the browser tier at a warm anti-detect browser. CAPTCHA-less by default.

***

### Monitor mode

Run on a schedule (Apify Schedules) and the actor computes a delta vs the prior run - new/changed segments and **club member-count trends** (an aggregate, privacy-safe "leaderboard trend" signal) - and can post a Slack digest (`slack_webhook_url`). Adds `scheduled_delta_run` only on scheduled runs.

***

### What this actor will NOT do

- No login, no athlete OAuth, no cookies carried in.
- No individual athlete records, names, IDs, photos, or follower graphs.
- No segment **leaderboards** (gated logged-out anyway) and no KOM/QOM holder identities.
- No personal **routes** or **activities** - those are an individual's movement trace and are deliberately not built.

These are hard product boundaries, not toggles.

***

### MCP / AI agents

A companion **`mcp-strava-segment-intel`** server exposes these as MCP tools (`get_segments`, `get_club`, `area_rollup`, `explore_segments`) for Claude, Cursor, OpenAI, and LangChain, with x402 (USDC on Base) and Skyfire agentic-payment support. The dataset also ships an MCP-compatible JSON link (see Output tab).

### Who it's for

Cycling/running businesses, coaches and route/segment-analytics tools, endurance-gear marketers, and AI agents doing route/area research - anyone shut out by the Nov-2024 API lockdown who needs the public segment/club layer without an application.

# Actor input Schema

## `mode` (type: `string`):

segment\_detail = normalize specific public segments (by ID/URL) + auto area rollups. club\_profile = aggregate public club info (member COUNT only, no member identities). area\_explore = best-effort bounding-box segment discovery (Strava's explore endpoint is auth-gated logged-out, so this fail-softs unless you supply a warm browser session).

## `segment_ids` (type: `array`):

Strava segment IDs (e.g. '229781') or full URLs (e.g. 'https://www.strava.com/segments/8109834'). Used in segment\_detail mode (and to seed area rollups in area\_explore). Hard cap of 200.

## `club_ids` (type: `array`):

Strava club IDs (e.g. '106667') or URLs (e.g. 'https://www.strava.com/clubs/106667'). Used in club\_profile mode. Output is aggregate (name, sport, location, member COUNT) - individual member identities are never collected. Hard cap of 100.

## `bounds` (type: `string`):

Geographic bounding box for area\_explore as 'sw\_lat,sw\_lng,ne\_lat,ne\_lng' (e.g. '37.82,-122.51,37.84,-122.48'). Alternatively use center\_lat + center\_lng + radius\_km.

## `center_lat` (type: `string`):

Latitude of the area center for area\_explore (alternative to bounds). Pair with center\_lng and radius\_km.

## `center_lng` (type: `string`):

Longitude of the area center for area\_explore (alternative to bounds). Pair with center\_lat and radius\_km.

## `radius_km` (type: `integer`):

Radius in km around the center for area\_explore (0.5-50). Default 5.

## `activity_type` (type: `string`):

Activity type for area\_explore discovery: 'riding' or 'running'.

## `include_derived_metrics` (type: `boolean`):

Fetch the public segment geometry stream and DERIVE distance, average/max grade, elevation gain/loss, and climb category. Adds a metric\_enrichment PPE charge per segment that yields metrics. On by default - it is the core value.

## `include_geometry` (type: `boolean`):

Attach the segment's full lat/lng polyline (its public road/trail shape) to each record. Off by default (bulky). Start/end points are always included as inherent public segment facts.

## `max_results` (type: `integer`):

Hard cap on how many segments or clubs are fetched this run. Default 100.

## `use_browser_fallback` (type: `boolean`):

When the cheap httpx tier is blocked, escalate to curl\_cffi TLS impersonation (residential) and then a stealth Playwright browser. Also enables the browser leg used for the auth-gated explore endpoint. Disable for the cheapest httpx-only runs.

## `browser_cdp_url` (type: `string`):

Optional. CDP endpoint of an already-running warm / anti-detect browser. The browser tier connects to it instead of launching a fresh Chromium - inheriting its session + IP. This is how an operator can reach the auth-gated explore endpoint with their own logged-in session; this actor never handles credentials itself.

## `slack_webhook_url` (type: `string`):

Optional. When this actor runs on a schedule, post a new/changed-segment (and club member-count delta) digest to this Slack incoming webhook. Adds scheduled\_delta\_run PPE on scheduled runs only.

## `use_apify_proxy` (type: `boolean`):

Route requests through Apify Proxy. DATACENTER is used for the cheap httpx pass; RESIDENTIAL is provisioned for the escalation legs.

## `apify_proxy_groups` (type: `array`):

Apify Proxy groups for the first (httpx) tier. DATACENTER is fine for Strava's public pages.

## `concurrency` (type: `integer`):

Parallel Strava requests. Capped at 6 and rate-limited with an inter-request delay to stay polite.

## Actor input object example

```json
{
  "mode": "segment_detail",
  "segment_ids": [
    "229781",
    "8109834"
  ],
  "club_ids": [],
  "bounds": "",
  "center_lat": "",
  "center_lng": "",
  "radius_km": 5,
  "activity_type": "riding",
  "include_derived_metrics": true,
  "include_geometry": false,
  "max_results": 25,
  "use_browser_fallback": true,
  "browser_cdp_url": "",
  "slack_webhook_url": "",
  "use_apify_proxy": true,
  "apify_proxy_groups": [
    "DATACENTER"
  ],
  "concurrency": 3
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Narrow, token-efficient slice of every record. Consumer: LLM agents (Claude, GPT, LangChain tools), MCP hosts, dashboards. Fields: type, name, sport, location, distance, grade, climb, members, URL.

## `datasetItemsSegments` (type: `string`):

Public segments with geometry-derived distance, grade, elevation, and climb category. Consumer: cycling/running businesses, coaches, route/segment analytics.

## `datasetItemsClubs` (type: `string`):

Aggregate public club info - member COUNT only, no member identities. Consumer: club/community analysts, endurance-gear marketers.

## `datasetItemsAreas` (type: `string`):

Popular-segments-by-area aggregation (region x activity). Consumer: route planners, local-segment leaderboards, area analytics.

## `datasetItemsMcp` (type: `string`):

First 50 overview records as a clean JSON array. Wrap on the agent side in an MCP tool-call response envelope, e.g. `{ "ok": true, "data": <this array>, "meta": { "actor": "strava-segment-intel", "count": <len>, "view": "overview" } }`. Consumer: MCP servers, Claude Desktop, Cursor, OpenAI Assistants tool calls.

## `datasetItemsCsv` (type: `string`):

Spreadsheet-friendly export of the overview view. Consumer: humans, analysts, Excel / Google Sheets users.

# 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 = {
    "mode": "segment_detail",
    "segment_ids": [
        "229781",
        "8109834"
    ],
    "max_results": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("seibs.co/strava-segment-intel").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 = {
    "mode": "segment_detail",
    "segment_ids": [
        "229781",
        "8109834",
    ],
    "max_results": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("seibs.co/strava-segment-intel").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "mode": "segment_detail",
  "segment_ids": [
    "229781",
    "8109834"
  ],
  "max_results": 25
}' |
apify call seibs.co/strava-segment-intel --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=seibs.co/strava-segment-intel",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Strava Segment & Club Intel - Public Segment, Climb & Club Data",
        "description": "Public Strava segment + club intelligence the locked-down API no longer hands out: normalized segments (distance, grade, elevation, climb category), aggregate club info, and popular-segments-by-area rollups. Logged-out, public-only, PII-minimized. For coaches and route analytics.",
        "version": "0.1",
        "x-build-id": "pNyuhB0bueB35dTvr"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/seibs.co~strava-segment-intel/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-seibs.co-strava-segment-intel",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/seibs.co~strava-segment-intel/runs": {
            "post": {
                "operationId": "runs-sync-seibs.co-strava-segment-intel",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/seibs.co~strava-segment-intel/run-sync": {
            "post": {
                "operationId": "run-sync-seibs.co-strava-segment-intel",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "mode"
                ],
                "properties": {
                    "mode": {
                        "title": "Mode",
                        "enum": [
                            "segment_detail",
                            "club_profile",
                            "area_explore"
                        ],
                        "type": "string",
                        "description": "segment_detail = normalize specific public segments (by ID/URL) + auto area rollups. club_profile = aggregate public club info (member COUNT only, no member identities). area_explore = best-effort bounding-box segment discovery (Strava's explore endpoint is auth-gated logged-out, so this fail-softs unless you supply a warm browser session).",
                        "default": "segment_detail"
                    },
                    "segment_ids": {
                        "title": "Segment IDs or URLs",
                        "maxItems": 200,
                        "type": "array",
                        "description": "Strava segment IDs (e.g. '229781') or full URLs (e.g. 'https://www.strava.com/segments/8109834'). Used in segment_detail mode (and to seed area rollups in area_explore). Hard cap of 200.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "club_ids": {
                        "title": "Club IDs or URLs",
                        "maxItems": 100,
                        "type": "array",
                        "description": "Strava club IDs (e.g. '106667') or URLs (e.g. 'https://www.strava.com/clubs/106667'). Used in club_profile mode. Output is aggregate (name, sport, location, member COUNT) - individual member identities are never collected. Hard cap of 100.",
                        "default": [],
                        "items": {
                            "type": "string"
                        }
                    },
                    "bounds": {
                        "title": "Bounding box (area_explore)",
                        "type": "string",
                        "description": "Geographic bounding box for area_explore as 'sw_lat,sw_lng,ne_lat,ne_lng' (e.g. '37.82,-122.51,37.84,-122.48'). Alternatively use center_lat + center_lng + radius_km.",
                        "default": ""
                    },
                    "center_lat": {
                        "title": "Center latitude (area_explore)",
                        "type": "string",
                        "description": "Latitude of the area center for area_explore (alternative to bounds). Pair with center_lng and radius_km.",
                        "default": ""
                    },
                    "center_lng": {
                        "title": "Center longitude (area_explore)",
                        "type": "string",
                        "description": "Longitude of the area center for area_explore (alternative to bounds). Pair with center_lat and radius_km.",
                        "default": ""
                    },
                    "radius_km": {
                        "title": "Radius km (area_explore)",
                        "minimum": 1,
                        "maximum": 50,
                        "type": "integer",
                        "description": "Radius in km around the center for area_explore (0.5-50). Default 5.",
                        "default": 5
                    },
                    "activity_type": {
                        "title": "Activity type (area_explore)",
                        "enum": [
                            "riding",
                            "running"
                        ],
                        "type": "string",
                        "description": "Activity type for area_explore discovery: 'riding' or 'running'.",
                        "default": "riding"
                    },
                    "include_derived_metrics": {
                        "title": "Derive segment metrics from public geometry",
                        "type": "boolean",
                        "description": "Fetch the public segment geometry stream and DERIVE distance, average/max grade, elevation gain/loss, and climb category. Adds a metric_enrichment PPE charge per segment that yields metrics. On by default - it is the core value.",
                        "default": true
                    },
                    "include_geometry": {
                        "title": "Include the full segment polyline",
                        "type": "boolean",
                        "description": "Attach the segment's full lat/lng polyline (its public road/trail shape) to each record. Off by default (bulky). Start/end points are always included as inherent public segment facts.",
                        "default": false
                    },
                    "max_results": {
                        "title": "Max segments/clubs to fetch",
                        "minimum": 1,
                        "maximum": 200,
                        "type": "integer",
                        "description": "Hard cap on how many segments or clubs are fetched this run. Default 100.",
                        "default": 100
                    },
                    "use_browser_fallback": {
                        "title": "Enable anti-bot escalation (curl_cffi + browser)",
                        "type": "boolean",
                        "description": "When the cheap httpx tier is blocked, escalate to curl_cffi TLS impersonation (residential) and then a stealth Playwright browser. Also enables the browser leg used for the auth-gated explore endpoint. Disable for the cheapest httpx-only runs.",
                        "default": true
                    },
                    "browser_cdp_url": {
                        "title": "Warm browser CDP URL (optional)",
                        "type": "string",
                        "description": "Optional. CDP endpoint of an already-running warm / anti-detect browser. The browser tier connects to it instead of launching a fresh Chromium - inheriting its session + IP. This is how an operator can reach the auth-gated explore endpoint with their own logged-in session; this actor never handles credentials itself.",
                        "default": ""
                    },
                    "slack_webhook_url": {
                        "title": "Slack webhook (monitor mode)",
                        "type": "string",
                        "description": "Optional. When this actor runs on a schedule, post a new/changed-segment (and club member-count delta) digest to this Slack incoming webhook. Adds scheduled_delta_run PPE on scheduled runs only.",
                        "default": ""
                    },
                    "use_apify_proxy": {
                        "title": "Use Apify Proxy",
                        "type": "boolean",
                        "description": "Route requests through Apify Proxy. DATACENTER is used for the cheap httpx pass; RESIDENTIAL is provisioned for the escalation legs.",
                        "default": true
                    },
                    "apify_proxy_groups": {
                        "title": "Proxy groups (httpx tier)",
                        "type": "array",
                        "description": "Apify Proxy groups for the first (httpx) tier. DATACENTER is fine for Strava's public pages.",
                        "default": [
                            "DATACENTER"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "concurrency": {
                        "title": "Max concurrent requests",
                        "minimum": 1,
                        "maximum": 6,
                        "type": "integer",
                        "description": "Parallel Strava requests. Capped at 6 and rate-limited with an inter-request delay to stay polite.",
                        "default": 3
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
