Skip to content

Activities

Data Model

For more information about data models related to activity data, please refer to the Data Model documentation.

Activity metadata

Activity metadata contains data such as an id, sport type, start and end times, etc. of activities.

Retrieving metadata for activities is done by using the get_activities method.

import sweatstack as ss


activities = ss.get_activities()

By default, this will return a list of the last 100 activities. Check the reference for more options for filtering the returned activities.

Alternatively, to receive the activities as a pandas DataFrame, you can use the as_dataframe keyword argument.

activities = ss.get_activities(as_dataframe=True)

The start and end columns of the returned DataFrame are timezone aware. Because these columns can contain datetime objects with different time zones and because pandas datatime64[ns] columns only support one timezone, the dtype of these columns is object. For your convenience, start_local and end_local columns are also included in the returned DataFrame, containing the localized start and end times.

A common usecase for the returned pandas DataFrame is to apply some rolling operation on the activity start times, for example a 7-day rolling sum of the activity distances. This is a typical usecase for the start_local column, which contains the localized start times.

activities.rolling("7d", on="start_local")["summary.distance"].sum()

Retrieve activity metadata by making a GET request to the activities endpoint:

curl -X GET "https://app.sweatstack.no/api/v1/activities/" \
    -H "Authorization: Bearer {your_access_token}"

This returns the last 50 activities by default. You can customize the request with query parameters:

curl -X GET "https://app.sweatstack.no/api/v1/activities/?limit=100&offset=0&start=2024-01-01&end=2024-12-31&sports=running,cycling" \
    -H "Authorization: Bearer {your_access_token}"

Available query parameters:

  • start - Filter activities after this date (YYYY-MM-DD format)
  • end - Filter activities before this date (YYYY-MM-DD format)
  • limit - Number of results to return (default: 50)
  • offset - Pagination offset (default: 0)
  • sports - Comma-separated list of sport types (e.g., running,cycling)
  • tags - Filter by tags

Activity data

Activity data is the timeseries data of an activity.

To get the activity data for an activity, you can use the get_activity_data method:

data = ss.get_activity_data(activity_id)

The returned dataframe is a pandas DataFrame with the activity data.

Retrieve timeseries data for a specific activity by making a GET request:

curl -X GET "https://app.sweatstack.no/api/v1/activities/{activity_id}/data" \
    -H "Authorization: Bearer {your_access_token}"

You can customize which metrics are returned and enable adaptive sampling:

curl -X GET "https://app.sweatstack.no/api/v1/activities/{activity_id}/data?metrics=duration,power,speed,heart_rate&adaptive_sampling_on=power" \
    -H "Authorization: Bearer {your_access_token}"

Available query parameters:

  • metrics - Comma-separated list of metrics to include (default: duration,power,speed,heart_rate)
  • adaptive_sampling_on - Enable adaptive sampling on a specific metric (power or speed)

Longitudinal data

Longitudinal data is activity data from multiple activities.

To get longitudinal data, you can use the get_longitudinal_data method:

data = ss.get_longitudinal_data(
    sports=["running"],
    start=start_date,
)

The returned dataframe is a pandas DataFrame with a timezone-aware datetime index.

Retrieve longitudinal data from multiple activities by making a GET request:

curl -X GET "https://app.sweatstack.no/api/v1/activities/longitudinal-data?sports=running&start=2024-01-01" \
    -H "Authorization: Bearer {your_access_token}"

You can customize the request with additional parameters:

curl -X GET "https://app.sweatstack.no/api/v1/activities/longitudinal-data?sports=running,cycling&start=2024-01-01&end=2024-12-31&metrics=power,heart_rate&adaptive_sampling_on=power" \
    -H "Authorization: Bearer {your_access_token}"

Available query parameters:

  • sports - Comma-separated list of sport types (required)
  • start - Start date for filtering (YYYY-MM-DD format, optional)
  • end - End date for filtering (YYYY-MM-DD format, optional)
  • metrics - Comma-separated list of metrics to include (optional)
  • adaptive_sampling_on - Enable adaptive sampling on a specific metric (power or speed, optional)

Uploading files

SweatStack allows uploading activity files. At the moment only .fit files are supported (contact me if you need other formats).

Required scopes

Uploading files requires an API key with scope data:write, ensure you request this scope during user authorization. More info here.

Warning

This is not yet implemented in the Python client.

Upload activity files by making a POST request with multipart/form-data:

curl -X POST "https://app.sweatstack.no/api/v1/activities/upload" \
    -H "Authorization: Bearer {your_access_token}" \
    -F "[email protected]" \
    -F "[email protected]"

Details:

  • Method: POST
  • Content-Type: multipart/form-data
  • File limitation: Up to 10 files can be uploaded simultaneously
  • Supported format: Currently only .fit files are supported

Responses:

  • Success: 202 Accepted
  • Validation error: 422 Unprocessable Entity

After the request is accepted, the activities will be processed in the background and the processed data will be available in the Activity data endpoint. Processing of uploaded files typically takes a few seconds.

Backfill status

When a user first connects their account, SweatStack automatically backfills their historical activities. The backfill status endpoint provides real-time progress updates showing which activities have been loaded. This can for example be useful if you application needs at least 4 weeks of historical activity data to function properly.

Monitor backfill progress using the SweatStack client:

from datetime import datetime, timedelta

import sweatstack as ss

four_weeks_ago = datetime.now() - timedelta(weeks=4)

# Loop over the status, new update every ~3s
for status in ss.watch_backfill_status():
    if status.backfill_loaded_until <= four_weeks_ago:
        print(f"Backfilled loaded at least 4 weeks!")
        break

# Or just check once
status = ss.get_backfill_status()
print(f"Backfilled to: {status.backfill_loaded_until}")

The endpoint returns a streaming newline-delimited JSON (NDJSON) response with updates approximately every few seconds, automatically closing the connection after 60 seconds. The backfill_loaded_until timestamp moves backward in time as activities are backfilled from newest to oldest. An error field is returned if the backfill status request fails.

Monitor backfill progress using cURL with streaming:

curl -N -X GET "https://app.sweatstack.no/api/v1/activities/backfill-status" \
    -H "Authorization: Bearer {your_access_token}"

The -N flag disables buffering to see updates in real-time.

Example response (NDJSON stream):

{"backfill_loaded_until": "2024-03-01T10:00:00Z"}
{"backfill_loaded_until": "2024-02-15T08:30:00Z"}
{"backfill_loaded_until": "2024-01-01T12:00:00Z"}