Skip to content
AF
Free Tool

Build a wearable API's OAuth request

Pick a vendor and this shows its documented authorization URL, token URL, scopes with what each grants, PKCE support, refresh-token behavior and token lifetime, each with a link to the vendor page it came from. Enter your client_id and redirect_uri, tick scopes, and it builds the authorize URL, generates a PKCE verifier and challenge in your browser, and prints the token-exchange and refresh curl commands. It covers Oura, WHOOP, Strava, Polar AccessLink, Withings, Wahoo, Dexcom, Suunto and Google Health API, read from their own documentation on 2026-11-05; only Oura and Wahoo document PKCE. The page sends no request and never asks for your client secret.

This page sends no request. It prints a URL for you to open and commands for you to run. It never asks for your client secret: the commands read it from $CLIENT_SECRET in your own shell, and the code and refresh token from $AUTH_CODE and $REFRESH_TOKEN. Nothing you type is stored.

Vendor
Scopes (joined with spaces)

Recommended. code_challenge_method must be S256; the verifier is 43 to 128 characters, hashed with SHA-256 and base64url-encoded without padding.

1. Authorization URL (open it in a browser)

https://cloud.ouraring.com/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback

2. Exchange the code for tokens

export AUTH_CODE='the code from the redirect'
read -rs CLIENT_SECRET && export CLIENT_SECRET   # paste it; not echoed or saved
curl -X POST 'https://api.ouraring.com/oauth/token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'User-Agent: YourApp/1.0' \
  --data-urlencode 'grant_type=authorization_code' \
  --data-urlencode "code=$AUTH_CODE" \
  --data-urlencode 'redirect_uri=http://localhost:3000/callback' \
  --data-urlencode 'client_id=YOUR_CLIENT_ID' \
  --data-urlencode "client_secret=$CLIENT_SECRET"

3. Refresh

curl -X POST 'https://api.ouraring.com/oauth/token' \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -H 'User-Agent: YourApp/1.0' \
  --data-urlencode 'grant_type=refresh_token' \
  --data-urlencode "refresh_token=$REFRESH_TOKEN" \
  --data-urlencode 'client_id=YOUR_CLIENT_ID' \
  --data-urlencode "client_secret=$CLIENT_SECRET"

Token lifetime: Returned in expires_in. The page states no fixed number for the server-side flow; the client-side flow's token is currently 30 days and has no refresh token. Source.

Each vendor’s OAuth facts, with sources

The playground builds from exactly these rows. Each was read from the vendor’s own page on 2026-11-05; where a page leaves something out, the row says so instead of filling it in.

Oura

Authorization URL
https://cloud.ouraring.com/oauth/authorize. Authorization URL. Source
Also
https://developer.ouraring.com/authorize. Universal-link authorization URL for new OAuth clients; on a phone with the Oura app it can open the consent page in the app. Source
Token URL
https://api.ouraring.com/oauth/token. Token URL. Source
Scope parameter
Space-separated. Left blank, the app requests every scope; the user can switch scopes off at consent. Source
PKCE
Recommended. Recommended. code_challenge_method must be S256; the verifier is 43 to 128 characters, hashed with SHA-256 and base64url-encoded without padding. Source
Client credentials
In the token request body, or as HTTP Basic. Source
Refresh
grant_type=refresh_token at the token URL returns a new access token and a new refresh token; each refresh token works once. Source
Token lifetime
Returned in expires_in. The page states no fixed number for the server-side flow; the client-side flow's token is currently 30 days and has no refresh token. Source
Note
Client credentials go in the form body or as HTTP Basic (client_id as user name, client_secret as password). Source
Note
Every request to the Oura API needs a non-empty User-Agent header, so the commands below send one. Source
Note
Revoke a token with GET https://api.ouraring.com/oauth/revoke?access_token=…. Source

Scopes (9)

  • email: Email address of the user Source
  • personal: Personal information (gender, age, height, weight) Source
  • daily: Daily summaries of sleep, activity and readiness Source
  • heartrate: Time series heart rate for Gen 3 users Source
  • workout: Summaries for auto-detected and user entered workouts Source
  • tag: User entered tags Source
  • session: Guided and unguided sessions in the Oura app Source
  • spo2: Daily SpO2 Average recorded during sleep Source
  • heart_health: Heart health data (listed in the OpenAPI document, not on the Authentication page) Source

Guide: Oura integration guide.

WHOOP

Authorization URL
https://api.prod.whoop.com/oauth/oauth2/auth. Authorization URL (the API reference's authorizationCode flow). Source
Token URL
https://api.prod.whoop.com/oauth/oauth2/token. Token URL, also used for refresh. Source
Scope parameter
The pages read here do not state the separator for the authorize request. WHOOP's sample token response lists granted scopes separated by spaces, so this tool joins them with spaces. Source
PKCE
Not documented. Not mentioned on the WHOOP OAuth page or API reference read here. Source
Client credentials
client_id and client_secret in the token request body. Source
Refresh
Using the refresh token invalidates the existing access tokens; the refresh token in the response replaces the old one, and of two simultaneous refreshes only the first succeeds. Source
Token lifetime
Returned in expires_in, in seconds; WHOOP's sample refresh response shows 3600. Source
Note
If you generate state yourself it must be eight characters long; this tool generates eight. Source
Note
The redirect URL must be registered in the WHOOP Developer Dashboard. Source
Note
WHOOP's sample refresh payload sends client_id, client_secret and scope offline in the body. Source

Scopes (7)

  • read:recovery: Recovery data, including score, heart rate variability, and resting heart rate Source
  • read:cycles: Cycles data, including day Strain and average heart rate during a physiological cycle Source
  • read:workout: Workout data, including activity Strain and average heart rate Source
  • read:sleep: Sleep data, including performance % and duration per sleep stage Source
  • read:profile: Profile data, including name and email Source
  • read:body_measurement: Body measurements data, including height, weight, and max heart rate Source
  • offline: A refresh token; without it WHOOP issues none Source

Guide: WHOOP integration guide.

Strava

Authorization URL
https://www.strava.com/oauth/authorize. Authorization URL for web apps. Source
Also
https://www.strava.com/oauth/mobile/authorize. Mobile apps (Android intent or iOS) use the mobile authorize endpoint; the Strava app opens if installed. Source
Token URL
https://www.strava.com/oauth/token. Token URL, with the client ID and secret, for both the code exchange and refresh. (Strava's own curl samples post to https://www.strava.com/api/v3/oauth/token.) Source
Scope parameter
Required. Comma- or space-delimited; this tool uses commas. The athlete can untick any requested scope, so check the scope the redirect returns. Source
PKCE
Not documented. Not mentioned on Strava's Authentication page. Source
Client credentials
client_id and client_secret in the token request body. Source
Refresh
Refresh with grant_type=refresh_token. If the current access token expires in more than an hour, the same one comes back; once a new refresh token is returned the old one stops working. Source
Token lifetime
Six hours from creation. Source
Note
The authorization code is short-lived and single-use. Source
Note
approval_prompt is auto by default; force always shows the prompt. Source
Note
localhost and 127.0.0.1 are allowed as redirect hosts. Source
Note
Deauthorize with POST https://www.strava.com/oauth/revoke (HTTP Basic, the token in the body), the only supported endpoint from June 1, 2027. Source

Scopes (7)

  • read: Public segments, public routes, public profile data, public posts, public events, club feeds, and leaderboards Source
  • read_all: Private routes, private segments, and private events for the user Source
  • profile:read_all: All profile information, even if the user set profile visibility to Followers or Only You Source
  • profile:write: Update the user's weight and Functional Threshold Power (FTP), and star or unstar segments Source
  • activity:read: Activities visible to Everyone and Followers, excluding privacy zone data; required for activity webhooks Source
  • activity:read_all: As activity:read, plus privacy zone data and Only You activities Source
  • activity:write: Create manual activities and uploads, and edit activities visible to the app Source

Guide: Strava integration guide.

Polar AccessLink

Authorization URL
https://flow.polar.com/oauth2/authorization. Authorization endpoint in Polar Flow. Source
Token URL
https://polarremote.com/v2/oauth2/token. Token endpoint in Polar Remote, authenticated with HTTP Basic. Source
Scope parameter
Optional: without it the user is asked to grant every scope linked to your client. Source
PKCE
Not documented. Not mentioned on the AccessLink reference. Source
Client credentials
HTTP Basic (client_id:client_secret) on the token request. Source
Refresh
No refresh flow is documented: the token response lists no refresh_token, and the reference says access tokens do not expire unless revoked. Source
Token lifetime
expires_in is in seconds; Polar's example, 31535999, is about one year. Source
Note
The code expires in 10 minutes and must be used once; reuse is denied and deletes every issued token. Source
Note
redirect_uri goes to the token endpoint only if it was sent to the authorization endpoint. Source
Note
After the exchange, register the user before reading their data. Source
Note
The token request sends Content-Type application/x-www-form-urlencoded and Accept application/json;charset=UTF-8. Source

Scopes (1)

  • accesslink.read_all: Access to the user's data Source

Guide: Polar AccessLink integration guide.

Withings

Authorization URL
https://account.withings.com/oauth2_user/authorize2. Authorization URL. Source
Token URL
https://wbsapi.withings.net/v2/oauth2. Token exchange: POST action=requesttoken to https://wbsapi.withings.net/v2/oauth2, with a nonce and a signature computed from your client secret (Withings' “Request Signature” page). Source
Scope parameter
Comma-separated, as in Withings' example URL. Source
PKCE
Not documented. Not mentioned on the Withings authorization or token pages. Source
Client credentials
client_id and client_secret in the token request body. Source
Refresh
Withings says to call the same requesttoken service with the refresh token and always keep the new refresh token, but its snippet shows only the code exchange, so this tool prints no refresh command rather than guess its parameters. Source
Token lifetime
Access token 3 hours; refresh token 1 year; the old refresh token lasts 8 hours after a new one is issued, or until the new access token is used. Source
Note
The authorization code is valid for 30 seconds. Source
Note
Refresh tokens rotate: replace the stored one every time. Source
Note
mode=demo on the authorization URL logs in a demo user for testing. Source
Note
The token request is signed: Withings' snippet adds a signature computed with the client secret. Source

Scopes (4)

  • user.info: Account information, linked devices, goals, and device linking; also needed to list and subscribe to user-related notifications Source
  • user.metrics: Health measurements, heart recordings, stethoscope data and goals; also needed for notification management Source
  • user.activity: Physical activity and sleep; also needed for notification management Source
  • user.sleepevents: Notifications for sleep events (bed in, bed out, inflate done) Source

Guide: Withings integration guide.

Wahoo

Authorization URL
https://api.wahooligan.com/oauth/authorize. Authorization URL (base_url is api.wahooligan.com). Source
Token URL
https://api.wahooligan.com/oauth/token. Token URL. Wahoo documents the parameters in the query string of the POST. Source
Scope parameter
Space-separated, or set the app's scopes in the developer portal instead. Source
PKCE
Supported. Supported once the app's Confidential field is set to No; S256 or plain. With PKCE the token and refresh calls send code_verifier instead of client_secret. Source
Client credentials
In the token request's query string (PKCE apps send code_verifier instead of client_secret). Source
Refresh
Refresh returns a new access and refresh token. The previous pair is revoked only when an API call uses the new access token, so refresh just before a request: apps are limited to 10 unrevoked tokens per user. Source
Token lifetime
Two hours. Source
Note
From January 1, 2026, 10 unrevoked access tokens per user; unrevoked tokens are deleted 60 days after creation. Source
Note
Old tokens are revoked once an API call is made with the refreshed token. Source

Scopes (12)

  • email: Access your email address Source
  • user_read: Access your user data; without it the API returns 403 Source
  • user_write: Update your user data Source
  • workouts_read: Access your workout history Source
  • workouts_write: Update your workout history Source
  • offline_data: Receive data even when the app is closed; needed for webhooks Source
  • power_zones_read: Listed on Wahoo's developer portal, without a description Source
  • power_zones_write: Listed on Wahoo's developer portal, without a description Source
  • plans_read: Listed on Wahoo's developer portal, without a description Source
  • plans_write: Listed on Wahoo's developer portal, without a description Source
  • routes_read: Listed on Wahoo's developer portal, without a description Source
  • routes_write: Listed on Wahoo's developer portal, without a description Source

Guide: Wahoo integration guide.

Dexcom

Authorization URL
https://api.dexcom.com/v3/oauth2/login. Login URL for the US production environment; the sandbox replaces the base URL with https://sandbox-api.dexcom.com. Source
Also
https://sandbox-api.dexcom.com/v3/oauth2/login. Sandbox login (no password; a drop-down of sandbox users). Source
Token URL
https://api.dexcom.com/v3/oauth2/token. Token URL (US production), form-encoded, for the exchange and refresh. Source
Scope parameter
One scope only: offline_access, always sent. Source
PKCE
Not documented. Not mentioned. Dexcom also requires tokens and the client secret to live on your server, not on a phone. Source
Client credentials
client_id and client_secret in the token request body. Source
Refresh
Each refresh token works once and is replaced by a new one; each lasts at most a year. A 400 on refresh means it is no longer valid: send the user through login again. Source
Token lifetime
expires_in is in seconds; Dexcom's sample response shows 7200 (two hours). Source
Note
The authorization code is single-use and expires after one minute. Source
Note
Tokens and the client secret must be stored on your servers, never on the mobile device. Source
Note
A refresh token is valid for at most one year. Source

Guide: Dexcom integration guide.

Suunto

Authorization URL
https://cloudapi-oauth.suunto.com/oauth/authorize. Authorization URL. Source
Token URL
https://cloudapi-oauth.suunto.com/oauth/token. Token URL, with HTTP Basic client credentials. Source
Scope parameter
No scope list is published on the pages read here and Suunto's authorization URL carries no scope parameter; its sample token response shows the scope workout. Source
PKCE
Not documented. Not mentioned on Suunto's quick-start or FAQ. Source
Client credentials
HTTP Basic (client_id:client_secret) on the token request. Source
Refresh
The token response includes a refresh_token, but the pages read here document no refresh request, so this tool prints none. Source
Token lifetime
Suunto's sample response shows expires_in 86400 (24 hours). The access token is a JWT whose user claim is the Suunto app user name. Source
Note
The token endpoint uses HTTP Basic: Base64(clientid:clientsecret). Source
Note
OAuth requests need no subscription key; Cloud API data calls do (Ocp-Apim-Subscription-Key). Source

Guide: Suunto integration guide.

Google Health API

Authorization URL
https://accounts.google.com/o/oauth2/v2/auth. Google's OAuth 2.0 authorization endpoint (HTTPS only). Source
Token URL
https://oauth2.googleapis.com/token. Token URL, for the exchange and refresh. Source
Scope parameter
Space-separated full scope URLs. The Google Health API's scopes are listed with Google's consent wording; add prompt=consent when you change them. Source
PKCE
Not documented. Not described on Google's web-server OAuth page, which this tool follows. Source
Client credentials
client_id and client_secret in the token request body. Source
Refresh
access_type=offline gets a refresh token on the first exchange only. Refresh tokens last until revoked or expired, and Google caps how many it issues per client and user. Source
Token lifetime
expires_in gives the remaining lifetime in seconds; Google's sample shows 3920. Source
Note
access_type=offline is what makes Google return a refresh token. Source
Note
Google limits refresh tokens per client/user pair and per user. Source
Note
A new OAuth client is unverified and capped at 100 users, each added as a test user. Source

Scopes (18)

  • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly: See your Google Health activity and fitness data. Source
  • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly: Add activity and fitness data to Google Health, and edit or delete the data it adds. Source
  • https://www.googleapis.com/auth/googlehealth.ecg.readonly: See your Google Health ECG data. Source
  • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly: See your Google Health health metrics and measurement data. Source
  • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.writeonly: Add health metric and measurements data to Google Health, and edit or delete the data it adds. Source
  • https://www.googleapis.com/auth/googlehealth.irn.readonly: See your Google Health Irregular Rhythm Notifications data. Source
  • https://www.googleapis.com/auth/googlehealth.location.readonly: See your Google Health GPS location recorded during an exercise. Source
  • https://www.googleapis.com/auth/googlehealth.logged_symptoms.writeonly: Add logged symptoms data to Google Health, and edit or delete the data it adds. Source
  • https://www.googleapis.com/auth/googlehealth.mindfulness.writeonly: Add mindfulness data to Google Health, and edit or delete the data it adds. Source
  • https://www.googleapis.com/auth/googlehealth.nutrition.readonly: See your Google Health nutrition data. Source
  • https://www.googleapis.com/auth/googlehealth.nutrition.writeonly: Add nutrition data to Google Health, and edit or delete the data it adds. Source
  • https://www.googleapis.com/auth/googlehealth.profile.readonly: See your Google Health profile data. Source
  • https://www.googleapis.com/auth/googlehealth.profile.writeonly: Add profile data to Google Health, and edit or delete the data it adds. Source
  • https://www.googleapis.com/auth/googlehealth.reproductive_health.writeonly: Add reproductive health data to Google Health, and edit or delete the data it adds. Source
  • https://www.googleapis.com/auth/googlehealth.settings.readonly: See your Google Health settings. Source
  • https://www.googleapis.com/auth/googlehealth.settings.writeonly: Add settings data to Google Health, and edit or delete the data it adds. Source
  • https://www.googleapis.com/auth/googlehealth.sleep.readonly: See your Google Health sleep data. Source
  • https://www.googleapis.com/auth/googlehealth.sleep.writeonly: Add sleep data to Google Health, and edit or delete the data it adds. Source

Guide: Google Health API reference.

Not included, and why

  • Garmin. Garmin's program FAQ says its APIs use OAuth 2.0, but no public page this tool could read states the authorization and token endpoints or the scopes. Garmin guide.
  • COROS. COROS's help center says it uses standard OAuth 2.0 and that partners apply by email; no public page this tool could read states the URLs or scopes. COROS guide.
  • Fitbit Web API. Google's setup page, read 2026-11-05, says the legacy Fitbit Web API and Fitbit OAuth endpoints are turned off on November 2, 2026. Their successor, the Google Health API, is listed above. Fitbit Web API retirement.
  • Terra. Terra connects users through its own widget session (see the Terra guide). This tool covers vendors whose OAuth endpoints your app calls itself. Terra guide.
How this works

Nothing here makes a network request. The authorize URL is text for you to open; the commands are text for you to run. The PKCE verifier is 48 random bytes from your browser's crypto.getRandomValues, base64url-encoded to 64 characters, and the S256 challenge is the base64url SHA-256 of it without padding, the construction Oura's Authentication page spells out. The code is checked against the verifier and challenge pair printed on that page.

The commands read your client secret from $CLIENT_SECRET and the code from $AUTH_CODE, so neither is typed into this page. Where a vendor documents the token request but not the refresh call (Withings, Suunto), or documents no refresh at all (Polar), no refresh command is printed.

Where a page does not state something, the row says not documented. PKCE marked not documented means the vendor's page does not mention it, not that the vendor rejects it.

A free tool from AIFitnessAPI. Once tokens flow, the next thing a wearable sends you is a webhook: see the webhook payload library and check a webhook’s signature. More at free tools for health-app builders.

Next step

Turning this into a choice of API: