Intervals.icu API
I sync all my Strava activities to intervals.icu, which calculates my training load, fitness score, and my weekly ramp rate. To test out this platform’s API
, I wanted to calculate the distance that I ran or cycled given a custom date range, as this is something that I don’t immediately see inside intervals.icu itself. GET /api/v1/athlete/{id}/activities
returns a list of activities between the parameters oldest
and newest
:
BASE_URL="https://intervals.icu/api/v1/athlete"OLDEST="2024-01-01"NEWEST="2024-12-31"curl -s -u API_KEY:$API_KEY \ "$BASE_URL/$INTERVALS_UID/activities?oldest=$OLDEST&newest=$NEWEST"
As we can’t select specific activity types through the API
(we’re only interested in runs for this example, but this list contains all types of activities), I made use of jq
— “a lightweight and flexible command-line JSON
processor” — to select the name, start time, and distance of running activities only:
BASE_URL="https://intervals.icu/api/v1/athlete"OLDEST="2024-01-01"NEWEST="2024-12-31"curl -s -u API_KEY:$API_KEY \ "$BASE_URL/$INTERVALS_UID/activities?oldest=$OLDEST&newest=$NEWEST" | \jq '[.[] | select(.type == "Run") | {name, start_date_local, distance}]'
[ ⋯, { "name": "Night Run", "start_date_local": "2024-08-06T21:44:54", "distance": 6699 }, { "name": "Afternoon Run", "start_date_local": "2024-08-06T16:06:24", "distance": 3400.5 }, { "name": "Evening Run", "start_date_local": "2024-08-04T20:58:21", "distance": 4928 }, ⋯]
This shows that our filter for running activities works. To now sum the distance of all our activities, we just need to select the distance of every activity and map add
over it. This returns the total distance in meters.
BASE_URL="https://intervals.icu/api/v1/athlete"OLDEST="2024-01-01"NEWEST="2024-12-31"curl -s -u API_KEY:$API_KEY \ "$BASE_URL/$INTERVALS_UID/activities?oldest=$OLDEST&newest=$NEWEST" | \jq 'map(select(.type == "Run") | .distance) | add'
701168.5
GitHub Actions for Hugo shortcode
As I wanted to do something with this distance, I made a GitHub Actions workflow that calculates the distance every day at midnight and uses sed
to replace the Hugo variable .Site.Params.distanceRun
. Using this variable, I created a Hugo shortcode {{< distance_run >}}
that returns the distance run in kilometers:
{{- $distanceMeters := .Site.Params.distanceRun -}}{{- $distanceKilometers := div $distanceMeters 1000 -}}{{ printf "%.1f" $distanceKilometers }} km
Using {{< distance_run >}}
in a Hugo content file returns: 996.6 km.
I can put this value in a tooltip with an explanation of the value, which is displayed as 996.6 kmTotal distance since 1st of Jan.
:
{{< tooltip >}}{{< distance_run >}} | Total distance since 1st of Jan.{{</ tooltip >}}