Changes to 1.5:
- Added OAuth Authorization Code flow for third-party applications
Changes to 1.3:
- Added new Training and Fitness Info endpoint
Changes to 1.2:
- Added Progression and Training Status to Activity Details
Changes to 1.1:
- Added Session, Images, Previous Signature and Medal return values to Activity Details
This document specifies the Oauth and REST methods to use to perform the following functions:
Obtain and refreshing a user authorization token
Authorizing a third-party application via the OAuth Authorization Code flow
Getting a list of workouts available for non-authenticated user
Getting a list of workouts for an authenticated user
Retrieving a workout definition
Uploading a FIT file
Example curl messages are exemplary calls that should be followed. Any questions should be sent to support@xertonline.com.
curl -u xert_public:xert_public -POST "https://www.xertonline.com/oauth/token" -d 'grant_type=password' -d 'username=AzureDiamond' -d 'password=Hunter2'~> {"access_token":"ee88cf29984d4fe205ca574ec1edd01ae67d74d2","expires_in":604800,"token_type":"Bearer","scope":"basic","refresh_token":"1badfdee0f72b847dc91d1baf9e5c095c774c14a"}
curl -u xert_public:xert_public -POST "https://www.xertonline.com/oauth/token" -d 'grant_type=refresh_token' -d 'refresh_token=1badfdee0f72b847dc91d1baf9e5c095c774c14a'~> {"access_token":"7d3fc2e8cb80caffd881f08e764e1b507168cce4","expires_in":604800,"token_type":"Bearer","scope":"basic","refresh_token":"da61ee326213aa9676c6e26faab41050b847bcc3"}
Third-party applications should use the Authorization Code flow: the user authenticates on xertonline.com itself and your application never sees their Xert credentials.
Client credentials are issued by Xert and are not currently available via self-service. Email support@xertonline.com with your application name and the redirect URI(s) you want to use, and we will issue you a client_id and client_secret.
Send the user’s browser to the authorize endpoint with the following query parameters:
GET https://www.xertonline.com/oauth/authorize?client_id=your_client_id&redirect_uri=https://yourapp.example.com/callback&response_type=code&state=RANDOM_OPAQUE_STRING
client_id – the client ID issued to your application.
redirect_uri – where Xert should send the user back to after authorization; should match a URI you registered.
response_type – always code.
state – an opaque value your application generates and can use to protect against CSRF; Xert returns it unmodified. We recommend always sending one, as Xert does not enforce its presence.
If the user is not already logged in to Xert, they will be prompted to log in first. They are then shown a consent screen naming your application and the data it is requesting access to (Activities, Workouts and Performance data – Xert currently issues a single basic scope covering all of these). If they approve, Xert redirects back to your redirect_uri with an authorization code:
https://yourapp.example.com/callback?code=AUTHORIZATION_CODE&state=RANDOM_OPAQUE_STRING
curl -u your_client_id:your_client_secret -POST "https://www.xertonline.com/oauth/token" -d 'grant_type=authorization_code' -d 'code=AUTHORIZATION_CODE' -d 'redirect_uri=https://yourapp.example.com/callback'~> {"access_token":"ee88cf29984d4fe205ca574ec1edd01ae67d74d2","expires_in":604800,"token_type":"Bearer","scope":"basic","refresh_token":"1badfdee0f72b847dc91d1baf9e5c095c774c14a"}
The resulting access_token and refresh_token are used exactly as described above under Token authentication – use the Authorization: Bearer header on subsequent API calls, and the refresh_token grant to obtain a new access token once it expires.
Retrieve User's Training, Fitness and Status Information
Obtain a user’s current fitness and training information.
curl
-X GET "https://www.xertonline.com/oauth/training_info?format=zwo"
-H "Authorization: Bearer
7d3fc2e8cb80caffd881f08e764e1b507168cce4"
curl -X get "https://www.xertonline.com/oauth/workout-download/vovdxww5i7fzqbun.zwo" -H "Authorization:
Bearer 7d3fc2e8cb80caffd881f08e764e1b507168cce4"
|
Attributes |
Sample Response |
||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||
curl -X GET "https://www.xertonline.com/oauth/workout"~> {"success":true,"workouts":[{"path":"MGLq16v2O6vrILBi","name":"Default Workout","description":"","last_modified":1457118394}]}⏎
curl -X GET "https://www.xertonline.com/oauth/workouts" -H "Authorization: Bearer 7d3fc2e8cb80caffd881f08e764e1b507168cce4"~> {"success":true,"workouts":[{"path":"0GWegmcHSK6JKHth","name":"workout1","description":"Workout description","last_modified":1456263137},{"path":"ISm75NAmocJ7eUHr","name":"This is a workout","description":"Description goes here.","last_modified":1457025192}]}⏎
Resolving a workout requires a specific user's fitness signature to calculate power values in watts, as well as interval durations, so a user's token is needed. Presently, the workout itself does not need to belong to the user whose token and signature are used.
The workout is specified by the path parameter given when obtaining a list of workouts. The parameter is added onto the request url.
curl -X GET "https://www.xertonline.com/oauth/workout/ISm75NAmocJ7eUHr" -H "Authorization: Bearer 7d3fc2e8cb80caffd881f08e764e1b507168cce4"~>{"success":true,"name":"test workout","description":"Description goes here","workout":[{"name":"Warmup","index":0,"power":213,"duration":300,"interval_count":1},{"name":"Intervals","index":1,"power":557.5,"duration":48.106355492065,"power_rest":0,"duration_rest":20.821684998231,"interval_count":1},{"name":"Intervals","index":1,"power":557.5,"duration":13.206337103223,"power_rest":0,"duration_rest":20.821684998231,"interval_count":31},{"name":"Cooldown","index":2,"power":213,"duration":300,"interval_count":1}]}⏎
The output's "workout" field is an array where each entry represents a set of similar intervals. Each set specifies the name of the interval to which it belongs, its index in the workout designer, as well as the target power in watts and set duration in seconds for both the work and rest interval. As in the above example, one set in the workout designer may be split into multiple set entries in this api call, depending on how mpa and time based intervals get resolved.
Retrieve User's Activity.
The activity is specified by the path parameter given when obtaining activity details. The parameter is added onto the request url.
curl -X GET "https://www.xertonline.com/oauth/activity/MGLq16v2O6vrILBi?include_session_data=1" -H "Authorization: Bearer 7d3fc2e8cb80caffd881f08e764e1b507168cce4"
| Attributes | Sample Response | ||||||||||||||||
|
|
||||||||||||||||
Retrieve User's Activity List.
Activity List are specified by a Date Range, "FROM" and "TO". The parameter is added onto the request url.
curl -X GET "https://www.xertonline.com/oauth/activity?from=1483230813&to=1506731613" -H "Authorization: Bearer 7d3fc2e8cb80caffd881f08e764e1b507168cce4"
| Attributes | Sample Response | ||||||||||||
|
|
||||||||||||
The .FIT file needs to be posted to xertonline as multipart/form-data.
The 'name' parameter is optional, and sets the name of the activity. If omitted, the name of the .FIT file will be used.
curl -POST "https://www.xertonline.com/oauth/upload" -H "Authorization: Bearer 7d3fc2e8cb80caffd881f08e764e1b507168cce4" -F 'file=@workout.fit' -F 'name=Morning Ride'~> {"success":true,"json":{"files":[{"name":"workout.fit","size":55358,"type":"application\/octet-stream","url":"\/activities\/JOWCIbZWuvuLQoE7","deleteType":"DELETE","deleteUrl":"\/activities\/JOWCIbZWuvuLQoE7"}]}}⏎
The "json" field of the response is mostly meaningless and will be removed later.