Authentication
The FitnessSyncer API uses OAuth2 for authentication. This is a standard authentication scheme that is well documented on the web; the sequence diagram below will help you understand the big picture and this documentation will describe what you need to do.

FitnessSyncer supports Proof of Key Code Exchange (PKCE), an extension of OAuth 2.0 which helps protect against interception attacks. You are not required to use this, but are highly encouraged to. You can enable this functionality in our developer console.
Personal Applications can be created in our developer console. For other use-cases, please contact us, provide us with your Redirect URL(s), and we will provide you with the following information:
- Client ID
- Client Secret
Note that the Redirect URL is case sensitive and should be SSL-based as our browser policy is to not redirect to non-SSL enabled locations.
Personal applications do not have a configurable Redirect URL. When the flow goes to that hard-coded Redirect URL, simply edit the URL to where you need it to go. You should only need to do this once.
Authenticating
To authenticate a web-application, the basic workflow is as follows:
- Redirect the user to FitnessSyncer to authorize your application’s access to their data. See Authorizing for details.
- Once approved, FitnessSyncer will redirect the user back to your site with a temporary token.
- With the temporary token, you can get the Access Token
- After the Access Token Expires, you must Refresh the Access Token.
The sections below will walk you through all of the steps but we have provided fitnesssyncer_oauth_authorization_flow.py for the authorization flow and fitnesssyncer_oauth_refresh_flow.py for the refresh flow as examples to help you get up and running faster. These examples do not support PKCE.
Authorizing
To start the authentication workflow, you will need to redirect the user to https://www.fitnesssyncer.com/api/oauth/authorize with following query string parameters:
Throughout this document, a parameter shown in bold in a table is required, and bold text within a URL is a placeholder for you to substitute.
| Query String Parameter Name | Description |
|---|---|
| response_type | Set to “code” |
| client_id | Set to your Client Id. |
| redirect_uri | Set to your Redirect URL |
| scope | Space separated set of scopes. See Scopes |
| state | Set to any state you wish to get returned on the redirect URL. We strongly recommend using this for CSRF protection, as described in RFC 6749. |
| code_challenge | If you are using PKCE, this is the BASE64 encoded SHA256 hash of a random verification string. PKCE does not need to be required to use this option, but if PKCE is required, this parameter is required. It is always required for a public client. |
| code_challenge_method | Set to “S256” when sending a code_challenge. S256 is the only method supported; a public client must send it. |
Here is an example URL:
https://www.fitnesssyncer.com/api/oauth/authorize?client_id=YourClientId&response_type=code&scope=source_read+destination_read+source_data_read&redirect_uri=YourRedirectURL&state=InformationForYourServiceScopes
The user will need to grant you access to their account. The scope query string will have each listed separated by a space. In order to allow minimal permissions for the information you need and to allow the user to control the access to their account, FitnessSyncer uses the following scopes:
| Scope | Description |
|---|---|
| profile_read | Read data from the User’s Profile |
| profile_write | Write data to the User’s Profile |
| source_read | View Sources in the User’s Account (but not associated data) |
| source_write | Add, Modify, and Delete Sources in the User’s Account |
| source_data_read | Access the data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. This is an alias for: source_data_activity_read source_data_allergy_read source_data_blood_panel_read source_data_blood_pressure_read source_data_cholesterol_read source_data_condition_read source_data_cycle_tracking_read source_data_ecg_read source_data_glucose_read source_data_medication_read source_data_nutrition_read source_data_oxygen_read source_data_sleep_read source_data_temperature_read source_data_weight_read |
| source_data_activity_read | Access the Activity data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_allergy_read | Access the Allergy data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_blood_pressure_read | Access the Blood Pressure data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_blood_panel_read | Access the Blood Panel data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_condition_read | Access the Condition data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_cycle_tracking_read | Access the Cycle Tracking data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_ecg_read | Access the ECG data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_glucose_read | Access the Glucose data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_medication_read | Access the Medication data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_nutrition_read | Access the Nutrition data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_oxygen_read | Access the Oxygen data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_sleep_read | Access the Sleep data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_temperature_read | Access the Temperature data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| source_data_weight_read | Access the Body Composition data associated with the User’s Sources and FitnessSyncer Notebook Items, including associated Goals. |
| annotation_read | View the notes the User has written on their charts. |
| annotation_write | Add, Modify, and Delete the notes the User has written on their charts. |
| destination_read | View Destinations in the User’s Account (but not associated data) |
| destination_write | Add, Modify, and Delete Destinations in the User’s Account |
| notebook_write | Add, Modify, and Delete FitnessSyncer Notebook Items in the User’s Account. This is an alias for: notebook_activity_write notebook_allergy_write notebook_blood_panel_write notebook_blood_pressure_write notebook_cholesterol_write notebook_condition_write notebook_cycle_tracking_write notebook_glucose_write notebook_medication_write notebook_nutrition_write notebook_oxygen_write notebook_sleep_write notebook_temperature_write notebook_weight_write |
| notebook_activity_write | Add, Modify, and Delete FitnessSyncer Notebook Activity Items in the User’s Account. |
| notebook_allergy_write | Add, Modify, and Delete FitnessSyncer Notebook Allergy Items in the User’s Account. |
| notebook_blood_pressure_write | Add, Modify, and Delete FitnessSyncer Notebook Blood Pressure Items in the User’s Account. |
| notebook_blood_panel_write | Add, Modify, and Delete FitnessSyncer Notebook Blood Panel Items in the User’s Account. |
| notebook_condition_write | Add, Modify, and Delete FitnessSyncer Notebook Condition Items in the User’s Account. |
| notebook_cycle_tracking_write | Add, Modify, and Delete FitnessSyncer Notebook Cycle Tracking Items in the User’s Account. |
| notebook_glucose_write | Add, Modify, and Delete FitnessSyncer Notebook Glucose Items in the User’s Account. |
| notebook_medication_write | Add, Modify, and Delete FitnessSyncer Notebook Medication Items in the User’s Account. |
| notebook_nutrition_write | Add, Modify, and Delete FitnessSyncer Notebook Nutrition Items in the User’s Account. |
| notebook_oxygen_write | Add, Modify, and Delete FitnessSyncer Notebook Oxygen Items in the User’s Account. |
| notebook_sleep_write | Add, Modify, and Delete FitnessSyncer Notebook Sleep Items in the User’s Account. |
| notebook_temperature_write | Add, Modify, and Delete FitnessSyncer Notebook Temperature Items in the User’s Account. |
| notebook_weight_write | Add, Modify, and Delete FitnessSyncer Notebook Body Composition Items in the User’s Account. |
| updatable_providers | For integrations that are the source of branded data, allows the integration to Add, Modify, and Delete Branded Items in the User’s Account |
| leaderboard_participate | Participate in Leaderboards via opt-in, viewing the data, viewing and updating personal preferences in the User’s Account. |
| leaderboard_admin | Add, Modify, Delete, and Administer Leaderboards in the User’s Account. |
| researcher_read | For FitnessSyncer for Researchers, list the participants who have consented to the study and their credentials. |
Accessing the token
On authorizing success, this will redirect back to your site with the following query string parameters:
| Redirect Query String Parameter Name | Description |
|---|---|
| code | A temporary Access Code. The code will be set to “error” if there was an error granting the permission. |
| state | The same value you passed in the above state, if any. Compare it against the value you generated for this user’s session before acting on the code, and discard the response if it does not match — see the note on the state parameter above. |
| iss | The issuer identifier of this authorization server, currently “https://www.fitnesssyncer.com”. |
If you are paying for the users of your application, this is where the subscription is activated unless the user has another active subscription on their account. The user can opt-out by removing the token.
Once you have the code, you can access the code by making a POST request to https://api.fitnesssyncer.com/api/oauth/access_token. The body of this request should contain as application/x-www-form-urlencoded:
| POST Parameter Name | Description |
|---|---|
| grant_type | Set to “authorization_code” |
| code | The temporary code received. |
| client_id | Set to your Client Id. |
| client_secret | Set to your Client Secret. A public client has none and must omit it. |
| redirect_uri | Set to your Redirect URL |
| code_verifier | If you are using PKCE, this is the raw, random verification string that was originally provided as a BASE64 encoded SHA256 hash. PKCE does not need to be required to use this option, but if PKCE is required, this parameter is required. |
Upon success, you will receive a 200-response code with a JSON Body as follows:
| Key | Description |
|---|---|
| expires_in | The lifetime of the access token, in seconds from when this response was generated. |
| access_token | Token to access the data. |
| refresh_token | A token to get a new access_token when the token expires. |
| scope | The space separate scopes that were provided to the application. |
| user_id | An opaque, stable identifier for the account this token was issued for. This is only useful for tagging your own diagnostics or a support request so an issue can be traced back to one account. |
To access any resources from this point forward, simply include the Authorization header with the value “Bearer ” followed by the access_token above. For example, if the access_token was “asdfasdf”, the Authorization header would be set to “Bearer asdfasdf”.
Refreshing the token
The access token will expire periodically. You may either track the expiration yourself, or detect it when a 401 status code is returned, at which point you will need to reauthenticate. You can renew the token by making a POST request to: https://api.fitnesssyncer.com/api/oauth/access_token. The body of this request should contain the following as application/x-www-form-urlencoded:
| POST Parameter Name | Description |
|---|---|
| grant_type | Set to “refresh_token” |
| refresh_token | Set to the refresh_token as received above. |
| client_id | Set to your Client Id. |
| client_secret | Set to your Client Secret. A public client has none and must omit it. |
| redirect_uri | Set to your Redirect URL as included in the original request |
Upon success, you will receive a 200-response code with a JSON Body as follows:
| Key | Description |
|---|---|
| expires_in | The lifetime of the access token, in seconds from when this response was generated. |
| access_token | Token to access the data. |
| refresh_token | A token to get a new access_token when the token expires. |
| scope | The space-separated scopes that were provided to the application. |
| user_id | An opaque, stable identifier for the account this token was issued for. This is only useful for tagging your own diagnostics or a support request so an issue can be traced back to one account. |
Revoking the token
You may revoke a token at any time by making a POST request to: https://api.fitnesssyncer.com/api/oauth/revoke_token.
We support both self-logout by simply using the Authorization header as defined above or we support the RFC 7009 method.
If you are paying for the users of your application, this request will also remove the payment details from their account and it will return to a free account afterwards.
Request Parameters
For self-logout, there are no parameters.
For RFC 7009, the body of the request should contain an application/x-www-form-urlencoded encoded body:
| POST Parameter Name | Description |
|---|---|
| token | Token to remove |
| token_type_hint | Optional: access_token or refresh_token |
| client_id | Set to your Client Id (or use BASIC auth) |
| client_secret | Set to your Client Secret (or use BASIC auth). A public client omits it. |
Response
On success, a 200 will be returned with a JSON object indicating the successful status.
This is also how you deregister a user. When someone stops using your application such as they delete their account with you, cancel, or disconnect FitnessSyncer from your side, revoke the token at that point rather than leaving it live.
Public Clients
An application that runs on the user’s own device, such as a phone app, a desktop app or a command-line tool, cannot keep a Client Secret: anything built into it can be extracted. Create it as a public client instead by checking Public client when you create the application in the developer console. A public client has a Client ID and no Client Secret, and the following rules apply:
- Send only your client_id to the token and revoke endpoints. Do not send a client_secret; a request that includes one is refused as an invalid client.
- PKCE is required. Send a code_challenge with code_challenge_method set to “S256” when authorizing, and the matching code_verifier when accessing the token.
- Each refresh returns a new refresh_token, and the previous one stops working. If a previous refresh token is used again within 30 seconds, the same new pair is returned, so two parts of your app refreshing at the same moment do not sign the user out. If it is used again later, every token your application holds for that user is revoked, and the user has to authorize again.
A public client’s Redirect URL can take three forms, following RFC 8252 (OAuth 2.0 for Native Apps):
- An HTTPS link your app has claimed, such as an iOS universal link or an Android App Link.
- A private-use URI scheme based on a domain you control, such as com.example.yourapp:/oauth/callback.
- A loopback address, such as http://127.0.0.1/callback. Any port is accepted, so a desktop app can listen on whichever port is free; the path must match.
As with any application, contact us with the Redirect URLs you need.
Creating users
If your application can create new users, you can do so using this API.
To do so, make a POST request to https://api.fitnesssyncer.com/api/oauth/access_token. The body of this request should contain the following as application/x-www-form-urlencoded:
| POST Parameter Name | Description |
|---|---|
| grant_type | Set to “password” |
| create | Set to “true” |
| username | The new user’s username. This must be in the form of an e-mail address. |
| password | The new user’s password |
| client_id | Set to your Client Id. |
| client_secret | Set to your Client Secret. |
| redirect_uri | Set to your Redirect URL |
Upon success, you will receive a 200-response code with a JSON Body as follows:
| Key | Description |
|---|---|
| expires_in | The lifetime of the access token, in seconds from when this response was generated. |
| access_token | Token to access the data. |
| refresh_token | A token to get a new access_token when the token expires. |
To access any resources from this point forward, simply include the Authorization header with the value “Bearer ” followed by the access_token above. For example, if the access_token was “asdfasdf”, the Authorization header would be set to “Bearer asdfasdf”.
Other Considerations
It is important to realize that a user can also revoke an access token. For example, under the Permissions tab of My Account, they may choose to revoke your permissions entirely. When this occurs, accessing and refreshing the token will fail with a 403 and you will need to reauthenticate from the beginning.
Changing a password also ends every authorization the user has granted. When a user changes their FitnessSyncer password, every access token, refresh token and API key issued for their account is invalidated, for your application and for every other one. Requests and refreshes made with them then fail with a 401 and an error code of “InvalidToken”, and the user has to authorize your application again.
A user may also delete their FitnessSyncer account outright, either themselves or by leaving it dormant long enough that we delete it for them. Once that happens the token you hold no longer resolves to a user, and requests made with it fail with a 401 and an error code of “InvalidToken”.