The Best Bike Split API

The Best Bike Split Partner API allows developers to connect to authorized user accounts to access course and race plan information. API data requests are limited to Premium Best Bike Split members. Changes may be made to add additional features or improve performance.

If you are interested in becoming an authorized BBS API Partner please contact us with your Company Name, Technical Contact and Project Description.


Version

1.0


Introduction

The Best Bike Split API is organized around REST. Our API is designed to use HTTP response codes to indicate API errors. JSON will be returned in all responses from the API, including errors.


Authorization

Best Bike Split uses the OAuth2 authentication protocol. This allows your applications to request authorization to a user's data. Each registered application will be assigned a client_id and client_secret. The SECRET should never be shared.

Sample Request

To request access to user data on behalf of your application, point the user to the Best Bike Split authorization page along with the required URL Parameters. The page will prompt the user to authorize the application. Please note that only users with a Premium or Coach Subscription may access the API.

Suggested Connect Button

connect best bike split (Download SVG Button)

This button should link to https://bestbikesplit.com/member-connect along with the assigned client_id and redirect_uri as shown below.

GET Resource URL

https://www.bestbikesplit.com/member-connect?

URL Parameters

client_id=ExampleApp&
redirect_uri=http://www.myExampleApp.com/app

Sample Response

Best Bike Split will respond to the user authorization selection by redirecting the user to the redirect_uri provided by your application. On success, a temporary code will be included with the redirect. If access is denied by the user a status=access_denied will be included in the redirect.

http://www.myExampleApp.com/app?code=xxxxxxxxxxxxxxxxxx

Authorization Parameters

Parameter Description Required
client_id
string
A unique client Id assigned by Best Bike Split to your company's APP. If you or your company is interested in working with our API, please contact us for details. Yes
redirect_uri
string
Specifies the URI to which the user's code should be returned to. Yes

Token Exchange

Upon successful authorization your application must now request a user access token through the following post call. This access token will be used for all future API calls and passed as authorization in the header parameters.

Sample Request

You can request a user token by sending the previously supplied temporary code as code and your application's SECRET code as client_secret in the post parameters.

POST Resource URL

https://www.bestbikesplit.com/api/v1/oauth

POST Parameters

code=xxxxxxxxxxxxxxxxxx
client_secret=xxxxxxxxxxxxxxxxxx

Sample Response

A unique access token will be returned as JSON for the user based on the code and client_secret passed in the post parameters.

{
   "access_token": "xxxxxxxxxxxxxxxxxx"		// unique token assigned per user
}

Token Exchange Parameters

Parameter Description Required
code
string
A temporary code assigned to the user. Yes
client_secret
string
A unique code assigned by Best Bike Split to your company's APP. Yes

Deauthorization

You can revoke access between the Best Bike Split user and your application by use of the deauthorize api call.

Sample Request

To revoke access between the Best Bike Split user and your application send the users's access_token in the header parameters.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

POST Resource URL

https://www.bestbikesplit.com/api/v1/deauthorize

Sample Response

A confirmation message will be returned as JSON for the user with the specific token passed as authorization in the header parameters.

{
   "reason": "The application has been deauthorized."	// confirmation of deauthorized user
}

Deauthorization Parameters

Parameter Description Required
authorization A unique token to authorize use of the Best Bike Split API. Yes

Course Information

The following demonstrates how to retrieve a specific course's information and groups of courses based on search parameters.

Sample Request (specific)

You can pull information on a single course by sending the course's unique ID as course_id in the request parameters. In this example the course ID of 321 is passed in as a request parameter.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

GET Resource URL

https://www.bestbikesplit.com/api/v1/course?

URL Parameters

course_id=321

Sample Response (specific)

Course information returned as JSON for the course with the specific id passed as course_id in the request parameters.

{
  courses:[
    {
      "course_id": 321,				// course unique identifier
      "course_name": "Ironman Coeur d'Alene",	// course name
      "course_city": "Coeur d'Alene",		// course city (start)
      "course_state": "ID",			// course state
      "course_country": "US",			// course country
      "start_latitude": 47.67597,		// course latitude (start)
      "start_longitude": -116.78881072,		// course longitude (start)
      "course_distance": 179408,		// course distance (meters)
      "course_verified": 1			// course verified (0 = false, 1 = true)
    }
  ]
}

Sample Request (group)

You can pull information for a group of courses by sending one or more request parameters without a specific course ID parameter. In this example the request parameter for the course's distance as course_distance is passed in. (note: to pull all courses, simply send the request with no search parameters)

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

GET Resource URL

https://www.bestbikesplit.com/api/v1/course?

URL Parameters

course_distance=180000
&course_country=US

Sample Response (group)

Course information returned as JSON for the courses that matched the supplied course_distance request parameters.

{
  courses:[
    {
      "course_id": 321,				// course unique identifier
      "course_name": "Ironman Coeur d'Alene",	// course name
      "course_city": "Coeur d'Alene",		// course city (start)
      "course_state": "ID",			// course state
      "course_country": "US",			// course country
      "start_latitude": 47.67597,		// course latitude (start)
      "start_longitude": -116.78881072,		// course longitude (start)
      "course_distance": 179408,		// course distance (meters)
      "course_verified": 1			// course verified (0 = false, 1 = true)
    },
    {
      "course_id": 496,
      "course_name": "2014 Ironman World Championship",
      "course_city": "Kailua-Kona",
      "course_state": "HI",
      "course_country": "US",
      "start_latitude": 19.64021,
      "start_longitude": -155.99682617,
      "course_distance": 180887,
      "course_verified": 1
    }
  ]
}

Course Parameters

Parameter Description Required
authorization
A unique token to authorize use of the Best Bike Split API. Yes
course_id
integer
Specifies the exact course to pull. Course Id overrides all other search parameters. If no course Id is supplied then search parameters are used to pull courses based on those parameters. No
course_group
integer
Filter courses by the following groups. (range: 1 to 3, default: 1)
1 = your courses
2 = your public courses
3 = your private courses
No
course_name
string
Filter courses by name. (example: "Boston Marathon") No
course_city
string
Filter courses by city. (example: "Hopkinton") No
course_state
string
Filter courses by state. (example: "MA") All US states are standard 2 character abbreviations. No
course_country
string
Filter courses by country. (example: "US") No
course_distance
integer
Filter courses by distance in meters (example: "180000"). If a distance is supplied, all courses within +/- 10,000 meters of that distance will be pulled. No

Course Details

The following demonstrates how to retrieve a specific course's detailed information.

Sample Request (RAW)

You can pull information on a single course by sending the course's unique ID as course_id in the request parameters. In this example the course ID of 496 is passed in as a request parameter.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

GET Resource URL

https://www.bestbikesplit.com/api/v1/course-details?

URL Parameters

course_id=496

Sample Response (RAW)

Course's detailed information returned as JSON for the course with the specific id passed as course_id and the dataType set to default (RAW) in the request parameters.

{
  course_details:[
    {
      "course_id": 496,				// course unique identifier
      "course_name": "IM World Championship",	// course name
      "data_type": "RAW",			// course data type
      "track_points":[				// course track points
          {
            "distance": 0,			// track distance (meters)
            "elevation": 1.1,			// track elevation (meters)
            "latitude": 19.64027,		// track latitude
            "longitude": -155.99675		// track longitude
          },
          {
            "distance": 10.712,
            "elevation": 1.4,
            "latitude": 19.64027,
            "longitude": -155.99675
          }
      ]
    }
  ]
}

Sample Request (GPX)

You can pull information on a single course as a base64 encoded GPX by sending the course's unique ID as course_id and setting the dataType in the request parameters. In this example the course ID of 496 and dataType of 2 is passed in as request parameters.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

GET Resource URL

https://www.bestbikesplit.com/api/v1/course-details?

URL Parameters

course_id=496
&data_type=2

Sample Response (GPX)

Course's detailed information returned as JSON for the course with the specific id passed as course_id and the dataType set to 2 (base64 encoded GPX) in the request parameters.

{
  course_details:[
    {
      "course_id": 496,				// course unique identifier
      "course_name": "IM World Championship",	// course name
      "data_type": "GPX",			// course data type
      "course_file": "PD94bWwgdmVyc2l..."	// base64 encoded course GPX
    }
  ]
}

Course Details Parameters

Parameter Description Required
authorization
A unique token to authorize use of the Best Bike Split API. Yes
course_id
integer
Specifies the exact course to pull. Yes
data_type
integer
Set the data type to be returned. (range: 1 to 2, default: 1)
1 = raw json
2 = base64 encoded GPX
No

Course Upload

The following demonstrates how to upload a GPX or FIT file to create a new course.

Sample Request

You can upload a course file by sending a multipart form request with the course file. The file must be a valid GPX or FIT file under 30MB.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx
Content-Type: multipart/form-data

POST Resource URL

https://www.bestbikesplit.com/api/v1/course-upload

Form Parameters

course_file=[GPX or FIT file]
course_name=My Course Name
elevation_type=1
public=0

Sample Response

Course information returned as JSON for the newly created course.

{
  "course_id": 12345,			// course unique identifier
  "course_name": "My Course Name",	// course name
  "city": "Austin",			// course city (start)
  "state": "TX",			// course state
  "country": "US",			// course country
  "distance": 40000.5,			// course distance (meters)
  "start_latitude": 30.2672,		// course latitude (start)
  "start_longitude": -97.7431		// course longitude (start)
}

Course Upload Parameters

Parameter Description Required
authorization
A unique token to authorize use of the Best Bike Split API. Yes
course_file
file
A GPX or FIT file containing the course data. Maximum file size is 30MB. Yes
course_name
string
Name for the course. If not provided, the filename will be used. No
elevation_type
integer
Elevation data source. (range: 1 to 2, default: 1)
1 = Use file elevation
2 = Use BBS elevation data
No
public
integer
Make course publicly searchable. (range: 0 to 1, default: 0)
0 = Private
1 = Public (Premium only)
No

Bike Information

The following demonstrates how to retrieve a user's bikes with full equipment data.

Sample Request (all bikes)

You can pull all bikes for the authenticated user by calling the endpoint without parameters.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

GET Resource URL

https://www.bestbikesplit.com/api/v1/bikes

Sample Request (specific bike)

You can pull a single bike by passing bike_id as a parameter.

URL Parameters

bike_id=45

Sample Response

Bike information returned as JSON array.

{
  "bikes": [
    {
      "bike_id": 45,                    // bike unique identifier
      "bike_name": "Cervelo P5",        // bike name
      "bike_type": 2,                   // 1=Road, 2=TT/Tri, 3=MTB, 4=Gravel
      "weight_imperial": 18.5,          // bike weight (lbs)
      "weight_metric": 8.39,            // bike weight (kg)
      "components": 1,                  // component level
      "helmet": 2,                      // helmet type
      "front_wheel_depth": 60,          // front wheel depth (mm)
      "front_wheel_width": 25,          // front wheel width (mm)
      "rear_wheel_depth": 90,           // rear wheel depth (mm)
      "rear_wheel_width": 25,           // rear wheel width (mm)
      "tire_type": 1,                   // tire type
      "tube_type": 1,                   // tube type
      "riding_style": 2,                // riding style
      "climbing_style": 2,              // climbing style
      "mechanical_loss": 0.025,         // drivetrain loss
      "rolling_resistance": 0.0032,     // tire rolling resistance
      "cda_yaw_0": 0.2300,              // CdA at 0° yaw
      "cda_yaw_5": 0.2280,              // CdA at 5° yaw
      "cda_yaw_10": 0.2250,             // CdA at 10° yaw
      "cda_yaw_15": 0.2220,             // CdA at 15° yaw
      "cda_yaw_20": 0.2200,             // CdA at 20° yaw
      "cda_yaw_climb_0": 0.3200,        // CdA climbing at 0° yaw
      "cda_yaw_climb_5": 0.3180,        // CdA climbing at 5° yaw
      "cda_yaw_climb_10": 0.3150,       // CdA climbing at 10° yaw
      "cda_yaw_climb_15": 0.3120,       // CdA climbing at 15° yaw
      "cda_yaw_climb_20": 0.3100,       // CdA climbing at 20° yaw
      "drag_option": 1,                 // drag calculation option
      "hip_shoulder": 45.0,             // hip to shoulder (cm)
      "hip_head": 55.0,                 // hip to head (cm)
      "shoulder_width": 40.0,           // shoulder width (cm)
      "hip_width": 35.0,                // hip width (cm)
      "seat_handlebar": 50.0,           // seat to handlebar (cm)
      "handle_width_racing": 42.0,      // handlebar width racing (cm)
      "handle_width_climbing": 44.0,    // handlebar width climbing (cm)
      "torso_angle_racing": 25.0,       // torso angle racing (degrees)
      "torso_angle_climbing": 35.0,     // torso angle climbing (degrees)
      "seat_tube_angle": 76.0           // seat tube angle (degrees)
    }
  ]
}

Bike Parameters

Parameter Description Required
authorization
A unique token to authorize use of the Best Bike Split API. Yes
bike_id
integer
Filter to a specific bike by ID. If not provided, returns all user bikes. No

Race Plan Information

The following demonstrates how to retrieve a specific race's information and groups of races based on search parameters.

Sample Request (specific)

You can pull information on a single race by sending the race's unique ID as race_id in the request parameters. In this example the race ID of 123 is passed in as a request parameter.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

GET Resource URL

https://www.bestbikesplit.com/api/v1/race?

URL Parameters

race_id=123

Sample Response (specific)

Race information returned as JSON for the race with the specific id passed as race_id in the request parameters.

{
  races:[
    {
      "race_id": 123,				// race unique identifier
      "race_name": "Ironman Texas",		// race name
      "course_id": 221,				// course unique identifier
      "course_name": "2016 IM Texas",		// course name
      "bike_name": "Trek",			// bike name
      "race_city": "Town Center",		// race city (start)
      "race_state": "TX",			// race state
      "race_country": "US",			// race country
      "race_distance": 179157.7,		// race distance (meters)
      "race_time": 20363.721,			// race time (seconds)
      "race_avg_speed": 8.7979,			// race average speed (meters/second)
      "race_avg_power": 178.89,			// race average power (watts)
      "race_avg_yaw": 6.4,			// race average yaw angle (degrees)
      "race_np": 182.01,			// race Normalized Power
      "race_if": 0.55,				// race Intensity Factor
      "race_tss": 172,				// race Training Stress Score
      "race_updated": "2016-04-20T14:23:08Z", 	// date and time of last record update
    }
  ]
}

Sample Request (group)

You can pull information for a group of races by sending one or more request parameters without a specific race ID parameter. In this example the request parameter for the races's distance as race_distance and country as race_country are passed in. (note: to pull all races, simply send the request with no search parameters)

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

GET Resource URL

https://www.bestbikesplit.com/api/v1/race?

URL Parameters

race_distance=180000
&race_country=US

Sample Response (group)

Race information returned as JSON for the races that matched the supplied race_distance request parameters.

{
  races:[
    {
      "race_id": 123,				// race unique identifier
      "race_name": "Ironman Texas",		// race name
      "course_id": 221,				// course unique identifier
      "course_name": "2016 IM Texas",		// course name
      "bike_name": "Trek",			// bike name
      "race_city": "Town Center",		// race city (start)
      "race_state": "TX",			// race state
      "race_country": "US",			// race country
      "race_distance": 179157.7,		// race distance (meters)
      "race_time": 20363.721,			// race time (seconds)
      "race_avg_speed": 8.7979,			// race average speed (meters/second)
      "race_avg_power": 178.89,			// race average power (watts)
      "race_avg_yaw": 6.4,			// race average yaw angle (degrees)
      "race_np": 182.01,			// race Normalized Power
      "race_if": 0.55,				// race Intensity Factor
      "race_tss": 172,				// race Training Stress Score
      "race_updated": "2016-04-20T14:23:08Z", 	// date and time of last record update
    },
    {
      "race_id": 164,
      "race_name": "Kona 2016",
      "course_id": 496,
      "course_name": "IM World Championship",
      "bike_name": "Tri Bike",
      "race_city": "Kailua-Kona",
      "race_state": "HI",
      "race_country": "US",
      "race_distance": 180887.26,
      "race_time": 19270.626,
      "race_avg_speed": 9.3867,
      "race_avg_power": 239.85,
      "race_avg_yaw": 5.91,
      "race_np": 245.78,
      "race_if": 0.75,
      "race_tss": 300,
      "race_updated": "2016-04-11T12:10:05Z",
    }
  ]
}

Race Parameters

Parameter Description Required
authorization
A unique token to authorize use of the Best Bike Split API. Yes
race_id
integer
Specifies the exact race to pull. Race Id overrides all other search parameters. If no race Id is supplied then search parameters are used to pull races based on those parameters. No
race_name
string
Filter races by name. (example: "Ironman Texas") No
course_name
string
Filter races by course by name. (example: "IM Texas 2016") No
bike_name
string
Filter races by bike by name. (example: "Trek Speed Concept") No
race_city
string
Filter races by city. (example: "Town Center") No
race_state
string
Filter races by state. (example: "TX") All US states are standard 2 character abbreviations. No
race_country
string
Filter races by country. (example: "US") No
race_distance
integer
Filter races by distance in meters (example: "180000"). If a distance is supplied, all courses within +/- 10,000 meters of that distance will be pulled. No
list_type
integer
Set the list type to be returned. (range: 1 to 2, default: 1)
1 = all data
2 = race_id and race_name only
No
list_limit
integer
Limit the number of races returned (example: "10"). No

Race Plan Details

The following demonstrates how to retrieve a specific race's detailed information.

Sample Request (specific)

You can pull information on a single race by sending the race's unique ID as race_id in the request parameters. In this example the race ID of 164 is passed in as a request parameter.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

GET Resource URL

https://www.bestbikesplit.com/api/v1/race-details?

URL Parameters

race_id=164

Sample Response

Race's detailed information returned as JSON for the race with the specific id passed as race_id in the request parameters.

{
  race_details:[
    {
      "race_summary":[					// race summary
          {
            "race_id": 164,				// race unique identifier
            "race_name": "Kona 2016",			// race name
            "course_id": 496,				// course unique identifier
            "course_name": "IM World Championship",	// course name
            "bike_name": "Tri Bike",			// bike name
            "race_city": "Kailua-Kona",			// race city (start)
            "race_state": "HI",				// race state
            "race_country": "US",			// race country
            "race_distance": 180887.26,			// race distance (meters)
            "race_time": 19270.626,			// race time (seconds)
            "race_avg_speed": 9.3867,			// race average speed (meters/second)
            "race_avg_power": 239.85,			// race average power (watts)
            "race_avg_yaw": 5.91,			// race average yaw angle (degrees)
            "race_np": 245.78,				// race Normalized Power
            "race_if": 0.75,				// race Intensity Factor
            "race_tss": 300,				// race Training Stress Score
            "race_updated": "2016-04-11T12:10:05Z", 	// date and time of last record update
          }
      ],
      "course_points":[					// course points
          {
            "distance": 0,				// course distance (meters)
            "latitude": 19.64021,			// course latitude
            "longitude": -155.99683,			// course longitude
            "power": 250,				// course power (watts)
            "speed": 10.284				// course speed (meters/second)
          },
          {
            "distance": 1885.315,
            "latitude": 19.64867,
            "longitude": -156.00451,
            "power": 247,
            "speed": 9.902
          }
      ],
      "track_points":[					// track points
          {
            "distance": 0,				// track distance (meters)
            "elevation": 1.1,				// track elevation (meters)
            "latitude": 19.64027,			// track latitude
            "longitude": -155.99675			// track longitude
          },
          {
            "distance": 10.712,
            "elevation": 1.4,
            "latitude": 19.64027,
            "longitude": -155.99675
          }
      ],
      "segments":[					// segments
          {
            "segment_count": 1,				// segment count
            "distance": 1885.315,			// segment distance (meters)
            "start_latitude": 19.64021,			// segment start latitude
            "end_latitude": 19.64867,			// segment end latitude
            "start_longitude": -155.99683,		// segment start longitude
            "end_longitude": -156.00451,		// segment end longitude
            "start_elevation": 1.1,			// segment start elevation (meters)
            "end_elevation": 13.7,			// segment end elevation (meters)
            "bearing": 319.472,				// segment bearing (degrees)
            "grade": 0.668,				// segment grade (percent)
            "time": 187.4369,				// segment time (seconds)
            "speed": 10.284,				// segment speed (meters/second)
            "average_speed": 10.093,			// segment average speed (meters/second)
            "power": 305,				// segment power (watts)
            "percent_ftp": 0.837,			// segment percent of ftp (percent)
            "yaw_angle": 7.48,				// segment yaw angle (degrees)
            "drag_effect": 0.3913,			// segment drag (cda)
            "wind_effect": -1.262,			// segment wind effect (meters/second)
            "air_density": 1.0914,			// segment air density (kg/m^3)
            "rolling_resistance": 0.0056,		// segment rolling resistance 
            "bike_weight": 9.98,			// segment bike weight (kilograms)
            "rider_weight": 74.84			// segment rider weight (kilograms)
          },
          {
            "segment_count": 2,
            "distance": 101.619,
            "start_latitude": 19.64867,
            "end_latitude": 19.64942,
            "start_longitude": -156.00451,
            "end_longitude": -156.00396,
            "start_elevation": 13.7,
            "end_elevation": 14.2,
            "bearing": 34.630,
            "grade": 0.492,
            "time": 10.4397,
            "speed": 9.902,
            "average_speed": 9.734,
            "power": 309,
            "percent_ftp": 0.865,
            "yaw_angle": 8.19,
            "drag_effect": 0.3902,
            "wind_effect": 0.793,
            "air_density": 1.0923,
            "rolling_resistance": 0.0056,
            "bike_weight": 9.98,
            "rider_weight": 74.84	
          }
      ]     
    }
  ]
}

Race Details Parameters

Parameter Description Required
authorization
A unique token to authorize use of the Best Bike Split API. Yes
race_id
integer
Specifies the exact race to pull. Yes

Race Plan Create

The following demonstrates how to create a new race plan from an existing course.

Sample Request

You can create a race plan by sending the required parameters. The race will be optimized using the GAMS engine and the result returned.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx
Content-Type: application/json

POST Resource URL

https://www.bestbikesplit.com/api/v1/race-create

POST Parameters (JSON)

{
  "course_id": 321,
  "bike_id": 45,
  "model_type": 1,
  "goal_watt": 250
}

Sample Response

Race information returned as JSON for the newly created race plan.

{
  "race_id": 12345,			// race unique identifier
  "course_id": 321,			// course unique identifier
  "status": "completed",		// race generation status
  "race_time": 18500.5,			// race time (seconds)
  "race_distance": 180000.0,		// race distance (meters)
  "race_avg_power": 248.5,		// race average power (watts)
  "race_np": 252.3,			// race Normalized Power
  "race_tss": 285,			// race Training Stress Score
  "race_if": 0.85			// race Intensity Factor
}

Race Create Parameters

Note: All units should be metric (Celsius, kph, kg, hPa, meters).

Parameter Description Required
authorization
A unique token to authorize use of the Best Bike Split API. Yes
course_id
integer
Specifies the course to use for the race plan. Must be a course owned by or accessible to the user. Yes
bike_id
integer
Specifies the bike profile to use. Must be owned by the user. Yes
model_type
integer
Set the optimization model type. (range: 1 to 3, default: 1)
1 = Normalized Power Model
2 = Goal Time Model
3 = Training Stress Score Model
No
The following goal parameter is required based on model_type selected.
goal_watt
integer
Goal normalized power target in watts. Required for model_type 1. Defaults to rider's FTP. No
goal_hours, goal_minutes, goal_seconds
integer
Goal finish time components. Required for model_type 2. No
goal_tss
integer
Goal target training stress score. Required for model_type 3. No
race_name
string
Name for the race plan. Defaults to "API Race" with timestamp. No
race_date
datetime
Race date and start time as ISO 8601. (example: 2024-06-24T07:00:00) No
weather_type
integer
Weather data source. (range: 1 to 3, default: 1)
1 = Standard (use manual weather params below)
2 = Advanced (auto-fetched 12 points along course based on race_date)
3 = Hourly (auto-fetched weather by hour based on race_date)
No
Standard Weather (weather_type=1) - Use the following single-point parameters. For Advanced/Hourly weather, these are ignored and weather is automatically fetched based on race_date.
temp
float
Temperature in degrees Celsius. No
humidity
integer
Humidity percentage. (range: 0 to 100, default: 60) No
wind_speed
float
Wind speed in kilometers per hour (kph). No
wind_dir
integer
Wind direction in degrees. (range: 0 to 359, default: 0) No
pressure
float
Barometric pressure in hPa. (default: 1013.25) No
road_type
integer
Road surface quality. (range: 1 to 7, default: 3)
1 = Perfect (track surface)
2 = Good (smooth asphalt)
3 = Average (typical road mix)
4 = Poor (cracked/worn roads)
5 = Rough (fresh chip seal)
6 = Off Road (gravel)
7 = Off Road (dirt)
No
course_terrain
integer
Course terrain type for wind calculations. (range: 1 to 6, default: 3)
1 = Open Coast
2 = Desert/Plains
3 = Mixed/Populated
4 = Heavy Forest
5 = Mountainous
6 = Inner City
No
surface_type
integer
Surface condition mode. (range: 1 to 2, default: 1)
1 = Standard (use road_type for entire course)
2 = Advanced (per-segment surface conditions; road_type used as default, Premium only)
No
race_type
integer
Type of race (affects default settings). (range: 1 to 6)
1 = Triathlon
2 = Time Trial
3 = Road Race
4 = Mountain Bike
5 = Other
6 = Gravel Race
No
max_watt
integer
Maximum power limit in watts. (default: 999) No
climb_speed
float
Speed threshold at which athlete changes position on climbs (kph). Lower = stays seated longer. Defaults by level: Pro=22, Advanced=24, Recreational=27. No
max_speed
float
Maximum descending speed the athlete is comfortable with (kph). Defaults vary by race_type and rider level. No
adv_climb_descent
integer
Enable advanced climb/descent settings. (0=OFF, 1=ON, default: 1) No
seg_reducer
integer
Segment smoothing. (0=OFF, 1=ON, default: 1) No
minimum_vi
float
Minimum Variability Index. Higher values force steadier power. Defaults vary by race_type and rider level (e.g., MTB=1.15, Gravel=1.10, Triathlon=1.00). No
rolling_start
integer
Account for rolling start (already at speed). (0=OFF, 1=ON, default: 0) No
alt_adjustNP
integer
Altitude adjustment for Normalized Power model. (0=OFF, 1=ON, default: 0) No
alt_adjustTSS
integer
Altitude adjustment for TSS model. (0=OFF, 1=ON, default: 0) No

Race Plan Update

The following demonstrates how to update a specific race plan with new parameters.

Sample Request

You can request a race plan update by sending parameters in the post parameters and receive the updated race details in the response.

Header Parameters

authorization: xxxxxxxxxxxxxxxxxx

POST Resource URL

https://www.bestbikesplit.com/api/v1/race-update

POST Parameters

race_id=164
model_type=1
goal_watt=325

Sample Response

Race's detailed information returned as JSON for the race with the specific id passed as race_id in the request parameters.

See above Race Plan Details for response example.

Race Parameters

Note: All units should be metric (Celsius, kph, kg, hPa, meters).

Parameter Description Required
authorization
A unique token to authorize use of the Best Bike Split API. Yes
race_id
integer
Specifies the exact race to update. Yes
model_type
integer
Set the model type to be used. (range: 1 to 3)
1 = Normalized Power Model
2 = Goal Time Model
3 = Training Stress Score Model
No
Please note that one of the following three parameters is required if a model_type is requested and is dependent on the model_type.
goal_watt
integer
Goal normalized power target in watts. No
goal_time
integer
Goal finish time in seconds. No
goal_tss
integer
Goal target training stress score. No
rider_weight
float
Rider's weight in kilograms. (range: 30 to 150, up to 2 decimal places) No
bike_weight
float
Bike's weight in kilograms. (range: 4 to 25, up to 2 decimal places) No
ftp
integer
Rider's functional threshold power in watts. No
race_drag
float
Drag coefficient for 0° yaw in a racing position. (up to 4 decimal places) No
climb_drag
float
Drag coefficient for 0° yaw in a climbing position. (up to 4 decimal places) No

Error Codes

The Best Bike Split API uses the standard set of HTTP response codes. For convenience, the most relevant ones are listed here.

Note that, in the event of an error, a message is returned in the response body.

Code Type Description
200 OK Success!
400 Bad Request The request could not be understood due to malformed syntax.
401 Unauthorized Authentication credentials were missing or incorrect.
403 Forbidden The request is understood but it has been refused due to insufficient permission.
404 Not Found The URI requested is invalid or the resource requested, such as a user, does not exist.
405 Method Not Allowed The URI requested does not support the specific HTTP method used in the request.
500 Internal Server Error Something is broken. Please contact us so our support team can investigate.
502 Bad Gateway The server is down or being upgraded.
503 Service Unavailable The servers are up, but overloaded with requests. Try again later.