Post

Stravas New Developer Program Just Killed Every Open-Source Self-Hosted Strava App

Stravas New Developer Program Just Killed Every Open-Source Self-Hosted Strava App

Strava’s New Developer Program Just Killed Every Open‑Source Self‑Hosted Strava App

INTRODUCTION

The recent announcement from Strava about an update to its developer program has sent shockwaves through the homelab and self‑hosted community. For developers who built their own analytics, activity‑tracking, or data‑visualisation tools on top of Strava’s public API, the change is nothing short of a death knell. The update restricts access to previously open endpoints, enforces stricter OAuth requirements, and introduces rate‑limiting policies that make many existing open‑source projects untenable without costly commercial licences.

For DevOps engineers and sysadmins who rely on self‑hosted solutions to keep data private, reduce latency, and avoid vendor lock‑in, this shift represents a critical infrastructure challenge. The implications extend beyond a single hobby project; they affect the entire stack of tools that power personal dashboards, training‑plan generators, and community‑driven analytics platforms.

In this comprehensive guide we will dissect exactly what Strava’s new developer program entails, why it effectively kills every open‑source self‑hosted Strava app, and how you can adapt your infrastructure to stay compliant while preserving the functionality you need. You will learn:

  • The technical specifics of the API changes and their impact on self‑hosted deployments. * How to redesign your architecture to handle stricter authentication and rate‑limiting.
  • Practical steps for migrating existing Docker‑based tooling to a compliant configuration.
  • Best practices for security, performance, and observability in a post‑update environment.

Whether you are maintaining a personal fitness dashboard, a community‑wide activity tracker, or a custom data‑export pipeline, this article will equip you with the knowledge to navigate Strava’s new policy landscape without sacrificing the self‑hosted ethos that defines modern DevOps practice.


UNDERSTANDING THE TOPIC

What is Strava’s Developer Program?

Strava provides a RESTful API that allows third‑party applications to read and, in limited cases, write data about athletes, activities, and segments. Historically, the API was divided into two tiers: a public, unauthenticated subset that exposed basic activity metadata, and a private, OAuth‑protected subset that required a registered developer key.

The recent “update to our developer program” introduced several breaking changes:

  1. Endpoint Consolidation – Several public endpoints that were previously accessible without authentication were deprecated.
  2. OAuth 2.0 Enforcement – All access now requires a fully vetted OAuth 2.0 flow, including scopes that were previously optional.
  3. Rate‑Limiting Overhaul – A tiered throttling system now caps requests per hour per client ID, with strict enforcement via HTTP 429 responses.
  4. Commercial Licensing – Access to certain high‑value endpoints now mandates a paid partnership or a “Premium API” subscription.

These changes were documented in the official Strava Community Hub post, which can be found here.

History and Development

Strava’s API started as a modest, community‑driven set of endpoints that enabled hobbyist developers to pull activity data for personal use. Over the years, the API grew in popularity, spawning a vibrant ecosystem of open‑source projects such as Statistics for Strava, Strava‑Explorer, and Strava‑Metrics. These tools typically ran in Docker containers, exposing web interfaces that visualised activity heatmaps, segment leaderboards, and training load metrics.

The shift toward a more restrictive API model reflects Strava’s desire to monetize data access, protect user privacy, and reduce abuse. However, the transition was announced with limited migration guidance, leaving many maintainers scrambling to adapt.

Key Features and Capabilities

  • Activity Feed Access – Retrieval of detailed activity metadata (distance, elevation, heart‑rate, power).
  • Segment Leaderboards – Querying segment rankings and personal performance relative to peers.
  • Athlete Profiles – Pulling personal bests, equipment usage, and training history. * Custom OAuth Scopes – Ability to request specific permissions such as activity:read_all.

The new program retains these capabilities but restricts them behind a commercial gate, effectively turning previously free services into paid offerings.

Pros and Cons of Using Strava’s API

ProsCons
Rich, granular activity dataNew OAuth flow adds complexity
Real‑time segment rankingRate limits can throttle bulk queries
Community‑driven open‑source toolsCommercial licensing required for many endpoints
Easy integration with personal dashboardsAPI versioning introduces breaking changes

Use Cases and Scenarios

  • Personal Fitness Dashboards – Self‑hosted Grafana panels that visualise weekly mileage, training load, and heart‑rate trends.
  • Community Activity Aggregators – Platforms that aggregate activities from multiple athletes to generate group‑wide heatmaps. * Training‑Plan Generators – Tools that auto‑create workout plans based on historic performance metrics.
  • Data‑Export Pipelines – Batch processes that export activity data for offline analysis or archival purposes. ### Current State and Future Trends

The current state is one of transition. Many open‑source projects have either shut down or pivoted to paid models. Future trends point toward tighter API governance, increased reliance on official SDKs, and a possible rise in self‑hosted data‑scraping solutions that operate within legal boundaries. ### Comparison to Alternatives

  • Garmin Connect API – Offers similar activity data with a more permissive rate‑limit structure, but requires hardware integration.
  • Fitbit Web API – Provides health‑focused endpoints with robust OAuth, yet is geared toward wearable data rather than cycling/running metrics.
  • OpenStreetMap + Custom Telemetry – Allows full data ownership but demands extensive cartography and data‑normalisation effort.

PREREQUISITES

System Requirements

  • Operating System – Linux (Ubuntu 22.04 LTS or later) is recommended for optimal Docker support.
  • Hardware – Minimum 2 CPU cores, 4 GB RAM, and 20 GB of storage for container images and persisted data.
  • Network – Outbound HTTPS (port 443) access to api.strava.com and inbound ports for any exposed services.

Required Software

ComponentMinimum VersionPurpose
Docker Engine24.0Container runtime for self‑hosted services
Docker Compose2.20Orchestration of multi‑container stacks
curl7.88HTTP client for API testing
jq1.6JSON processing for API responses
git2.35Source‑code retrieval for open‑source projects

Network and Security Considerations

  • Firewall Rules – Allow outbound traffic to api.strava.com on port 443; restrict inbound traffic to only trusted IP ranges if exposing services publicly.
  • TLS Termination – Use a reverse proxy (e.g., Caddy or Nginx) with valid certificates (Let’s Encrypt) to terminate TLS before forwarding to containers.
  • Secret Management – Store OAuth client secrets, refresh tokens, and API keys in Docker secrets or an external vault (e.g., HashiCorp Vault).

User Permissions * Docker Group – Users must belong to the docker group to run Docker commands without sudo.

  • Least‑Privilege Principle – Run containers with non‑root users where possible; avoid mounting host directories with elevated permissions.

Pre‑Installation Checklist

  1. Verify Docker Engine installation (docker --version).
  2. Confirm Docker Compose version (docker compose version).
  3. Create a dedicated system user for running containers (e.g., strava_app).
  4. Generate a strong OAuth client secret and store it securely.
  5. Set up a domain name with DNS pointing to your homelab IP.
  6. Obtain an SSL certificate for the domain (via Certbot or similar).

INSTALLATION & SETUP

Pulling the Base Image

The most common approach to self‑hosting a Strava‑related service is to use an existing Docker image that wraps the open‑source codebase. For illustration, consider the statistics-for-strava project, which provides a Flask‑based API and a React front‑end.

1
docker pull ghcr.io/robiningelbrecht/statistics-for-strava:latest

Note: Replace the image reference with the exact tag used by the maintainer if a newer version exists.

Configuring Environment Variables

The application requires several environment variables to operate securely:

VariableDescriptionExample Value
STRAVA_CLIENT_IDOAuth client identifier registered in the Strava developer console12345678
STRAVA_CLIENT_SECRETSecret associated with the client IDa1b2c3d4e5f6g7h8i9j0
STRAVA_REFRESH_TOKENRefresh token obtained after the initial OAuth consent floweyJ0eXAiOiJKV1QiLCJh...
BASE_URLBase URL of the Strava API (usually https://www.strava.com)https://www.strava.com
CACHE_ENABLEDFlag to enable Redis caching for activity look‑upstrue
CACHE_URLRedis endpoint for caching layerredis://redis:6379

These variables are typically defined in a .env file that Docker Compose reads automatically.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# docker-compose.yml (excerpt)
services:
  app:
    image: ghcr.io/robiningelbrecht/statistics-for-strava:latest
    container_name: $CONTAINER_NAMES
    restart: unless-stopped
    environment:
      - STRAVA_CLIENT_ID=$STRAVA_CLIENT_ID
      - STRAVA_CLIENT_SECRET=$STRAVA_CLIENT_SECRET
      - STRAVA_REFRESH_TOKEN=$STRAVA_REFRESH_TOKEN
      - BASE_URL=$BASE_URL
      - CACHE_ENABLED=$CACHE_ENABLED
      - CACHE_URL=$CACHE_URL
    ports:
      - "8080:80"
    volumes:
      - ./data:/app/data
    depends_on:
      - redis

Starting the Stack

1
docker compose up -d

After the containers are up, verify that the service is responding:

1
curl -s http://localhost:8080/health | jq .

A successful response should return a JSON object with a status field set to ok.

Setting Up Reverse Proxy and TLS

To expose the service securely, configure an Nginx container as a reverse proxy:

1
2
3
4
5
6
7
8
9
10
11
12
13
# docker-compose.yml (additional service)
services:
  nginx:
    image: nginx:alpine
    container_name: $CONTAINER_NAMES-nginx
    restart: unless-stopped
    ports:
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./certs:/etc/letsencrypt:ro
    depends_on:
      - app

The Nginx configuration (conf.d/strava.conf) might look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
    listen 443 ssl;
    server_name strava.example.com;

    ssl_certificate /etc/letsencrypt/live/strava.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/strava.example.com/privkey.pem;

    location / {
        proxy_pass http://app:80;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Reload Nginx after any changes:

1
docker exec $CONTAINER_NAMES-nginx nginx -s reload

Verifying OAuth Flow

The initial OAuth consent must be performed manually in

This post is licensed under CC BY 4.0 by the author.