Skip to content

Add NIP-101e: Workout Events#1816

Open
DocNR wants to merge 1 commit into
nostr-protocol:masterfrom
DocNR:nip-101e-workout-events
Open

Add NIP-101e: Workout Events#1816
DocNR wants to merge 1 commit into
nostr-protocol:masterfrom
DocNR:nip-101e-workout-events

Conversation

@DocNR

@DocNR DocNR commented Mar 2, 2025

Copy link
Copy Markdown
Contributor

NIP-101e: Workout Events

This NIP proposes a standardized way to represent fitness and workout data in Nostr, including:

  • Exercise Templates (kind: 33401) for storing reusable exercise definitions
  • Workout Templates (kind: 33402) for defining workout plans
  • Workout Records (kind: 1301) for recording completed workouts

The format provides structured data for fitness tracking while following Nostr conventions for data representation.

Rationale

Many fitness applications use proprietary formats, locking user data into specific platforms. This NIP enables decentralized fitness tracking, allowing users to control their workout data and history while facilitating social sharing and integration between fitness applications.

@TheWildHustle

TheWildHustle commented Mar 19, 2025

Copy link
Copy Markdown

I'm working on a run tracking app on Nostr and love the NIP-101e proposal. I'd like to suggest some additional running-specific extensions that would enhance the proposal's utility for cardio activities while maintaining compatibility with the established framework.

Suggested Additions to NIP-101e for Running Activities

Running Exercise Template

For running activities, I suggest a standardized exercise template format:

{
  "kind": 33401,
  "content": "Easy pace run on flat terrain. Focus on maintaining consistent effort.",
  "tags": [
    ["d", "<UUID>"],
    ["title", "Easy Run"],
    ["format", "distance", "duration", "pace", "gps_data", "elevation_gain"],
    ["format_units", "km", "seconds", "min/km", "polyline", "m"],
    ["equipment", "cardio"],
    ["difficulty", "beginner"],
    ["t", "running"],
    ["t", "cardio"]
  ]
}

Running-Specific Workout Record

Run tracking records could then be represented as:

{
  "kind": 1301,
  "content": "Morning run felt great. Perfect weather conditions.",
  "tags": [
    ["d", "<UUID>"],
    ["title", "Morning 5K"],
    ["type", "cardio"],
    ["start", "1706454000"],
    ["end", "1706455800"],
    ["exercise", "33401:<pubkey>:<UUID-running>", "<relay-url>", "5", "1800", "4:52", "encoded_polyline_string", "125"],
    ["cadence_avg", "172", "spm"],
    ["heart_rate_avg", "142", "bpm"],
    ["weather_temp", "18", "c"],
    ["weather_humidity", "65", "%"],
    ["weather_condition", "partly_cloudy"],
    ["completed", "true"],
    ["t", "running"]
  ]
}

Split Data

For analyzing portions of runs:

{
  "kind": 1301,
  "tags": [
    ["split", "1", "1000", "m", "3:45", "155", "bpm"],
    ["split", "2", "1000", "m", "3:52", "158", "bpm"]
  ]
}

These additions would enhance the practical utility of NIP-101e for run tracking applications while maintaining compatibility with the core structure of the original proposal. They extend the "Additional parameters" flexibility mentioned in the NIP while providing standardized tags for the running-specific metrics that matter most to runners.

@Sebastix

Copy link
Copy Markdown
Contributor

We need this for other GPX based activities too, like cycling

See #1423

@DocNR

DocNR commented Mar 19, 2025

Copy link
Copy Markdown
Contributor Author

@erskingardner had some ideas for storing gpx data on blossom servers that we can then reference in the workout record event

@NielLiesmons

Copy link
Copy Markdown

@Sebastix How do Activity events and Work outs fit together then? Can we just implement work-outs in Zpachat / Cahchi and get Activities for free?

@Sebastix

Sebastix commented Apr 16, 2025

Copy link
Copy Markdown
Contributor

@NielLiesmons Good question, let me take some time to think more deeply on this. To me workouts are an activity event type so if you implement activity events correctly you get all types for free (in theory).
See https://github.com/nostr-protocol/nips/pull/1423/files#diff-c22f4e5a3b123915c89f75b40c3012ac87c47a6534e9303ff1efc834de0ef114R92

Here are some activity types from the more famous platforms.

Strava (https://support.strava.com/hc/en-us/articles/216919407-Supported-Sport-Types-on-Strava)
Foot Sports
Run
Trail Run
Walk
Hike
Virtual Run

Cycle Sports
Ride
Mountain Bike Ride
Gravel Ride
E-Bike Ride
E-Mountain Bike Ride
Velomobile
Virtual Ride

Water Sports
Canoe
Kayak
Kitesurf
Rowing
Stand Up Paddling
Surf
Swim
Windsurf
Sail

Winter Sports
Ice Skate
Alpine Ski
Backcountry Ski
Nordic Ski
Snowboard
Snowshoe

Other Sports:
Handcycle
Inline Skate
Rock Climb
Roller Ski
Golf
Skateboard
Football (Soccer)
Wheelchair
Badminton
Tennis
Pickleball
Crossfit
Elliptical
Stair Stepper
Weight Training
Yoga
Workout
HIIT
Pilates
Table Tennis
Squash
Racquetball
Virtual Rowing

Whoop (https://support.whoop.com/s/article/List-of-WHOOP-Activities?language=en_US)
Assault Bike
Australian Football
Babywearing
Badminton
Barre
barr3
Barry's
Baseball
Basketball
Bowling
Box Fitness
Boxing
Caddying
Canoeing
Cheerleading
Circus Arts
Cleaning
Climber
Coaching
Commuting
Cooking
Cricket
Cross Country Skiing
Cycling
Dance
Dedicated Parenting
Disc Golf
Diving
Dog Walking
Driving
Duathlon
Elliptical
F45
Fencing
Field Hockey
Fishing
Foam Rolling
Football
Functional Fitness
Gaelic Football
Gaming
Golf
Gymnastics
Handball
High-Stress Work
HIIT
Hiking/Rucking
Horseback Riding
Hot Yoga
Hurling/Camogie
Ice Hockey
Ice Skating
Inline Skating
Jiu Jitsu
Jumping Rope
Kayaking
Kickboxing
Kite Surfing
Kiteboarding
Lacrosse
Manual Labor
Martial Arts
Motocross
Motor Racing
Mountain Biking
Musical Performance
Netball
Obstacle Course Racing
Operations - Flying
Operations - Medical
Operations - Tactical
Operations - Water
Other
Paddle Tennis
Paddleboarding
Padel
Paintball
Parkour
Pickleball
Pilates
Ping Pong
Powerlifting
Public Speaking
Race Walking
Refereeing
Rock Climbing
Rowing
Rucking (new icon for rucking)
Rugby
Running
Sailing
Scootering
Skateboarding
Skiing
Snowboarding
Soccer
Softball
Spikeball®
Spin
Squash
Stage Performance
Stairmaster
Strength Trainer
Stroller Walking
Stroller Jogging
Surfing
Swimming
Table Tennis
Tennis
Thrill Ride
Toddler wearing
Track & Field
Triathlon
Ultimate
Volleyball
Walking
Watching Sports
Water Skiing
Water Polo
Weightlifting
Wheelchair Pushing
WHOOP Labs
Wrestling
Yard Work/Gardening
Yoga

Komoot (https://support.komoot.com/hc/en-us/articles/360024733031-Sport-types-on-komoot)
Alpine skiing
Climbing
Cross-country skiing
Cycling
Downhill mountain biking
Enduro mountain biking
Gravel riding
Hiking
Mountaineering
Mountain biking
Nordic walking
Other sport
Road cycling
Running
Skating
Ski touring
Sledding
Snowboarding
Snowshoeing
Unicycling

@NielLiesmons

Copy link
Copy Markdown

Ah ok, so in the opposite sense. Gotcha!

@TheWildHustle

Copy link
Copy Markdown

I want to use NIP101e for building fitness communities and events. Would it be alright to add new kinds to the NIP for challenges, teams, and events. I'd want to include optional tags in kind 1301 to help filter.

Enhanced NIP-101e: Building Fitness Communities on Nostr

Core Architecture

Three-Tier System:

  1. Kind 33401 - Exercise Templates (reusable workout definitions)
  2. Kind 33402 - Workout Plans (structured training programs)
  3. Kind 1301 - Workout Records (actual completed activities)

New Event Kinds for Community Features

Kind 33403 - Fitness Challenge

{
  "kind": 33403,
  "content": "Complete 100 miles of running in 30 days. All paces welcome!",
  "tags": [
    ["d", "<challenge-uuid>"],
    ["name", "100 Mile Challenge"],
    ["start", "1706454000"],
    ["end", "1709046000"],
    ["goal_type", "distance_total"],
    ["goal_value", "100", "miles"],
    ["activity_types", "running", "walking"],
    ["rules", "GPS verification required"],
    ["public", "true"],
    ["t", "challenge"],
    ["t", "running"]
  ]
}

Kind 33404 - Fitness Team

{
  "kind": 33404,
  "content": "A community of runners training together for marathons",
  "tags": [
    ["d", "<team-uuid>"],
    ["name", "Marathon Training Squad"],
    ["type", "running_club"],
    ["location", "New York, NY"],
    ["captain", "<pubkey>"],
    ["member", "<pubkey1>"],
    ["member", "<pubkey2>"],
    ["public", "true"],
    ["t", "team"],
    ["t", "running"]
  ]
}

Kind 33405 - Fitness Event

{
  "kind": 33405,
  "content": "Annual 5K charity run through Central Park",
  "tags": [
    ["d", "<event-uuid>"],
    ["name", "Central Park 5K"],
    ["date", "1709046000"],
    ["location", "Central Park, NYC"],
    ["distance", "5", "km"],
    ["registration_deadline", "1708700000"],
    ["max_participants", "500"],
    ["t", "event"],
    ["t", "race"]
  ]
}

Linking System

Enhanced Kind 1301 with Community Links:

{
  "kind": 1301,
  "content": "Great team run today! Feeling strong for the upcoming race.",
  "tags": [
    ["d", "<workout-uuid>"],
    ["title", "Team Training Run"],
    ["exercise", "33401:<pubkey>:<exercise-uuid>", "<relay>", "10", "3600", "6:00"],
    
    // Community connections
    ["challenge", "33403:<pubkey>:<challenge-uuid>", "<relay>"],
    ["team", "33404:<pubkey>:<team-uuid>", "<relay>"],
    ["event", "33405:<pubkey>:<event-uuid>", "<relay>"],
    
    // Data quality
    ["accuracy", "exact", "gps_watch"],
    ["client", "NostrFit", "v1.0.0"],
    
    // Verification
    ["gps_polyline", "<encoded_data>"],
    ["device", "Garmin Forerunner 945"]
  ]
}

Smart Aggregation Tags

Progress Tracking:

["challenge_progress", "<challenge-id>", "45.5", "miles", "45.5%"]
["team_contribution", "<team-id>", "10", "km", "weekly"]

Discovery and Filtering

REQ Filter Examples:

// Find all workouts for a specific team
{
  "kinds": [1301],
  "tags": {
    "team": ["33404:<pubkey>:<team-uuid>"]
  }
}

// Find all active challenges
{
  "kinds": [33403],
  "tags": {
    "end": [">", "<current_timestamp>"]
  }
}

// Find workouts contributing to a challenge
{
  "kinds": [1301],
  "tags": {
    "challenge": ["33403:<pubkey>:<challenge-uuid>"]
  }
}

Implementation Benefits

  1. Decentralized Fitness Communities: No central platform needed
  2. Interoperable: Any client can display/interact with the data
  3. Verifiable: GPS data and device info prevent cheating
  4. Flexible: Supports various activity types and goals
  5. Social: Enables team dynamics and friendly competition

Privacy Considerations

  • Use ["private", "true"] tags for invite-only teams/challenges
  • Encrypted content for sensitive location data
  • Optional GPS data sharing
  • Granular privacy controls per workout

This structure creates a complete ecosystem for fitness communities while maintaining the decentralized nature of Nostr and building on the solid foundation of NIP-101e.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants