There is no especially charming way to ask somebody to reconnect a wearable they already connected. From their side, an app that worked now needs another favour. We owe them a reason they can understand, a short journey through consent, and some care with the history they expect to find afterwards.
Google's overview schedules the legacy Fitbit Web API shutdown for September 2026; it gives the month, without an exact day. Existing Fitbit access and refresh tokens cannot transfer to Google Health. Users have to authorize the new integration through Google OAuth. However tidy the backend change, finishing this migration involves persuading people to do something.
Our May guide covers the Google Health API architecture. This September, the interesting work is making that architecture disappear again, so somebody can open their app and get on with using it.
If you already get Fitbit data through Terra, your application keeps using the same API and normalised data models while Terra handles the provider-side changes. You don't need to rewrite your integration around Google's new endpoints and response formats. Users still need to complete Google's renewed consent. The implementation details below are for direct integrations.
Another consent screen needs a reason
The provider's infrastructure changes matter to developers. They make poor copy for a reconnect banner. “Reconnect your health account to resume sleep updates” gives someone a reason to bother. An explanation of your new OAuth implementation asks them to take an interest in your afternoon.
While the legacy API remains active, Google recommends supporting both authorization systems, routing existing users through their current connection until they re-consent. People who have not finished can keep using that connection during the overlap. The arrangement lasts only as long as the old service does.
The return from Google deserves as much attention as the button that sent the person there. Authorization completed, identity confirmed, and data arriving are different events. A green “Connected” badge while the first import is failing is an unhelpful reward for doing what you asked. Showing the import's actual progress gives the user a more honest answer and gives support something to work with.
There is also a less visible follow-through: tomorrow's background job needs credentials. Google's authorization guide requires access_type=offline to obtain a refresh token; its setup guide explains when prompt=consent is appropriate. The useful test is whether the job refreshes credentials after the initial access token expires. The request made while the person is still looking at the screen cannot tell you that.
A successful login can still be the wrong account
One of the more useful details in this migration is a small endpoint: getIdentity. The OAuth token response does not include the health identity, so Google recommends calling it after consent. It returns both legacyUserId and healthUserId, giving you an explicit connection between the old account and the new system. Both are strings; a numeric-looking health ID is still a string. The identity reference defines those fields.
We like this kind of API feature. It gives developers a way to preserve an existing relationship without guessing from names or email addresses. Your own application account can stay put, with the provider identifiers stored alongside it.
That becomes especially valuable when a person has several Google accounts. Suppose a returning member completes consent using an account whose legacy identity differs from the Fitbit account already linked to your app. OAuth has succeeded. Joining that new account to the member's old history would still be a mistake.
This is a good place for deliberate friction: explain the mismatch and let the person choose the right account or get help. Keep the existing association intact while resolving it, and prevent one provider identity from silently attaching to unrelated application accounts. A matching display name is no substitute for the mapping.
There is another case to distinguish: Google warns that getIdentity can fail when the person lacks a Google Health account. That is a different problem from choosing the wrong account, and deserves a different message.
The history may still be there
There is welcome news for anyone who reconnects late. Google's migration guide says historical data can be backfilled after reauthorization if the person continued syncing their device to the Google Health app. An interruption in your application's access need not mean the underlying history vanished. The qualification matters: this cannot recover measurements that were never captured or synced.
That makes a patient recovery flow worth building. The application can fetch the recent information somebody came to see, then fill older gaps in the background. Keeping the last successfully imported period for each data type gives that work a starting point. “Connection restored” and “History restored” deserve separate states, even if the interface expresses them more pleasantly.
One easily missed detail: the current list method caps sleep and exercise pages at 25 records. A month of sleep can require another page. Having persuaded someone to reconnect, it would be a shame to lose the rest of their history behind an unconsumed nextPageToken. Google's historical-query guidance also documents rate limits and aggregation date-range constraints; recovery needs room to work within them.
The importer should survive being interrupted, too. Saving progress after records are committed and making a repeated window safe to replay allows recovery to resume without another demand on the user. There is enough consent in this process already.
Nor is fetching more records automatically an improvement. Google documents overlapping raw intervals and a reconciled view that resolves conflicts. Mixing old stored totals with newly fetched raw intervals can produce a strange-looking activity chart. Consistent interpretation matters as much as completeness; otherwise the migration can appear to have found exercise that nobody did.
Consent still means someone can say no
Google's scope guidance requires graceful handling of partial consent. Someone can grant activity access while withholding sleep access. We think preserving the working activity features is a much better response than treating their choice as a broken connection. The sleep feature can explain what permission it needs.
This distinction is available in the API, too. Missing required scope produces 403 with MISSING_OAUTH_SCOPE, rather than an empty data result. “You haven't shared this” and “We haven't found any records” tell the person different things. The product should know which one it means.
Google has its own approval process. Its overview classifies all Google Health scopes as Restricted, and the app-verification guide describes OAuth review, an annual third-party CASA assessment, a 100-user limit for unverified apps, and prominent in-app disclosure of data access, use and sharing. The broader restricted-scope guidance covers exceptions and assessment requirements for server access to restricted data. Check applicability and the actual production project's approval before inviting people through its consent screen.
Feature coverage deserves the same attention. Match the features people use to documented data types, read or write operations, scopes and notifications. Roadmap dates describe plans; consumer features do not establish API access. Neither is much comfort to someone whose favourite chart is missing.
The callback is a little early to celebrate
The identity mapping earns its keep again when updates start arriving. Google's webhook guide requires a registered subscriber endpoint, supports automatic or manual subscription policies, and identifies the affected person through healthUserId. That mapping lets the worker find the correct credentials. A notification signals a change; it does not contain the underlying health record.
There is a fair amount of work between receiving that message and updating a chart: authenticating it, validating its signature, queueing it durably, looking up the account and fetching the data. Watching the delay through that whole path can expose a stuck worker or a failed account lookup while the receiver's HTTP responses look perfectly healthy. With Terra's webhooks, the normalised health data arrives in the payload, so your receiver can process the record without making that second request to the provider. Our webhooks and polling explainer covers how delivery fits into that flow.
Google also documents duplicate notifications and recommends idempotent handling. For delivery failures, it retains a backlog for up to seven days, discarding older notifications. Those delivery limits are another reason to retain the ability to investigate and retrieve missing periods after an outage.
We would measure migration progress at the point where useful data resumes, while keeping consent failures, identity mismatches, missing permissions and unfinished imports visible separately. That gives a developer somewhere specific to look and saves the person at the other end from being asked to reconnect indiscriminately.
Somebody who ignores the banners and comes back late still deserves a usable recovery flow. After shutdown, an application rollback cannot revive the old upstream service. What you can offer is the correct account match, a clear explanation of any remaining gaps, and the history available to retrieve. They have already done the annoying part. The remaining work belongs with the software.
Any one of these jobs is manageable. The trouble is collecting a separate version of each for Fitbit, Garmin, Oura and whichever wearable your users buy next. Our WHOOP integration walkthrough covers the same decision from another provider's side. Terra gives the application one integration and a common data model, while we maintain the provider-specific connections underneath. For this migration, that means keeping your Terra integration instead of rebuilding it around Google's endpoints and schemas. You can spend that time on the feature somebody connected their watch to use.