Sunday, 8 January 2017

Using the Resources of the Fitbit API

In previous posts I've covered the basics of using a Raspberry Pi and the Fitbit API to extract and analyse the data created by a Fitbit Fitness tracker.  In particular, in this post I covered using OAUTH2.0 to access the API.

For this post I thought I'd do a more general overview of the range of data available through the Fitbit API.  So go back to the OAUTH2.0 post to see how to get access and refresh tokens etc.  Then come back here to see what you can do with the API.

Once you've got the required tokens, all you need to do to access data is specify different URLs.  In this post I'll describe a range of URLs that can be used to access different data.  There's a massive variety of data available and almost limitless combinations so just use this as a set of worked examples then use the Fitbit Developer documentation to work out other options.

Remember I'm just a guy that does this for a hobby and likes to help other people along the way.  If I use the wrong terms or describe things in a less than 100% accurate manner then please take this in the right spirit or even comment below to help me correct matters.

Activity Data
The most generic data available from the API.  Here's a simple URL to give you summary of activity data for a given date:

https://api.fitbit.com/1/user/-/activities/date/2016-12-27.json

So a simple base URL and extra elements to specify "activities" and a date to get data for.  This yields:

{"activities":[],"goals":{"activeMinutes":30,"caloriesOut":2812,"distance":8.05,"floors":25,"steps":10000},"summary":{"activeScore":-1,"activityCalories":1952,"caloriesBMR":1725,"caloriesOut":3353,"distances":[{"activity":"total","distance":16.93},{"activity":"tracker","distance":16.93},{"activity":"loggedActivities","distance":0},{"activity":"veryActive","distance":13.18},{"activity":"moderatelyActive","distance":0.59},{"activity":"lightlyActive","distance":3.16},{"activity":"sedentaryActive","distance":0}],"elevation":155.45,"fairlyActiveMinutes":15,"floors":51,"heartRateZones":[{"caloriesOut":1546.2586,"max":89,"min":30,"minutes":793,"name":"Out of Range"},{"caloriesOut":271.2272,"max":124,"min":89,"minutes":47,"name":"Fat Burn"},{"caloriesOut":21.8036,"max":151,"min":124,"minutes":2,"name":"Cardio"},{"caloriesOut":861.961,"max":220,"min":151,"minutes":57,"name":"Peak"}],"lightlyActiveMinutes":206,"marginalCalories":1332,"restingHeartRate":55,"sedentaryMinutes":725,"steps":17309,"veryActiveMinutes":83}}

So even with it in JSON format you can see some of the key Fitbit metrics that are returned (I've marked these in red).

Step Data
The main reason people get their Fitbit is to count their steps!

Here's a simple example of a URL that provides data for 7 days up to and including the date you specify:

https://api.fitbit.com/1/user/-/activities/steps/date/2016-12-27/7d.json"

The response is as follows:

{"activities-steps":[{"dateTime":"2016-12-21","value":"16156"},{"dateTime":"2016-12-22","value":"9075"},{"dateTime":"2016-12-23","value":"7963"},{"dateTime":"2016-12-24","value":"18698"},{"dateTime":"2016-12-25","value":"11316"},{"dateTime":"2016-12-26","value":"11473"},{"dateTime":"2016-12-27","value":"17309"}]}

So here you can see the 7 measurements and how the value for 2016-12-27 matches that of the activity data above.

You could get the same data but by specifying a start and end date by using:

https://api.fitbit.com/1/user/-/activities/steps/date/2016-12-21/2016-12-27.json

If you ask Fitbit nicely they will give you access to intraday data.  See here for more details on how to do this.  An example URL to get 15 minute segments for a single day is:

https://api.fitbit.com/1/user/-/activities/steps/date/2016-12-27/1d/15min.json

Which gives data like this:

{"activities-steps":[{"dateTime":"2016-12-27","value":"17309"}],"activities-steps-intraday":{"dataset":[{"time":"00:00:00","value":0},{"time":"00:15:00","value":0},{"time":"00:30:00","value":0},{"time":"00:45:00","value":0},{"time":"01:00:00","value":0},{"time":"01:15:00","value":0},

...not that interesting for this time period as I was asleep.  It gets better later in the day when I went for a run!

{"time":"08:45:00","value":350},{"time":"09:00:00","value":2016},{"time":"09:15:00","value":2522},{"time":"09:30:00","value":2508},{"time":"09:45:00","value":2555},{"time":"10:00:00","value":628}

Other Measurements
You can use the same URL structure for other key tracker metrics like:

/calories
/distance
/floors

(i.e. replace "/steps" in the above examples with these words).

Sleep
If you have a tracker that measures sleep then you can use a URL like the one below to get sleep data:

https://api.fitbit.com/1/user/-/sleep/date/2016-12-27.json

Which gives data like this at the start:

{"sleep":[{"awakeCount":4,"awakeDuration":4,"awakeningsCount":32,"dateOfSleep":"2016-12-27","duration":29580000,"efficiency":88,"isMainSleep":true,"logId":13314423872,"minuteData":[{"dateTime":"22:38:00","value":"2"},{"dateTime":"22:39:00","value":"3"},{"dateTime":"22:40:00","value":"1"},{"dateTime":"22:41:00","value":"1"},{"dateTime":"22:42:00","value":"1"},{"dateTime":"22:43:00","value":"1"}

So some generic information then (by default) a record for every minute of your sleep.  Here the values are:
1=Asleep
2=Awake
3=Really awake

Then a summary at the end:

"summary":{"totalMinutesAsleep":434,"totalSleepRecords":1,"totalTimeInBed":493}}

Heart Rate
Finally, if you have a tracker that also measures heart rate you can use a URL like the one below to get data:

https://api.fitbit.com/1/user/-/activities/heart/date/2016-12-27/1d.json


{"activities-heart":[{"dateTime":"2016-12-27","value":{"customHeartRateZones":[],"heartRateZones":[{"caloriesOut":1546.2586,"max":89,"min":30,"minutes":793,"name":"Out of Range"},{"caloriesOut":271.2272,"max":124,"min":89,"minutes":47,"name":"Fat Burn"},{"caloriesOut":21.8036,"max":151,"min":124,"minutes":2,"name":"Cardio"},{"caloriesOut":861.961,"max":220,"min":151,"minutes":57,"name":"Peak"}],"restingHeartRate":55}}],"activities-heart-intraday":{"dataset":[{"time":"00:00:00","value":65},{"time":"00:01:00","value":65},{"time":"00:02:00","value":65},{"time":"00:03:00","value":65},{"time":"00:08:00","value":65},{"time":"00:09:00","value":65},{"time":"00:10:00","value":65},{"time":"00:11:00","value":64},{"time":"00:12:00","value":64},{"time":"00:13:00","value":65},{"time":"00:14:00","value":66},{"time":"00:15:00","value":64},{"time":"00:16:00","value":61},

So first some general data then some measurements at up to one minute intervals (if you have access to this data).

Summary
So that was a whistle-stop tour of using the API.  Have a play, use different URLs and see what you can get!