The various PHP libraries for FitBit OAuth-based access are very poorly documented, and unfortunately few of them have been updated in the last few years.

So here is a quick-start guide.

I picked djchen/oauth2-fitbit, since it seems to be the most recently updated php library I could find.

First, you will need a URL where you will host your project. Use a new file we will create called “auth.php” as the Callback URL. Log in to https://dev.fitbit.com and create your application. Choose Browser and Server modes.

Next, install composer and install the library. Run these four commands to get composer.phar, then run:

php composer.phar require djchen/oauth2-fitbit

That will download the library and all of its prerequisites into a new subdirectory called ‘vendor’.

Then you will want to set up two files, one for authorization/authentication (eg: auth.php), and one for whatever you actually want to do.

The auth file is verbatim from the readme (under “Authorization Code Grant”), but is missing these lines:

<?php
require __DIR__ . '/vendor/autoload.php';

The important part is that once you get $accessToken, you need to store that somewhere. For short-lived use (just while the user is on your site), you can store it in $_SESSION), for longer-term use, you will want to cookie the user and store their tokens in a database, or tie it to an existing account you have with them.

<?
require __DIR__ . '/vendor/autoload.php';
use djchen\OAuth2\Client\Provider\Fitbit;

$provider = new djchen\OAuth2\Client\Provider\Fitbit([
    'clientId'          => '{fitbit-oauth2-client-id}',
    'clientSecret'      => '{fitbit-client-secret}',
    'redirectUri'       => 'https://example.com/callback-url'
]);

# Here, figure out what user is visiting, and retrieve their $accessToken from wherever you stored it.
$accessToken = unserialize( ... );

# Check if the token is expired, and if so, refresh it.
if ($accessToken->hasExpired()) {
    $newAccessToken = $provider->getAccessToken('refresh_token', [
            'refresh_token' => $accessToken->getRefreshToken()
    ]);
    if ($newAccessToken) {
            $accessToken = $newAccessToken;

            # Here, we got an updated token, so you need to store it again
            ... serialize($newAccessToken);
    }
}

# Finally, do the request you really want to do, look at <a href="https://dev.fitbit.com/docs/activity/">https://dev.fitbit.com/docs/activity/</a> for more options:
$request = $provider->getAuthenticatedRequest(
    Fitbit::METHOD_GET,
    Fitbit::BASE_FITBIT_API_URL . '/1/user/-/activities/goals/daily.json',
    $accessToken,
    ['headers' => [Fitbit::HEADER_ACCEPT_LANG => 'en_US'], [Fitbit::HEADER_ACCEPT_LOCALE => 'en_US']]
);
$response = $provider->getResponse($request);
if ($response) {
    print "Step Goal is: " . $response{'goals'}{'steps'} . "<br/>\n";
    print_r($response);
}
?>

For POSTing, you need to set the content type:

$request = $provider->getAuthenticatedRequest(
    Fitbit::METHOD_POST,
    Fitbit::BASE_FITBIT_API_URL . '/1/user/-/activities/goals/daily.json',
    $accessToken,
    [
            'body' => 'steps=10000&floors=10',
            'headers' => ['Content-Type' => 'application/x-www-form-urlencoded'], [Fitbit::HEADER_ACCEPT_LANG => 'en_US'], [Fitbit::HEADER_ACCEPT_LOCALE => 'en_US']
    ]
);
$response = $provider->getResponse($request);

Now, visit auth.php in your browser. You will get redirected to Fitbit’s authorization page. Click Allow and you will be redirected back to your script again. It will dump a pile of diagnostic information, and if you did it properly, it will also save your $accessToken.

Next, visit the second file created, and it will list your current step (and other) goals. Going forward, update the second script to do what it is you want your application to do. Of course, you can combine the two scripts if you want with a little logic around whether or not you already know of an accessToken for them or not.