Skip to content

Profile

profile


GET /api/v1/profile/tags/

List Profile Tags

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
token cookie string No

Responses

Schema of the response body

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/sports/

List Profile Sports

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
only_root query boolean False No
refreshed-token header No
token cookie string No

Responses

Schema of the response body

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/template-week

Get Profile Template Week

Description

Get a template week for the user based on their training history. The template week is a list of days, each with a name, a list of sports, and a typical and average training duration for that day.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
token cookie string No

Responses

{
    "monday": {
        "sports": [
            "string"
        ],
        "avg_training_duration": "string",
        "typical_training_duration": "string"
    },
    "tuesday": null,
    "wednesday": null,
    "thursday": null,
    "friday": null,
    "saturday": null,
    "sunday": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "monday": {
            "$ref": "#/components/schemas/TemplateDay"
        },
        "tuesday": {
            "$ref": "#/components/schemas/TemplateDay"
        },
        "wednesday": {
            "$ref": "#/components/schemas/TemplateDay"
        },
        "thursday": {
            "$ref": "#/components/schemas/TemplateDay"
        },
        "friday": {
            "$ref": "#/components/schemas/TemplateDay"
        },
        "saturday": {
            "$ref": "#/components/schemas/TemplateDay"
        },
        "sunday": {
            "$ref": "#/components/schemas/TemplateDay"
        }
    },
    "type": "object",
    "required": [
        "monday",
        "tuesday",
        "wednesday",
        "thursday",
        "friday",
        "saturday",
        "sunday"
    ],
    "title": "TemplateWeekResponse"
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/status

Get Account Status (beta)

Description

Beta. This endpoint 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.

Why this user has little or no data, and what to do about it.

issue is null when nothing is wrong with the data your app uses; otherwise show issue.message, and when issue.destination is set, a button that creates a Portal link with POST /portal/sessions. There is only ever one issue: we decide which matters most for your app right now, so you never sort, filter, or choose. An issue is always temporary, and only about the capabilities your app declared it uses (its settings, or capabilities when creating it). capabilities is a keyed map of facts about the user's connected sources, the same for every app, for apps with a specific requirement (past activities, dailies, pushing workouts).

Branch on issue.status (action_required or syncing, never a third) and display message. Do not branch on code: which code appears first is ours to change as we improve the ordering.

Accepts data:read or profile: an app staring at an empty activity list is exactly the one that needs this, and it does not necessarily hold profile.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
token cookie string No

Responses

{
    "issue": null,
    "capabilities": {}
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "issue": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/StatusIssueResponse"
                },
                {
                    "type": "null"
                }
            ]
        },
        "capabilities": {
            "additionalProperties": {
                "$ref": "#/components/schemas/CapabilityStatus"
            },
            "propertyNames": {
                "$ref": "#/components/schemas/Capability"
            },
            "type": "object",
            "title": "Capabilities"
        }
    },
    "type": "object",
    "required": [
        "capabilities"
    ],
    "title": "AccountStatusResponse",
    "description": "Why this user has little or no data, and what the app should do about it.\n\nShaped so the default integration never iterates over anything: `issue` is singular and\nnullable, and `capabilities` is a keyed map read by direct lookup, not a list to sort. Two\nfields, and nothing provider-specific: the Portal is the surface for the full picture\n(plan 052)."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/intensity-duration-model/power

Get Intensity Duration Model Power (beta)

Description

Beta. This endpoint 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.

The athlete's intensity-duration curve for power, modeled from their training data.

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

SweatStack fits its model to the athlete's recent training up to date (currently the 90 days ending on date) and returns the curve as {duration, power} points (seconds; whole W) at the durations you pass or at the 19 default durations it shares with the raw mean-max endpoints. How much history is used is part of the model and may change. No model parameters are returned and there is no model to choose.

The curve describes the best efforts in recent training, not the athlete's capacity: it is only meaningful if the athlete went all-out at least once at the durations you care about. It keeps declining beyond about 30 minutes by design, so long-duration values sit below the threshold reported by /profile/metabolic-map/power, which is where thresholds live.

Without enough data the curve is empty, never an error.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The profile as of this date (inclusive). Defaults to today.
durations query No Durations to evaluate the curve at, in seconds: omit for the same 19 defaults as the raw mean-max endpoints (1 s to 6 h), 'all' for the full grid up to the longest effort, or a comma-separated list (e.g. '60,300,1200').
refreshed-token header No
sport query string No `cycling` or `running`. Subsports are not accepted: every activity of the sport is used.
token cookie string No

Responses

{
    "curve": [
        {
            "duration": 0,
            "power": 10.12
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "curve": {
            "items": {
                "$ref": "#/components/schemas/PowerDurationPoint"
            },
            "type": "array",
            "title": "Curve"
        }
    },
    "type": "object",
    "required": [
        "curve"
    ],
    "title": "PowerDurationModelResponse",
    "description": "The fitted intensity-duration curve (plan 062): the curve, and only the curve. The model,\nits parameters and the history it is fitted over are SweatStack's and may change; this shape\nchanges only with notice. Nothing the caller sent is echoed back, and the window is not\nexposed (plan 062, decision 5 as amended)."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/intensity-duration-model/speed

Get Intensity Duration Model Speed (beta)

Description

Beta. This endpoint 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.

The athlete's intensity-duration curve for speed, modeled from their training data.

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

SweatStack fits its model to the athlete's recent training up to date (currently the 90 days ending on date) and returns the curve as {duration, speed} points (seconds; m/s to 2 decimals) at the durations you pass or at the 19 default durations it shares with the raw mean-max endpoints. How much history is used is part of the model and may change. No model parameters are returned and there is no model to choose.

The curve describes the best efforts in recent training, not the athlete's capacity: it is only meaningful if the athlete went all-out at least once at the durations you care about. It keeps declining beyond about 30 minutes by design, so long-duration values sit below the threshold reported by /profile/metabolic-map/speed, which is where thresholds live.

Without enough data the curve is empty, never an error.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The profile as of this date (inclusive). Defaults to today.
durations query No Durations to evaluate the curve at, in seconds: omit for the same 19 defaults as the raw mean-max endpoints (1 s to 6 h), 'all' for the full grid up to the longest effort, or a comma-separated list (e.g. '60,300,1200').
refreshed-token header No
sport query string No `running`. Subsports are not accepted: every activity of the sport is used.
token cookie string No

Responses

{
    "curve": [
        {
            "duration": 0,
            "speed": 10.12
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "curve": {
            "items": {
                "$ref": "#/components/schemas/SpeedDurationPoint"
            },
            "type": "array",
            "title": "Curve"
        }
    },
    "type": "object",
    "required": [
        "curve"
    ],
    "title": "SpeedDurationModelResponse",
    "description": "The fitted intensity-duration curve (plan 062): the curve, and only the curve. The model,\nits parameters and the history it is fitted over are SweatStack's and may change; this shape\nchanges only with notice. Nothing the caller sent is echoed back, and the window is not\nexposed (plan 062, decision 5 as amended)."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/metabolic-map/power

Get Metabolic Map Power (beta)

Description

Beta. This endpoint 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.

The athlete's metabolic map for power: their resolved markers for one root sport as of a date, each with its provenance, and the inputs the model used (plan 069).

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

Every marker is null or {"value": ..., "provenance": ...}. provenance says where the winning value came from: modeled (fitted from the athlete's recent training, currently the 90 days ending on date), measured (a test), declared (set by the athlete or their coach) or external (a device or another system). A fresh measured or declared value outranks the model; a stale one yields to it; an external value counts only when nothing else does. Intensities are whole W; W' is kJ to 1 decimal; inputs.body_mass is the daily on date, in kg to 1 decimal.

Values carry only the digits the estimates support. To track progression, call with a series of dates. To read what was written rather than what wins, use /profile/markers.

Errors are application/problem+json with a code: missing_body_mass (log one with POST /api/v1/dailies/body_mass), insufficient_data (no activity in recent training lasted 15 minutes).

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The profile as of this date (inclusive). Defaults to today.
refreshed-token header No
sport query string No `cycling` or `running`. Subsports are not accepted: every activity of the sport is used.
token cookie string No

Responses

{
    "fatmax": null,
    "first_threshold": null,
    "second_threshold": null,
    "critical_power": null,
    "max_aerobic_power": null,
    "w_prime": null,
    "mlss": null,
    "lt1": null,
    "lt2": null,
    "vt1": null,
    "vt2": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "fatmax": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Power at maximum fat oxidation (W). Null when no source has a value for it."
        },
        "first_threshold": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "The aerobic threshold (W). Modeled as FatMax. Null when no source has a value for it."
        },
        "second_threshold": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "The threshold, FTP (W): build zones and targets on this. Modeled as the maximal lactate steady state. Null when no source has a value for it."
        },
        "critical_power": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Critical power (W): the asymptote of the power-duration curve. Null when no source has a value for it."
        },
        "max_aerobic_power": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Maximal aerobic power (W): where oxygen uptake reaches VO2max. Null when no source has a value for it."
        },
        "w_prime": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "W' (kJ): the work capacity above critical power; pair it with `critical_power`. Null when the fit could not determine it. Null when no source has a value for it."
        },
        "mlss": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Maximal lactate steady state, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "lt1": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "First lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "lt2": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Second lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "vt1": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "First ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "vt2": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Second ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        }
    },
    "type": "object",
    "required": [
        "fatmax",
        "first_threshold",
        "second_threshold",
        "critical_power",
        "max_aerobic_power",
        "w_prime",
        "mlss",
        "lt1",
        "lt2",
        "vt1",
        "vt2"
    ],
    "title": "PowerMapResponse",
    "description": "The metabolic map for power (plan 069). Intensities are whole W; W' is kJ to 1 decimal."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/metabolic-map/speed

Get Metabolic Map Speed (beta)

Description

Beta. This endpoint 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.

The athlete's metabolic map for speed: their resolved markers for one root sport as of a date, each with its provenance, and the inputs the model used (plan 069).

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

Every marker is null or {"value": ..., "provenance": ...}. provenance says where the winning value came from: modeled (fitted from the athlete's recent training, currently the 90 days ending on date), measured (a test), declared (set by the athlete or their coach) or external (a device or another system). A fresh measured or declared value outranks the model; a stale one yields to it; an external value counts only when nothing else does. Intensities are m/s to 2 decimals; D' is whole metres; inputs.body_mass is the daily on date, in kg to 1 decimal.

Values carry only the digits the estimates support. To track progression, call with a series of dates. To read what was written rather than what wins, use /profile/markers.

Errors are application/problem+json with a code: missing_body_mass (log one with POST /api/v1/dailies/body_mass), insufficient_data (no activity in recent training lasted 15 minutes).

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The profile as of this date (inclusive). Defaults to today.
refreshed-token header No
sport query string No `running`. Subsports are not accepted: every activity of the sport is used.
token cookie string No

Responses

{
    "fatmax": null,
    "first_threshold": null,
    "second_threshold": null,
    "critical_speed": null,
    "max_aerobic_speed": null,
    "d_prime": null,
    "mlss": null,
    "lt1": null,
    "lt2": null,
    "vt1": null,
    "vt2": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "fatmax": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Speed at maximum fat oxidation (m/s). Null when no source has a value for it."
        },
        "first_threshold": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "The aerobic threshold (m/s). Modeled as FatMax. Null when no source has a value for it."
        },
        "second_threshold": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "The threshold, threshold pace (m/s): build zones and targets on this. Modeled as the maximal lactate steady state. Null when no source has a value for it."
        },
        "critical_speed": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Critical speed (m/s): the asymptote of the speed-duration curve. Null when no source has a value for it."
        },
        "max_aerobic_speed": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Maximal aerobic speed (m/s): where oxygen uptake reaches VO2max. Null when no source has a value for it."
        },
        "d_prime": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "D' (m): the distance capacity above critical speed; pair it with `critical_speed`. Null when the fit could not determine it. Null when no source has a value for it."
        },
        "mlss": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Maximal lactate steady state, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "lt1": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "First lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "lt2": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Second lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "vt1": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "First ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "vt2": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Second ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        }
    },
    "type": "object",
    "required": [
        "fatmax",
        "first_threshold",
        "second_threshold",
        "critical_speed",
        "max_aerobic_speed",
        "d_prime",
        "mlss",
        "lt1",
        "lt2",
        "vt1",
        "vt2"
    ],
    "title": "SpeedMapResponse",
    "description": "The metabolic map for speed (plan 069). Intensities are m/s to 2 decimals; D' is whole\nmetres."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/metabolic-map/vo2

Get Metabolic Map Vo2 (beta)

Description

Beta. This endpoint 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.

The athlete's metabolic map for oxygen uptake: their resolved markers for one root sport as of a date, each with its provenance, and the inputs the model used (plan 069).

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

Every marker is null or {"value": ..., "provenance": ...}. provenance says where the winning value came from: modeled (fitted from the athlete's recent training, currently the 90 days ending on date), measured (a test), declared (set by the athlete or their coach) or external (a device or another system). A fresh measured or declared value outranks the model; a stale one yields to it; an external value counts only when nothing else does. One VO2max per sport, in whole mL/min, fitted from speed for running and from power for cycling; divide by inputs.body_mass for mL/kg/min.

Values carry only the digits the estimates support. To track progression, call with a series of dates. To read what was written rather than what wins, use /profile/markers.

Errors are application/problem+json with a code: missing_body_mass (log one with POST /api/v1/dailies/body_mass), insufficient_data (no activity in recent training lasted 15 minutes).

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The profile as of this date (inclusive). Defaults to today.
refreshed-token header No
sport query string No `cycling` or `running`. Subsports are not accepted: every activity of the sport is used.
token cookie string No

Responses

{
    "vo2max": null,
    "vo2max_relative": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "vo2max": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Maximum oxygen uptake, absolute, in whole mL/min. Null when no source has a value for it."
        },
        "vo2max_relative": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "The same maximum oxygen uptake relative to body mass, in mL/kg/min to 1 decimal, using the athlete's body mass on `date`. Null when no body mass is stored. Null when no source has a value for it."
        }
    },
    "type": "object",
    "required": [
        "vo2max",
        "vo2max_relative"
    ],
    "title": "Vo2MapResponse",
    "description": "The metabolic map for oxygen uptake (plan 069): one VO2max per sport, fitted from speed for\nrunning and from power for cycling, published absolute and relative to body mass because\nboth are how VO2max is read (plan 077 D13)."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/metabolic-map/heart_rate

Get Metabolic Map Heart Rate (beta)

Description

Beta. This endpoint 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.

The athlete's metabolic map for heart rate: their resolved markers for one root sport as of a date, each with its provenance, and the inputs the model used (plan 069).

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

Every marker is null or {"value": ..., "provenance": ...}. provenance says where the winning value came from: modeled (fitted from the athlete's recent training, currently the 90 days ending on date), measured (a test), declared (set by the athlete or their coach) or external (a device or another system). A fresh measured or declared value outranks the model; a stale one yields to it; an external value counts only when nothing else does. SweatStack has no heart-rate model yet, so nothing here is modeled: the values are what the athlete, their coach, a test or a device said, in whole bpm. inputs.resting_hr is the 7-day median of the athlete's resting_hr dailies ending on date, used by the heart-rate zones.

Values carry only the digits the estimates support. To track progression, call with a series of dates. To read what was written rather than what wins, use /profile/markers.

Errors are application/problem+json with a code: unsupported_sport (not a root sport).

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The profile as of this date (inclusive). Defaults to today.
refreshed-token header No
sport query string No Any root sport, e.g. `running`, `cycling`, `xc_skiing`. Subsports are not accepted: every activity of the sport is used.
token cookie string No

Responses

{
    "heart_rate_max": null,
    "first_threshold": null,
    "second_threshold": null,
    "mlss": null,
    "lt1": null,
    "lt2": null,
    "vt1": null,
    "vt2": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "heart_rate_max": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Maximum heart rate (bpm). Null when no source has a value for it."
        },
        "first_threshold": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "The aerobic threshold (bpm). Null when no source has a value for it."
        },
        "second_threshold": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "The threshold heart rate, LTHR (bpm). Null when no source has a value for it."
        },
        "mlss": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Maximal lactate steady state, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "lt1": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "First lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "lt2": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Second lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "vt1": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "First ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        },
        "vt2": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/MarkerValue"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Second ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it."
        }
    },
    "type": "object",
    "required": [
        "heart_rate_max",
        "first_threshold",
        "second_threshold",
        "mlss",
        "lt1",
        "lt2",
        "vt1",
        "vt2"
    ],
    "title": "HeartRateMapResponse",
    "description": "The metabolic map for heart rate (plan 069): what the athlete, their coach, a test or a\ndevice said, in whole bpm. SweatStack has no heart-rate model yet, so nothing here is\n`modeled`."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/zones/power

Get Zones Power (beta)

Description

Beta. This endpoint 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.

The athlete's power training zones, resolved to absolute values.

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

Cut from the resolved metabolic map's fatmax, second_threshold and maximal aerobic intensity for the same sport and date, at the map's precision. three_zone and five_zone end at maximal aerobic intensity; the top zone of seven_zone is open (upper is null). Whole W. A zone holds lower <= x < upper; each upper is the next lower and the first lower is 0. Zones carry no provenance: which markers they were cut from is the method's business; read /profile/metabolic-map/power for that.

Zones move over weeks: cache them per athlete per day. To build a workout, turn a zone into a range target: an SWF zone target is resolved by the device against its own zones, not these.

Errors are application/problem+json with a code: unsupported_zone_system, missing_body_mass (log one with POST /api/v1/dailies/body_mass), insufficient_data (no activity in recent training lasted 15 minutes).

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The zones as of this date (inclusive). Defaults to today.
refreshed-token header No
sport query string No `cycling` or `running`. Subsports are not accepted: every activity of the sport is used.
token cookie string No
zone_system query No Defaults to `seven_zone`.

Responses

{
    "zone_system": "three_zone",
    "zones": [
        {
            "name": "string",
            "label": "string",
            "lower": null,
            "upper": null
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "zone_system": {
            "type": "string",
            "enum": [
                "three_zone",
                "five_zone",
                "seven_zone",
                "olt_i_scale"
            ],
            "title": "Zone System"
        },
        "zones": {
            "items": {
                "$ref": "#/components/schemas/Zone"
            },
            "type": "array",
            "title": "Zones",
            "description": "Ordered from low to high; the position is the index."
        }
    },
    "type": "object",
    "required": [
        "zone_system",
        "zones"
    ],
    "title": "ZonesResponse",
    "description": "Training zones (plan 065), resolved on the server from the metabolic map's markers as of\na date, or from the Olympiatoppen I-scale for RPE.\nNothing the caller sent is echoed except `zone_system`, because a default may have applied;\nthe markers and any correction applied to them are not exposed."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/zones/speed

Get Zones Speed (beta)

Description

Beta. This endpoint 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.

The athlete's speed training zones, resolved to absolute values.

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

Cut from the resolved metabolic map's fatmax, second_threshold and maximal aerobic intensity for the same sport and date, at the map's precision. three_zone and five_zone end at maximal aerobic intensity; the top zone of seven_zone is open (upper is null). m/s to 2 decimals. A zone holds lower <= x < upper; each upper is the next lower and the first lower is 0. Zones carry no provenance: which markers they were cut from is the method's business; read /profile/metabolic-map/speed for that.

Zones move over weeks: cache them per athlete per day. To build a workout, turn a zone into a range target: an SWF zone target is resolved by the device against its own zones, not these.

Errors are application/problem+json with a code: unsupported_zone_system, missing_body_mass (log one with POST /api/v1/dailies/body_mass), insufficient_data (no activity in recent training lasted 15 minutes).

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The zones as of this date (inclusive). Defaults to today.
refreshed-token header No
sport query string No `running`. Subsports are not accepted: every activity of the sport is used.
token cookie string No
zone_system query No Defaults to `five_zone`.

Responses

{
    "zone_system": "three_zone",
    "zones": [
        {
            "name": "string",
            "label": "string",
            "lower": null,
            "upper": null
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "zone_system": {
            "type": "string",
            "enum": [
                "three_zone",
                "five_zone",
                "seven_zone",
                "olt_i_scale"
            ],
            "title": "Zone System"
        },
        "zones": {
            "items": {
                "$ref": "#/components/schemas/Zone"
            },
            "type": "array",
            "title": "Zones",
            "description": "Ordered from low to high; the position is the index."
        }
    },
    "type": "object",
    "required": [
        "zone_system",
        "zones"
    ],
    "title": "ZonesResponse",
    "description": "Training zones (plan 065), resolved on the server from the metabolic map's markers as of\na date, or from the Olympiatoppen I-scale for RPE.\nNothing the caller sent is echoed except `zone_system`, because a default may have applied;\nthe markers and any correction applied to them are not exposed."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/zones/heart_rate

Get Zones Heart Rate (beta)

Description

Beta. This endpoint 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.

The athlete's heart-rate training zones, resolved to absolute values.

The values may change without notice as the model improves. The response shape changes only with a dated changelog entry and 30 days before it ships.

Five zones as percentages of heart-rate reserve (Karvonen): a boundary at p % is resting_hr + p * (heart_rate_max - resting_hr), at 60, 70, 80 and 90 %, in whole bpm; Z1 starts at 0 and Z5 is open. heart_rate_max is the resolved marker, resting_hr the 7-day median of the athlete's dailies. These bands are population conventions, not the athlete's own thresholds. A zone holds lower <= x < upper; each upper is the next lower and the first lower is 0. Zones carry no provenance: which markers they were cut from is the method's business; read /profile/metabolic-map/heart_rate for that.

Zones move over weeks: cache them per athlete per day. To build a workout, turn a zone into a range target: an SWF zone target is resolved by the device against its own zones, not these.

Errors are application/problem+json with a code: unsupported_sport, missing_heart_rate_max (enter one with POST /api/v1/profile/markers/heart_rate_max), missing_resting_hr (log one with POST /api/v1/dailies/resting_hr), unusable_heart_rate_range.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
date query string No The zones as of this date (inclusive). Defaults to today.
refreshed-token header No
sport query string No Any root sport. Subsports are not accepted: every activity of the sport is used.
token cookie string No
zone_system query No Defaults to `five_zone`, the only heart-rate system.

Responses

{
    "zone_system": "three_zone",
    "zones": [
        {
            "name": "string",
            "label": "string",
            "lower": null,
            "upper": null
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "zone_system": {
            "type": "string",
            "enum": [
                "three_zone",
                "five_zone",
                "seven_zone",
                "olt_i_scale"
            ],
            "title": "Zone System"
        },
        "zones": {
            "items": {
                "$ref": "#/components/schemas/Zone"
            },
            "type": "array",
            "title": "Zones",
            "description": "Ordered from low to high; the position is the index."
        }
    },
    "type": "object",
    "required": [
        "zone_system",
        "zones"
    ],
    "title": "ZonesResponse",
    "description": "Training zones (plan 065), resolved on the server from the metabolic map's markers as of\na date, or from the Olympiatoppen I-scale for RPE.\nNothing the caller sent is echoed except `zone_system`, because a default may have applied;\nthe markers and any correction applied to them are not exposed."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/zones/rpe_cr10

Get Zones Rpe Cr10 (beta)

Description

Beta. This endpoint 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.

Olympiatoppen's I-scale on the CR10 scale: integer scale points with both ends inclusive, taken as published. On CR10, 2 is in I-1 and I-2. These zones need no training data or body mass, so they work for every athlete.

The response shape changes only with a dated changelog entry and 30 days before it ships.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
token cookie string No
zone_system query No Defaults to `olt_i_scale`, the only RPE system.

Responses

{
    "zone_system": "three_zone",
    "zones": [
        {
            "name": "string",
            "label": "string",
            "lower": null,
            "upper": null
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "zone_system": {
            "type": "string",
            "enum": [
                "three_zone",
                "five_zone",
                "seven_zone",
                "olt_i_scale"
            ],
            "title": "Zone System"
        },
        "zones": {
            "items": {
                "$ref": "#/components/schemas/Zone"
            },
            "type": "array",
            "title": "Zones",
            "description": "Ordered from low to high; the position is the index."
        }
    },
    "type": "object",
    "required": [
        "zone_system",
        "zones"
    ],
    "title": "ZonesResponse",
    "description": "Training zones (plan 065), resolved on the server from the metabolic map's markers as of\na date, or from the Olympiatoppen I-scale for RPE.\nNothing the caller sent is echoed except `zone_system`, because a default may have applied;\nthe markers and any correction applied to them are not exposed."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/zones/rpe_borg

Get Zones Rpe Borg (beta)

Description

Beta. This endpoint 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.

Olympiatoppen's I-scale on the Borg scale: integer scale points with both ends inclusive, taken as published. On CR10, 2 is in I-1 and I-2. These zones need no training data or body mass, so they work for every athlete.

The response shape changes only with a dated changelog entry and 30 days before it ships.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
token cookie string No
zone_system query No Defaults to `olt_i_scale`, the only RPE system.

Responses

{
    "zone_system": "three_zone",
    "zones": [
        {
            "name": "string",
            "label": "string",
            "lower": null,
            "upper": null
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "zone_system": {
            "type": "string",
            "enum": [
                "three_zone",
                "five_zone",
                "seven_zone",
                "olt_i_scale"
            ],
            "title": "Zone System"
        },
        "zones": {
            "items": {
                "$ref": "#/components/schemas/Zone"
            },
            "type": "array",
            "title": "Zones",
            "description": "Ordered from low to high; the position is the index."
        }
    },
    "type": "object",
    "required": [
        "zone_system",
        "zones"
    ],
    "title": "ZonesResponse",
    "description": "Training zones (plan 065), resolved on the server from the metabolic map's markers as of\na date, or from the Olympiatoppen I-scale for RPE.\nNothing the caller sent is echoed except `zone_system`, because a default may have applied;\nthe markers and any correction applied to them are not exposed."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

POST /api/v1/profile/markers/{marker}

Upsert Marker (beta)

Description

Beta. This endpoint 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.

Store a marker value: a declared FTP, threshold HR or max HR, or a value another system reported (external). Writing the same sport, metric and date again replaces the value and answers 200; a new identity answers 201. provenance is required: declared (a person set it) or external; measured values are tests (422 measured_is_a_test). A declared value can be pinned to keep it until it is changed. Markers are per root sport.

The map (/profile/metabolic-map/{metric}) shows what wins; this store shows what was written. Errors are application/problem+json: unsupported_marker_metric, measured_is_a_test, unsupported_provenance, unsupported_sport, pinned_requires_declared.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
marker path No
refreshed-token header No
token cookie string No

Request body

{
    "sport": "string",
    "metric": "power",
    "value": 10.12,
    "date": "2022-04-13",
    "provenance": "modeled",
    "pinned": true
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "properties": {
        "sport": {
            "type": "string",
            "title": "Sport",
            "description": "A root sport (`cycling`, `running`, `xc_skiing`); subsports are not accepted."
        },
        "metric": {
            "type": "string",
            "enum": [
                "power",
                "speed",
                "vo2",
                "heart_rate"
            ],
            "title": "Metric",
            "description": "The metric the value is in: `power` (W), `speed` (m/s) or `heart_rate` (bpm)."
        },
        "value": {
            "type": "number",
            "exclusiveMinimum": 0.0,
            "title": "Value",
            "description": "In the metric's canonical unit."
        },
        "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "When the value was determined: set, read from a device, estimated."
        },
        "provenance": {
            "$ref": "#/components/schemas/Provenance",
            "description": "`declared` (a person set it) or `external` (a device or another system). Measured values are test results: write a test."
        },
        "pinned": {
            "type": "boolean",
            "title": "Pinned",
            "description": "Keep until changed: a pinned declared value never goes stale. Declared rows only.",
            "default": false
        }
    },
    "type": "object",
    "required": [
        "sport",
        "metric",
        "value",
        "date",
        "provenance"
    ],
    "title": "MarkerWrite",
    "description": "A stored marker value, written by an app or the web UI. `provenance` is required and has\nno default: the party that knows whether a person entered the value states it."
}

Responses

{
    "id": "string",
    "sport": "string",
    "marker": "heart_rate_max",
    "metric": "power",
    "value": 10.12,
    "date": "2022-04-13",
    "provenance": "modeled",
    "pinned": true,
    "source": null,
    "application_id": null,
    "activity_id": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "id": {
            "type": "string",
            "title": "Id"
        },
        "sport": {
            "type": "string",
            "title": "Sport"
        },
        "marker": {
            "$ref": "#/components/schemas/MarkerName"
        },
        "metric": {
            "type": "string",
            "enum": [
                "power",
                "speed",
                "vo2",
                "heart_rate"
            ],
            "title": "Metric"
        },
        "value": {
            "type": "number",
            "title": "Value"
        },
        "date": {
            "type": "string",
            "format": "date",
            "title": "Date"
        },
        "provenance": {
            "$ref": "#/components/schemas/Provenance"
        },
        "pinned": {
            "type": "boolean",
            "title": "Pinned"
        },
        "source": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/DailySource"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Who wrote it: `manual` (the athlete), `application` (an app; see `application_id`) or an integration (`garmin_connect`, ...). New values may be added."
        },
        "application_id": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Application Id",
            "description": "The app that wrote it, with `source` `application`; null when the app was deleted."
        },
        "activity_id": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Activity Id",
            "description": "The activity an external value was read from."
        }
    },
    "type": "object",
    "required": [
        "id",
        "sport",
        "marker",
        "metric",
        "value",
        "date",
        "provenance",
        "pinned",
        "source",
        "application_id",
        "activity_id"
    ],
    "title": "MarkerRowResponse",
    "description": "A stored marker value exactly as written (plan 069, D18): the store never resolves."
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/markers/{marker}

List Markers (beta)

Description

Beta. This endpoint 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.

The stored values of one marker, exactly as written, newest first. Every filter is optional. This is the history, never a resolution: for the current winner read /profile/metabolic-map/{metric}.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
end query No Rows dated on or before this date.
marker path No
metric query No Filter on a metric.
refreshed-token header No
sport query No Filter on a root sport.
start query No Rows dated on or after this date.
token cookie string No

Responses

[
    {
        "id": "string",
        "sport": "string",
        "marker": "heart_rate_max",
        "metric": "power",
        "value": 10.12,
        "date": "2022-04-13",
        "provenance": "modeled",
        "pinned": true,
        "source": null,
        "application_id": null,
        "activity_id": null
    }
]
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "array",
    "items": {
        "$ref": "#/components/schemas/MarkerRowResponse"
    },
    "title": "Response List Markers Api V1 Profile Markers  Marker  Get"
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

DELETE /api/v1/profile/markers/{marker}/{row_id}

Delete Marker (beta)

Description

Beta. This endpoint 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.

Delete one stored value by its id.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
marker path No
refreshed-token header No
row_id path string No
token cookie string No

Responses

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

POST /api/v1/profile/max-efforts

Upsert Max Effort (beta)

Description

Beta. This endpoint 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.

Store a max effort: an all-out effort as a point on the intensity-duration curve, with no activity behind it. Two forms, exactly one per request: a race as distance + duration (measured; the speed is derived), or an estimate as duration + value (declared). Efforts in the profile window are injected into the fit before the markers are modeled and are used as truth: enter only what the athlete can hold. An effort below what training already shows changes nothing. The same sport, metric, duration and date again replaces the row (200).

Errors are application/problem+json: unsupported_max_effort_metric, invalid_max_effort_form, unsupported_provenance, unsupported_sport.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
token cookie string No

Request body

{
    "sport": "string",
    "metric": "power",
    "date": "2022-04-13",
    "duration": 0,
    "distance": null,
    "value": null,
    "provenance": "modeled",
    "title": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the request body
{
    "properties": {
        "sport": {
            "type": "string",
            "title": "Sport",
            "description": "A root sport (`cycling`, `running`); subsports are not accepted."
        },
        "metric": {
            "type": "string",
            "enum": [
                "power",
                "speed"
            ],
            "title": "Metric",
            "description": "`power` (W) or `speed` (m/s): the curve the effort is injected into."
        },
        "date": {
            "type": "string",
            "format": "date",
            "title": "Date",
            "description": "When the effort happened or was estimated."
        },
        "duration": {
            "type": "integer",
            "exclusiveMinimum": 0.0,
            "title": "Duration",
            "description": "Seconds the effort was held."
        },
        "distance": {
            "anyOf": [
                {
                    "type": "number",
                    "exclusiveMinimum": 0.0
                },
                {
                    "type": "null"
                }
            ],
            "title": "Distance",
            "description": "Metres, for a race: the speed is derived."
        },
        "value": {
            "anyOf": [
                {
                    "type": "number",
                    "exclusiveMinimum": 0.0
                },
                {
                    "type": "null"
                }
            ],
            "title": "Value",
            "description": "The intensity held, in the metric's unit, for an estimate."
        },
        "provenance": {
            "$ref": "#/components/schemas/Provenance",
            "description": "`measured` (it happened and was timed) or `declared` (an estimate)."
        },
        "title": {
            "anyOf": [
                {
                    "type": "string",
                    "maxLength": 80
                },
                {
                    "type": "null"
                }
            ],
            "title": "Title",
            "description": "For recognition only, e.g. `Oslo 10K`. Never parsed."
        }
    },
    "type": "object",
    "required": [
        "sport",
        "metric",
        "date",
        "duration",
        "provenance"
    ],
    "title": "MaxEffortWrite",
    "description": "A max effort (plan 069, D24): a race as `distance` + `duration`, or an estimate as\n`duration` + `value`. Exactly one of the two forms per request."
}

Responses

{
    "id": "string",
    "sport": "string",
    "metric": "power",
    "duration": 0,
    "distance": null,
    "value": 10.12,
    "date": "2022-04-13",
    "provenance": "modeled",
    "title": null,
    "source": null,
    "application_id": null,
    "activity_id": null
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "id": {
            "type": "string",
            "title": "Id"
        },
        "sport": {
            "type": "string",
            "title": "Sport"
        },
        "metric": {
            "type": "string",
            "enum": [
                "power",
                "speed",
                "vo2",
                "heart_rate"
            ],
            "title": "Metric"
        },
        "duration": {
            "type": "integer",
            "title": "Duration"
        },
        "distance": {
            "anyOf": [
                {
                    "type": "number"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Distance"
        },
        "value": {
            "type": "number",
            "title": "Value",
            "description": "Always in the metric's canonical unit; derived from distance and duration for a race."
        },
        "date": {
            "type": "string",
            "format": "date",
            "title": "Date"
        },
        "provenance": {
            "$ref": "#/components/schemas/Provenance"
        },
        "title": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Title"
        },
        "source": {
            "anyOf": [
                {
                    "$ref": "#/components/schemas/DailySource"
                },
                {
                    "type": "null"
                }
            ],
            "description": "Who wrote it: `manual` (the athlete), `application` (an app; see `application_id`) or an integration (`garmin_connect`, ...). New values may be added."
        },
        "application_id": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Application Id",
            "description": "The app that wrote it, with `source` `application`; null when the app was deleted."
        },
        "activity_id": {
            "anyOf": [
                {
                    "type": "string"
                },
                {
                    "type": "null"
                }
            ],
            "title": "Activity Id"
        }
    },
    "type": "object",
    "required": [
        "id",
        "sport",
        "metric",
        "duration",
        "distance",
        "value",
        "date",
        "provenance",
        "title",
        "source",
        "application_id",
        "activity_id"
    ],
    "title": "MaxEffortRowResponse"
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

GET /api/v1/profile/max-efforts

List Max Efforts (beta)

Description

Beta. This endpoint 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.

The stored max efforts, exactly as written, newest first. Every filter is optional.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
end query No Rows dated on or before this date.
metric query No Filter on a metric.
refreshed-token header No
sport query No Filter on a root sport.
start query No Rows dated on or after this date.
token cookie string No

Responses

[
    {
        "id": "string",
        "sport": "string",
        "metric": "power",
        "duration": 0,
        "distance": null,
        "value": 10.12,
        "date": "2022-04-13",
        "provenance": "modeled",
        "title": null,
        "source": null,
        "application_id": null,
        "activity_id": null
    }
]
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "type": "array",
    "items": {
        "$ref": "#/components/schemas/MaxEffortRowResponse"
    },
    "title": "Response List Max Efforts Api V1 Profile Max Efforts Get"
}

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

DELETE /api/v1/profile/max-efforts/{row_id}

Delete Max Effort (beta)

Description

Beta. This endpoint 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.

Delete one max effort by its id.

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
row_id path string No
token cookie string No

Responses

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

PUT /api/v1/profile/app-metadata

Put Profile Metadata

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
token cookie string No

Request body

Schema of the request body
{
    "type": "object",
    "additionalProperties": true,
    "title": "Data"
}

Responses

Schema of the response body

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

DELETE /api/v1/profile/app-metadata

Delete Profile Metadata

Input parameters

Parameter In Type Default Nullable Description
HTTPBearer header string N/A No JWT Bearer token
refreshed-token header No
token cookie string No

Responses

{
    "detail": [
        {
            "loc": [
                null
            ],
            "msg": "string",
            "type": "string"
        }
    ]
}
⚠️ This example has been generated automatically from the schema and it is not accurate. Refer to the schema for more information.

Schema of the response body
{
    "properties": {
        "detail": {
            "items": {
                "$ref": "#/components/schemas/ValidationError"
            },
            "type": "array",
            "title": "Detail"
        }
    },
    "type": "object",
    "title": "HTTPValidationError"
}

Schemas

AccountStatusResponse

Name Type Description
capabilities
issue

Capability

Type: string

CapabilityStatus

Type: string

DailySource

Type: string

HeartRateMapResponse

Name Type Description
first_threshold The aerobic threshold (bpm). Null when no source has a value for it.
heart_rate_max Maximum heart rate (bpm). Null when no source has a value for it.
lt1 First lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
lt2 Second lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
mlss Maximal lactate steady state, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
second_threshold The threshold heart rate, LTHR (bpm). Null when no source has a value for it.
vt1 First ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
vt2 Second ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.

HTTPValidationError

Name Type Description
detail Array<ValidationError>

IssueStatus

Type: string

MarkerName

Type: string

MarkerRowResponse

Name Type Description
activity_id The activity an external value was read from.
application_id The app that wrote it, with `source` `application`; null when the app was deleted.
date string(date)
id string
marker MarkerName
metric string
pinned boolean
provenance Provenance
source Who wrote it: `manual` (the athlete), `application` (an app; see `application_id`) or an integration (`garmin_connect`, ...). New values may be added.
sport string
value number

MarkerValue

Name Type Description
provenance Provenance `modeled` (from the athlete's training), `measured` (a test), `declared` (set by the athlete or coach) or `external` (a device or another system).
value number

MarkerWrite

Name Type Description
date string(date) When the value was determined: set, read from a device, estimated.
metric string The metric the value is in: `power` (W), `speed` (m/s) or `heart_rate` (bpm).
pinned boolean Keep until changed: a pinned declared value never goes stale. Declared rows only.
provenance Provenance `declared` (a person set it) or `external` (a device or another system). Measured values are test results: write a test.
sport string A root sport (`cycling`, `running`, `xc_skiing`); subsports are not accepted.
value number In the metric's canonical unit.

MaxEffortRowResponse

Name Type Description
activity_id
application_id The app that wrote it, with `source` `application`; null when the app was deleted.
date string(date)
distance
duration integer
id string
metric string
provenance Provenance
source Who wrote it: `manual` (the athlete), `application` (an app; see `application_id`) or an integration (`garmin_connect`, ...). New values may be added.
sport string
title
value number Always in the metric's canonical unit; derived from distance and duration for a race.

MaxEffortWrite

Name Type Description
date string(date) When the effort happened or was estimated.
distance Metres, for a race: the speed is derived.
duration integer Seconds the effort was held.
metric string `power` (W) or `speed` (m/s): the curve the effort is injected into.
provenance Provenance `measured` (it happened and was timed) or `declared` (an estimate).
sport string A root sport (`cycling`, `running`); subsports are not accepted.
title For recognition only, e.g. `Oslo 10K`. Never parsed.
value The intensity held, in the metric's unit, for an estimate.

PortalDestination

Type: string

PowerDurationModelResponse

Name Type Description
curve Array<PowerDurationPoint>

PowerDurationPoint

Name Type Description
duration integer Seconds.
power number Modeled power at that duration, whole W.

PowerMapResponse

Name Type Description
critical_power Critical power (W): the asymptote of the power-duration curve. Null when no source has a value for it.
fatmax Power at maximum fat oxidation (W). Null when no source has a value for it.
first_threshold The aerobic threshold (W). Modeled as FatMax. Null when no source has a value for it.
lt1 First lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
lt2 Second lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
max_aerobic_power Maximal aerobic power (W): where oxygen uptake reaches VO2max. Null when no source has a value for it.
mlss Maximal lactate steady state, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
second_threshold The threshold, FTP (W): build zones and targets on this. Modeled as the maximal lactate steady state. Null when no source has a value for it.
vt1 First ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
vt2 Second ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
w_prime W' (kJ): the work capacity above critical power; pair it with `critical_power`. Null when the fit could not determine it. Null when no source has a value for it.

Provenance

Type: string

SpeedDurationModelResponse

Name Type Description
curve Array<SpeedDurationPoint>

SpeedDurationPoint

Name Type Description
duration integer Seconds.
speed number Modeled speed at that duration, m/s to 2 decimals.

SpeedMapResponse

Name Type Description
critical_speed Critical speed (m/s): the asymptote of the speed-duration curve. Null when no source has a value for it.
d_prime D' (m): the distance capacity above critical speed; pair it with `critical_speed`. Null when the fit could not determine it. Null when no source has a value for it.
fatmax Speed at maximum fat oxidation (m/s). Null when no source has a value for it.
first_threshold The aerobic threshold (m/s). Modeled as FatMax. Null when no source has a value for it.
lt1 First lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
lt2 Second lactate threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
max_aerobic_speed Maximal aerobic speed (m/s): where oxygen uptake reaches VO2max. Null when no source has a value for it.
mlss Maximal lactate steady state, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
second_threshold The threshold, threshold pace (m/s): build zones and targets on this. Modeled as the maximal lactate steady state. Null when no source has a value for it.
vt1 First ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.
vt2 Second ventilatory threshold, as measured. Only when a test reported it, or the athlete entered a lab result; never modeled. Null when no source has a value for it.

StatusIssueCode

Type: string

StatusIssueResponse

Name Type Description
code StatusIssueCode
destination
message string
status IssueStatus

TemplateDay

Name Type Description
avg_training_duration string(duration)
sports Array<string>
typical_training_duration string(duration)

TemplateWeekResponse

Name Type Description
friday TemplateDay
monday TemplateDay
saturday TemplateDay
sunday TemplateDay
thursday TemplateDay
tuesday TemplateDay
wednesday TemplateDay

ValidationError

Name Type Description
loc Array<>
msg string
type string

Vo2MapResponse

Name Type Description
vo2max Maximum oxygen uptake, absolute, in whole mL/min. Null when no source has a value for it.
vo2max_relative The same maximum oxygen uptake relative to body mass, in mL/kg/min to 1 decimal, using the athlete's body mass on `date`. Null when no body mass is stored. Null when no source has a value for it.

Zone

Name Type Description
label string Human-readable name, e.g. `Endurance`.
lower Lower boundary. Power and speed: W or m/s, inclusive. RPE: an integer scale point, inclusive.
name string Stable short name: `Z1` to `Z7`, or `I-1` to `I-5`.
upper Upper boundary. Power and speed: W or m/s, exclusive, and null for the open top zone of `seven_zone`. RPE: an integer scale point, inclusive.

ZonesResponse

Name Type Description
zone_system string
zones Array<Zone> Ordered from low to high; the position is the index.

Security schemes

Name Type Scheme Description
HTTPBearer http bearer
HTTPBasic http basic