RTRT.me - Real Time Race Tracking

Real-Time Race Tracking for World-Class Events

TCP API Reference ( Updated 2011-11-09 ) CHANGELOG
  • 2011-11-09
    - Commands > 'Call' command now available for single API queries.
  • 2011-10-16
    - Commands > Streaming - Resuming or Advancing > 'ugt' & 'agt' polling mode option

The RTRT.me TCP API allows developers to interact with the event data via a simple TCP socket connection.

Formatting

All commands and responses are terminated by carriage return + line feed (\r\n)

Client commands are separated by a tilde (~).

Server responses are entirely JSON encoded. Instead of parsing on a separator, the client must JSON decode each server response. This allows the server responses to be schema-less, meaning a response can have any number of key=values, similar to the Web API.


Access

When in service, the RTRT.me TCP API server runs on port 39399 at an assigned address for your event. For example:

tcp://tcp.rtrt.me:39399

Access is restricted by firewall, and only approved client hosts will be allowed to connect.

A pre-registered Application ID and Token is required (see Connecting below).


Connecting

Upon initial connection, the client must send an auth message to the server with the following format:

auth~<client software name>~<application id>~<application token>\r\n

Example: auth~SMSTool~4c5d9d5ef469f69057f7766a~c133185f0d53b9a818bb6d3d5b506215\r\n

Server will respond with a JSON encoded API message terminated with '\r\n'.

If ID and token are accepted, the response will include a JSON encoded 'ack' object with 'cmd' equal to 'auth' and 'resp' containing various application settings and token details. For example:

{
	"ack":{
		"cmd":"auth",
		"resp":{
			"api":"RTRT.me",
			"description":"Real Time Race Tracking Service API.",
			"documentation":"http://rtrt.me/docs/api",
			"application":{
				"name":"Demo App",
				"events":["EVENTDEMO"],
				"insplit":["name",
				"timeOfDay",
				"milePace",
				"mph",
				"kmPace",
				"kmh",
				"etnp",
				"etfp",
				"etf",
				"startTime"],
				"counts":true,
				"pagelinks":true,
				"id":"4c5d9d5ef469f69057f7766a",
				"api":"1.0"
			},
			"info":{
				"cacheKey":0
			}
		}
	}
}

NOTE: '\r\n' terminator is implied throughout the rest of this document but excluded for readablity.

If the appid or token is not accepted, you will receive an ack response that includes an 'error' object such as:

{
	"ack":{
		"cmd":"auth",
		"resp":{
			"error":{
				"type":"access_denied",
				"msg":"Either you did not specify an Application ID, or your App ID is not currently valid for any events."
			},
			"info":{
				"cacheKey":0
			}
		}
	}
}

Commands

Streaming

To make the RTRT.me TCP server start sending you a stream of data, you need to provide a query for it to perform. The query (API path) is formatted much like those in the Web API.

Use the stream command along with an API path.

stream~< API path >

NOTE: Streaming is supported for 'polling' queries only, which currently includes "splits" to pull the live data, and on "profiles" to poll on changes to roster list. For other API queries (non-polling), use the 'call' command instead.

Splits data can be streamed with the following command.

stream~/events/[EVENT NAME]/points/[POINT OR LIST OF POINTS]/splits

Example: stream~/events/EVENTDEMO/points/5K,10K,FINISH/splits

You will receive a JSON encoded ack.

{
	"ack":{
		"cmd":"stream",
		"resp":{
			"path":"/events/EVENTDEMO/points/5K,10K,FINISH/splits"
		}
	}
}

Streaming starts immediately. The client will begin receiving transmissions of all splits for these points as they become available in the system. Each transmission includes one or more splits contained in a 'list' object.

{
	"list":[{
		"time":"1289122196.76",
		"timeOfDay":"9:29:57 am",
		"waveTime":"00:18:39.28",
		"i":"1296493798_228",
		"point":"5K",
		"tag":"111",
		"name":"Kim Smith",
		"milePace":"06:01",
		"milePaceAvg":"06:01",
		"mph":"9.99",
		"kmPace":"03:44",
		"kmh":"16.08",
		"etnp":"5M~00:30:02~9:41 am",
		"etfp":"FINISH~02:37:26~11:48 am",
		"etf":"11:48 am",
		"epc":"19",
		"startTime":"9:11:18 am"
	},
	{
		"time":"1289122196.86",
		"timeOfDay":"9:29:57 am",
		"waveTime":"00:18:39.38",
		"i":"1296493798_232",
		"point":"5K",
		"tag":"107",
		"name":"Mara Yamauchi",
		"milePace":"06:01",
		"milePaceAvg":"06:01",
		"mph":"9.99",
		"kmPace":"03:44",
		"kmh":"16.08",
		"etnp":"5M~00:30:02~9:41 am",
		"etfp":"FINISH~02:37:27~11:48 am",
		"etf":"11:48 am",
		"epc":"19",
		"startTime":"9:11:18 am"
	},
	{
		"time":"1289122196.86",
		"timeOfDay":"9:29:57 am",
		"waveTime":"00:18:39.38",
		"i":"1296493798_234",
		"point":"5K",
		"tag":"106",
		"name":"Teyba Erkesso",
		"milePace":"06:01",
		"milePaceAvg":"06:01",
		"mph":"9.99",
		"kmPace":"03:44",
		"kmh":"16.08",
		"etnp":"5M~00:30:02~9:41 am",
		"etfp":"FINISH~02:37:27~11:48 am",
		"etf":"11:48 am",
		"epc":"19",
		"startTime":"9:11:18 am"
	}],
	"info":{
		"first":1,
		"last":3,
		"lasti":"1295193703_7",
		"cacheKey":42837
	}
}

Stop streaming with the stop command.

stop

You will receive a JSON encoded ack 'stop' with an empty response.

{
	"ack":{
		"cmd":"stop",
		"resp":{
		}
	}
}

NOTE: Presently, only one stream is supported per connection.

Streaming - Resuming or Advancing

You can resume or advance a stream by calling the stream command with an API path and a 3rd field of [insertion/update timestamp] or [insertion/update timestamp]_[increment] to ask for results where records are 'greater than' the value specified.

stream~< API path >~< [insertion/update timestamp]_[increment] >

Example: stream~/events/EVENTDEMO/points/ALL_POINTS/splits~1295193703_7

Finally, by default, the polling mode is 'igt' which will stream only new 'inserts'. Other polling modes are 'ugt' and 'agt' (see Polling section in Web API for more details).

You can set the polling mode with a 4th parameter.

stream~< API path >~< [timestamp]_[increment] >~< [polling mode igt/ugt/agt] >

Example: stream~/events/EVENTDEMO/points/ALL_POINTS/splits~1295193703_7~agt

Example: stream~/events/EVENTDEMO/categories/elite-men-half/splits~1295193703_7~agt

Example: stream~/events/EVENTDEMO/points/FINISH/splits~0~ugt

Limiting

You can set the max number of items per response returned while streaming.

query_max~< max results >

You will receive a JSON encoded ack 'query_max' with a response including the setting specified.

{
	"ack":{
		"cmd":"query_max",
		"resp":{
			"max":<###>
		}
	}
}

Example: query_max~300

Ping

Check to make sure the connection is active with ping.

ping

You will receive a JSON encoded ack 'ping' with a response including the systems unix timestamp generated when ping was received.

{
	"ack":{
		"cmd":"ping",
		"resp":{
			"ts":"1295150086"
		}
	}
}

Call

You can make any normal single query as available in the Web API by using the 'call' command.

call~< API path >~< querystring parameters >

Example: call~/events

Example: call~/events/EVENTDEMO/categories~max=50

Example: call~/events/EVENTDEMO/profiles~search=jam&fields=fname,lname,tag

You will receive a single JSON encoded ack 'call' with a response as defined in the Web API.

{
	"ack":{
		"cmd":"call",
		"resp":{
			"list":[{
				"fname":"Jamal",
				"lname":"Nash",
				"tag":"103"
			},
			{
				"fname":"James",
				"lname":"Mercer",
				"tag":"1374"
			},
			{
				"fname":"Jamal",
				"lname":"Love",
				"tag":"1430"
			},
			{
				"fname":"Jameson",
				"lname":"Craft",
				"tag":"1432"
			},
			{
				"fname":"James",
				"lname":"Trujillo",
				"tag":"1461"
			},
			{
				"fname":"Charity",
				"lname":"James",
				"tag":"1556"
			}],
			"info":{
				"first":1,
				"last":6,
				"cacheVer":"0~0"
			}
		}
	}

You can perform the call command anytime after authenticating, even while streaming, but only one call at a time per connection is supported. Thus you must receive and handle the 'ack' for call with response before calling again.