GarminRunerz.Connect 1.2.0

dotnet add package GarminRunerz.Connect --version 1.2.0
                    
NuGet\Install-Package GarminRunerz.Connect -Version 1.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="GarminRunerz.Connect" Version="1.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="GarminRunerz.Connect" Version="1.2.0" />
                    
Directory.Packages.props
<PackageReference Include="GarminRunerz.Connect" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add GarminRunerz.Connect --version 1.2.0
                    
#r "nuget: GarminRunerz.Connect, 1.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package GarminRunerz.Connect@1.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=GarminRunerz.Connect&version=1.2.0
                    
Install as a Cake Addin
#tool nuget:?package=GarminRunerz.Connect&version=1.2.0
                    
Install as a Cake Tool

GarminRunerz.Connect

Uploads workouts built with GarminRunerz.Workout.Models / GarminRunerz.Workout.Services to a Garmin Connect account.

Authentication (Garmin SSO, MFA, token caching) is handled by the unofficial Unofficial.Garmin.Connect client; workout creation posts your serialized workout JSON directly to Garmin Connect's workout-service API — the same API the Garmin Connect web app uses.

⚠️ This relies on Garmin Connect's private web API. It is intended for personal automation with your own account. It may break without notice if Garmin changes their API, and heavy or multi-account use may violate Garmin's terms of service.

Installation

dotnet add package GarminRunerz.Connect

Usage

Registration

services.AddGarminConnectUploader(options =>
{
    options.Email = Environment.GetEnvironmentVariable("GARMIN_EMAIL")!;
    options.Password = Environment.GetEnvironmentVariable("GARMIN_PASSWORD")!;
    options.TokenCacheFilePath = "garmin-tokens.json"; // optional: persist tokens between runs
});

Uploading a workout

var uploader = provider.GetRequiredService<IWorkoutUploadService>();

// Build the workout with GarminRunerz.Workout.Services, then:
var created = await uploader.CreateWorkoutAsync(workout);
Console.WriteLine($"Created workout {created.WorkoutId}");

// Optionally schedule it on the Garmin Connect calendar:
await uploader.ScheduleWorkoutAsync(created.WorkoutId!.Value, new DateOnly(2026, 8, 20));

Once created (and synced), the workout appears in Garmin Connect and on your watch.

MFA accounts

If your account uses multi-factor authentication, provide an IMfaCodeProvider:

options.MfaCodeProvider = new StaticMfaCode("123456");
// or implement IMfaCodeProvider to prompt/fetch the code dynamically

With TokenCacheFilePath set, the MFA prompt only happens on the first run — subsequent runs reuse the cached OAuth tokens.

Token-based upload (no password)

If you already hold a Garmin OAuth2 access token — for example one minted from a stored long-lived OAuth1 token via GarminRunerz.Connect.Auth — you can upload without a password or a GarminConnectContext. Requests go straight to connectapi.garmin.com carrying only Authorization: Bearer <token> and the di-backend header.

// token is a GarminOAuth2Token obtained from GarminRunerz.Connect.Auth
// (e.g. authClient.RefreshOAuth2Async(storedOAuth1Token)).
services.AddGarminConnectTokenUploader(token);

// then, exactly as with the password path:
var uploader = provider.GetRequiredService<IWorkoutUploadService>();
var created = await uploader.CreateWorkoutAsync(workout);
await uploader.ScheduleWorkoutAsync(created.WorkoutId!.Value, new DateOnly(2026, 8, 20));

For long-running hosts where the ~1-hour token expires, register your own IGarminAccessTokenProvider (which refreshes from the stored OAuth1 token) and call AddGarminConnectTokenUploader() with no arguments — the provider is resolved from the container. Both the token path and the password path implement the same IWorkoutUploadService.

Multi-user hosting: IGarminConnectionManager

For a hosted app serving several users, IGarminConnectionManager is the one-call layer that ties everything together per user key. Given a user key it loads that user's stored OAuth1 token, mints (and caches until near expiry) an OAuth2 access token, uploads through the token path, and — if Garmin rejects the token with a 401 — refreshes once and retries.

services.AddGarminConnectionManager();
// Register your own encrypted IOAuth1TokenStore before this call for durable storage;
// the default is in-memory.
var manager = provider.GetRequiredService<IGarminConnectionManager>();

try
{
    // "userKey" is your app's own id for the user — the same key their OAuth1 token is stored under.
    var created = await manager.CreateWorkoutAsync(userKey, workout);
    await manager.ScheduleWorkoutAsync(userKey, created.WorkoutId!.Value, new DateOnly(2026, 8, 20));
}
catch (GarminReconnectRequiredException)
{
    // The user has never connected, or their stored token has expired/been revoked —
    // prompt them to log in again. The dead token is purged from the store automatically.
}

Connecting a user (once) is a GarminRunerz.Connect.Auth concern: log in, then persist the returned GarminOAuth1Token under the user key via your IOAuth1TokenStore. After that the manager never needs a password again.

API

Method Description
CreateWorkoutAsync(workout) Creates the workout; returns it with the Garmin-assigned WorkoutId.
UpdateWorkoutAsync(workout) Updates an existing workout (WorkoutId required).
ScheduleWorkoutAsync(id, date) Schedules the workout on the Garmin Connect calendar.
DeleteWorkoutAsync(id) Deletes the workout.

The registration also exposes the full IGarminConnectClient (activities, devices, SendWorkoutToDevices, …) for anything beyond workout upload.

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.2.0 151 8/19/2026
1.0.0 98 8/19/2026