Live Timing Standard v2 (not used)

🚧

Proposal currently in draft form waiting for timer feedback

This document covers a draft proposal for Version 2 of the Triathlon.org Live Timing Standard. The current version 1 may be found here.

Overview

The aim of Version 2 of the Triathlon.org Live Timing Standard is to produce a higher quality of real-time timing data directly from races which may be delivered via the Triathlon.org API platform to subscribers. The improvements proposed in the standard reduce timing latency and greatly increase the potential for displaying timing data and developing feature-rich timing applications when used in conjunction with other available APIs. The proposal also removes the requirement for timers to host any web-facing hosts as timing will be pushed to the Triathlon.org API platform which will handle the delivery of timing messages to all connected clients. Significantly, the standard is designed to support all ITU sanctioned events including Paratriathlon by incorporating custom data fields. Whilst greatly simplified, this timing standard is much more similar in scope to the Olympic Data Feed.

Delivery

Timing should be delivered by a series of timing messages that each contain full information as to the current state of the race. Each message, which contains valid JSON as the body of a POST request with a corresponding Content-type: application/json header, should be delivered to the /live/timing API endpoint.

Authentication

Timers will use the standard API authentication method adding authentication parameters to the header of all requests sent. Each timer will be provided a unique API key to use specific to their timing application.

Response Codes

The Triathlon.org API will respond with a 2xx response on successful receipt of the message. All other response codes should be considered a failure. Badly formatted or unauthenticated messages will result in a 4xx code. For reference, our general response codes are available here.

Retry Policy

Timers should implement a sensible (needs more clarification) retry policy to primarily cover the case of a loss of internet connectivity at the venue. As each message contains entire timing information if a later message is available (defined as a later timing message id) there is no need to retry an earlier message. For reference you may also consult the retries policy of the Subscription API.

Validation

All timing messages should validate against current JSON standards. Any messages that do not contain valid JSON or are missing required data fields will be rejected by the Triathlon API validation mechanism and a 400 response code returned.

Push Frequency

Timing messages should be pushed immediately on receipt of new timing information i.e. an athlete crossing a timing point. For times when there would be an overwhelming number of updates e.g. a large bike pack crossing a timing point, messages should be combined into a single message such that push frequency does not exceed one push every 500ms (limit subject to discussion). Messages should only be pushed when there is a change of information in the message and messages should not be sent according to a fixed time schedule.

Message Persistence

Timers do not need to persist timing messages as this will be handled via the Triathlon API platform with specific messages available for historical analysis / replay via the Live API.

Concurrent Races

Often there will be more than one race occurring at the same time (defined by race_code or prog_id which are both unique). Each race should be considered a single entity and formatted according to the specification. Logic should be present to handle instances when multiple athletes from different races cross a timing point at the same time.

Testing

For development purposes you may use the sandbox boolean to indicate that you wish to send to the sandbox environment, which will perform exactly as the production environment with the exception that messages will not be published.

Timing Message Format

Each timing message should contain complete timing information such that a user may be able to retrieve all information by receiving the latest timing push message. All message characters should be UTF-8 formatted.

A curtailed sample format of timing messages is as follows:

{
   "id":1234,
   "date":"2017-01-01 13:34:59.123Z",
   "race_code":"EM",
   "event":"2017 ITU World Triathlon Abu Dhabi",
   "sandbox": true,
   "event_id":35645,
   "prog_id":23567,
   "start_time":"2017-01-01 13:26:59.123Z",
   "num_athletes":2,
   "latest":{
      "segment_id":3,
      "segment_name":"Bike Lap 4",
      "num_athletes":1
   },
   "athletes":[
      {
         "athlete_id":12345,
         "start_num":23,
         "athlete_name":"Test Athlete",
         "athlete_nat":"GBR",
         "latest_segment":3,
         "position":1,
         "time":"01:23:23",
         "splits":[
            {
               "segment_id":1,
               "segment_name":"Swim Lap 1",
               "segment_time":"00:08:12",
               "segment_distance":0.75,
               "cumulative":"00:08:12",
               "position":12,
               "difference":"00:00:15"
            },
            {
               "segment_id":2,
               "segment_name":"Swim Exit",
               "segment_time":"00:08:15",
               "segment_distance":0.75,
               "cumulative":"00:16:27",
               "position":9,
               "difference":"00:00:12"
            },
            {
               "segment_id":3,
               "segment_name":"T1",
               "segment_time":"00:00:54",
               "segment_distance":null,
               "cumulative":"00:17:21",
               "position":9,
               "difference":"00:00:11"
            }
         ]
      },
      {
         "athlete_id":54321,
         "start_num":22,
         "athlete_name":"Another Test Athlete",
         "athlete_nat":"CAN",
         "latest_segment":2,
         "position":12,
         "time":"01:23:23",
         "splits":[
            {
               "segment_id":1,
               "segment_name":"Swim Lap 1",
               "segment_time":"00:08:12",
               "segment_distance":0.75,
               "cumulative":"00:18:12",
               "position":15,
               "difference":"00:00:15"
            },
            {
               "segment_id":2,
               "segment_name":"Swim Exit",
               "segment_time":"00:08:17",
               "segment_distance":0.75,
               "cumulative":"00:16:29",
               "position":12,
               "difference":"00:00:12"
            }
         ]
      }
   ]
}

A breakdown of each parameter is listed below:

Parameter

Example

Description

Format

id

1

The id of the message which should be sequential and start from 1 for each race (defined by the prog_id)

number

date

2017-01-01 13:34:59.123Z

An ISO 8601 formatted date of the time of the message

string

race_code

EM

A descriptive name for the race

string

event

2016 ITU World Triathlon Abu Dhabi

A descriptive name for the event

string

sandbox

true

Boolean to indicate whether to use the sandbox environment for development (defaults to false)

boolean

event_id

12345

The unique event_id corresponding to the event_id in the Events API

number

prog_id

54321

The unique prog_id corresponding to the prog_id in the Events API

number

start_time

2017-01-01 13:34:59.123Z

An ISO 8601 formatted date corresponding to the start time of the race

string

num_athletes

12

The number of athletes in the race (which must correspond to the number of items in the athletes array)

number

latest

The latest object contains information regarding the latest timing point data (may be null if no timing data)

object

latest.segment_id

1

The segment_id containing the latest result

number

latest.segment_name

Swim Exit

The segment name containing the latest results

string

latest.num_athletes

12

The number of athletes that have passed through the timing point

number

athletes

An object containing an array of all athletes in the race

object

athletes.id

123456

The unique athlete_id corresponding to the athlete_id in the Athletes API

number

athletes.start_num

12

The start number of the athlete

number

athletes.name

Alistair Brownlee

The name of the athlete

string

athletes.nat

GBR

The three letter IOC country code

string

athletes.latest_segment_id

3

The latest segment_id that contains data for the athlete (may be nullif no data)

number

athletes.position

12

The latest position of the athlete (may be null if no data)

number

athletes.time

00:17:16.145

An ISO 8601 formatted time

string

athletes.splits

An array of split objects containing data for each segment completed by the athlete (may be nullif no data)

object

athletes.splits.segment_id

3

The segment_id of the split

number

athletes.splits.segment_name

Swim Exit

The name of the timing segment

string

athletes.splits.segment_time

00:08:16.345

The time to complete this segment

string

athletes.splits.segment_distance

750

The distance of the segment specified in m (may be nullif not defined)

number

athletes.splits.cumulative_time

00:14:12.345

The cumulative time of all segments to this point

string

athletes.splits.position

12

The position of the athlete at this timing point

number

athletes.splits.difference

00:01:07.123

The difference of the athlete to the leader at this timing point

string

Notes

  • All athletes must be present in the athlete array regardless of their status in the race.
  • Millisecond data may be provided where available.
  • Athletes should be ordered in the athletes array according to the latest timing point information, naturally athletes crossing the latest timing point will be ordered first and DNF athletes will be at the end of this list with the remainder of the athletes ordered in relation to their position at the previous timing point.
  • A list of segment_ids & names will need to be provided by the timers prior to the start of an event as these are subject to course conditions.
  • The segment_distance parameter is optional and may be included if such data is available and relevant.

Paratriathlon

A para object is provided within the athlete object (athletes.para) for Paratriathlon events indicating additional Paratriathlon specific information for the athlete. These fields are optional depending on the Paratriathlon class.

Parameter

Example

Description

Format

athlete.para

A Paratriathlon specific object

object

athlete.para.guide_name

David Barnett

The name of the Paratriathlon guide

string

athlete.para.guide_id

1234

The athlete_id of the Paratriathlon guide according to the Athletes API

number

athlete.para.start_delay

15

The number of seconds delay in a staggered start format event

number

Optional Data Objects

The format allows in the future for additional data objects to be provided if such data becomes available such as real-time weather data or GPS positioning of athletes. The schema of such objects will be devised when delivering this data becomes feasible.

Distribution

Timing will be distributed by the Triathlon API platform to applications through the Live REST API, Subscriptions API and Streaming APIs to all connected applications.