03-20-2016 08:59
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-20-2016 08:59
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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.
03-21-2016 12:16
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-21-2016 12:16
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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...

03-21-2016 20:55
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-21-2016 20:55
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hey,
It is hard to say for certain what went wrong. You'll want to be sure you've made the following requests:
- the authorization request in the browser
- https://api.fitbit.com/oauth2/token?grant_type=authorization_code
- 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?

03-22-2016 05:07 - edited 03-22-2016 05:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 05:07 - edited 03-22-2016 05:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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.

03-22-2016 07:33
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 07:33
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 08:53
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 08:53
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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" \
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
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

03-22-2016 09:52
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 09:52
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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.

03-22-2016 11:58
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 11:58
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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" \
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}

03-22-2016 14:24
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 14:24
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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.

03-22-2016 14:56
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 14:56
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
will send, to the email listed for you on your site with the blog. 🙂 Hope that works.

03-22-2016 15:00
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 15:00
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 15:40
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 15:40
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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

03-22-2016 18:47
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 18:47
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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}

03-22-2016 18:57
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 18:57
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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.

03-22-2016 19:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 19:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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

03-22-2016 23:13
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 23:13
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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

03-22-2016 23:16
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 23:16
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 23:26
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 23:26
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
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

03-22-2016 23:28
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 23:28
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 23:33
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2016 23:33
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

