Documentation
Authentication
Strava uses OAuth 2.0 for authentication. This guide covers the complete authorization flow, permission scopes, and token management.
OAuth 2.0 Flow Overview
The OAuth flow allows users to grant your application access to their Strava data without sharing their password. Here's how it works:
- 1
Redirect to Strava
Your app redirects the user to Strava's authorization page
- 2
User Grants Permission
User logs in and approves the requested permissions (scopes)
- 3
Receive Authorization Code
Strava redirects back to your app with a temporary authorization code
- 4
Exchange for Tokens
Your server exchanges the code for access and refresh tokens
Step 1: Redirect to Authorization URL
Construct the authorization URL and redirect users to it:
https://www.strava.com/oauth/authorize?
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_CALLBACK_URL&
response_type=code&
scope=read,activity:read_all| Parameter | Description |
|---|---|
| client_id | Your application's Client ID |
| redirect_uri | URL to redirect to after authorization (must match your app settings) |
| response_type | Must be code |
| scope | Comma-separated list of requested permissions |
| state | (Optional) Random string to prevent CSRF attacks |
Permission Scopes
Scopes define what data your app can access. Request only the scopes you need:
| Scope | Access Granted |
|---|---|
| read | Public segments, routes, profile data, posts, events, club feeds, leaderboards |
| read_all | Private routes, segments, and events (in addition to read) |
| profile:read_all | All profile information, including email and private data |
| profile:write | Update athlete weight, FTP, and star/unstar segments |
| activity:read | Activities visible to "Everyone" or "Followers" |
| activity:read_all | All activities, including "Only You" and privacy zones |
| activity:write | Create manual activities, upload files, and edit activities |
Best Practice: Only request the minimum scopes your app needs. Users are more likely to authorize apps that request limited permissions.
Step 2: Exchange Authorization Code for Tokens
After the user authorizes your app, they're redirected to your callback URL with a code parameter. Exchange this code for tokens:
curl -X POST https://www.strava.com/oauth/token \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET \
-d code=AUTHORIZATION_CODE \
-d grant_type=authorization_codeResponse
{
"token_type": "Bearer",
"expires_at": 1704931200,
"expires_in": 21600,
"refresh_token": "REFRESH_TOKEN_HERE",
"access_token": "ACCESS_TOKEN_HERE",
"athlete": {
"id": 12345678,
"username": "athlete_username",
"firstname": "John",
"lastname": "Doe"
}
}| Field | Description |
|---|---|
| access_token | Token to use for API requests |
| refresh_token | Token to get new access tokens (save this securely!) |
| expires_at | Unix timestamp when the access token expires |
| expires_in | Seconds until expiration (6 hours = 21600) |
Refreshing Access Tokens
Access tokens expire after 6 hours. Use the refresh token to get a new access token:
curl -X POST https://www.strava.com/oauth/token \
-d client_id=YOUR_CLIENT_ID \
-d client_secret=YOUR_CLIENT_SECRET \
-d refresh_token=CURRENT_REFRESH_TOKEN \
-d grant_type=refresh_tokenImportant: Refresh Token Rotation
Each refresh request returns a new refresh token. You must save the new refresh token and use it for subsequent refresh requests. The old refresh token becomes invalid.
JavaScript Example
async function refreshAccessToken(refreshToken) {
const response = await fetch('https://www.strava.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
client_id: process.env.STRAVA_CLIENT_ID,
client_secret: process.env.STRAVA_CLIENT_SECRET,
refresh_token: refreshToken,
grant_type: 'refresh_token'
})
});
const data = await response.json();
// IMPORTANT: Save the new refresh token!
await saveTokens(data.access_token, data.refresh_token, data.expires_at);
return data.access_token;
}Deauthorization
Users can revoke access from their Strava settings, or your app can programmatically deauthorize:
curl -X POST https://www.strava.com/oauth/deauthorize \
-H "Authorization: Bearer ACCESS_TOKEN"This invalidates all tokens and removes your app from the athlete's authorized applications.