Training Data API
This guide explains how to access Pascal’s Strava training data — runs, hikes, ski tours, bike rides — including heart rate, pace, elevation profile, and per-second streams. No Strava account or login required.
Contents
1. Access & Authentication
The API is accessible over HTTPS from any browser, curl command, Python script, or tool like Postman. Every request needs the API key added as a URL parameter.
https://wagenhofer.ch/me/wp-json/strava/v1
?key=contact Pascal
Example — paste this directly into a browser to verify it works:
2. Quick Start — 3 URLs to bookmark
🏃 Last 10 runs with HR and pace
📈 Full lifetime training stats
💕 Per-second HR + elevation for a specific activity
Replace 18781993073 with the Strava activity ID (visible in the Strava URL or in the strava_id field of any activity).
3. All Endpoints
Example
Response (excerpt)
“total_km”: 8544.9,
“total_moving_h”: 900.1,
“total_elevation_m”: 208192,
“total_calories”: 607014,
“avg_heartrate”: 135.4,
“by_type”: {
“Run”: { “count”: 581, “km”: 6843.2 },
“Hike”: { “count”: 49, “km”: 192.3 },
“AlpineSki”: { “count”: 44, “km”: 846.2 },
“EBikeRide”: { “count”: 34, “km”: 492.3 }
}
| Parameter | Required | Description |
|---|---|---|
| key | Yes | API key |
| limit | Optional | Number of results, 1–200. Default: 10 |
| type | Optional | Filter by sport. See sport types below. |
| since | Optional | Only activities from this date onwards. Format: YYYY-MM-DD |
Sport types
Examples
https://wagenhofer.ch/me/wp-json/strava/v1/activities?key=YOUR_KEY&limit=20&type=Run
# All activities since 1 Jan 2026
https://wagenhofer.ch/me/wp-json/strava/v1/activities?key=YOUR_KEY&since=2026-01-01&limit=200
# Last 5 hikes
https://wagenhofer.ch/me/wp-json/strava/v1/activities?key=YOUR_KEY&limit=5&type=Hike
| Parameter | Required | Description |
|---|---|---|
| key | Yes | API key |
| streams | Optional | Set to 1 to also include per-second HR, distance, altitude in the same response |
Examples
https://wagenhofer.ch/me/wp-json/strava/v1/activity/18781993073?key=YOUR_KEY
# Activity detail + per-second streams in one call
https://wagenhofer.ch/me/wp-json/strava/v1/activity/18781993073?key=YOUR_KEY&streams=1
Example
Response
“strava_id”: 18781993073,
“resolution”: “high”, // always “high” (1-second resolution)
“data_points”: 3115, // number of seconds recorded
“hr_summary”: {
“min”: 111,
“max”: 184,
“avg”: 159.6
},
“data”: [
{ “t_s”: 78, “dist_m”: 194.1, “alt_m”: 472.0, “hr_bpm”: 141 },
{ “t_s”: 79, “dist_m”: 197.5, “alt_m”: 472.6, “hr_bpm”: 141 },
{ “t_s”: 80, “dist_m”: 200.7, “alt_m”: 472.8, “hr_bpm”: 141 },
// … one entry per second …
]
}
4. Field Reference
Every field returned by /activities and /activity/{id}, explained in plain terms.
Activity summary fields
Run) and sub-type (e.g. TrailRun).Garmin fēnix 8.Detail fields (single activity only)
5. Heart Rate & Elevation Streams (per-second)
The /streams endpoint goes beyond averages and gives you the complete second-by-second recording. Every row in the data array represents one second of the activity:
How to find a Strava activity ID
Two ways:
- From the
/activitiesendpoint: look for thestrava_idfield in any activity. - From Strava.com: the number in the URL, e.g.
strava.com/activities/18781993073
6. Coach Use Cases
Reviewing the last training block
Returns every activity since 1 May 2026 with distance, HR, pace, elevation, and calories. Load into Excel or Google Sheets by pasting the URL into the JSON import tool.
Analysing a specific long run
Returns per-km splits and per-lap HR. Look at splits_metric[].avg_hr to see if HR was drifting upward (cardiac decoupling) or stable across the run.
Seeing exactly where HR spiked on a climb
The full second-by-second log. Plot alt_m and hr_bpm against t_s on the same chart to correlate climbs with cardiac response.
Checking Google Sheets import
In Google Sheets, use Extensions → Apps Script and paste:
var url = “https://wagenhofer.ch/me/wp-json/strava/v1/activities?key=YOUR_KEY&limit=50&type=Run”;
var data = JSON.parse(UrlFetchApp.fetch(url).getContentText()).activities;
var sheet = SpreadsheetApp.getActiveSheet();
var headers = [“date”,”name”,”distance_km”,”moving_time”,”pace_per_km”,”avg_hr”,”max_hr”,”elevation_m”,”calories”,”suffer_score”,”strava_url”];
sheet.getRange(1,1,1,headers.length).setValues([headers]);
data.forEach(function(a, i) {
sheet.getRange(i+2,1,1,headers.length).setValues([[
a.date, a.name, a.distance_km, a.moving_time, a.pace_per_km,
a.avg_hr, a.max_hr, a.elevation_m, a.calories, a.suffer_score, a.strava_url
]]);
});
}
Run the function once to pull the last 50 runs into a spreadsheet. Change limit=50 or add &since=YYYY-MM-DD to adjust the range.
7. Tips & Limits
- Data freshness: Activities sync automatically from Strava via webhook. New activities appear within a few minutes of Pascal finishing a session.
- Streams are live: The
/streamsendpoint calls Strava’s API in real time. It takes 1–3 seconds to respond and requires an active internet connection on the server. If Strava is down, it will return an error. - Max results: The
limitparameter goes up to 200. For larger exports, usesinceto paginate by date range. - HR not always present: Some activities (e.g. indoor workouts without a chest strap) may have no
avg_hr. These fields will simply be absent from the response. - Streams resolution: Strava records at “high” resolution (1-second intervals during movement). Pauses in the activity are excluded from the stream — the
t_scounter may jump. - Activity IDs never change: Once a Strava activity ID is noted, it always refers to the same activity. Safe to bookmark or store.
Strava Training Data API · wagenhofer.ch · Updated June 2026