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.
1.0
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.
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.
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.
This button should link to https://bestbikesplit.com/member-connect along with the assigned client_id and redirect_uri as shown below.
https://www.bestbikesplit.com/member-connect?
client_id=ExampleApp& redirect_uri=http://www.myExampleApp.com/app
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
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 |
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.
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.
https://www.bestbikesplit.com/api/v1/oauth
code=xxxxxxxxxxxxxxxxxx client_secret=xxxxxxxxxxxxxxxxxx
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 }
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 |
You can revoke access between the Best Bike Split user and your application by use of the deauthorize api call.
To revoke access between the Best Bike Split user and your application send the users's access_token in the header parameters.
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/deauthorize
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 }
Parameter | Description | Required |
---|---|---|
authorization |
A unique token to authorize use of the Best Bike Split API. | Yes |
The following demonstrates how to retrieve a specific course's information and groups of courses based on search parameters.
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.
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/course?
course_id=321
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) } ] }
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)
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/course?
course_distance=180000 &course_country=US
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 } ] }
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 |
The following demonstrates how to retrieve a specific course's detailed information.
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.
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/course-details?
course_id=496
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 } ] } ] }
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.
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/course-details?
course_id=496 &data_type=2
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 } ] }
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 |
The following demonstrates how to retrieve a specific race's information and groups of races based on search parameters.
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.
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/race?
race_id=123
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 } ] }
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)
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/race?
race_distance=180000 &race_country=US
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", } ] }
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 |
The following demonstrates how to retrieve a specific race's detailed information.
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.
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/race-details?
race_id=164
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 } ] } ] }
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 |
The following demonstrates how to update a specific race plan with new parameters.
You can request a race plan update by sending parameters in the post parameters and receive the updated race details in the response.
authorization: xxxxxxxxxxxxxxxxxx
https://www.bestbikesplit.com/api/v1/race-update
race_id=164 model_type=1 goal_watt=325
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.
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. | No |
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 |
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. |