API Docs Test the API Right Here!

The API hews as closely as possible to the REST architectural style. The API is organized around a set of resources that populate the world of endurance racing, like events, races, race entries, etc. With the API, your application can perform operations on these resources through the HTTP protocol. You can use the documentation below to learn about the API. In particular, you can test out API calls right here on this page to see exactly how API calls work and how to incorporate them into your application.

Terminology

A resource is some object of interest targeted by the API. In the world of endurance racing this includes events, races, athletes, timing devices, and others. We'll refer to a specific resource sometimes as a resource entity to distinguish that specific entity from all entities of that resource type. A resource collection is a number of resource entities of the same type.

The ChronoTrack Live Open Platform API is comprised of operations on these resources. All operations are executed by sending HTTP requests to one of our API endpoints. An API endpoint is a URI to which a API request is directed.

Endpoints

All API requests should be sent to one of the following two endpoints:

Endpoint Type Endpoint URL
Production https://api.chronotrack.com/api
Testing https://qa-api.chronotrack.com/api

The production endpoint should only be used in live, production code and never for testing. The production endpoint is backed by the ChronoTrack Live production database, which means all changes to data via the production API will be immediately visible to ChronoTrack Live users.

The testing endpoint is backed by a separate testing database that is refreshed every night with a copy of the production database. This means any API activity that changes data via the testing endpoint will have those changes disappear the next day. Please note the QA environment is not 100% guaranteed up at all times as it is a test environment.

Note: Both endpoints are secured by the https (TLS/SSL) protocol. Any requests sent via the non-secure http protocol will be redirected to the secure endpoint.

Security

All requests to our production API must be through the secure HTTPS protocol. Any requests that come in on a non-secure port will be redirected to our TLS/SSL secured service.

All requests must also be authenticated. First, a request must originate from an application that is registered and approved by ChronoTrack. Second, the application must authenticate the ChronoTrack Live user on whose behalf it is making requests to our system.

Supported Authorization Methods

We support four authentication methods, each suited for a different kind of application environment. For applications that have easy access to the user's browser, like a web or mobile application, we support the OAuth 2.0 Web Flow. For applications without browser access, like native desktop/laptop applications, we provide two alternatives. If the environment your application operates in has the capacity to securely store your users' ChronoTrack Live account credentials, then you can use HTTP Basic authentication. If you can't, or prefer not to, locally store your users' credentials, we support the OAuth 2.0 Password Flow.

Finally, for certain testing environments where data security requirements are minimal, we support a simple authentication scheme where you can pass a user id and password as parameters to the API call. All our methods are described in detail below.

OAuth2 Web Flow

Web applications can acquire an OAuth2 access token for a ChronoTrack Live user by following these steps:

  1. Obtain a ChronoTrack Live developer account here. Creating a developer account will also register your client application.

  2. Your application will be assigned a client_id and a client_secret. The client_id is public information, but you should take care to safeguard your client_secret. During the process of registering your application with us, you will be asked to provide a redirect_uri, that is, a URL within your web application where users will be redirected after granting your application permission to access their ChronoTrack Live resources. An example redirect_uri is:

    https://mywebapp.com/oauth2
  3. When the user first invokes a function in your application requiring access to their ChronoTrack Live resources, you should redirect the user to our authorization end-point:

    GET /oauth2/authorize?response_type=code
    Make sure to add a Basic HTTP Authorization header to this request using your client_id and client_secret as the username and password. This is required to verify the authorization request is coming from your application. See the specific instructions in the HTTP Basic Authentication section for the mechanics of how to construct the Authorization header.

    This will redirect your user to our authentication service. They will have to login as they normally would to ChronoTrack Live. They then will be presented with a screen that allows them to grant your application permission to access their ChronoTrack Live resources.

  4. Upon authorizing your application, the user will be redirected back to your application's specified redirect_uri:

    https://mywebapp.com/oauth2?code=bef10603874b

    The code parameter appended to your redirect uri is a short-lived (10 minutes), single-use authorization code that your application can convert into a longer-lived access token.

  5. To obtain an access token, your application should make a GET API call to our token endpoint:

    GET /oauth2/token?grant_type=authorization_code&code=bef10603874b

    passing in the code parameter returned to your application in the last step and making sure to add an Authorization header that provides Basic HTTP authentication for your client app (using your client_id as the username and your client_secret as the password).

    This API token endpoint will return a json formatted object containing an OAuth 2.0 access token that allows your application to access the user's ChronoTrack Live resources for a lengthy period of time (usually 72 hours).

    {
      "access_token":  "2YotnFZFEjr1zCsicMWpAA",
      "token_type":    "Bearer",
      "expires":       "1343309220",
      "refresh_token": "tGzv3JOkF0XG5Qx2TlKWIA"
    }

    You also will receive a refresh token that you can send to our token endpoint to receive another access token, good for another 72 hours of use. The refresh token is valid for one year or until the user revokes your application's access to their resources.

    You send a refresh token request like this:

    GET /oauth2/token?grant_type=refresh_token&refresh_token=597262138b23

    making sure to again provide Basic HTTP authentication for your client app (using your client_id as the username and your client_secret as the password). This will send you another access token that you can use for another 72 hours. It will also return a new refresh token that you can use to extend your access.

  6. Finally, with a fresh access token, you can make API requests, like getting a list of events the user has access to:

    GET /api/event

    making sure to pass in an Authorization header with the access token like so:

    Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA

OAuth2 Password Flow

For applications where the OAuth2 Web Flow cannot be used (for example, native applications without a browser layer), an OAuth access token can be acquired by making a single call to our token endpoint and passing the end-user’s ChronoTrack Live account credentials as the username and password parameters with a grant_type of password.

GET /oauth2/token?grant_type=password&username=joesmith%40someplace.com&password=some_password
Note: In order for this to work you must pass in an Authorization header using HTTP Basic Auth where the username is your client_id and the password is your client_secret. Follow the instructions under the "HTTP Basic Auth" tab for how to construct this header.
Note: that users need only enter their username and password once for the application to authenticate. Applications using the password flow SHOULD NOT store the user's credentials.

HTTP Basic Authentication

This method involves passing in the resource owner's ChronoTrack Live account username and password directly, according to the HTTP Basic Authentication protocol. You simply construct an Authorization header as follows:

  1. Obtain the resource owner's ChronoTrack Live account credentials. For example, you could provide a dialog through your application asking for their ChronoTrack Live account username and password requesting their permission to use those credentials for accessing their account data on their behalf.
  2. Concatenate their username and password with a colon (:). For example, if their username is "zooba" and their password is "tooba", you would construct the string zooba:tooba.
  3. Now base64 encode that concatenated string to produce: em9vYmE6dG9vYmE=.
  4. Finally, add an authorization header to your request like this:
    Authorization: Basic em9vYmE6dG9vYmE=

WARNING! This method can be less secure than using one of the OAuth2 methods, and as such we do not recommend you use it. However, we still provide support for this authentication method because some applications may find it simpler to use.

There are two risks in using this method. The first risk lies in sending a request over a non-TLS/SSL connection. While we automatically redirect all non-secure requests to our TLS/SSL port, an initial non-secure request risks exposing your user's ChronoTrack Live account credentials to anyone sophisticated enough to be sniffing network packets, allowing man-in-the-middle attacks. This risk can be completely mitigated by sending all requests over TLS/SSL.

A second risk is that your application has to ask for and store the user's ChronoTrack Live credentials. You then become responsible for safeguarding their password and making sure it is not exposed via an insecure storage medium, which adds complexity to your application security aparatus. The only way to mitigate this risk is to not use this method and instead use one of the OAuth2 methods.

Test Auth Scheme

In certain situations, like when using our docs here to test the API, security requirements are minimal and using oauth or basic authentication is infeasible. For these special cases we support a simple method of passing in the ChronoTrack Live resource owner credentials via parameters. For instance, if you have a test account for a resource owner called test-user@myorg.com with password 12345, then you could make authenticated requests to our API on behalf of that test user:

GET /api/event?client_id=abcdefgh&user_id=test-user%40myorg.com&user_pass=12345

To prevent exposing the password, you should SHA1-encode the password:

GET /api/event?client_id=abcdefgh&user_id=test-user%40myorg.com&user_pass=8cb2237d0679ca88db6464eac60da96345513964
WARNING! We provide this authorization method for convenience and testing. We strongly recommend you do not use this in a production environment. If you do, at least make sure you only do so over TLS/SSL and SHA1-encode the password.

Formats

The following table describes the formats used for the content of API requests and responses. The first column contains a short format code for each format, while the second column contains the standard Internet Assigned Numbers Authority MIME type for the format.

Format Code MIME Type Description
json application/json Javascript Object Notation. See http://www.json.org/ for details.
xml application/xml Extensible Markup Language. See http://www.w3.org/XML/ for details.
yaml application/yaml Yet Another Markup Language. See http://www.yaml.org/ for details.
csv text/csv Comma Separated Values. A tabular plain-text format. Columns within each row are delimited by a comma character (","). Columns that contain literal commas are escaped by double quotes. Rows are delimited by a carriage-return/line-feed ("\r\n") sequence. See http://tools.ietf.org/html/rfc4180 for more details.
tsv text/tab-delimited-values Tab Separated Values. A tabular plain-text format. Columns within each row are delimited by a tab character ("\t"). Rows are delimited by a carriage-return/line-feed ("\r\n") sequence. See http://www.iana.org/assignments/media-types/text/tab-separated-values for more details.

Requests

API requests to our servers are just standard HTTP requests. As with all HTTP requests, a request to our API always contains a method which denotes the operation to be done, always has a URL (specifying the resource to operate on), usually has some parameters you send to qualify your request, and sometimes those parameters are specified in the URL itself, sometimes in the request headers and sometimes in the request body (formatted as JSON, XML, or CSV). We'll look at each of these request components in this section.

Request Methods

HTTP Method Example Requests
GET

This method is used to retrieve either a list of resource entities or a single resource entity.

GET /api/event
Return a list of all events the user has access to
GET /api/event/123
Return a single event specified by its resource ID
GET /api/event/123/entry
Return a list of all entries (registrants) in event 123
PUT

This method is used to update a single existing resource entity.

PUT /api/entry/123456
Update an existing entry (body is a single entry entity)
POST

This method is used to create or update one or more resource entities.

POST /api/event/123/entry
Create new and/or update existing entries in event 123 (body is one or more entry entities)
DELETE

This method is used to delete an existing resource entity.

DELETE /api/entry/123456
Delete an existing entry by specifying its resource ID

Request URL

The URL path specifies the resource or resource collection the request operates on.

/api/{resource-name}.{format}/{resource-id}/{sub-resource-name}?{url-params}
URL Component Required Meaning
/api/ Yes All API request URLs begin with this prefix.
resource-name Yes All API request URLs must contain the name of the resource type to operate on.
format No The format of the response that you prefer. May be one of format codes specified in the formats section.
resource-id No The identifier for a specific resource. If you are interested in getting or setting the properties of a specific resource or getting a collection of sub-resources belonging to a specific resource, you must specify this URL component in your request to identify the resource.
sub-resource-name No For requests where you want the collection of resources that belong to a specific resource (like all the entries in a given event, for instance), you use this URL component to name the type of sub-resource you want.
url-params No Ampersand (&) separated list of request parameters, URL-encoded as per RFC 1738.

Request Parameters

Most API requests will have one or more parameters that define some context for the request. For instance, all requests must specify the client_id parameter, which identifies the application the request originates from. The request parameters may be specified in several different places, including the URL path, the URL query, the request header and the request body. We'll consider each in turn.

URL Path Parameters

Two optional, but significant, parameters are commonly specified in the path of a URL request. First, the resource_id of the resource being operated on. Second, the desired format of the response. The following example illustrates the use of both of the parameters to request a particular event's properties in xml format:

GET /api/event.xml/123

URL Query Parameters

The query portion of a URL is the list of parameters that comes after the question mark following the URL path. If more than one parameter is specified, it must be separated from the others by an ampersand (&). The following URL requests the details for event 123 in xml format for the client application with id abcdef:

GET /api/event.xml/123?client_id=abcdef

Instead of specifying the format of the request in the URL path, you could instead specify it as a query parameter:

GET /api/event/123?client_id=abcdef&format=xml

Header Parameters

Request headers can also be used to specify context for a request. The following table provides a list of headers you can use with API requests.

Header Meaning
Accept This is an alternative to specifying the desired format of the response in the URL path or query. The value should be set to one of the MIME types specified in the formats section. Defaults to application/json.
Accept-Encoding If you have the capacity to uncompress gzipped or deflated content, set this header to either "gzip" or "default" to trigger automatic compression of the response content to save network bandwidth.
Accept-Language The languages you'd prefer the response to be sent back using. See RFC 1766 for more details.
Authorization Authorization for the request. The value here depends on what kind of authorization method you are using. See the security section for details on the setting.
X-Http-Method-Override Specify this header to override the value of the HTTP method for a request. This should only be used if your application wants to submit a PUT or DELETE request but your HTTP library only supports GET and POST. You can tell your library to use the POST method (instead of PUT) or the GET method (instead of DELETE) and set then this header to PUT or DELETE.
Content-Type The MIME type of the content body of your request. Must be set to one of the MIME types listed in the formats section. Defaults to application/json.
Content-Length The size (in bytes, not characters) of the request body. Usually this will be set by your HTTP library and does not need to be set manually.
Date The RFC 822 date-time on the client when the request is sent. This should be set by your HTTP library.

Body Parameters

Method Expected Content
GET No content sent with request.
POST One or more properly encoded entities containing the fields of each new resource to create or existing resource to update. In the case of updating resources, you must provide either the resource id or some other defined identifier to allow our server to find the existing resource.
PUT A properly encoded (possibly partial) entity containing the data items of the specified resource to be updated. You only need to provide those data items that require updating. The id of the resource being updated is specified as part of the URL path of the request.
DELETE No content sent with request.
When sending a body in your request that is not formatted as json, remember to set the Content-Type header appropriately so our API server can decode it.

Common API Request Parameters

The following table enumerates some commonly used request parameters and where they are usually included in the request.

Parameter Placement Comment
format Path, Query
client_id Query
page Query
last_id Query
modified_after Query
modified_before Query
columns Query
user_id Query
user_pass Query

Rate Limiting

When 1500 concurrent connections, from the same IP address, are reached within a 60 second time frame, the user will be blacklisted for the remaining duration of that time frame and will receive the 503 over rate error.

Responses

An API response from our servers has several salient characteristics worth drawing attention to. First, each response has a numeric HTTP code that indicates success or failure. Second, a response usually contains a body formatted as JSON, XML, or CSV that contains the data you requested. Third, for many requests that return multiple entities (like a list of all events your user has access to, for instance), there are headers in the response that contain useful information on the size of the total result set and what portion of that total result set the current body of the request contains. We'll elaborate on each of these in turn.

Response Codes

Code Meaning
Success
200 Success With Content. The request succeeded and content was returned. The content of the response body depends on the type of request. A GET on a single resource will return the entity corresponding to that resource. A GET on a resource collection will return one or more entities. A POST will return a data structure for each requested entity indicating either that the resource was created or updated. The responses will correspond one for one with the order of entities in the request.
202 Accepted. The request has been accepted for processing, but the processing has not been completed. The response to the initial request provides a url that can be used to get further information about the status of processing. This allows our server to accept a request that might take some time to complete without requiring your connection persist until that process is done.
Client Errors
400 Bad Request. The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications. Details of the error are provided in the body of the response.
401 Unauthenticated. The request requires authentication (of the ChronoTrack Live user) and either the credentials provided are not a match, or no credentials were provided. Details of the error are provided in the body of the response.
403 Forbidden. The server understood the request, but is refusing to fulfill it. Authorization will not help and the request SHOULD NOT be repeated. More details are in the body of the response. Usually this is caused by going over usage limits for a request type by an application.
404 Not Found. The server could not find any resources requested by the client.
Server Errors
500 Internal Server Error. The server encountered an unexpected condition which prevented it from fulfilling the request.
501 Not Implemented. The server does not support the functionality required to fulfill the request.
503 Server Unavailable. The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay may be indicated in a Retry-After header. If no Retry-After is given, the client should handle the response as it would for a 500 response.

503 over rate This 'IP', 'IP range' or 'email address' has been blacklisted, please contact esupport@chronotrack.com or call (812) 759-7877 to work with our support staff to resolve this issue.

Response Bodies

For responses that return content (basically all responses except PUT and DELETE) the format of the response body can be set to one of several alternatives.

You may specify the response format you want in one of two ways. First, you can add an Accept header to your request with the appropriate MIME type for your preferred format. Second, you can add an extension to the resource name in the URL (for example, to request a list of all accessible events in XML format, you could use GET /api/event.xml. If neither of these methods is used, the response format defaults to JSON. The proper extension is just the lower-case form of the name in the table above.

Response Headers

Header Meaning
Standard HTTP Headers
Content-Type The MIME type of the response body.
Content-Length The size (in bytes, not characters) of the response body.
Content-Encoding If the request indicates it can accept compression via the Accept-Encoding header, our API server will compress the response body to save network bandwidth. In this case, the Content-Encoding response header contains the compression method used, either "gzip" (see RFC 1952) or "deflate" (see RFC 1951) depending on which algorithm was requested.
Transfer-Encoding If set, it will be set to "chunked". The chunked encoding modifies the response body in order to transfer it as a series of chunks, each with its own size indicator, followed by an optional trailer containing entity-header fields. This allows dynamically produced content to be transferred along with the information necessary for the recipient to verify that it has received the full message.
Content-Language The language used in the response represented as in RFC 1766 using ISO-639 language abbreviations and, optionally, ISO-3166 country codes to construct the language-tag.
Date The date and time on the server when the response was sent. This is in RFC 822 date-time format, for example: "Tue, 04 Dec 2012 05:44:04 GMT."
WWW-Authenticate The WWW-Authenticate response header field is included only in 401 (Unauthorized) response messages. The field value consists of at least one challenge that indicates the authentication scheme and parameters applicable to the request URI. For more details see RFC 2617.
Link For resource collection requests, provides a list of links to first, last, previous and next pages for use in pagination interfaces in the client application. This various relation types (first, prev, next, last) are defined in RFC 5988.
Custom ChronoTrack Live Headers
X-Ctlive-Api-Version Provides the current version number of the API.
X-Ctlive-Row-Count For resource collection requests, provides the total number of entities in the collection (of which only a portion may be returned in the current response).
X-Ctlive-Current-Rows For resource collection requests, provides the current range of rows contained in the response body in the format min-max (so on page 1 of a response with a page size of 10, this header's value would be "1-10", page 2 would be "11-20", and so on).
X-Ctlive-Page-Count For resource collection requests, provides the total number of pages, given the current page size.
X-Ctlive-Page-Size For resource collection requests, provides the number of entities returned in a single "page" or results.
X-Ctlive-Current-Page For resource collection requests, provides the current page of results within the total number of pages contained in the collection, given the page size setting.

Character Encoding

We use UTF-8 encoding through and through to guarantee proper encoding of all international character sets. All data you send to an API endpoint is assumed to be, and therefore must be, encoded in UTF-8. All data transmitted from an API endpoint is encoded in UTF-8.

Data Types

The API uses a pretty standard collection of types for all data that it processes, as described below.

Type Description
resource_id A non-semantic (numeric) identifier associated with a particular resource. This identifier is guaranteed to be unique within the collection of all resources of that resource type. Resource identifiers are assigned by ChronoTrack Live and will not change over the life cycle of a resource. Resources may also have one or more semantically significant identifiers assigned by event and timer related organizations.
string A UTF-8 encoded character string without any line breaks, and rarely longer than 250 characters.
text A UTF-8 encoded character string that may contain line breaks and is likely to be longer than 250 characters.
boolean May take either the value 0, meaning false, or 1, meaning true.
integer An integral number (a number without any fractional part).
float A floating point number (a number that may have a fractional part).
enum Several data items in the API may take on a value drawn from a small enumeration of possible strings. All enumerated values are represented as strings.
date Dates (without a time) are represented in ISO-8601 standard format, namely YYYY-MM-DD.
epoch_time Datetimes are represented as unix epoch times, namely the number of seconds since midnight January 1, 1970 UTC. Information on how to convert unix epoch times to other date/time formats can be found at http://epochconverter.com.

Resources (Live Testing Sandbox)

This section describes the the list of available resource types as well as the operations available for each. Click on the resource names below to expand the documentation for each. Each operation can be tested live right here on this web page to get a better sense of how the API works.

For each API operation below, you must provide a valid application client_id as well as administrative credentials from a valid ChronoTrack Live account that has access to at least one event. If you sign-in with your developer credentials and revisit this page, these values will be filled in automatically for you. Otherwise, common test credentials will be used that have limited access to a few test events.

Loading resources...