---
title: "How to Integrate the Fitbit API (2026)"
canonical: "https://aifitnessapi.com/integrate/fitbit-api"
cluster: "Integration Guides"
primary_query: "how to integrate the Fitbit API"
last_reviewed: "2026-07-09"
description: "Integrate the Fitbit API with OAuth 2.0 and PKCE — plus the critical 2026 migration to Google Health you must plan for before you build. Verify docs."
publisher: "AIFitnessAPI — independent, not sponsored"
cite_as: "\"How to Integrate the Fitbit API (2026)\", AIFitnessAPI, https://aifitnessapi.com/integrate/fitbit-api"
---

# How to Integrate the Fitbit API (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.

- Canonical: https://aifitnessapi.com/integrate/fitbit-api
- Last reviewed: 2026-07-09
- Publisher: AIFitnessAPI (https://aifitnessapi.com) — independent, not sponsored
- Cite as: "How to Integrate the Fitbit API (2026)", AIFitnessAPI, https://aifitnessapi.com/integrate/fitbit-api

---

## 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](/fitness-apis/fitbit-api-vs-garmin-api) and the [wearable data APIs](/fitness-apis/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).

```http
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:

```bash
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:

```json
{
  "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:

```bash
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:

```bash
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:

```bash
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:

```bash
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](/fitness-apis/fitbit-api-vs-garmin-api); for the wider category, the [wearable data APIs](/fitness-apis/wearable-data-apis) guide covers the approval gates and rate limits across providers.

## FAQ

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

[Permalink](https://aifitnessapi.com/integrate/fitbit-api#faq-1)

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

[Permalink](https://aifitnessapi.com/integrate/fitbit-api#faq-2)

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

[Permalink](https://aifitnessapi.com/integrate/fitbit-api#faq-3)

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

[Permalink](https://aifitnessapi.com/integrate/fitbit-api#faq-4)

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

[Permalink](https://aifitnessapi.com/integrate/fitbit-api#faq-5)
