03-10-2023 12:05 - edited 03-10-2023 12:21
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-10-2023 12:05 - edited 03-10-2023 12:21
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi, I'm working to integrate Fitbit API on my app, I'm using typescript for backend, and is working fine for auth and get activities, but to refresh the tokens and revoke the permissions is getting errors.
For refresh token when I try to run an mutation I get this: Request failed with status code 401.
And when I try direct post on insomnia throw this: Bad request content type. Expecting: application/x-www-form-urlencoded.
On code is like this:
const basicToken = Buffer.from(
`${process.env.FITBIT_CLIENT_ID}:${process.env.FITBIT_CLIENT_SECRET}`
).toString('base64');
const access_token = await axios.post(
'https://api.fitbit.com/oauth2/token',
{
headers: { authorization: `Basic ${basicToken}` },
params: {
grant_type: 'refresh_token',
refresh_token: `${refresh_token}`,
},
}
);
And on Headers is with authorization Base and encoded cliend_id:client_secret like on code.
When I try to revoke by mutation just receive Bad request too but when I run on insominia it work just fine, don't get why doesn't work just on code.
Thanks

- Labels:
-
JavaScript
03-21-2023 06:38
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



03-21-2023 06:38
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @GPierre
For the refresh token errors:
- When trying to refresh the token and get the status code 401, what additional error message do you receive?
- When trying the post on insomnia, you need to set the header "Content-Type: application/x-www-form-urlencoded"
For the revoke token error, would you provide me with either your code or the syntax that you're using? Also, is there another error message that is returned with the "Bad Request"?
Gordon
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

03-21-2023 09:39
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-21-2023 09:39
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Adding Content-Type worked.
I realized that the error on revoke is because I try to refresh before revoke, so the error is the same and is just the Request failed with status code 401.
async revoke(refresh_token: string): Promise<void> {
const basicToken = Buffer.from(
`${process.env.FITBIT_CLIENT_ID}:${process.env.FITBIT_CLIENT_SECRET}`
).toString('base64');
const { access_token } = (
await axios.post('https://api.fitbit.com/oauth2/token', {
headers: {
authorization: `Basic ${basicToken}`,
Content-Type: 'application/x-www-form-urlencoded',
},
params: {
grant_type: 'refresh_token',
refresh_token: `${refresh_token}`,
},
})
).data;
console.log(refresh_token);
await axios.delete('https://api.fitbit.com/oauth2/revoke', {
headers: {
authorization: `Basic ${basicToken}`,
},
params: {
token: `${access_token}`,
},
});
}
Additionally, I'm trying to create subscription for activities when the user connect, and get the insufficient_permissions error when the request is done, I believe this occurs when there is no scope confirmed for activity but I accept when connect.

03-21-2023 11:11
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



03-21-2023 11:11
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @GPierre
That's great news the content-type header helped. Your pictures are really small so I'm having trouble reading them.
I see you're sending the I see you're specifying the DELETE verb for the revoke endpoint. The revoke endpoint uses POST. See https://dev.fitbit.com/build/reference/web-api/authorization/revoke-token/.
For create subscriptions, it looks like you're sending the authorization header as a query parameter. This is incorrect. You should send it as a request header. See https://dev.fitbit.com/build/reference/web-api/subscription/create-subscription/.
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

03-21-2023 13:36
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-21-2023 13:36
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Sorry for the pictures.
I forgot to change to post on revoke but he works fine since I remove the part of token:
const basicToken = Buffer.from(
`${process.env.FITBIT_CLIENT_ID}:${process.env.FITBIT_CLIENT_SECRET}`
).toString('base64');
const { access_token } = (
await axios.post('https://api.fitbit.com/oauth2/token', {
headers: {
authorization: `Basic ${basicToken}`,
Content-Type: 'application/x-www-form-urlencoded',
},
params: {
grant_type: 'refresh_token',
refresh_token: `${refresh_token}`,
},
})
).data;
On isomnia it worked by adding content-type, but in code still not working.
Sorry for the miss on subscription, I changed and now is 100% thanks.

03-21-2023 14:20
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post



03-21-2023 14:20
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
No worries. For refreshing your token in the code, are you getting an error message besides the 401?
Senior Technical Solutions Consultant
Fitbit Partner Engineering & Web API Support | Google

03-22-2023 08:16
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

03-22-2023 08:16
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
No, is just the Request failed with status code 401,

