Fortes


Extracting FitBit Weight Data

Stealing your history back from FitBit, minus the janky interpolated values

Spices for sale

Spices for sale Barra da Tijuca, Brazil

Being just barely off the spectrum, I’m inexorably drawn to measuring and recording all sorts things. Without going into the (boring) details, I’ve been weighing myself on a near-daily basis since my mid-twenties. In 2013, I gave into temptation and got an internet-connected scale that automatically uploads to FitBit, depriving me of the joy of manual data entry every morning.

Like any normal, well-adjusted person, I want to run esoteric multivariate analysis on my weight data. FitBit provides basic export functionality, but it’s not made for my serious business™:

  1. Only weight is provided, no body fat percentage
  2. If there is no measurement in a given day, the weight value is silently interpolated between the nearest measurements

Though I can be a bit obsessive about data, I’m fine living without the body fat percentage, since these cheap scales aren’t particularly accurate anyway. However, interpolating weight data across days is simply unacceptable, and I’m not the only one incredibly offended.

After waiting a few years for FitBit developers to fix this, today I decided to take matters into my own hands and get the data myself. I’ve documented the steps here for my future self along with other weight-conscious obsessives.

If you go to the FitBit Weight Page, there’s a nice little chart you can use to see all your historical measurements without any interpolated values. Poking around in the browser developer tools, you’ll see that this chart is generated on the browser-side which means that at some point in time the raw data is downloaded by the browser. This is fantastic news.

Fire up the Network Panel in the browser web tools and keep an eye out for a request to the following URL:

https://web-api.fitbit.com/1.1/user/-/body/log/weight/graph/all.json?durationType=all

If you take a look at the server response, you’ll see something like:

{
  "graphValues": [
    {
      "bmi": 23.9,
      "dateTime": "2013-09-05T12:00:00",
      "fat": 19.358999252319336,
      "weight": 80900
    },
    {
      "bmi": 23.83,
      "dateTime": "2013-09-06T12:00:00",
      "fat": 19.68600082397461,
      "weight": 80670
    },
    // <thousands of entries omitted>
  ],
}

That’s a bingo! The weight value is provided in grams, and it even includes the body fat percentage, which is missing from FitBit’s export.

Save this huge JSON blob to it’s own file called all.json. Now you’re gonna have to open up the command line and use jq to convert this JSON into something easier to use. We’ll start by running:

jq '.graphValues[] | [ .dateTime, .weight, .fat ]' all.json

Note that I don’t bother grabbing the BMI data here because it’s easily derived later. That jq command above will output thousands of lines that look something like:

[
  "2013-09-05T12:00:00",
  80900,
  19.358999252319336
]
[
  "2013-09-06T12:00:00",
  80670,
  19.68600082397461
]

This isn’t quite usable yet, so let’s ask jq to convert it to CSV:

jq -r '.graphValues[] | [ .dateTime, .weight, .fat ] | @csv' all.json > all.csv

Hooray, now you have everything in a CSV file which you can use to import into Excel, Sheets, or (my biased choice) Coda. Don’t forget to convert grams into your preferred unit, which is either dram, mercantile stone, or pennyweight, depending on which 19th century British village you hail from. Now it’s time for you to touch grass and burn some calories, nerd.