Skip to content
AFAIFitnessAPI
Integration Guides

How to Integrate the Fitbit API (2026)

Updated July 9, 2026

The Fitbit Web API returns a user's activity, steps, heart rate, sleep, and profile data after they authorize your app over OAuth 2.0 (authorization-code grant, PKCE recommended). You register an app, send the user through Fitbit's authorize page, exchange the code for a Bearer access token, and call the REST API with it. Critically, the legacy Fitbit Web API is being turned down around September 2026 (exact day TBD, verify) and replaced by the Google Health API using Google OAuth 2.0 — tokens do not transfer and users must re-consent, so new integrations should target Google Health directly.

The Fitbit Web API gives your app a user's Fitbit-account data — daily activity and steps, heart rate, sleep, and profile — after that user authorizes you over OAuth 2.0 (authorization-code grant, PKCE recommended). The one-line "how": register an app, send the user through Fitbit's authorize page, exchange the returned code for a Bearer access token, and call the REST API with that token. Before you write a line of code, though, read the migration warning below — it changes what you should build.

Read this first: the legacy Fitbit Web API is being turned down

Google, which owns Fitbit, has announced "the next phase of the Fitbit Web API": the legacy Fitbit Web API described on this page is being retired and replaced by the new Google Health API, which uses Google OAuth 2.0 instead of Fitbit's own authorization server. The turndown is targeted for around September 2026 — the exact day in that month is still to be confirmed by Google, so verify it against the current docs before you plan around it.

The critical detail for developers: existing Fitbit access tokens and refresh tokens do not transfer to the Google Health API and will not work there. Every user must actively re-consent through Google OAuth 2.0.

Migration callout (verify against current docs). If you are starting a NEW integration in 2026, target the Google Health API (https://developers.google.com/health) with Google OAuth 2.0 directly — do not build fresh on the legacy Fitbit Web API, which is short-lived. The legacy turndown is targeted for around September 2026 (exact day TBD). Tokens do not migrate; users re-consent. Use the legacy flow below only for an existing integration you must keep running until turndown, and plan a phased re-consent path onto Google Health. Confirm the current timeline and GA date on the Google Health API pages.

With that context set, the rest of this guide covers the legacy Fitbit Web API OAuth 2.0 flow — useful for maintaining an existing integration through the transition. For a broader look at how Fitbit compares in this space, see Fitbit API vs Garmin API and the wearable data APIs overview.

What you'll need

  • A Fitbit (or Google) account to sign in to the developer portal.
  • A registered app at https://dev.fitbit.com, which gives you a Client ID and (for server apps) a Client Secret.
  • A redirect/callback URL under your control to receive the authorization code.
  • For minute- or second-level intraday data (heart rate, steps), a separate approval — see the last step.

Step 1: Register your app

Sign in at https://dev.fitbit.com and choose "Register an App." The important field is the OAuth 2.0 Application Type, which governs how you authenticate:

  • Client — mobile apps or single-page apps that omit the Client Secret. These must use PKCE.
  • Server — confidential backends that authenticate with the Client Secret. PKCE is still recommended.
  • Personal — required to access intraday data for your own account without extra approval.

Set your Callback URL and the default scopes you plan to request. You will receive a Client ID, and server/confidential apps also get a Client Secret. Note that Fitbit does not let you force users to grant every scope — the user chooses per data collection.

Step 2: Generate a PKCE pair and redirect the user to authorize

For public (Client) apps, create a PKCE pair first. The code_verifier is a cryptographically random string of 43 to 128 characters; the code_challenge is the BASE64URL-encoded SHA-256 hash of that verifier, sent with code_challenge_method=S256.

Then send the user to Fitbit's authorize endpoint. The documented scopes include activity, heartrate, sleep, and profile (the full set also covers location, nutrition, oxygen_saturation, respiratory_rate, settings, social, temperature, and weight — verify the current list in the docs).

GET https://www.fitbit.com/oauth2/authorize
  ?client_id=CLIENT_ID
  &response_type=code
  &scope=activity%20heartrate%20sleep%20profile
  &code_challenge=CODE_CHALLENGE
  &code_challenge_method=S256
  &state=RANDOM_STATE
  &redirect_uri=https%3A%2F%2Fyourapp.example.com%2Fcallback

On approval, Fitbit redirects back to your redirect_uri with ?code=AUTH_CODE&state=RANDOM_STATE. Always check that the returned state matches the value you sent.

Step 3: Exchange the authorization code for tokens

POST the authorization code to Fitbit's token endpoint. Public (Client) apps authenticate with the client_id plus the PKCE code_verifier and no secret:

curl -X POST "https://api.fitbit.com/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=CLIENT_ID" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE" \
  -d "code_verifier=CODE_VERIFIER" \
  -d "redirect_uri=https://yourapp.example.com/callback"

Confidential (Server) apps additionally send an HTTP Basic auth header instead of relying only on PKCE: -H "Authorization: Basic BASE64(client_id:client_secret)".

A successful response returns JSON with the Bearer token you will use for all API calls:

{
  "access_token": "eyJ...",
  "expires_in": 28800,
  "refresh_token": "c643...",
  "scope": "activity heartrate sleep profile",
  "token_type": "Bearer",
  "user_id": "ABC123"
}

The expires_in value of 28800 seconds (8 hours) is the commonly documented lifetime — verify the current value against the docs.

Step 4: Fetch data with the Bearer token

Call the REST API with Authorization: Bearer ACCESS_TOKEN. In the path, - means "the authenticated user" (user/-) and the leading 1 is the API version. Here is a daily activity summary:

curl -X GET "https://api.fitbit.com/1/user/-/activities/date/2026-07-08.json" \
  -H "Authorization: Bearer ACCESS_TOKEN"

And a steps time series covering the 30 days ending on a date:

curl -X GET "https://api.fitbit.com/1/user/-/activities/steps/date/2026-07-08/30d.json" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Responses are application/json. Sleep, heart rate, and profile follow the same user/- pattern under their own resource paths.

Step 5: Refresh tokens before they expire

Access tokens are short-lived, so refresh with the stored refresh_token to get a new access token without sending the user back through consent:

curl -X POST "https://api.fitbit.com/oauth2/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "refresh_token=REFRESH_TOKEN" \
  -d "client_id=CLIENT_ID"

Confidential apps include the same HTTP Basic auth header used in Step 3. Persist the returned tokens and refresh proactively (for example, shortly before expiry) rather than waiting for a 401.

Step 6: Handle rate limits and request intraday access

Two production limits matter most:

  • Rate limit: 150 API requests per hour, per consented user. The counter resets around the top of each hour and applies to all calls made with a given user's access token. Over the limit returns HTTP 429 with a header indicating seconds until reset (commonly Retry-After or a Fitbit-Rate-Limit-Reset header — verify the exact name in the docs). Back off and retry after the reset rather than hammering the endpoint.
  • Intraday data requires special approval. Minute- or second-level series (for example steps or heart rate) are available by default only to Personal apps for their own data. Other app types must request intraday access from Fitbit/Google. Intraday requests are also limited to a 24-hour window per request; wider date ranges return summary data only.

An intraday steps request (1-minute detail, requires approval) looks like this:

curl -X GET "https://api.fitbit.com/1/user/-/activities/steps/date/2026-07-08/1d/1min.json" \
  -H "Authorization: Bearer ACCESS_TOKEN"

Gotchas and production notes

  • Plan for the migration now. The single biggest risk with any legacy Fitbit integration in 2026 is the targeted ~September turndown. Do not start new builds here; if you are maintaining an existing one, build a phased re-consent flow onto the Google Health API and Google OAuth 2.0 before the deadline. Verify the exact turndown day and the Google Health GA date in the current docs.
  • Tokens do not transfer. Nothing you store today carries over to Google Health — every user re-authorizes.
  • PKCE is mandatory for public clients. Mobile and SPA apps that omit the Client Secret must use S256.
  • Scopes are per-collection and user-controlled. Verify the granted scope in the token response; users can decline individual collections.
  • Volatile values change. Token TTL, the rate-limit header name, and the turndown date are all flagged "verify against current docs" — confirm them on the primary developer pages before you ship.

For how Fitbit stacks up against another major wearable platform, see Fitbit API vs Garmin API; for the wider category, the wearable data APIs guide covers the approval gates and rate limits across providers.

Frequently asked questions

Is the Fitbit Web API being shut down?
Yes. Google is retiring the legacy Fitbit Web API and replacing it with the Google Health API, which uses Google OAuth 2.0. The turndown is targeted for around September 2026, with the exact day still to be confirmed — verify it against the current docs before planning around it.
Do my existing Fitbit OAuth tokens transfer to the Google Health API?
No. Existing Fitbit access and refresh tokens do not transfer to the Google Health API and will not work there. Every user must actively re-consent through Google OAuth 2.0, so build a phased re-consent flow before the turndown.
Should I build a new integration on the Fitbit Web API or Google Health?
For a new integration in 2026, target the Google Health API with Google OAuth 2.0 directly, since the legacy Fitbit Web API is short-lived. Use the legacy flow only to maintain an existing integration through the transition. Verify the current GA date and timeline in the docs.
Which OAuth scopes do I need to request from Fitbit?
Only the collections your features actually use. The documented scopes include activity, heartrate, sleep, and profile, with the full set also covering location, nutrition, oxygen_saturation, respiratory_rate, settings, social, temperature, and weight — verify the current list in the docs. Fitbit does not let you force a user to grant everything: consent is per data collection, so someone can approve activity and decline heart rate. Read the scope value returned with the token rather than assuming you got what you asked for, and degrade the UI when a collection is missing.
Does Fitbit require approval for intraday data?
Yes. Minute- and second-level intraday data is available by default only to Personal apps for their own account. Other app types must request intraday access from Fitbit/Google, and each intraday request is limited to a 24-hour window.

Keep reading

Independent comparison, last reviewed July 9, 2026. Pricing, rate limits, and feature availability change often — confirm current details in each provider’s official documentation before you commit. Product and company names are trademarks of their respective owners; AIFitnessAPI is not affiliated with, endorsed by, or sponsored by any product listed here.

← All integration guides · by AIFitnessAPI