Fitness API

What a person does, not just what one workout was.

Sahha returns a 0 to 100 activity score, a readiness score that says whether someone is recovered enough to train, 88 exercise types normalized to one vocabulary, and archetypes describing how a person trains rather than how they performed. It reads from 86 connected sources on one schema.

Free for 30 days · No credit card

88
exercise types
2
scores: activity and readiness
14
scored factors
5
behavioral archetypes
FitFocusSuggesticPrescribeLife.AIPrismatic StackIntervengineNowFit
Why Sahha

What a workout feed leaves out.

  • readiness

    minimallowmediumhigh

    A score of 0.70 lands at medium. Exercise strain capacity is the factor holding it there.

    Readiness, not just activity

    Knowing someone ran 10k tells you what happened. Readiness tells you what to do next. Eight factors, including how much strain capacity is left in the legs and the lungs, resting heart rate and HRV, resolve into one call: train hard, train easy, or rest.

    • Garminsame day
    • Apple Watchsame day
    • iPhonesame day
    steps11,420

    One daily number, every source kept

    A run recorded by a watch, synced to Strava and separately counted by the phone in a pocket is the same effort three times. Sahha reconciles them into one value per metric per day, so training volume is never silently inflated. The raw sessions from every source stay available, so you can audit which reading fed the number rather than trusting a black box.

  • 88

    exercise types, one vocabulary across every connected source

    One name for 88 exercises

    Strava calls it a Ride, Garmin calls it cycling, Apple Health calls it HKWorkoutActivityTypeCycling. Sahha returns exercise_session_biking whatever recorded it, across 88 types from running to pickleball, so your code never branches on the source of a session.

API reference

Every endpoint, payload and field.

Exercise sessions and activity samples as they arrive, each typed against one of 88 exercise names and stamped with the device that recorded it. This is the one layer delivered by webhook only.

POST your webhook endpoint
[
  {
    "logType": "exercise",
    "dataType": "exercise_session_running",
    "externalId": "ext-733",
    "receivedAtUtc": "2026-08-11T07:12:00+00:00",
    "dataLogs": [
      {
        "id": "3aa61b74-9d02-4e55-8c31-0f5b2d7a9e14",
        "parentId": null,
        "value": 42,
        "unit": "minute",
        "source": "Strava",
        "recordingMethod": "RECORDING_METHOD_AUTOMATICALLY_RECORDED",
        "deviceType": "Garmin Forerunner 265",
        "startDateTime": "2026-08-11T06:20:00+12:00",
        "endDateTime": "2026-08-11T07:02:00+12:00",
        "additionalProperties": {}
      }
    ]
  }
]

The daily rollup, one typed record per metric per day, reconciled across every device a user has connected.

GET /api/v1/profile/biomarker/{externalId}?categories=activity
{
  "id": "f4a1c7d2-58e9-4b03-9a6f-2c81d0e37b45",
  "type": "steps",
  "category": "activity",
  "value": "11420",
  "valueType": "long",
  "unit": "count",
  "aggregation": "total",
  "periodicity": "daily",
  "startDateTime": "2026-08-11T00:00:00+12:00",
  "endDateTime": "2026-08-11T23:59:59+12:00",
  "createdAtUtc": "2026-08-12T06:10:00Z"
}

Activity biomarkers 10

FieldDescriptionUnit
steps Total steps taken count
active_hours Hours with significant activity hour
active_duration Total time active minute
activity_low_intensity_duration Time at low intensity minute
activity_medium_intensity_duration Time at medium intensity minute
activity_high_intensity_duration Time at high intensity minute
activity_sedentary_duration Time spent sedentary minute
active_energy_burned Energy burned through activity kcal
total_energy_burned Overall energy burned kcal
floors_climbed Flights of stairs climbed count

All ten are available without a wearable. VO2 max, resting heart rate and HRV sit in the vitals category and do need one.

Two scores share one shape. Activity says how much someone moved; readiness says whether they should train. Both return every contributing factor with its own sub-score.

GET /api/v1/profile/score/{externalId}?types=activity&types=readiness
{
  "type": "readiness",
  "score": 0.7,
  "state": "medium",
  "factors": [
    { "name": "sleep_duration", "value": 412, "goal": 480, "score": 0.8, "state": "medium" },
    { "name": "physical_recovery", "value": 62, "goal": 90, "score": 0.72, "state": "medium" },
    { "name": "mental_recovery", "value": 93, "goal": 120, "score": 0.78, "state": "medium" },
    { "name": "sleep_debt", "value": 2.75, "goal": 0, "score": 0.8, "state": "medium" },
    { "name": "walking_strain_capacity", "value": 0.68, "goal": 1, "score": 0.68, "state": "medium" },
    { "name": "exercise_strain_capacity", "value": 0.57, "goal": 1, "score": 0.57, "state": "low" },
    { "name": "resting_heart_rate", "value": 60, "goal": 58, "score": 0.95, "state": "high" },
    { "name": "heart_rate_variability", "value": 50, "goal": 55, "score": 0.8, "state": "medium" }
  ],
  "dataSources": ["activity", "exercise", "sleep", "vitals"],
  "scoreDateTime": "2026-08-11T00:00:00+12:00"
}

Score factors 14

FactorScoreWhat it measures
steps Activity Total steps taken through the day
active_hours Activity Hours with recorded activity or exercise
active_calories Activity Energy burned through movement
intense_activity_duration Activity Time spent at high intensity
extended_inactivity Activity Unbroken sedentary time
floors_climbed Activity Flights of stairs climbed
sleep_duration Readiness Total time spent asleep
physical_recovery Readiness Deep sleep phase duration
mental_recovery Readiness REM sleep phase duration
sleep_debt Readiness Accumulated sleep deficit
walking_strain_capacity Readiness Capacity for low-intensity activity
exercise_strain_capacity Readiness Capacity for high-intensity exercise
resting_heart_rate Readiness Heart rate at rest
heart_rate_variability Readiness Variation between heartbeats

Repeat the types parameter to request both at once. Sub-scores are research-backed curves, not a value divided by its goal.

How a person trains rather than how they performed, recomputed weekly and monthly as behavior changes.

GET /api/v1/profile/archetypes/{externalId}
{
  "id": "d51c8f37-6b24-4a90-bf13-9e0a25c7d846",
  "name": "primary_exercise_type",
  "value": "cardio_oriented",
  "dataType": "categorical",
  "periodicity": "monthly",
  "startDateTime": "2026-08-01T00:00:00+12:00",
  "endDateTime": "2026-08-31T00:00:00+12:00",
  "createdAtUtc": "2026-09-01T13:08:53.322886Z"
}

Activity archetypes 5

ArchetypeTypeValues
activity_level Ordinal sedentary · lightly_active · moderately_active · highly_active
exercise_frequency Ordinal rare_exerciser · occasional_exerciser · regular_exerciser · frequent_exerciser
primary_exercise Categorical Most frequent exercise, e.g. running or weightlifting
primary_exercise_type Categorical strength · cardio · mind_body · hybrid · sport · outdoor oriented
secondary_exercise Categorical Second most frequent exercise

Five of Sahha’s fourteen archetypes describe activity and exercise. Primary and secondary exercise are drawn from the same 88 names as the session logs.

Whether a number is moving, and whether it is high for this person or high for everyone like them.

GET /api/v1/profile/insight/comparison/{externalId}
{
  "name": "steps",
  "category": "biomarker",
  "value": 11420,
  "unit": "count",
  "data": [
    {
      "type": "demographic",
      "value": 7180,
      "percentile": 0.74,
      "percentageDifference": 0.59,
      "properties": { "sex": "male", "ageRange": "30-35" }
    }
  ],
  "startDateTime": "2026-07-13T00:00:00+12:00",
  "endDateTime": "2026-08-11T00:00:00+12:00"
}

Activity signals with insights 11

SignalTypeAvailable as
activity score Trend and comparison
steps factor, biomarker Trend and comparison
vo2_max biomarker Comparison
active_hours factor Trend
active_calories factor Trend
intense_activity_duration factor Trend
extended_inactivity factor Trend
floors_climbed factor Trend
activity_regularity factor Trend
walking_strain_capacity factor Trend
exercise_strain_capacity factor Trend

Every activity and readiness factor is tracked as its own trend, so you can see which one moved rather than only that the score did.

The layer that runs both ways. Reserved tags such as fatigue and generalized_body_ache arrive on their own when a user logs them in their phone’s health app; races, injuries and training blocks you post yourself.

POST /api/v1/profile/tag/{externalId}
{
  "type": "state",
  "category": "training",
  "name": "injury",
  "value": "calf_strain",
  "source": "acme.runapp",
  "startDateTime": "2026-08-12T18:00:00+12:00",
  "endDateTime": "2026-08-26T09:00:00+12:00",
  "additionalProperties": {
    "severity": "moderate"
  }
}

The ideas behind the factors, rather than the fields themselves. Each links to the guide that covers it in full.

Strain capacity
How much load someone has left rather than how much they have done. Walking and exercise capacity are tracked separately, because legs and lungs recover at different rates.
Readiness
A 0 to 100 read on whether a body is recovered enough to train, built from sleep, recovery, strain capacity, resting heart rate and HRV. Read the guide
Intense activity duration
Time spent at high intensity, scored separately from total active time. Twenty hard minutes and two easy hours are not the same day.
Extended inactivity
Unbroken sedentary time rather than total sedentary time. A long uninterrupted block reads differently from the same hours spread out.
Primary exercise type
Whether someone trains cardio, strength, sport, mind-body, hybrid or outdoor. Computed from what they actually do, not from what they said at signup. Read the guide
VO2 max
Maximum oxygen uptake during exercise, the standard proxy for cardiorespiratory fitness. Read from a wearable, and comparable against a matched cohort.
  • REST API

    Pull any of it on demand, per profile, whenever your app asks.

  • Webhooks

    Or have it pushed to your endpoint as it arrives, so you never have to poll for it.

  • Mobile SDK

    Read straight from the device on iOS and Android, with no round trip.

What you build

What activity and recovery data lets you ship.

Call the training day

Prescribe hard, easy or rest from the readiness score, and show the factor that decided it rather than asking someone how they feel.

Sahha Scores

Recommend the right session

A cardio-oriented frequent exerciser and a strength-oriented occasional one need different plans. Archetypes tell you which you have.

Sahha Archetypes

Accept every tracker at once

Take sessions from Strava, Garmin, Peloton or an Apple Watch without writing a mapper per provider or branching on source.

Browse integrations

Catch the overreach

Strain capacity falling while training volume holds is the shape of someone heading for injury or burnout. Watch it against their own baseline.

Sahha Insights

Skip the onboarding quiz

Know activity level, exercise frequency and preferred sport from behavior in the first week, instead of asking six questions nobody answers honestly.

Sahha Biomarkers

Run a challenge that is fair

Rank a cohort on percentile against matched peers rather than raw step counts, so a desk worker is not competing with a courier.

Fitness solutions
How it compares

Three ways to get activity data into your app.

Sahha Fitness API Workout-tracking APIs Build it yourself
Routes, pace and splits
Readiness and strain capacity Eight factors
One exercise vocabulary 88 types On you
Behavioral archetypes Five
Works with no wearable Activity only
Time to ship Days Weeks Months

The first row is the honest one: Sahha does not record workouts and has no GPS, route, pace or split data. If that is what you need, a workout-tracking API is the right tool and the two sit together happily. Workout-tracking APIs = services built around recording and reading individual sessions. Build it yourself = reading HealthKit and Health Connect directly.

What building it yourself actually costs

FAQ

Questions that come up before you integrate.

Does Sahha give me GPS routes, pace or splits?

No. There is no GPS, route, elevation, pace, split, lap or cadence data. Sahha reads that a 42 minute run happened, typed against a standard exercise name, and what it means for the person’s activity and readiness. If you need the shape of the route or a per-kilometre breakdown, use a workout-tracking API alongside Sahha rather than instead of it.

Is this an exercise or workout database?

No. Sahha does not supply exercise libraries, instructions, muscle groups or training plans. The 88 exercise types are a vocabulary for classifying sessions a user actually did, not a catalogue of movements to prescribe.

What is the difference between the activity and readiness scores?

Activity measures how much someone moved: steps, active hours, calories, intense minutes, inactivity and floors. Readiness measures whether they are recovered enough to train, from sleep duration and debt, physical and mental recovery, walking and exercise strain capacity, resting heart rate and HRV. Activity looks back at the day; readiness looks forward to the next one.

Does it need a wearable?

The activity score does not. All ten activity biomarkers come from Apple Health or Health Connect on the handset alone. Readiness is different: two of its eight factors are resting heart rate and heart rate variability, which need a wearable, so readiness is only as good as the vitals data a user supplies.

How are exercise types normalized across sources?

Every session is mapped to one of 88 standard names regardless of origin, so a ride logged in Strava, a cycling session from Garmin and an Apple Watch workout all arrive as exercise_session_biking. Your code never branches on the provider.

What happens when two devices record the same workout?

Sahha reconciles them before you see the data. Someone wearing a watch while their phone also counts steps produces overlapping records; you receive one value per metric, so totals stay honest and a session is not counted twice.

How far back does data go when a user connects?

Sahha backfills up to 30 days on connect, so archetypes and baselines have something to work from and personalization works in the first session rather than after weeks of waiting.

Is Sahha HIPAA and GDPR compliant?

Yes, and SOC 2. Health data is handled under all three, and the end-user consent screens are configurable to carry your brand rather than Sahha’s.

Add activity and recovery in days.

One integration for every tracker your users already own, typed to one vocabulary with the scoring already done.

Free for 30 days · No credit card

  • Activity and readiness scores, with every factor returned
  • 88 exercise types normalized across every source
  • Five archetypes describing how a person trains
  • HIPAA, GDPR and SOC 2, with your brand on the consent screen