---
title: "Build a wearable API's OAuth request"
canonical: "https://aifitnessapi.com/tools/oauth-playground"
markdown: "https://aifitnessapi.com/tools/oauth-playground.md"
type: "tool"
last_reviewed: "2026-11-05"
description: "Authorize URLs, scopes, PKCE and token curl for Oura, WHOOP, Strava, Polar, Withings, Wahoo, Dexcom, Suunto and Google Health, from their own docs."
publisher: "AIFitnessAPI — funded by KinesteX; first-party pages disclose it"
cite_as: "\"Build a wearable API's OAuth request\", AIFitnessAPI, https://aifitnessapi.com/tools/oauth-playground"
---

# 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.

- Canonical: https://aifitnessapi.com/tools/oauth-playground
- Last reviewed: 2026-11-05
- Publisher: AIFitnessAPI (https://aifitnessapi.com)
- Cite as: "Build a wearable API's OAuth request", AIFitnessAPI, https://aifitnessapi.com/tools/oauth-playground

---

*[Interactive: the authorize-URL, PKCE and curl builder, in the browser at https://aifitnessapi.com/tools/oauth-playground; not reproduced in this mirror.]*

## 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](https://cloud.ouraring.com/docs/authentication)
- **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](https://cloud.ouraring.com/docs/authentication)
- **Token URL** https://api.ouraring.com/oauth/token. Token URL. [Source](https://cloud.ouraring.com/docs/authentication)
- **Scope parameter** Space-separated. Left blank, the app requests every scope; the user can switch scopes off at consent. [Source](https://cloud.ouraring.com/docs/authentication)
- **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](https://cloud.ouraring.com/docs/authentication)
- **Client credentials** In the token request body, or as HTTP Basic. [Source](https://cloud.ouraring.com/docs/authentication)
- **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](https://cloud.ouraring.com/docs/authentication)
- **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](https://cloud.ouraring.com/docs/authentication)
- **Note** Client credentials go in the form body or as HTTP Basic (client_id as user name, client_secret as password). [Source](https://cloud.ouraring.com/docs/authentication)
- **Note** Every request to the Oura API needs a non-empty User-Agent header, so the commands below send one. [Source](https://cloud.ouraring.com/docs/authentication)
- **Note** Revoke a token with GET https://api.ouraring.com/oauth/revoke?access_token=…. [Source](https://cloud.ouraring.com/docs/authentication)

#### Scopes (9)

- `email`: Email address of the user [Source](https://cloud.ouraring.com/docs/authentication)
- `personal`: Personal information (gender, age, height, weight) [Source](https://cloud.ouraring.com/docs/authentication)
- `daily`: Daily summaries of sleep, activity and readiness [Source](https://cloud.ouraring.com/docs/authentication)
- `heartrate`: Time series heart rate for Gen 3 users [Source](https://cloud.ouraring.com/docs/authentication)
- `workout`: Summaries for auto-detected and user entered workouts [Source](https://cloud.ouraring.com/docs/authentication)
- `tag`: User entered tags [Source](https://cloud.ouraring.com/docs/authentication)
- `session`: Guided and unguided sessions in the Oura app [Source](https://cloud.ouraring.com/docs/authentication)
- `spo2`: Daily SpO2 Average recorded during sleep [Source](https://cloud.ouraring.com/docs/authentication)
- `heart_health`: Heart health data (listed in the OpenAPI document, not on the Authentication page) [Source](https://cloud.ouraring.com/v2/static/json/openapi-1.43.json)

Guide: [Oura integration guide](https://aifitnessapi.com/integrate/oura-api).

### WHOOP

- **Authorization URL** https://api.prod.whoop.com/oauth/oauth2/auth. Authorization URL (the API reference's authorizationCode flow). [Source](https://developer.whoop.com/api/)
- **Token URL** https://api.prod.whoop.com/oauth/oauth2/token. Token URL, also used for refresh. [Source](https://developer.whoop.com/api/)
- **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](https://developer.whoop.com/docs/developing/oauth/)
- **PKCE** Not documented. Not mentioned on the WHOOP OAuth page or API reference read here. [Source](https://developer.whoop.com/api/)
- **Client credentials** client_id and client_secret in the token request body. [Source](https://developer.whoop.com/api/)
- **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](https://developer.whoop.com/docs/developing/oauth/)
- **Token lifetime** Returned in expires_in, in seconds; WHOOP's sample refresh response shows 3600. [Source](https://developer.whoop.com/docs/developing/oauth/)
- **Note** If you generate state yourself it must be eight characters long; this tool generates eight. [Source](https://developer.whoop.com/docs/developing/oauth/)
- **Note** The redirect URL must be registered in the WHOOP Developer Dashboard. [Source](https://developer.whoop.com/docs/developing/oauth/)
- **Note** WHOOP's sample refresh payload sends client_id, client_secret and scope offline in the body. [Source](https://developer.whoop.com/docs/developing/oauth/)

#### Scopes (7)

- `read:recovery`: Recovery data, including score, heart rate variability, and resting heart rate [Source](https://developer.whoop.com/api/)
- `read:cycles`: Cycles data, including day Strain and average heart rate during a physiological cycle [Source](https://developer.whoop.com/api/)
- `read:workout`: Workout data, including activity Strain and average heart rate [Source](https://developer.whoop.com/api/)
- `read:sleep`: Sleep data, including performance % and duration per sleep stage [Source](https://developer.whoop.com/api/)
- `read:profile`: Profile data, including name and email [Source](https://developer.whoop.com/api/)
- `read:body_measurement`: Body measurements data, including height, weight, and max heart rate [Source](https://developer.whoop.com/api/)
- `offline`: A refresh token; without it WHOOP issues none [Source](https://developer.whoop.com/docs/developing/oauth/)

Guide: [WHOOP integration guide](https://aifitnessapi.com/integrate/whoop-api).

### Strava

- **Authorization URL** https://www.strava.com/oauth/authorize. Authorization URL for web apps. [Source](https://developers.strava.com/docs/authentication/)
- **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](https://developers.strava.com/docs/authentication/)
- **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](https://developers.strava.com/docs/authentication/)
- **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](https://developers.strava.com/docs/authentication/)
- **PKCE** Not documented. Not mentioned on Strava's Authentication page. [Source](https://developers.strava.com/docs/authentication/)
- **Client credentials** client_id and client_secret in the token request body. [Source](https://developers.strava.com/docs/authentication/)
- **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](https://developers.strava.com/docs/authentication/)
- **Token lifetime** Six hours from creation. [Source](https://developers.strava.com/docs/authentication/)
- **Note** The authorization code is short-lived and single-use. [Source](https://developers.strava.com/docs/authentication/)
- **Note** approval_prompt is auto by default; force always shows the prompt. [Source](https://developers.strava.com/docs/authentication/)
- **Note** localhost and 127.0.0.1 are allowed as redirect hosts. [Source](https://developers.strava.com/docs/authentication/)
- **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](https://developers.strava.com/docs/authentication/)

#### Scopes (7)

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

Guide: [Strava integration guide](https://aifitnessapi.com/integrate/strava-api).

### Polar AccessLink

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

#### Scopes (1)

- `accesslink.read_all`: Access to the user's data [Source](https://www.polar.com/accesslink-api/)

Guide: [Polar AccessLink integration guide](https://aifitnessapi.com/integrate/polar-api).

### Withings

- **Authorization URL** https://account.withings.com/oauth2_user/authorize2. Authorization URL. [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)
- **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](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/access-and-refresh-tokens-no-recover/)
- **Scope parameter** Comma-separated, as in Withings' example URL. [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)
- **PKCE** Not documented. Not mentioned on the Withings authorization or token pages. [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)
- **Client credentials** client_id and client_secret in the token request body. [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/access-and-refresh-tokens-no-recover/)
- **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](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/access-and-refresh-tokens-no-recover/)
- **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](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/access-and-refresh-tokens-no-recover/)
- **Note** The authorization code is valid for 30 seconds. [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)
- **Note** Refresh tokens rotate: replace the stored one every time. [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/access-and-refresh-tokens-no-recover/)
- **Note** mode=demo on the authorization URL logs in a demo user for testing. [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)
- **Note** The token request is signed: Withings' snippet adds a signature computed with the client secret. [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/access-and-refresh-tokens-no-recover/)

#### Scopes (4)

- `user.info`: Account information, linked devices, goals, and device linking; also needed to list and subscribe to user-related notifications [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)
- `user.metrics`: Health measurements, heart recordings, stethoscope data and goals; also needed for notification management [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)
- `user.activity`: Physical activity and sleep; also needed for notification management [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)
- `user.sleepevents`: Notifications for sleep events (bed in, bed out, inflate done) [Source](https://developer.withings.com/developer-guide/v3/integration-guide/public-health-data-api/get-access/oauth-authorization-url/)

Guide: [Withings integration guide](https://aifitnessapi.com/integrate/withings-api).

### Wahoo

- **Authorization URL** https://api.wahooligan.com/oauth/authorize. Authorization URL (base_url is api.wahooligan.com). [Source](https://cloud-api.wahooligan.com/)
- **Token URL** https://api.wahooligan.com/oauth/token. Token URL. Wahoo documents the parameters in the query string of the POST. [Source](https://cloud-api.wahooligan.com/)
- **Scope parameter** Space-separated, or set the app's scopes in the developer portal instead. [Source](https://cloud-api.wahooligan.com/)
- **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](https://cloud-api.wahooligan.com/)
- **Client credentials** In the token request's query string (PKCE apps send code_verifier instead of client_secret). [Source](https://cloud-api.wahooligan.com/)
- **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](https://cloud-api.wahooligan.com/)
- **Token lifetime** Two hours. [Source](https://cloud-api.wahooligan.com/)
- **Note** From January 1, 2026, 10 unrevoked access tokens per user; unrevoked tokens are deleted 60 days after creation. [Source](https://cloud-api.wahooligan.com/)
- **Note** Old tokens are revoked once an API call is made with the refreshed token. [Source](https://cloud-api.wahooligan.com/)

#### Scopes (12)

- `email`: Access your email address [Source](https://cloud-api.wahooligan.com/)
- `user_read`: Access your user data; without it the API returns 403 [Source](https://cloud-api.wahooligan.com/)
- `user_write`: Update your user data [Source](https://cloud-api.wahooligan.com/)
- `workouts_read`: Access your workout history [Source](https://cloud-api.wahooligan.com/)
- `workouts_write`: Update your workout history [Source](https://cloud-api.wahooligan.com/)
- `offline_data`: Receive data even when the app is closed; needed for webhooks [Source](https://cloud-api.wahooligan.com/)
- `power_zones_read`: Listed on Wahoo's developer portal, without a description [Source](https://developers.wahooligan.com/cloud)
- `power_zones_write`: Listed on Wahoo's developer portal, without a description [Source](https://developers.wahooligan.com/cloud)
- `plans_read`: Listed on Wahoo's developer portal, without a description [Source](https://developers.wahooligan.com/cloud)
- `plans_write`: Listed on Wahoo's developer portal, without a description [Source](https://developers.wahooligan.com/cloud)
- `routes_read`: Listed on Wahoo's developer portal, without a description [Source](https://developers.wahooligan.com/cloud)
- `routes_write`: Listed on Wahoo's developer portal, without a description [Source](https://developers.wahooligan.com/cloud)

Guide: [Wahoo integration guide](https://aifitnessapi.com/integrate/wahoo-api).

### 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](https://developer.dexcom.com/docs/dexcom/authentication)
- **Also** https://sandbox-api.dexcom.com/v3/oauth2/login. Sandbox login (no password; a drop-down of sandbox users). [Source](https://developer.dexcom.com/docs/dexcom/authentication)
- **Token URL** https://api.dexcom.com/v3/oauth2/token. Token URL (US production), form-encoded, for the exchange and refresh. [Source](https://developer.dexcom.com/docs/dexcom/authentication)
- **Scope parameter** One scope only: offline_access, always sent. [Source](https://developer.dexcom.com/docs/dexcom/authentication)
- **PKCE** Not documented. Not mentioned. Dexcom also requires tokens and the client secret to live on your server, not on a phone. [Source](https://developer.dexcom.com/docs/dexcom/authentication)
- **Client credentials** client_id and client_secret in the token request body. [Source](https://developer.dexcom.com/docs/dexcom/authentication)
- **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](https://developer.dexcom.com/docs/dexcom/authentication)
- **Token lifetime** expires_in is in seconds; Dexcom's sample response shows 7200 (two hours). [Source](https://developer.dexcom.com/docs/dexcom/authentication)
- **Note** The authorization code is single-use and expires after one minute. [Source](https://developer.dexcom.com/docs/dexcom/authentication)
- **Note** Tokens and the client secret must be stored on your servers, never on the mobile device. [Source](https://developer.dexcom.com/docs/dexcom/authentication)
- **Note** A refresh token is valid for at most one year. [Source](https://developer.dexcom.com/docs/dexcom/authentication)

Guide: [Dexcom integration guide](https://aifitnessapi.com/integrate/dexcom-api).

### Suunto

- **Authorization URL** https://cloudapi-oauth.suunto.com/oauth/authorize. Authorization URL. [Source](https://apizone.suunto.com/how-to-start)
- **Token URL** https://cloudapi-oauth.suunto.com/oauth/token. Token URL, with HTTP Basic client credentials. [Source](https://apizone.suunto.com/how-to-start)
- **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](https://apizone.suunto.com/how-to-start)
- **PKCE** Not documented. Not mentioned on Suunto's quick-start or FAQ. [Source](https://apizone.suunto.com/how-to-start)
- **Client credentials** HTTP Basic (client_id:client_secret) on the token request. [Source](https://apizone.suunto.com/how-to-start)
- **Refresh** The token response includes a refresh_token, but the pages read here document no refresh request, so this tool prints none. [Source](https://apizone.suunto.com/how-to-start)
- **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](https://apizone.suunto.com/how-to-start)
- **Note** The token endpoint uses HTTP Basic: Base64(clientid:clientsecret). [Source](https://apizone.suunto.com/faq)
- **Note** OAuth requests need no subscription key; Cloud API data calls do (Ocp-Apim-Subscription-Key). [Source](https://apizone.suunto.com/faq)

Guide: [Suunto integration guide](https://aifitnessapi.com/integrate/suunto-api).

### Google Health API

- **Authorization URL** https://accounts.google.com/o/oauth2/v2/auth. Google's OAuth 2.0 authorization endpoint (HTTPS only). [Source](https://developers.google.com/identity/protocols/oauth2/web-server)
- **Token URL** https://oauth2.googleapis.com/token. Token URL, for the exchange and refresh. [Source](https://developers.google.com/identity/protocols/oauth2/web-server)
- **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](https://developers.google.com/health/setup)
- **PKCE** Not documented. Not described on Google's web-server OAuth page, which this tool follows. [Source](https://developers.google.com/identity/protocols/oauth2/web-server)
- **Client credentials** client_id and client_secret in the token request body. [Source](https://developers.google.com/identity/protocols/oauth2/web-server)
- **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](https://developers.google.com/identity/protocols/oauth2/web-server)
- **Token lifetime** expires_in gives the remaining lifetime in seconds; Google's sample shows 3920. [Source](https://developers.google.com/identity/protocols/oauth2/web-server)
- **Note** access_type=offline is what makes Google return a refresh token. [Source](https://developers.google.com/identity/protocols/oauth2/web-server)
- **Note** Google limits refresh tokens per client/user pair and per user. [Source](https://developers.google.com/identity/protocols/oauth2/web-server)
- **Note** A new OAuth client is unverified and capped at 100 users, each added as a test user. [Source](https://developers.google.com/health/setup)

#### Scopes (18)

- `https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly`: See your Google Health activity and fitness data. [Source](https://developers.google.com/health/scopes)
- `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://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.ecg.readonly`: See your Google Health ECG data. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly`: See your Google Health health metrics and measurement data. [Source](https://developers.google.com/health/scopes)
- `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://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.irn.readonly`: See your Google Health Irregular Rhythm Notifications data. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.location.readonly`: See your Google Health GPS location recorded during an exercise. [Source](https://developers.google.com/health/scopes)
- `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://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.mindfulness.writeonly`: Add mindfulness data to Google Health, and edit or delete the data it adds. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.nutrition.readonly`: See your Google Health nutrition data. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.nutrition.writeonly`: Add nutrition data to Google Health, and edit or delete the data it adds. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.profile.readonly`: See your Google Health profile data. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.profile.writeonly`: Add profile data to Google Health, and edit or delete the data it adds. [Source](https://developers.google.com/health/scopes)
- `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://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.settings.readonly`: See your Google Health settings. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.settings.writeonly`: Add settings data to Google Health, and edit or delete the data it adds. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.sleep.readonly`: See your Google Health sleep data. [Source](https://developers.google.com/health/scopes)
- `https://www.googleapis.com/auth/googlehealth.sleep.writeonly`: Add sleep data to Google Health, and edit or delete the data it adds. [Source](https://developers.google.com/health/scopes)

Guide: [Google Health API reference](https://aifitnessapi.com/google-health-api).

## 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](https://aifitnessapi.com/integrate/garmin-api).
- **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](https://aifitnessapi.com/integrate/coros-api).
- **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](https://aifitnessapi.com/fitbit-api-shutdown).
- **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](https://aifitnessapi.com/integrate/terra-api).

## 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](https://aifitnessapi.com/webhooks) and [check a webhook’s signature](https://aifitnessapi.com/tools/webhook-verifier). More at [free tools for health-app builders](https://aifitnessapi.com/tools).

## The other 15 tools

- [Which error is this?](https://aifitnessapi.com/tools/error-diagnoser): Paste an error string and get the matching HKError.Code case in Apple's wording, plus the guide that covers it.
- [Sum it or average it?](https://aifitnessapi.com/tools/aggregation-checker): Whether Apple describes a quantity type as cumulative or discrete, with the sentence that says so.
- [Apple type, Android record](https://aifitnessapi.com/tools/identifier-translator): Two-way lookup between HealthKit identifiers and Health Connect records — verified pairs only.
- [HealthKit permission builder](https://aifitnessapi.com/tools/permission-builder): Pick the types your app touches: the Info.plist keys, the toShare/toRead Swift, and the Health Connect record names.
- [HealthKit query generator](https://aifitnessapi.com/tools/query-generator): Pick a quantity type and a window; get the HKStatisticsQuery with the aggregation option Apple's own prose states.
- [Fitness app stack generator](https://aifitnessapi.com/tools/stack-generator): Answer four questions and get the HealthKit types and APIs that survive them, with the exclusions shown.
- [Synthetic health data generator](https://aifitnessapi.com/tools/sample-data): Seeded synthetic HealthKit, Health Connect and Google Health API fixtures as JSON or CSV, with per-record UTC offsets.
- [Is this webhook real?](https://aifitnessapi.com/tools/webhook-verifier): Paste an Oura, WHOOP, Terra, Polar, Strava, Withings, Wahoo or Google Health API webhook: the vendor's documented check, run in your browser.
- [Starter scaffold generator](https://aifitnessapi.com/tools/starter-scaffold): Pick Express, Next.js or FastAPI and Oura, WHOOP, Polar, Strava or Wahoo: a tested project skeleton with OAuth routes, a token store and verified webhooks, as a .zip.
- [Pose keypoint playground](https://aifitnessapi.com/tools/keypoint-playground): Click a joint and see its index in BlazePose, COCO, OpenPose, ML Kit and Apple Vision, then copy an index map built from matching names only.
- [Exercise form rules](https://aifitnessapi.com/tools/exercise-form-rules): The joint-angle thresholds open-source exercise trackers use for squats, push-ups, lunges, planks, curls and presses, each quoted from its code; null where none says.
- [Exercise taxonomy crosswalk](https://aifitnessapi.com/tools/exercise-taxonomy-crosswalk): free-exercise-db, wger and ExerciseDB v1 categories, equipment and muscles against HealthKit and Health Connect workout types, matched by name only.
- [Health data schema converter](https://aifitnessapi.com/tools/schema-converter): Paste a HealthKit export row, Health Connect record or Google Health API data point and see it in one unified schema, each field traced to its source.
- [Fitbit to Google Health API map](https://aifitnessapi.com/tools/fitbit-to-google-health): Search every Fitbit Web API endpoint and see its Google Health API data type, method and scopes from Google's migration tables, or that none is listed.
- [Deprecation scanner](https://aifitnessapi.com/tools/deprecation-scanner): Paste code or a manifest and find Fitbit Web API, Google Fit and other retired fitness API calls, each with its replacement. Also a GitHub Action.

The planners and demos — the API picker, the cost planner, the side-by-side comparison, the day-boundary demo, the pose-model benchmark, the Bluetooth heart-rate lab and the step lab — are listed with these on [free tools for health-app builders](https://aifitnessapi.com/tools).

## Next step

Turning this into a choice of API:

- [Integration Guides](https://aifitnessapi.com/integrate)
- [The Best Wearable Fitness & Health-Data APIs (2026)](https://aifitnessapi.com/fitness-apis/wearable-data-apis)
- [The Best Wearable Health-Data Aggregator APIs (2026)](https://aifitnessapi.com/fitness-apis/health-data-aggregator-apis)
