Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Intraday Heart Rate Time Series Writeup

I wrote up my experience getting intraday time series heart rate data from the Fitbit API.

 

https://tomhummel.com/2016/03/19/fitbit-heart-rate/

 

Sorry if this is not the right venue for this. 

Best Answer
0 Votes
31 REPLIES 31

Great write-up Tom!  Thanks for putting it together.

 

I was able to follow all of it, create my Fitbit Token, my ssl key and everything just fine.  When I try to get my data however I can't get past this error.

 

{"errors":[{"errorType":"invalid_request","message":"Missing 'grant_type' parameter value. Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."}],"success":false}

 

I'm using your curl code with my specific items and have looked it over for any typos many many times.  Would LOVE to get this scripted up and running.  

 

Thanks again...

Best Answer
0 Votes

Hey,

 

It is hard to say for certain what went wrong. You'll want to be sure you've made the following requests:

 

  1. the authorization request in the browser
  2. https://api.fitbit.com/oauth2/token?grant_type=authorization_code
  3. https://api.fitbit.com/1/user/-/activities/heart/date/2016-01-01/1d.json

Are you seeing the error on request #2 or request #3?

 

Best Answer
0 Votes

I can get the authorization request to grant me a token. So I'm good with step 1.  Your Step 2 and 3 give me the an authorization header error.  

 

{"errors":[{"errorType":"invalid_request","message":"Authorization header required. Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."}],"success":false}

 

I tried the same tab as the token was provided, placing my token into the URL.  A fresh tab with the same browser.  Step 2 and 3 do the same thing.  None of it worked.  a little annoying. 

 

 

Best Answer
0 Votes
Wait. You are making requests #2 and #3 in the browser? I wouldn't do that. The 'curl' commands from the Fitbit docs or my writeup should be run in a terminal with your relevant details replaced
Best Answer
0 Votes

I run it from command line, and I also tried using the browser.  

 

Here are my steps.

 

After recieving my code=TOKEN (via browser and granting "allow"), and creating my openssl key out of my ID and Secret, I place my components into a script that runs the command you specified.  The top command is the list below is the you provided, with my bits  When I run it I get the 

"unsupported_grant_type" error.  

 

curl -X POST \

  --header "Content-Type: application/x-www-form-urlencoded" \

  --header "Authorization: Basic MjI5SExKOmFjMTc1YTFkYmQ3NDU3ZjdjYjI2ODM1NjAxNWZkYzky" \

  https://api.fitbit.com/oauth2/token?grant_type=authorization_code?client_id=229HLJ&&redirect_uri=htt...

 

You mentioned running this in steps in your last post.  Is there another way to step through this instead of run it as one command.  How is that done using curl?  I tried these and they failed as expected without my bits.  So I'm not following you there.

 

curl -X POST \

  --header "Content-Type: application/x-www-form-urlencoded" \

  --header "Authorization: Basic MjI5SExKOmFjMTc1YTFkYmQ3NDU3ZjdjYjI2ODM1NjAxNWZkYzky" \

  https://api.fitbit.com/oauth2/token?grant_type=authorization_code

  #https://api.fitbit.com/oauth2/token?grant_type=authorization_code?client_id=229HLJ&&redirect_uri=htt...

 

curl -X POST \

  --header "Content-Type: application/x-www-form-urlencoded" \

  --header "Authorization: Basic MjI5SExKOmFjMTc1YTFkYmQ3NDU3ZjdjYjI2ODM1NjAxNWZkYzky" \

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

  #https://api.fitbit.com/oauth2/token?grant_type=authorization_code?client_id=229HLJ&&redirect_uri=htt...

 

Best Answer
0 Votes

I would take a step back from running all of these steps consecutively in a script until you know that they work individually. By individually, I'm suggesting that you open a new terminal window and run `curl ...`. I'm assuming you are on Mac OSX or Linux. 

 

1. make the browser request to get the authorization code

2. open a terminal window. run `curl ... ?grant_type=authorization_code&code=your-code-from browser

 

Step 2 needs to happen within 10 minutes of step 1, but it doesn't sound like that is your issue from the error messages you are pasting. 

 

Can you confirm you are able to do the above? Don't worry about step 3 yet.

Best Answer
0 Votes

First, real quick I appreciate you helping me out!  🙂

 

So, when I get a fresh token, and only run the authorization curl command (correct, from my mac terminal) which only has the curl statement up to the grant, followed by code=my token.  My command looks like this, IF it doesn't get compressed.

 

curl -X POST \

  --header "Content-Type: application/x-www-form-urlencoded" \

  --header "Authorization: Basic MjI5SExKOmFjMTc1YTFkYmQ3NDU3ZjdjYjI2ODM1NjAxNWZkYzky" \

  https://api.fitbit.com/oauth2/token?grant_type=authorization_code&code=4c7e5e75387c42bc702f5be03eec0...

 

In summary, just in case.

 

curl -X POST \

-- header Content Type .....

-- header Authorization Basic openssl key

https://api.....grant_type=authorization_code&code=my_token

 

I get this message.  

 

{"errors":[{"errorType":"invalid_request","message":"Missing parameters: code Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."}],"success":false}

Best Answer
0 Votes

There appears to be something wrong with the parameters you are sending via `curl`. It is hard to diagnose with the formatting of your pastes here in the forum. Can you create a (gist.github.com) with the full commands (less the secret bits). and can you add the curl flags `-i -v` to get additional detail? 

 

Don't excerpt snippets out or reorder things. Just paste as faithfully as possible without exposing sensitive info. 

Best Answer
0 Votes

will send, to the email listed for you on your site with the blog. 🙂  Hope that works.

Best Answer
0 Votes
When you request the heart rate data, change the Authorization header from Basic to Bearer. Also you may need to send it as a GET rather than POST.
Best Answer
0 Votes

Here is the problem:

https://api.fitbit.com/oauth2/token?grant_type=authorization_code?client_id=229HLJ&redirect_uri=http://www.ahwair.com&code=5cac4736ab81cf6a6da943d4762d4ccb7c084c7b

 

your url is not formatted correctly. `?` ends the path and begins the querystring. then each key=value pair should be separated by an ampersand. you've got two `?` in your url

Best Answer
0 Votes

Ohh the lovely typo.  OK I changed the second ? into an &.  I attempted Bearer instead of Basic, GET instead of POST.  Nothing works. I ran curl with -i -v, and it looks like the issue in the verbose output is pointing at the openssl key I get from the `echo ID:SECRET | openssl base64` command.  Patience is wearing thin on this.  

 

Here is the output of the verbose curl command.

 

Trying 104.16.66.50...

* Connected to api.fitbit.com (104.16.66.50) port 443 (#0)

* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

* Server certificate: *.fitbit.com

* Server certificate: COMODO RSA Domain Validation Secure Server CA

* Server certificate: COMODO RSA Certification Authority

* Server certificate: AddTrust External CA Root

> POST /oauth2/token?grant_type=authorization_code HTTP/1.1

> Host: api.fitbit.com

> User-Agent: curl/7.43.0

> Accept: */*

> Content-Type: application/x-www-form-urlencoded

> Authorization: Basic MjI5SExKOmFjMTc1YTFkYmQ3NDU3ZjdjYjI2ODM1NjAxNWZkYzky

< HTTP/1.1 400 Bad Request

HTTP/1.1 400 Bad Request

< Server: cloudflare-nginx

Server: cloudflare-nginx

< Date: Wed, 23 Mar 2016 01:40:58 GMT

Date: Wed, 23 Mar 2016 01:40:58 GMT

< Content-Type: application/json;charset=utf-8

Content-Type: application/json;charset=utf-8

< Transfer-Encoding: chunked

Transfer-Encoding: chunked

< Connection: keep-alive

Connection: keep-alive

< Cache-control: no-cache, private

Cache-control: no-cache, private

< Content-Language: en-US

Content-Language: en-US

< Vary: Accept-Encoding

Vary: Accept-Encoding

< X-Frame-Options: SAMEORIGIN

X-Frame-Options: SAMEORIGIN

< CF-RAY: 287e2da75d7702b5-IAD

CF-RAY: 287e2da75d7702b5-IAD

 

* Connection #0 to host api.fitbit.com left intact

{"errors":[{"errorType":"invalid_request","message":"Missing parameters: code Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."}],"success":false}

 

With Bearer instead of Basic I get a different error.

 

Trying 104.16.66.50...

* Connected to api.fitbit.com (104.16.66.50) port 443 (#0)

* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

* Server certificate: *.fitbit.com

* Server certificate: COMODO RSA Domain Validation Secure Server CA

* Server certificate: COMODO RSA Certification Authority

* Server certificate: AddTrust External CA Root

> POST /oauth2/token?grant_type=authorization_code HTTP/1.1

> Host: api.fitbit.com

> User-Agent: curl/7.43.0

> Accept: */*

> Content-Type: application/x-www-form-urlencoded

> Authorization: Bearer MjI5SExKOmFjMTc1YTFkYmQ3NDU3ZjdjYjI2ODM1NjAxNWZkYzky

< HTTP/1.1 401 Unauthorized

HTTP/1.1 401 Unauthorized

< Server: cloudflare-nginx

Server: cloudflare-nginx

< Date: Wed, 23 Mar 2016 01:46:52 GMT

Date: Wed, 23 Mar 2016 01:46:52 GMT

< Content-Type: application/json;charset=utf-8

Content-Type: application/json;charset=utf-8

< Transfer-Encoding: chunked

Transfer-Encoding: chunked

< Connection: keep-alive

Connection: keep-alive

< Cache-control: no-cache, private

Cache-control: no-cache, private

< WWW-Authenticate: Bearer realm="api.fitbit.com"

WWW-Authenticate: Bearer realm="api.fitbit.com"

< Content-Language: en-US

Content-Language: en-US

< Vary: Accept-Encoding

Vary: Accept-Encoding

< X-Frame-Options: SAMEORIGIN

X-Frame-Options: SAMEORIGIN

< CF-RAY: 287e364eb9cd23f0-IAD

CF-RAY: 287e364eb9cd23f0-IAD

 

* Connection #0 to host api.fitbit.com left intact

{"errors":[{"errorType":"invalid_token","message":"Access token invalid: MjI5SExKOmFjMTc1YTFkYmQ3NDU3ZjdjYjI2ODM1NjAxNWZkYzky. Visit https://dev.fitbit.com/docs/oauth2 for more information on the Fitbit Web API authorization process."}],"success":false}

 

Best Answer
0 Votes

I just swapped the tokens around. Replace the openssl key with the Fitbit token. Tom, if you could put your working code onto github and point me to that, I'll replace my secure bits with yours.  If that doesn't work, then it must be something specific with my account/app setup.  

 

I'm using "Personal" in the oAuth2.0 settings.  Simple and straight forward commands. Driving me nuts.

Best Answer
0 Votes

I just copied the exact code posted on the blog, created my ssl key.  Pasted the exact code into my curl script.  Changed my bits, ran it and got no further. Same grant_type error.  

 

It would be GREAT if maybe someone from Fitbit would chime in.  If i'm using the exact same code as Tom, with my keys, then this is a FITBIT issue IMO.  

 

Does anyone from Fitbit every chime in on the community chats or is this just for people to talk with each other.  lol  

Best Answer
0 Votes
I'm bummed this is proving so difficult. It means my post isn't accomplishing its purpose.

i would go back to the start and follow my post explicitly with your typo removed.

For the "authorization_code" request use "Basic" not "Bearer" as was suggested.

I'll take a look at your updated github repo now that the typo has been fixed
Best Answer
0 Votes
Oh and this isn't a Fitbit issue. We can figure this out. The details of this workflow are very particular and need to be followed painstakingly.
Best Answer
0 Votes
One other thing to try, i saw you paste this command a few messages back:

echo "ID:secret" | openssl base64

You need the '-n' flag on the echo command as I have it in my post. This is very important.

echo -n 'ABC123:12345678123456781234567812345678' | openssl base64
Best Answer
0 Votes
And for reference here is the script we are talking about: https://github.com/roshepard/fitbit/blob/master/get_fitbit_stepped.sh
Best Answer
0 Votes
If you don't want to hassle with "echo | openssl" you can use the -u or --user switch in curl: https://curl.haxx.se/docs/httpscripting.html#Basic_Authentication
Best Answer
0 Votes