The Google Health API is a new API built from the ground up allowing developers to query Fitbit user data. This is not just an update, it's a strategic move to ensure your apps are secure, reliable, and ready for future advancements in health technology. The API supports a new console for registering your apps, Google OAuth 2.0 support, new data types, new endpoint schema, and new response format.
The guide is designed to help developers migrate their existing Fitbit Web API apps to the new Google Health API.
Why should you migrate?
The benefits of using the Google Health API are:
- Enhanced Security: Compliance with Google's security best practices, aligning with Google's security, privacy, and identity standards.
- Consistency: Eliminates legacy inconsistencies in data formats, time zones, measurement units, and error handling for a more intuitive developer experience.
- Scalability & Future-Proofing: Designed to scale to meet future demands and supports modern protocols like gRPC.
App Registration
All Google Health API apps must be registered using the Google Cloud console, which serves as a central hub for managing all of your Google apps.
For instructions on how to register your app, follow the steps at Getting Started. Here are the differences you'll notice when registering your apps.
| Fitbit Web API | Google Health API | |
| Public link(s) | https://dev.fitbit.com/apps | https://console.cloud.google.com |
| Adding a new app | Press Register a new app |
|
| Basic Info | Fields to complete:
|
Fields to complete:
|
| Application Types | A developer is required to select:
|
|
| Client ID | Registered when the application settings are saved | Registered separately |
| Access Type | Read and Write access is controlled at the app level | Read and Write access is controlled at the scope level |
| Additional URLs |
|
|
OAuth Implementation
Google Health API apps only support the Google OAuth2 Client libraries. Client libraries are available for popular frameworks, which makes implementing OAuth 2.0 simpler. The differences between the Google OAuth2 libraries and the open source OAuth2 libraries are as follows:
| Fitbit Web API | Google Health API | |
| OAuth2 library support | Open Source | Google OAuth2 Client libraries |
| Functionality | Inconsistent across platforms | Consistent across platforms |
| Authorization URL | https://www.fitbit.com/oauth2/authorize | https://accounts.google.com/o/oauth2/v2/auth |
| Token URL | https://api.fitbit.com/oauth2/token | https://oauth2.googleapis.com/token |
| Access Token Lifetime | 8 hours | 1 hour |
| Access Token Size | 1024 bytes | 2048 bytes |
| Refresh Token | Refresh tokens are generated when using the Authorization Code Grant Flow. Only 1 refresh token can be generated for a user. Tokens never expire and can only be used once. | To generate a refresh token, the authorization string must contain the query parameter "access_type=offline". Multiple refresh tokens can be created for a single user. Refresh tokens can be timed-based. They will expire if they have not been used in 6 months, the user granted time- based access, or the app is in "Testing" mode. See Refresh token expiration for more details. |
| Token Response | JSON response contains:
|
JSON response contains:
To obtain the user id, use the users.getIdentity endpoint. |
User Re-authentication (Mandatory Re-consent)
Fitbit users must re-consent to your new integration, because your app is using a different OAuth library. It is not possible for access tokens and refresh tokens to be transferred to the Google Health API and work.
Scopes
You must update your authorization request to use the Google Health API scopes. The scopes define whether your app supports read or write operations. Don't use scopes that are not needed for your app. You can always add more scopes later if the design of your app changes.
The Google Health API scopes are a HTTP URL beginning with https://www.googleapis.com/auth/googlehealth.{scope}. For example, https://www.googleapis.com/auth/googlehealth.activity_and_fitness.
Scope mappings
Here is how the Fitbit Web API scopes map to the Google Health API scopes:
| Fitbit Web API Scopes | Google Health API Scopes |
|---|---|
| activity | .activity_and_fitness .activity_and_fitness.readonly |
| cardio_fitness | .activity_and_fitness .activity_and_fitness.readonly |
| heartrate | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
| location | .location.readonly |
| nutrition | .nutrition .nutrition.readonly |
| oxygen_saturation | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
| profile | .profile .profile.readonly |
| respiratory_rate | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
| settings | .settings .settings.readonly |
| sleep | .sleep .sleep.readonly |
| temperature | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
| weight | .health_metrics_and_measurements .health_metrics_and_measurements.readonly |
Data types
Here is a list of Google Health API data types and how they map to the Fitbit Web API.
| Fitbit Web API Data Type | Google Health API Data Type Endpoint ID |
|---|---|
| Active Zone Minutes | Active Zone Minutesactive-zone-minutes
|
| Contains changes to the user's activity levels | Activity Levelactivity-level
|
| Elevation | Altitudealtitude
|
| Body fat | Body Fatbody-fat
|
caloriesOut in each heart rate zone |
Calories In Heart Rate Zonecalories-in-heart-rate-zone
|
| HRV summary | Daily Heart Rate Variabilitydaily-heart-rate-variability
|
| SpO2 summary | Daily Oxygen Saturationdaily-oxygen-saturation
|
| Resting heart rate | Daily Resting Heart Ratedaily-resting-heart-rate
|
| Skin temperature | Daily Sleep Temperature Derivationsdaily-sleep-temperature-derivations
|
| Distance | Distancedistance
|
| Recorded activity | Exerciseexercise
|
| Floors | Floorsfloors
|
| Heart Rate | Heart Rateheart-rate
|
| HRV Intraday | Heart Rate Variabilityheart-rate-variability
|
| SpO2 Intraday | Oxygen Saturationoxygen-saturation
|
| VO2 Max value when the user runs | Run VO2 Maxrun-vo2-max
|
| Activity time series minutes sedentary | Sedentary Periodsedentary-period
|
| Sleep | Sleepsleep
|
| Steps | Stepssteps
|
Activity caloriesOut |
Total Caloriestotal-calories
|
| VO2 Max value | VO2 Maxvo2-max
|
| Weight | Weightweight
|
Endpoints
The REST endpoints adopt a consistent syntax for all data types.
- Service Endpoint: The base HTTP URL changes to https://health.googleapis.com.
- Endpoint Syntax: The Google Health API supports a limited number of endpoints, which can be used by most of the supported data types. This provides consistent syntax for all data types and makes the endpoints easier to use.
- User Identifier: Either the user ID or me should be specified in the endpoint syntax. When using me, the user ID is inferred from the access token.
Example: Here's an example of the GET Profile endpoint called using the Google Health API
GET https://health.googleapis.com/v4/users/me/profile
Endpoint mappings
See Data Type Availability table for a list of data types available and the API methods they support.
| Fitbit Web API Endpoint Type | Google Health API |
| GET (Log | Summary | Daily Summary) where you are requesting a single day of data | dailyRollup method with windowSize = 1 day |
| GET (Intraday) where you are requesting granular data | list method |
| GET (Time Series) by Date or Interval | rollUp or dailyRollUp method including a date range |
| GET (Log List) | list method |
| CREATE & UPDATE Logs | patch method |
| DELETE Logs | batchDelete method |
| GET Profile | users.getProfile returns the user's specific information
users.getSettings returns the user's units and timezones |
| UPDATE Profile | users.updateProfile modifies the user's specific information
users.updateSettings modifies the user's units and timezones |
| Get User ID | users.getIdentity returns the user's Fitbit legacy and Google user ID. |
Migrate your Users
Migrating from the Fitbit Web API to the Google Health API is more than a technical update. Your users must re-consent to your new integration due to changing the OAuth library. It is not possible for access tokens and refresh tokens to be transferred to the Google Health API and work. To assist with user retention during your migration, here are some technical and strategic suggestions for a successful migration.
The Dual-Library Strategy
Because Fitbit Web API and the Google Health API use different OAuth2 libraries, you must manage a "bridging" period where both libraries exist in your codebase.
Parallel Authorization Management
- Encapsulate Clients: Create an abstraction layer or interface for your "Health Service." This allows the rest of your app to request data without knowing which library (Fitbit OAuth versus Google OAuth) is active for that specific user.
- Database Schema Update: Update your user table to include a
oauth_typeflag. For example, usefitbitfor Fitbit OAuth andgooglefor Google OAuth.- New Users: Default to Google Health API and the Google OAuth
library. Set
oauth_typetogoogle. - Existing Users: Keep on Fitbit Web API until they complete
the re-consent flow. Set
oauth_typetofitbit.
- New Users: Default to Google Health API and the Google OAuth
library. Set
The "Step-Up" Re-consent Flow
Instead of forcing a logout, use an incremental authorization approach:
- Detect Fitbit Open Source Token: When a Fitbit Web API user opens the app, trigger a "Service Update" notification.
- Launch Google OAuth Flow: When the user clicks "Update," initiate the Google OAuth2 library flow.
- Replace & Revoke: Once the Google OAuth token is successfully
received, save it to the user profile, update the
oauth_typefromfitbittogoogle, and (if possible) programmatically revoke the oldfitbittoken to keep the user's security profile clean.
Maximize User Retention
Re-consent is the "danger zone" for churn. To prevent users from abandoning the app, follow these UX best practices:
The "Value-First" Communication
Don't lead with "We updated our API." Lead with the benefits of the new Google-backed system:
- Enhanced Security: Mention Google's industry-leading account protection and 2FA.
- Reliability: Faster sync times and more stable data connections.
- Feature Gating: Gently inform users that new features and data types require the update.
Smart Timing
- Don't Interrupt High-Value Tasks: Never trigger the re-consent screen while a user is in the middle of a workout or logging food.
- The "Nudge" Phase: For the first 30 days, use a dismissible banner.
- The "Hard Cutoff" Phase: Only make the re-consent mandatory after several weeks of warnings, coinciding with the official Fitbit Web API deprecation deadlines.
Migration Flow Comparison
A clear visual distinction between the old and new flows helps developers understand where the logic forks.
| Feature | Fitbit Web API (Legacy) | Google Health API (Google-Identity) |
| Auth Library | Standard Open Source | Google Identity Services (GIS) / Google Auth |
| User Accounts | Fitbit Legacy Credentials | Google Account |
| Token Type | Fitbit-specific Access / Refresh | Google-issued Access/Refresh tokens |
| Scope Management | Broad permissions | Granular / Incremental permissions |
Handle the Account Migration Nuance
According to Fitbit's documentation, users migrating their account to Google generally don't lose their 3rd-party connections immediately, but changing the API version is a developer-side requirement.
- Check Token Validity: Use a backgroundworker to check if Fitbit tokens are failing with "Unauthorized" errors. This may indicate the user has migrated their account but your app hasn't caught up.
- Graceful Failures: If a Fitbit OAuth call fails, redirect the user to a custom "Reconnect Fitbit" page that specifically uses the new Google OAuth flow.
Code example
To migrate from the legacy Fitbit Web API to Google Health API, you will move from general OAuth2 libraries to the Google Auth Library. Following is an architectural suggestion and a pseudo-code implementation written in Javascript to handle this "Dual-Library" state.
1. The "Middleware Switch"
Since you cannot migrate all users at once, your backend needs to determine
which library to use based on the user's current apiVersion stored in your
database.
Implementation
const { OAuth2Client } = require('google-auth-library');
const FitbitV1Strategy = require('fitbit-oauth2-library').Strategy;
// 1. Initialize the Google Health API Client
const GHAClient = new OAuth2Client(
process.env.GOOGLE_CLIENT_ID,
process.env.GOOGLE_CLIENT_SECRET,
process.env.REDIRECT_URI
);
// 2. Create a Unified Fetcher
async function fetchSteps(user) {
if (user.apiVersion === 4) {
// ---- GOOGLE OAUTH LIBRARY LOGIC ----
GHAClient.setCredentials({ refresh_token: user.refreshToken });
const url = 'GET https://health.googleapis.com/v4/users/me/dataTypes/steps/dataPoints';
const res = await GHAClient.request({ url });
return res.data;
} else {
// ---- FITBIT WEB API LEGACY LOGIC ----
// Use your existing Fitbit open-source library logic here
return callLegacyV1Api(user.accessToken);
}
}
2. Migrate the UX flow
To maximize retention, use an "Interrupt-and-Upgrade" pattern. This ensures the user isn't forced to re-login until they are already engaged with the app.
Redirect logic
When a Fitbit Web API user hits a specific feature, trigger the migration:
app.get('/dashboard', async (req, res) => {
const user = await db.users.find(req.user.id);
if (user.apiVersion === 1) {
// Render a "soft" migration page explaining the Google transition
return res.render('migrate-to-google', {
title: "Keep your data syncing",
message: "Fitbit is moving to Google accounts. Re-connect now to stay updated."
});
}
const data = await fetchSteps(user);
res.render('dashboard', { data });
});
3. Key Technical Transitions
When writing your JavaScript migration scripts, keep these differences in mind:
| Feature | Fitbit Web API (Legacy) | Google Health API (Google-Identity) |
| Token Endpoint | https://api.fitbit.com/oauth2/token | https://oauth2.googleapis.com/token |
| Auth Library | Standard Open Source | Google Auth |
| Scope | activity | https://www.googleapis.com/auth/googlehealth.activity_and_fitness |
| User ID | Fitbit Encoded ID returned in /oauth2/token response | User ID returned from users.getIdentity endpoint |
4. Retention checklist
- Session Persistence: Do not clear the user's old Fitbit Web API session until the Google Health API access_token is successfully verified and saved to your database.
- Auto-Revoke: Once the Google Health API migration is complete, use a POST request to the legacy Fitbit revoke endpoint: https://api.fitbit.com/oauth2/revoke. This ensures the user doesn't see "duplicate" app permissions in their Fitbit settings.
- Error Handling: If a Fitbit call returns a 401 Unauthorized, automatically redirect to the Google OAuth flow instead of showing an error message.