HevyHeart synchronizes heart rate data from Strava activities to Hevy workouts, allowing you to track your cardiovascular performance during strength training sessions by combining Strava's heart rate monitoring with Hevy's workout tracking.
HevyHeart is available in two versions:
A modern Windows desktop application with an intuitive graphical interface.
Features:
- Visual selection of activities and workouts
- Real-time status updates and progress indicators
- Easy authentication with Strava and Hevy
- Synchronization summary with heart rate statistics
- No command-line knowledge required
A command-line interface for advanced users and automation.
Features:
- Interactive command-line workflow
- Detailed console output and logging
- Suitable for scripting and automation
- Cross-platform support (Windows, macOS, Linux)
→ Continue reading for Console documentation below
The application:
- Authenticates with both Strava and Hevy APIs
- Fetches your recent Strava activities with heart rate data
- Retrieves your Hevy workouts
- Synchronizes heart rate data from a selected Strava activity to a selected Hevy workout
- Creates a new Hevy workout with the heart rate data included
Before using HevyHeart, you need:
-
Strava API Credentials
- Client ID
- Client Secret
-
Hevy API Key
- API Key from Hevy
-
Hevy Account Credentials
- Username or Email
- Password
-
.NET 9 Runtime or SDK
- Required to run the application
- Go to Strava API Settings
- Log in to your Strava account
- Create a new application by clicking Create An App (or My API Application if you already have one)
- Fill in the required information:
- Application Name: HevyHeart (or any name you prefer)
- Category: Choose the most appropriate category (e.g., "Training & Planning")
- Club: Optional - leave blank if not applicable
- Website: Can be your personal website, GitHub repository, or just
http://localhost - Application Description: Brief description of what the app does
- Authorization Callback Domain: Enter
localhost(this is critical!)
- Agree to the API terms and create the application
- After creation, you'll see your application page with:
- Client ID: A numeric value - copy this
- Client Secret: An alphanumeric string - copy this (keep it secure!)
- You can click "show" next to Client Secret to reveal it
Important: Keep your Client Secret secure and never commit it to public repositories!
- Visit the Hevy Developer Portal or check their documentation
- Sign in to your Hevy account
- Navigate to API settings or developer settings
- Request or generate an API key
- Copy and save your API key securely
Note: If you're unable to find API settings, you may need to contact Hevy support to request API access.
Important Note for Third-Party Authentication Users:
If you currently sign in to Hevy using Google, Apple, or another third-party authentication provider, you can still use this application! Hevy allows you to set a password for your account even if you typically use social login. This password is specifically for API authentication and doesn't affect your ability to continue using social login for normal access.
- Open the Hevy mobile app or visit the Hevy website
- Go to Settings → Account → Security (or similar path)
- Look for an option to Set Password, Add Password, or Change Password
- Create a strong password for your Hevy account
- Save your changes
- Use this password in the HevyHeart application configuration
- You can continue to use Google/Apple sign-in for your normal Hevy app usage
If you cannot find the password setting option:
- Check if there's an "Account Security" or "Login Methods" section
- Try accessing Hevy from a web browser instead of the mobile app
- Contact Hevy support for assistance in setting up a password for API access
The application requires configuration through the appsettings.json file located in the HevyHeartConsole directory.
- Navigate to the
HevyHeartConsolefolder in your cloned repository - Open
appsettings.jsonin a text editor (Visual Studio, VS Code, Notepad++, etc.) - Update the configuration with your credentials:
{
"Strava": {
"ClientId": "YOUR_STRAVA_CLIENT_ID",
"ClientSecret": "YOUR_STRAVA_CLIENT_SECRET",
"RedirectUri": "http://localhost:8080/callback",
"Scope": "read,activity:read_all"
},
"Hevy": {
"ApiKey": "YOUR_HEVY_API_KEY",
"BaseUrl": "https://api.hevyapp.com",
"AuthToken": null,
"EmailOrUsername": "YOUR_HEVY_EMAIL_OR_USERNAME",
"Password": "YOUR_HEVY_PASSWORD"
},
"Server": {
"Port": 8080,
"Host": "localhost"
}
}| Field | Description | Required | Default Value |
|---|---|---|---|
ClientId |
Your Strava API Client ID (numeric) | ✅ Yes | - |
ClientSecret |
Your Strava API Client Secret (alphanumeric string) | ✅ Yes | - |
RedirectUri |
OAuth callback URL | ✅ Yes | http://localhost:8080/callback |
Scope |
API permissions requested | ✅ Yes | read,activity:read_all |
- Do not change
RedirectUriunless you also update your Strava API application settings - Do not modify
Scopeunless you understand OAuth permissions - The port in
RedirectUrimust match theServer.Portsetting
| Field | Description | Required | Default Value |
|---|---|---|---|
ApiKey |
Your Hevy API Key | ✅ Yes | - |
BaseUrl |
Hevy API endpoint | ✅ Yes | https://api.hevyapp.com |
AuthToken |
Optional V2 API token for advanced features | ❌ Optional | null |
EmailOrUsername |
Your Hevy account email or username | ✅ Yes* | - |
Password |
Your Hevy account password | ✅ Yes* | - |
*Required unless you have a pre-configured AuthToken. Most users should leave AuthToken as null and provide credentials.
Security Notes:
- Your credentials are stored locally and only transmitted to official Strava/Hevy APIs over HTTPS
- Never commit your
appsettings.jsonwith real credentials to a public repository - Consider using environment variables or secret management for production deployments
| Field | Description | Required | Default Value |
|---|---|---|---|
Port |
Local server port for OAuth callback | ✅ Yes | 8080 |
Host |
Local server host | ✅ Yes | localhost |
When to change these:
- If port 8080 is already in use by another application
- If you modify these, update
Strava.RedirectUriaccordingly
- Open the
HevyHeart.slnsolution file in Visual Studio - Ensure
HevyHeartConsoleis set as the startup project- Right-click on
HevyHeartConsolein Solution Explorer - Select Set as Startup Project
- Right-click on
- Press F5 to run with debugging, or Ctrl+F5 to run without debugging
- The console window will open and guide you through the process
- Open a terminal/command prompt/PowerShell window
- Navigate to the
HevyHeartConsoledirectory:cd HevyHeartConsole - Build the application (first time only):
dotnet build
- Run the application:
dotnet run
To create a standalone executable:
- Open a terminal in the solution root directory
- Run the publish command:
# For Windows 64-bit dotnet publish -c Release -r win-x64 --self-contained # For Windows 64-bit (single file) dotnet publish -c Release -r win-x64 --self-contained -p:PublishSingleFile=true # For macOS (Intel) dotnet publish -c Release -r osx-x64 --self-contained # For macOS (Apple Silicon) dotnet publish -c Release -r osx-arm64 --self-contained # For Linux dotnet publish -c Release -r linux-x64 --self-contained
- Navigate to the publish directory (e.g.,
HevyHeartConsole\bin\Release\net9.0\win-x64\publish\) - Copy the entire contents to your desired location
- Run the executable:
- Windows: Double-click
HevyHeartConsole.exeor run from command line - macOS/Linux:
./HevyHeartConsolefrom terminal
- Windows: Double-click
When you run HevyHeart, it guides you through an interactive workflow:
--- Step 0: Hevy Authentication ---
- The app authenticates with Hevy using your configured credentials
- If credentials are provided in
appsettings.json, authentication is automatic - If not configured, you'll be prompted to enter your email/username and password manually
- Your password input is hidden for security
Possible outcomes:
- ✅ Success: "Successfully authenticated with Hevy"
- ❌ Error: "Failed to authenticate with Hevy" - check credentials
--- Step 1: Strava Authentication ---
- A web browser window will automatically open to Strava's authorization page
- Log in to Strava (if not already logged in)
- Review the requested permissions
- Click Authorize to grant the application access
- The browser will redirect to a success page
- Return to the console - authentication will complete automatically
Manual steps (if browser doesn't open):
- Copy the URL displayed in the console
- Paste it into your web browser
- Complete the authorization
- The app will detect the callback automatically
--- Step 2: Fetching Strava Activities ---
- The app fetches your recent Strava activities that have heart rate data
- A numbered list is displayed showing:
- Activity name
- Date and time
- Activity type (Run, Ride, Workout, etc.)
- Duration
- Average heart rate (if available)
Example:
Found 10 activities with heart rate data:
1. Morning Run
Date: 2026-01-01 07:30
Type: Run
Duration: 00:45:23
Avg HR: 142 bpm
2. Evening Strength Training
Date: 2025-12-31 18:00
Type: Workout
Duration: 01:15:00
Avg HR: 128 bpm
Select an activity (1-10):
- Enter the number corresponding to your desired activity
- The activity will be selected and detailed data fetched
--- Step 3: Fetching Strava Activity Details ---
- The app retrieves:
- Complete activity details
- Heart rate stream data (second-by-second measurements)
- Data is automatically saved to local JSON files for debugging:
strava_activity_{id}_{timestamp}.jsonstrava_heartrate_{id}_{timestamp}.json
--- Step 4: Fetching Hevy Workouts ---
- The app fetches your recent Hevy workouts
- A numbered list is displayed showing:
- Workout title
- Date and time
- Duration
- Number of exercises
- Description (if available)
Example:
Found 15 Hevy workouts:
1. Upper Body Power
Date: 2026-01-01 18:00
Duration: 01:15:30
Exercises: 8
Description: Chest and back focus
2. Leg Day
Date: 2025-12-30 17:30
Duration: 01:30:00
Exercises: 6
Select a workout (1-15):
- Enter the number corresponding to your desired workout
- The workout data is fetched and saved to:
hevy_workout_fromlist_{id}_{timestamp}.json
--- Step 5: Synchronizing Heart Rate Data ---
- The app processes and synchronizes the heart rate data
- Shows a summary:
Synchronizing heart rate data from Strava activity 'Evening Strength Training' to Hevy workout 'Upper Body Power' Generated 4530 heart rate samples Total calories: 629 Heart rate - Min: 85 bpm, Avg: 128 bpm, Max: 167 bpm - Saves synchronized data to:
synchronized_biometrics_{workout_id}_{timestamp}.json
- Confirmation prompt:
Do you want to update the Hevy workout with this heart rate data? (y/N):- Enter
yoryesto proceed - Enter
norno(or just press Enter) to skip
- Enter
If you confirmed the update:
- The app creates a new Hevy workout with heart rate data
- Shows success message with important information
✅ Hevy workout updated successfully!
⚠️ IMPORTANT: A new workout with heart rate data has been created in Hevy.
Old workout ID: abc123
📱 Please check the Hevy app to verify the new workout appears correctly
before deleting the old one to avoid duplicates.
Have you verified the new workout in Hevy and want to delete the old one? (y/N):
Why a new workout is created:
- The Hevy API creates a new workout rather than updating the existing one
- This preserves your original data until you verify the sync was successful
- Prevents data loss if something goes wrong
Recommended workflow:
- Let the app create the new workout
- Open the Hevy mobile app on your phone
- Find and review the new workout (it will have the same name, date, and exercises)
- Verify the heart rate data appears correctly
- Return to the console and confirm deletion (
y) - The old workout will be automatically deleted
If you choose not to delete immediately:
- The old workout remains in your Hevy account
- You'll see duplicate workouts for that session
- You can manually delete the old workout later from the Hevy app
✅ Heart rate synchronization completed successfully!
Press any key to exit...
The application has successfully:
- ✅ Authenticated with Strava and Hevy
- ✅ Retrieved heart rate data from Strava
- ✅ Synchronized data to match your Hevy workout timeline
- ✅ Created a new Hevy workout with heart rate data
- ✅ (Optionally) Deleted the old workout to prevent duplicates
-
Duration Matching:
- Strava heart rate data is trimmed to exactly match the Hevy workout duration
- Start and end times are aligned precisely
-
Timestamp Alignment:
- Heart rate samples are created at 1-second intervals
- Each sample uses Unix timestamps (milliseconds)
- Timestamps align with the Hevy workout's start time
-
Data Interpolation:
- If Strava samples are sparse, data is interpolated to create smooth transitions
- If Strava samples are dense, data is aggregated to 1-second intervals
- Ensures consistent data quality regardless of recording device
-
Calorie Transfer:
- Total calories from Strava activity are included
- Hevy uses this for workout metrics
The synchronized biometrics follow Hevy's JSON structure:
{
"biometrics": {
"total_calories": 629.0,
"heart_rate_samples": [
{
"timestamp_ms": 1735682400000,
"bpm": 97
},
{
"timestamp_ms": 1735682401000,
"bpm": 98
}
// ... more samples at 1-second intervals
]
}
}The application saves several JSON files during execution for debugging and verification:
| File Pattern | Description | Purpose |
|---|---|---|
strava_activity_{id}_{timestamp}.json |
Complete Strava activity details | Debugging, backup |
strava_heartrate_{id}_{timestamp}.json |
Raw heart rate stream from Strava | Debugging, verification |
hevy_workout_fromlist_{id}_{timestamp}.json |
Hevy workout data | Debugging, verification |
synchronized_biometrics_{id}_{timestamp}.json |
Final synchronized heart rate data | Verification, manual import |
Note: These files are created in the same directory where you run the application.
Cleanup: You can safely delete these files after successful synchronization, or keep them for troubleshooting future issues.
- Open
appsettings.json - Replace
"YOUR_STRAVA_CLIENT_ID"with your actual Client ID - Ensure no quotation marks are missing
- Save the file
- Verify you've obtained an API key from Hevy
- Replace
"YOUR_HEVY_API_KEY"inappsettings.json - Ensure the key is correct (no extra spaces or characters)
- This is a warning, not an error
- Add your Hevy
EmailOrUsernameandPasswordtoappsettings.json - Alternatively, you can log in manually when prompted
Possible causes:
- Incorrect username/email or password
- API key is invalid or expired
- Network connectivity issues
Solutions:
- Double-check credentials in
appsettings.json - If using third-party login (Google/Apple), ensure you've created a password for API access
- Try logging in to Hevy's website/app to verify credentials work
- Contact Hevy support to verify API key is active
Solution:
- Copy the URL displayed in the console
- Manually paste it into your web browser
- Complete the authorization
- The app will automatically detect the callback
Possible causes:
- Callback redirect failed
- Port 8080 is blocked or in use
RedirectUridoesn't match Strava API settings
Solutions:
- Check your Strava API application settings
- Ensure "Authorization Callback Domain" is set to
localhost - Try changing the port in
appsettings.json(bothServer.PortandStrava.RedirectUri) - Temporarily disable firewall/antivirus
Possible causes:
- Your recent Strava activities don't have heart rate data
- Heart rate monitor wasn't connected during activities
- Authorization scope is insufficient
Solutions:
- Ensure your Strava activities were recorded with a heart rate monitor
- Check that activities have uploaded successfully to Strava
- Record a new activity with heart rate data
- Verify
Scopeinappsettings.jsonincludesactivity:read_all
Possible causes:
- No workouts in your Hevy account
- API key doesn't have permission to read workouts
- Date range is outside available workouts
Solutions:
- Log a workout in the Hevy app first
- Verify API key permissions
- Check network connectivity
Possible causes:
- Network issues
- Strava API rate limiting
- Activity doesn't have heart rate data
Solutions:
- Check internet connection
- Wait a few minutes and try again (rate limiting)
- Select a different activity
Possible causes:
- API key lacks write permissions
- Hevy V2 API endpoint is not available/accessible
- Network issues
Solutions:
- Check the generated
synchronized_biometrics_*.jsonfile - You can attempt to manually import this data to Hevy
- Verify your API key has write permissions
- Contact Hevy support about V2 API access
Not critical - This means:
- The new workout was created successfully
- The old workout wasn't deleted automatically
- You need to manually delete the old workout in the Hevy app
Solution:
- Open Hevy app
- Find the duplicate workout (same name, date, but no heart rate data)
- Swipe to delete or use the menu to remove it
Solution:
- Close other applications using port 8080
- Or change the port:
- Edit
appsettings.json - Change
Server.Portto a different port (e.g.,8081,8888,3000) - Update
Strava.RedirectUrito match:http://localhost:8081/callback
- Edit
- Restart the application
Solution:
- Temporarily disable firewall/antivirus
- If that works, add an exception for:
HevyHeartConsole.exe- Port 8080 (or your configured port)
- Re-enable firewall/antivirus
Solutions:
- Check the console for error messages
- Review the last operation that was running
- Ensure you have .NET 9 runtime installed
- Try running from command line to see full error output:
dotnet run --project HevyHeartConsole
Solutions:
- Review the generated JSON files
- Verify the Strava activity and Hevy workout are the correct ones
- Check that times/dates align properly
- Contact support with the JSON files for investigation
| Endpoint | Method | Purpose |
|---|---|---|
/oauth/authorize |
GET | Initial OAuth authorization |
/oauth/token |
POST | Exchange authorization code for access token |
/athlete/activities |
GET | Fetch user's activities |
/activities/{id} |
GET | Get detailed activity information |
/activities/{id}/streams |
GET | Get heart rate stream data |
Documentation: Strava API Documentation
| Endpoint | Method | Purpose |
|---|---|---|
/v1/workouts |
GET | Fetch user's workouts |
/v2/workouts/{id} |
GET | Get detailed workout information |
/v2/workouts |
POST | Create new workout with biometrics |
/v2/workouts/{id} |
DELETE | Delete a workout |
Note: Hevy V2 API endpoints are undocumented and may change. The application attempts to use these for biometrics updates.
- ✅ All configuration data is stored locally on your machine
- ✅ Credentials are only transmitted to official Strava and Hevy APIs over HTTPS
- ✅ No third-party services receive your data
- ✅ No telemetry or analytics are collected
- ✅ API tokens are stored in memory and cleared when the application closes
- 🔒 Never commit
appsettings.jsonwith real credentials to public repositories - 🔒 Use
.gitignoreto exclude sensitive files - 🔒 Rotate your API keys periodically
- 🔒 Only grant necessary OAuth permissions
- 🔒 Keep your Client Secret secure
- 📖 The source code is open and available for review
- 🔍 You can audit exactly what the application does
- 🤝 Community contributions are welcome
- Operating System: Windows 10/11, macOS 10.15+, or Linux
- .NET: .NET 9 Runtime or SDK
- Memory: Minimum 512MB RAM
- Disk Space: ~50MB for application + space for JSON data files
- Internet: Required for API communication
- Browser: Any modern web browser for Strava OAuth
⚠️ Hevy V2 API is undocumented and may change without notice⚠️ Creating a new workout instead of updating existing (by design)⚠️ No batch processing - processes one activity/workout at a time⚠️ Limited error recovery - most errors require restart⚠️ No GUI - console-only interface
A: Yes, keep it open until you see the "Press any key to exit..." message.
A: No, currently the application processes one activity-to-workout pair at a time. Run the application multiple times for multiple syncs.
A: Yes! As long as the heart rate data is recorded in your Strava activity, it doesn't matter what device captured it.
A: The heart rate data is automatically trimmed to match the exact duration of your Hevy workout.
A: You should select a Strava activity that covers the full duration of your workout for best results. The application won't extrapolate missing data.
A: Not through the application UI, but you can manually edit the synchronized_biometrics_*.json file before importing it to Hevy.
A: No, this is an independent third-party application using public APIs. It is not officially affiliated with or endorsed by Strava or Hevy.
A: The old workout is preserved initially. If you haven't deleted it yet, just delete the new workout and keep the old one. If you already deleted the old workout, you'll need to recreate it manually in Hevy.
A: The application itself is free and open-source. However, you need:
- Strava account (free or paid)
- Hevy account (free or paid)
- API access (check with Hevy for any associated costs)
- 🐛 Bug Reports: GitHub Issues
- 💡 Feature Requests: GitHub Issues
- 📖 Documentation: This README and code comments
- 💬 Questions: GitHub Discussions
Contributions are welcome! Here's how:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Test thoroughly
- Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Areas where contributions are especially welcome:
- Improved error handling and recovery
- GUI/Web interface
- Batch processing capabilities
- Additional API integrations
- Better documentation
- Unit tests
See CHANGELOG.md for version history and release notes.
[Specify your license here - e.g., MIT, GPL, Apache 2.0]
- Built with ❤️ using .NET 9
- Uses official Strava API v3
- Uses Hevy API (undocumented V2 endpoints)
- Created to help fitness enthusiasts track complete workout metrics
- Special thanks to the open-source community
Important Legal Notice:
This application is not officially affiliated with, endorsed by, or connected to Strava, Inc. or Hevy. All product names, logos, and brands are property of their respective owners.
- Use of this application is at your own risk
- The developers are not responsible for any data loss or corruption
- Always verify synchronized data before deleting original workouts
- Ensure compliance with Strava and Hevy's Terms of Service
- API access may be revoked by Strava or Hevy at any time
By using this application, you agree to:
- Strava's Terms of Service
- Hevy's Terms of Service
- The terms of this application's license
Made with 💪 for the fitness community
If you find this application useful, consider:
- ⭐ Starring the repository
- 🐛 Reporting bugs
- 💡 Suggesting features
- 🤝 Contributing code
- 📢 Sharing with friends