Skip to content

Scopes

A scope is a category of information and a verb. Your app requests the categories it uses; the user sees one line per category on the consent screen, with your reason under it, and your token reaches the endpoints of those categories and nothing else. Request less, and the screen is shorter.

The scopes

Scope What it reaches What the user reads
activities:read Activities, sources and uploads, tests, traces, markers, max efforts, the metabolic map, training zones, the intensity-duration model, the template week, sports and tags: everything under /activities/, /tests/, /traces/ and the derived endpoints under /profile/. Read your activities, tests, traces and the training analysis built from them, over time. Training analysis might use your wellness data as well.
activities:write Uploads, app metadata, tests, traces, markers and max efforts: creating, changing and deleting them. Upload activities and record tests, traces and thresholds.
wellness:read Every daily measure except the menstrual cycle day: GET /api/v1/dailies/{measure}. Read your daily wellness, such as sleep, heart-rate variability and body composition, over time. Does not include menstrual cycle data.
wellness:write Recording and deleting those measures. Record daily wellness on your behalf.
reproductive_health:read GET /api/v1/dailies/menstrual_cycle_day. Standalone: it neither needs nor implies wellness. Read your menstrual cycle.
reproductive_health:write Recording and deleting the cycle day. Record your menstrual cycle on your behalf.
workouts:read The user's scheduled workouts. See your planned workouts.
workouts:write Scheduling, changing and deleting workouts, which sends them to the user's connected devices. Plan workouts on your calendar and send them to your connected devices.
sharing:read Who shares data with the user and whom the user shares with: the users and teams listings, team rosters, and POST /api/v1/oauth/delegated-token. See who shares their data with you and act on their behalf, and see whom you share with.
sharing:write Creating, updating and deleting managed accounts, and authorizing or revoking a team. Change who you share your data with, and manage the accounts you created. Includes deleting those accounts.
openid sub on userinfo and the ID token. Sign you in with your SweatStack account.
profile The name claims: name, given_name, family_name. See your name.
email email on userinfo. See your email address.
offline_access A refresh token for PKCE clients. Clients with a client secret always get one. Keep access while you are not using the app.

Every endpoint's scope is in the API reference, and a 403 names the scope the token lacks.

A few endpoints need a valid token and no scope: GET /api/v1/profile/status, POST /api/v1/portal/sessions and GET /api/v1/oauth/principal-token.

What the training analysis reveals

A model may use any value the user stored. What your app can see is what the consent line names. The metabolic map and the zones use the user's body mass and resting heart rate, and they do not echo them: there is no inputs field. Two values are nevertheless derivable from activities:read alone, because the sport's own units need them; the consent line says that training analysis uses wellness data, and this is the exact list:

  • Body mass, from the VO2max the map publishes both absolute (mL/min) and relative to body mass (mL/kg/min).
  • Resting heart rate, from heart-rate zones, which are cut on heart-rate reserve.

Nothing else about the user's wellness is derivable through an activities endpoint, on any date. Body composition, sleep, heart-rate variability and stress may steer a model and never come back out. The menstrual cycle day and the email address are never exposed through any other scope, in any form. If you find a wellness value reachable through an activities endpoint that is not one of the two above, tell us: we treat it as a vulnerability.

Purposes

For every category your app requests, except the identity scopes openid and profile and offline_access, you write one sentence under What your app uses in the app's settings: why your app needs it. The user reads it on the consent screen as a "Purpose" line under the category, marked as your words. One purpose per category, 20 to 160 characters, plain text, no links.

Purposes are optional while only you connect to your app. Once anyone else can (your app is public), a request for a category without a purpose shows the user a "not ready to connect yet" page instead of the consent screen. The owner never meets that page, so test with a second account, and use Preview the consent screen on the edit form to read your purposes as the user will. What makes a good purpose.

When your app asks for a scope the user has not granted yet, the consent screen shows only the new lines, with what they already allowed listed below. On consent, the grant becomes the union of old and new. A later request for fewer scopes never removes any: two flows of one app cannot cancel each other's grant, and a refresh token minted by either keeps its scopes. The user revokes your app as a whole, under Privacy.

Acting for someone else

A delegated token (a coach for an athlete, a manager for a managed account) never carries more than the token it was minted from, and never email, sharing or offline_access. For a consented grant it carries the grant intersected with your token; for a managed account it carries your token minus those three. openid and profile ride with every grant, so userinfo works on a delegated token and returns the athlete's id and name, never their email. The endpoints are in the quick reference.

Before October 2026: data:read and data:write

Until plan 077 shipped, every app requested one of two bundles. They are retired. An app registered before the release may keep sending them until the end of the window named in the changelog; a request that carries one is read as the categories the bundle reached:

You send SweatStack reads
data:read activities:read wellness:read reproductive_health:read workouts:read sharing:read
data:write activities:write wellness:write reproductive_health:write workouts:write sharing:write
profile together with a bundle openid profile email sharing:read sharing:write

A request without a bundle is taken as it is, so profile on its own means the name only, as OpenID says; add email for the address. Your app announces its move by dropping the bundle. An app registered after the release gets invalid_scope for a bundle. Tokens and refresh tokens issued before the release keep working: grants were translated in place, so no user re-consents.