Sign in with Sporty
If all you need is to know who someone is, you need OpenID Connect, which is
the authorization code flow with openid in the scope.
Point any OIDC library at https://api.sporty.plus/.well-known/openid-configuration and it
will configure itself. Writing the verification by hand is possible but rarely worth it.
The id_token
Returned alongside the access token when openid was granted. An RS256 JWT:
{
"iss": "https://api.sporty.plus",
"sub": "9f1c2e40-...",
"aud": "your-client-id",
"iat": 1789304059,
"nbf": 1789304059,
"exp": 1789307659,
"auth_time": 1789304050,
"nonce": "what-you-sent",
"at_hash": "xQ7f...",
"name": "Ada Lovelace",
"given_name": "Ada",
"family_name": "Lovelace",
"locale": "hr",
"email": "ada@example.com",
"email_verified": true
}
| Claim | Notes |
|---|---|
sub | The member's permanent id. This is the one to store. It never changes; an email address can. |
aud | Your client id. Check it. |
nonce | Present if you sent one. Check it. |
at_hash | Binds this id_token to the access token issued with it. |
auth_time | When the member approved. Not necessarily when they signed in — we do not record that, so do not build max_age behaviour on it. |
name, given_name, family_name, locale | Only with profile. |
email, email_verified | Only with email. |
Verifying it
Fetch https://api.sporty.plus/oauth2/jwks, pick the key whose kid matches the token
header, verify RS256, then check iss, aud and exp.
curl https://api.sporty.plus/oauth2/jwks
Cache the JWKS — an hour is sensible — but re-fetch when you meet a kid you do not know,
rather than failing.
/userinfo
An id_token is a snapshot. For current values:
curl https://api.sporty.plus/oauth2/userinfo \
-H "Authorization: Bearer $ACCESS_TOKEN"
The same claims, gated the same way by scope, always including sub.
Key rotation
We rotate the signing key rarely, and when we do:
- the new public key appears in the JWKS, alongside the old one, before anything is signed with it;
- every existing access token stops working. The signing key is shared with access tokens, so a rotation ends them. Your refresh tokens survive — use them, and be ready to re-authorise if that fails.
If you ever see a valid-looking token suddenly rejected, refresh once before assuming anything is broken.