Xert Online API Version 1.4

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:

  1. Obtain and refreshing a user authorization token

  2. Getting a list of workouts available for non-authenticated user

  3. Getting a list of workouts for an authenticated user

  4. Retrieving a workout definition

  5. Uploading a FIT file

Example curl messages are exemplary calls that should be followed. Any questions should be sent to support@xertonline.com.

Token authentication

Obtaining token

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"}

Refreshing token

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"}

Getting User Information

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

success:

Boolean
Indicates that the request is successful/unsuccessful.

signature:

Object
The user’s current fitness signature containing values for ftp, ltp, hie and pp representing Threshold Power, Lower Threshold Power, High Intensity Energy and Peak Power respectively.

status:

String
The user’s current training status: Detraining, Very fresh, Fresh, Tired, Very tired representing the user’s current freshness status

weight:

Number
The user’s weight in kilograms.

tl:

Object
The user’s current training loads containing values for low, high, peak, total representing the training load for each individual system and the total.

targetXSS:

Object
The user’s current training targets containing values for low, high, peak, total representing the training targets recommended by the system for each system and the total.

source:

String

The source of training information.

wotd:

Object
The user’s workout-of-the-day information:

 

type:

Type of workout-of-the-day

None, Forecast, Scheduled representing No workout-of-the-day, workout-of-the-day was assigned to a Forecast AI training placeholder, workout-of-the-day was a planned workout.

 

name:

Name of the workout

 

workoutId:

Id of the workout

 

description:

Description text

 

difficulty:

Difficulty score

 

url:

URL of the workout file for the workout-of-the-day. Note that the URL will need to be requested with the user’s token.

Parameters

format:

String | optional

Value is erg or zwo and indicates the format of the workout file to be returned. If not provided, no workout file will be returned.

{
"success": true,
"weight": 81,
"status": "Fresh",
"signature": {
    "ltp": 243.9623680703351,
    "ftp": 314.6014550178407,
    "hie": 28.25563477900224,
    "pp": 1251.5005813659977
    },
"tl": {
    "low": 123.32987160482055,
    "high": 6.563550862763262,
    "peak": 1.8767393717439016,
    "total": 131.7701618393277
    },
"source": "Workout",
"targetXSS": {
    "low": 74.8839053229011,
    "high": 0,
    "peak": 0,
    "total": 74.8839053229011
    },
"wotd": {
    "name": "AI Generated Workout",
    "workoutId": "vovdxww5i7fzqbun",
    "description": "AI generated workout powered by Xert\n\nThis has 3 declining sets starting with 2 x 07:53 at 242W with 00:00 rest in-between.",
    "type": "Forecast",
    "difficulty": 2.155537419064349,
    "url": "https://www.xertonline.com/oauth/workout-download/vovdxww5i7fzqbun.zwo"
    }
}

 

Getting workouts

List default workouts - no authentication required.

curl -X GET "https://www.xertonline.com/oauth/workout" ~> {"success":true,"workouts":[{"path":"MGLq16v2O6vrILBi","name":"Default Workout","description":"","last_modified":1457118394}]}⏎ 

List a user's workouts.

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}]}⏎ 

Retrieve a workout

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.

Getting Activities

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
success: Boolean
Indicates that the request is successful.
name: Integer
Name of the activity.
description: String
Description of the activity.
session_data: Object
Per second MPA data object.
summary: Object
Summary details of activity including XSS, XLSS, XHSS, XPSS, XEP, MEP, TWS, SP, SFD, Focus, Specificity, Activity Type, Activity Date, Signature, Difficulty Rating, Distance (km), Duration (minutes) Difficulty, Total grams of Carbs, Total grams of Fat and Street View Image
Parameters
id/path: String | required
The identifier of the activity.
include_session_data: Integer | optional
Values are 1 and 0, default is 0. Set to 1 to include session_data value from the response.

{
"success": true,
"name": "Sample Title",
"description": "Sample Description",
"session_data": [
 {
"power": 37.4,
"unix_time": 1501327986000,
"mpa": 2433.9170179125,
"cad": null,
"alt": 169,
"hr": null,
"spd": 39636,
"tgt": null,
"lat": 43.622447289526,
"lng": -79.792798189446,
"dist": 42605.14,
"tws": 147.53,
"xds": 84.483105789006
},
{
"power": 33.8,
"unix_time": 1501327987000,
"mpa": 2434.0872751323,
"cad": null,
"alt": 169,
"hr": null,
"spd": 39132,
"tgt": null,
"lat": 43.62251887098,
"lng": -79.792894916609,
"dist": 42616.01,
"tws": 147.53,
"xds": 84.444223240528
},
],
"summary":{
"session": {
"max_power": 765,
"avg_power": 234.37876486,
"max_cadence": 99,
"total_elevation_gain": 974,
"total_calories": 3903
},
"xss": 552.19146965358,
"xlss": 465.43228697047,
"xhss": 78.156195599284,
"xpss": 8.602987083827,
"xep": 200.59242389133,
"focus": "Rouleur",
"mep": 173,
"tws": 507736.33294669,
"sp": 0.51640347500268,
"sfd": 398.82093884511,
"specificity": "Mixed",
"difficulty": 256.78248819058,
"difficulty_rating": "5 - Hard",
"distance":30,
"duration":3600
"sig": {
"ftp": 250,
"atc": 41139,
"pp": 1447
},
"medal": 2,
"breakthrough": 1,
"prev_sig": {
"ftp": 300.48137188449,
"atc": 27284.630970804,
"pp": 1361.5247761747,
"ltp": 232.26979445748
},
"activity_type": "Cycling",
"start_date": {
"date": "2018-09-22 09:54:21.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"distance": 93.0061,
"duration": 13209,
"total_grams_carbs": 248.78449606004,
"total_grams_fat": 120.94966162224,
"progression": {
"date": "2018-09-22 09:54:20",
"tl": {
"ftp": 92.706161948713,
"hie": 5.4803348960987,
"pp": 1.5145020294862
},
"rl": {
"ftp": 57.114808191115,
"hie": 4.5317592024292,
"pp": 0.93325134033198
},
"form": 37.121180140421
},
"training_status": 3.7057428249799,
"freshness": "Fresh",
"street_view": "https://xertonline.com/assets/images/maps/street_view/user-2/aortnwffwgptcxfy.png",
"activity_map": "https://xertonline.com/assets/images/maps/activity_map_aortnwffwgptcxfy.png",
"chart_view": "https://xertonline.com/assets/images/charts/aortnwffwgptcxfy"
}

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
success: Boolean
Indicates that the request is successful.
activities: Object
Activity details including Name, Description, Activity Type, Start Date and Activity Path/ID
Parameters
from: Integer, Timestamp | required
A timestamp where the filtering of activities will Start.
to: Integer, Timestamp | required
A timestamp where the filtering of activities will End.
updated_from: Integer, Timestamp | optional
A timestamp where the filtering of activities will Start based on Updated Time.
{
"success": true,
"activities": [
 {
"name": "Morning Run",
"start_date": {
"date": "2017-08-12 11:08:29.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"description": "Lorem Imposum",
"path": "4j9o4hhg5zrl0pah",
"activity_type": "Run"
},
{
"name": "Evening Ride",
"start_date": {
"date": "2017-08-12 11:08:29.000000",
"timezone_type": 3,
"timezone": "UTC"
},
"description": "Lorem Imposum",
"path": "4j9o4hhg5zrl0pah",
"activity_type": "Cycling"
}
]
}



Uploading .FIT file

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.