Skip to content

Accumulated work duration

Beta

Accumulated work duration is in beta and is subject to breaking changes. If you plan to use it in production, email info@sweatstack.no before you integrate, so we can tell you about changes in advance and help you migrate.

Accumulated work duration (AWD) is the total time an athlete spent at or above each intensity within a single activity. For any intensity, it answers one question: how long, in total, were you at least this hard?

Why it's useful

AWD is computed at every intensity. Unlike time in zone, it doesn't round efforts into a handful of buckets or lose detail at zone boundaries.

Two use cases matter most:

  • Compliance. Did the athlete complete the session as prescribed? If the plan was 20 minutes at or above 200 W, AWD at 200 W tells you directly.
  • Capacity and safe progression. AWD is a record of what the athlete has already demonstrated. If their best AWD at 200 W is 20 minutes, prescribing 40 minutes at 200 W asks for double a proven capacity. AWD gives you the evidence to progress load in defensible steps instead of guessing.

Get the data

AWD is available per activity and across a date range.

Per activity

GET /api/v1/activities/{activity_id}/accumulated-work-duration returns the AWD curve for one activity.

from sweatstack import Client

client = Client()

awd = client.activities.awd(activity_id, metric="power")

activities.awd returns a DataFrame.

curl -X GET "https://app.sweatstack.no/api/v1/activities/{activity_id}/accumulated-work-duration?metric=power" \
    -H "Authorization: Bearer {your_access_token}"

Query parameters:

  • metric (optional): power or speed. Defaults to power for cycling and speed for every other sport.

Requires the activities:read scope.

The response is Parquet with one row per intensity, from the highest value in the activity down to 0, in steps of 1 W for power and 0.05 km/h (about 0.014 m/s) for speed. Two columns: the metric (power in W or speed in m/s, a 32-bit float as in mean-max) and duration, the total time at or above that intensity, in seconds. duration never decreases as the intensity falls. No index. An activity that didn't record the metric has no rows.

Across a date range

GET /api/v1/activities/longitudinal-accumulated-work-duration returns, for each intensity, the AWD the athlete can sustain for easy, medium and hard sessions, and the highest AWD they reached in one day.

from datetime import date

from sweatstack import Client

client = Client()

awd = client.activities.longitudinal.awd(
    sport=["cycling"],
    metric="power",
    start=date(2026, 1, 1),
    end=date(2026, 3, 31),
)

activities.longitudinal.awd returns a DataFrame.

curl -X GET "https://app.sweatstack.no/api/v1/activities/longitudinal-accumulated-work-duration?sport=cycling&metric=power&start=2026-01-01&end=2026-03-31" \
    -H "Authorization: Bearer {your_access_token}"

Query parameters:

  • sport (optional): a sport code. Repeat the parameter for more than one sport.
  • metric (required): power or speed.
  • start (optional): first day of the range, YYYY-MM-DD. Included.
  • end (optional, default today): last day of the range, YYYY-MM-DD. Included.
  • format (optional, default parquet): parquet or json.

Requires the activities:read scope.

The response is one row per intensity, from the highest value in the range down to 0, in the same steps as the per-activity curve. Five columns: the metric (power or speed), as in the per-activity curve, and the durations max (the highest AWD in a single day), hard, medium and easy (the AWD the athlete sustains in sessions of that intensity), in seconds. A duration of 0 means no session reached that intensity. Activities that didn't record the metric don't count. No index. With format=json, the same rows as a list of objects with the same keys, for example {"power": 250.0, "max": 1260, "hard": 840, "medium": 588, "easy": 336}, durations as whole seconds. See the API reference for the full schema.