Sign In

Authentication

How to authenticate your requests using OAuth 2.0 and PKCE.

Coach Watts uses standard OAuth 2.0 with PKCE (Proof Key for Code Exchange) to secure user data. This ensures that third-party applications can securely access athlete data with explicit permission.

The Authorization Code Flow

  1. Redirect the user to the authorization endpoint.
  2. Receive the authorization code via callback.
  3. Exchange the code for an access token.

1. Request Authorization

Direct the user's browser to our authorization endpoint. You must include your client_id and the requested scopes.

GET /api/oauth/authorize
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=YOUR_REDIRECT_URI
  &scope=profile:read workout:read
  &state=RANDOM_STRING
  &code_challenge=PKCE_CHALLENGE
  &code_challenge_method=S256

2. Handle Callback

If the user approves the request, they will be redirected back to your redirect_uri with a temporary code:

YOUR_REDIRECT_URI?code=AUTHORIZATION_CODE&state=RANDOM_STRING

3. Exchange Token

Make a server-side POST request to exchange the code for an access_token and refresh_token:

POST /api/oauth/token
Content-Type: application/json

{
  "grant_type": "authorization_code",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET",
  "code": "AUTHORIZATION_CODE",
  "redirect_uri": "YOUR_REDIRECT_URI",
  "code_verifier": "PKCE_VERIFIER"
}

Example successful response:

{
  "access_token": "...token...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "...refresh...",
  "scope": "profile:read workout:read"
}

expires_in always refers to the access token lifetime.

refresh_token_expires_in may also be returned when the server is enforcing a refresh token lifetime. If present, it is the number of seconds until the refresh token expires.

Clients should always persist the latest refresh_token returned by the token endpoint. Future versions of the API may rotate refresh tokens during a successful refresh response.

Making Authenticated Requests

Once you have an access token, include it in the Authorization header as a Bearer token:

GET /api/workouts
Authorization: Bearer YOUR_ACCESS_TOKEN
Back to Index