Migration guide

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
  1. Create a Google Cloud Project
  2. Enable Google Health API
Basic Info Fields to complete:
  • Application Name
  • Description
  • Application Website URL
  • Organization
  • Organization Website URL
  • Terms of Service URL
  • Privacy Policy URL
Fields to complete:
  • Application name
  • Support email
  • Audience (internal or external)
  • Contact email
  • Logo icon
  • Application website URL
  • Privacy policy URL
  • Terms of Service URL
  • Authorized Domain
Application Types A developer is required to select:
  • Server
  • Client
  • Personal
  • Web application
  • Android
  • Chrome Extension
  • iOS
  • TVs
  • Desktop app
  • Universal Windows platform
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
  • Redirect URL: Site where users are redirected to after the authorize the scopes
  • Authorized JavaScript Origins: HTTP origin that hosts the web application
  • Redirect URL: Site where users are redirected to after the authorize the scopes

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:
  • access token
  • access token expiration
  • scopes
  • token type
  • refresh token
  • user ID
JSON response contains:
  • access token
  • access token expiration
  • scopes
  • token type
  • refresh token

To obtain the user id, use the users.getIdentity endpoint.

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:

Table: Fitbit Web API to Google Health API scope mappings
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.

Table: Fitbit Web API to Google Health API data type mappings
Fitbit Web API Data Type Google Health API Data Type
  Endpoint ID
Active Zone Minutes Active Zone Minutes
  active-zone-minutes
Contains changes to the user's activity levels Activity Level
  activity-level
Elevation Altitude
  altitude
Body fat Body Fat
  body-fat
caloriesOut in each heart rate zone Calories In Heart Rate Zone
  calories-in-heart-rate-zone
HRV summary Daily Heart Rate Variability
  daily-heart-rate-variability
SpO2 summary Daily Oxygen Saturation
  daily-oxygen-saturation
Resting heart rate Daily Resting Heart Rate
  daily-resting-heart-rate
Skin temperature Daily Sleep Temperature Derivations
  daily-sleep-temperature-derivations
Distance Distance
  distance
Recorded activity Exercise
  exercise
Floors Floors
  floors
Heart Rate Heart Rate
  heart-rate
HRV Intraday Heart Rate Variability
  heart-rate-variability
SpO2 Intraday Oxygen Saturation
  oxygen-saturation
VO2 Max value when the user runs Run VO2 Max
  run-vo2-max
Activity time series minutes sedentary Sedentary Period
  sedentary-period
Sleep Sleep
  sleep
Steps Steps
  steps
Activity caloriesOut Total Calories
  total-calories
VO2 Max value VO2 Max
  vo2-max
Weight Weight
  weight

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_type flag. For example, use fitbit for Fitbit OAuth and google for Google OAuth.
    • New Users: Default to Google Health API and the Google OAuth library. Set oauth_type to google.
    • Existing Users: Keep on Fitbit Web API until they complete the re-consent flow. Set oauth_type to fitbit.

The "Step-Up" Re-consent Flow

Instead of forcing a logout, use an incremental authorization approach:

  1. Detect Fitbit Open Source Token: When a Fitbit Web API user opens the app, trigger a "Service Update" notification.
  2. Launch Google OAuth Flow: When the user clicks "Update," initiate the Google OAuth2 library flow.
  3. Replace & Revoke: Once the Google OAuth token is successfully received, save it to the user profile, update the oauth_type from fitbit to google, and (if possible) programmatically revoke the old fitbit token 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.