Concepts
Scopes and grants
A grant is one athlete's permission for one app. Scopes say what the grant covers. Both are under the athlete's control the whole time.
Scopes
| Scope | Endpoints | What your app can read |
|---|---|---|
activities:read | GET /GET / | The athlete's activity summaries, newest first. |
profile:read | GET /v1/profile | sub, an ID for this athlete that only your app sees. No email or name. |
Ask for what you'll use. Scopes go in the authorize link, separated by spaces: scope=activities:read profile:read. An unknown scope, or an empty list, stops the authorization with invalid_scope.
Calling an endpoint without its scope returns 403 insufficient_ with a WWW-Authenticate header naming the scope you need.
Grants
The first time an athlete approves your app, CorrConnect creates a grant holding the scopes you asked for. Each later approval by the same athlete reuses that grant and replaces its scopes with the ones in the new request. So if you ask again for profile:read alone, the grant drops activities:read, and tokens that had it stop passing the scope check.
A grant is active or revoked. Tokens only work while their grant is active and only carry scopes the grant still holds.
The athlete's subject
GET /v1/profile returns sub, for example ccu_. It is:
- the same every time for this athlete and your app, including after they revoke and approve again,
- different for every app, so two apps can't match athletes by comparing IDs,
- the same value as
subjectin your webhook events.
Use sub as your key for the athlete. CorrConnect never gives your app an email address or a name. If an athlete deletes their CorrConnect account and makes a new one, the new account has a different sub.
How access ends
Every one of these ends the grant, deletes its tokens and codes, and sends grant.revoked to your webhook:
| What happened | Who did it |
|---|---|
| The athlete revoked your app in their CorrConnect account | Athlete |
| The athlete reset their password | Athlete |
| The athlete deleted their CorrConnect account | Athlete |
Your app called POST / | You |
| A spent refresh token came back after the 10-second grace window | CorrConnect, to protect the athlete |
Deleting your app also ends all of its grants, but by then the app has no webhook subscriptions left to notify.
After grant.revoked, calls with that athlete's tokens fail with 401 invalid_ and refreshes fail with invalid_grant. To read their data again, the athlete has to approve your app again. What to do with data you already stored is covered in revocation and deletion.