RTRT.me - Real Time Race Tracking

Real-Time Race Tracking for World-Class Events

Admin API Reference ( Updated 2014-09-08 ) CHANGELOG
  • 2014-09-08
    - Managing Events > Profiles > Add or Update: List can now be sent as JSON content type.
  • 2013-11-12
    - Managing Events > Profiles > Add or Update: Changed default behavoir to always 'extend' roster ( excluded fields are not removed unless forced by 'extend=0' ).

The RTRT.me Admin API allows developers to manage event data and perform other tasks via a private, secure JSON+REST interface.

Access

Your Admin appid and token can be found in the RTRT.me Web Console in your Account page under Preferences->ADMIN API CREDENTIALS.

Provide your appid and token in the querystring of the URL. When accessing the Admin API, only SSL (https) requests will be accepted.

https://api.rtrt.me?appid=[YOUR ADMIN APP ID]&token=[YOUR TOKEN]

WARNING: PLEASE DO NOT SHARE OR SEND YOUR APPID AND TOKEN OVER A NON-SECURE METHOD OF COMMUNICATION. EMAILS ARE NOT SECURE!

Tokens remain available and do not expire unless reset by you via the Account Preferences page.

Your Admin credentials can also be used to peform any of the requests as documented in the Web API. However, such requets must still use the secure protocol (https).


Managing Events

You can perform a number of tasks on your events by requesting a URL in the '/admin' API path while and passing various options.

Below is a list of currently available requests.

Profiles - Add or Update http://rtrt.me/docs/api/admin#profiles-addupdate

/admin/events/[EVENT SYSTEM NAME]/profiles

Make the '/profiles' call on your event while passing a list parameter. The list parameter should consist of one or more roster records (participants) represeted as a JSON string. For example:

list=[{ "reg_id" :'406279',"fname": "Thomas","lname": "Holloway","birthdate": "1944-07-12","city": "Torrington","country": "USA","race": "Half Marathon","sex": "M","state": "NY","tag": "1331"}]

NOTE: The field names passed to this call will be translated to our standards a explained in Profile Fields. Also see Profile Mapping below.

If the profile is new, it will be created. If the profile exists, it will be updated.

You can send the list parameter as JSON (application/json), a form POST (application/x-www-form-urlencoded), or a GET. If you use GET, you must properly URL Encode the JSON object. Make sure to set charset=UTF-8.

Sample using curl and JSON:

curl \
  --header "Content-type: application/json; charset=UTF-8" \
  --request POST \
  --data '{ "list":[{ "reg_id" :'406279',"fname": "Thomas","lname": "Holloway","birthdate": "1944-07-12","city": "Torrington","country": "USA","race": "Half Marathon","sex": "M","state": "NY","tag": "1331"}]}' \
  'https://api.rtrt.me/admin/events/EVENTDEMO/profiles?appid=51003740aad3e3d63ca5a7b1&token=96b411a6418132f3dd6179d7897af9e9'

Sample using curl and -F to send list as POST:

curl -F 'list=[{ "reg_id" :"406279","fname": "Thomas","lname": "Holloway","birthdate": "1944-07-12","city": "Torrington","country": "USA","race": "Half Marathon","sex": "M","state": "NY","tag": "1331"}]' \
     'https://api.rtrt.me/admin/events/EVENTDEMO/profiles?appid=51003740aad3e3d63ca5a7b1&token=96b411a6418132f3dd6179d7897af9e9'

Same example as a GET request (list object is URL Encoded):

https://api.rtrt.me/admin/events/EVENTDEMO/profiles?appid=51003740aad3e3d63ca5a7b1&token=96b411a6418132f3dd6179d7897af9e9&list=%5B%7B%20%22reg_id%22%20%3A%22406279%22%2C%22fname%22%3A%20%22Thomas%22%2C%22lname%22%3A%20%22Holloway%22%2C%22birthdate%22%3A%20%221944-07-12%22%2C%22city%22%3A%20%22Torrington%22%2C%22country%22%3A%20%22USA%22%2C%22race%22%3A%20%22Half%20Marathon%22%2C%22sex%22%3A%20%22M%22%2C%22state%22%3A%20%22NY%22%2C%22tag%22%3A%20%221331%22%7D%5D

If successful, the response will return with a 'success' object and the 'info' section will include 'stats' and 'records_affected'. For example:

{

    "success": {
        "type": "ok",
        "msg": "Successfully completed your request."
    },
    "info": {
        "stats": {
            "processed": "2",
            "inserts": "0",
            "skipped": "0",
            "duplicates": "0",
            "unchanged": "1",
            "updates": "1",
            "reclaimed": "2",
            "removed": "0"
        },
        "records_affected": [
            {
                "key_field": "pid",
                "key_val": "R7W6UNSE",
                "version": "3",
                "status": {
                    "success": {
                        "type": "updated",
                        "msg": "Profile Updated. PID reclaimed using pid eq R7W6UNSE."
                    }
                },
                "updated": {
                    "fname": "Tom",
                    "birthdate": "1944-07-14",
                    "name": "Tom Holloway"
                }
            },
            {
                "key_field": "pid",
                "key_val": "RSF56NBR",
                "version": "20",
                "status": {
                    "success": {
                        "type": "unchanged",
                        "msg": "No Changes. PID reclaimed using pid eq RSF56NBR."
                    }
                }
            }
        ]
    }

}

Number of records in this request that were:

processed = valid records (rows)
inserts = newly created
skipped = ignored, failed because of some issue with a row
duplicates = detected to be identical (or nearly identical)
unchanged = not changed
updates = updated ( one or more fields )
reclaimed = imported previously and would receive an 'update' rather than 'insert' a new record. Reclaimed is good to see on subsequent imports because this means that profile tracking will continue to be linked up to original record as subcribed to
removed = deleted during in this request
What do the stats mean?

For each record in the batch, we return an object in the 'records_affected' in the order submitted in your request. This object includes:

 
'key_field' - for RTRT, this will be our unique identifier 'pid'
'key_val' - unique key value (Participant ID)
'version' - version number of the record.  When first inserted, is '1'.  
            Upon each change to the record, this advances by 1.
'status' - conventiontal 'success' or 'error' objects with type and msg.  
    Possible values for 'status.success.type' include: 
      'inserted', 'updated', 'conflicted', 'unchanged'
        
        If success.type is 'updated', the response will tell you what fields got changed in the 'updated' object.
          
        If success.type is 'conflicted', the response will tell you what fields (if any) got changed in the 'updated' object, and also which fields were not changed in the 'locked' object.

    Possible values for 'status.error.type' include: 
      'skipped'
          

NOTE: By default, profiles fields passed are updated and fields that are excluded not removed. To force removal fields not included, pass 'extend=0' as a parameter in GET or POST.

If not successful, the response will return with a 'error' object and a 'msg' explaining why the failure has occured. For example:

{
   "error":{
      "type":"failed",
      "msg":"No Changes were made. Sorry, Import failed. Could not find value for key field of (reg_id). Make sure Import Key Field is set properly in Event Settings->Roster Options. and make sure you have unique values populated in that field."
   },
   "info":{
      "cacheVer":"0~6"
   }
}

To handle more than one record at a time, add more than one to the list object.

list=[{ "reg_id" :"406279",... all fields for participant },{ "reg_id" :'3235125',... all fields for participant }]

Example: Add/Update 2 Demo Participants: /admin/events/EVENTDEMO/profiles?list=%5B%7B%20%22reg_id%22%20%3A%22406279%22...

Profiles - Remove http://rtrt.me/docs/api/admin#profiles-removing

To remove (delete) a profile from your event, make the '/profiles' request, and include an extra field of "delete_record" with a value of "1" to the participant rows which you want to have removed. For example:

list=[{ "reg_id" :'406279',"fname": "Thomas","lname": "Holloway","birthdate": "1944-07-12","city": "Torrington","country": "USA","race": "Half Marathon","sex": "M","state": "NY","tag": "1331", "delete_record": "1"}]

If the profile is matched (reclaimed), it will be deleted. If the profile was not found, it will be skipped.

Example: Delete a Demo Participant: /admin/events/EVENTDEMO/profiles?list=%5B%7B%20%22reg_id%22%20%3A%22406279%22...

Profiles - Field Mapping http://rtrt.me/docs/api/admin#profiles-mapping

Sometimes it is useful to know what field translation will occur based on RTRT.me import standards ( see profile fields ). The following request accepts a list of fields and responds with the standardized RTRT field names that would be used on an import.

/admin/events/[EVENT SYSTEM NAME]/profiles/mapping

Make the '/profiles/mapping' call on your event while passing a GET (querystring) parameter of fields. The fields parameter should consist of one or more roster field names (sometimes called headings or keys) in a comma separated list. For example:

&fields=UserID,Bib,Chip,FirstName,LastName,Gender,Age,BirthDate,City,State,Country,TeamCode,TeamName

Example: Get Field Mapping: /admin/events/EVENTDEMO/profiles/mapping?fields=UserID,Bib,Chip,FirstName,LastName,Gender,Age,BirthDate,City,State,Country,TeamCode,TeamName

If successful, the response will return a 'list' object with original field to RTRT field mapping. For example:

{

    "list": {
        "UserID": "reg_id",
        "Bib": "bib",
        "Tag": "tag",
        "FirstName": "fname",
        "LastName": "lname",
        "Gender": "sex",
        "Age": "age",
        "BirthDate": "birthdate",
        "City": "city",
        "State": "state",
        "Country": "country",
        "TeamCode": "teamcode",
        "TeamName": "teamname"
    },
    "info": {
        "cacheVer": "14~2069"
        "standards": [
        {
            "field": "pid",
            "name": "Participant ID",
            "desc": "RTRT internal unique participant identifier for this Event. This is always auto-generated by our system and should not change once assigned to participant (assuming consistency of unique keys in registration data)."
        },
        {
            "field": "name",
            "name": "Full Name",
            "desc": "Full Name of Participant. This field is automatically created from fname and lname if not specified. If 'name' is provided without 'fname' and 'lname', 'fname' and 'lname' will be created from 'name'."
        },

        ... more

    }

}

Also, in the info section, you will find an object called 'standards'. This defines our most commoly used roster fields along with a display name and a description.

If successful, the response will return with a 'success' object and the 'info' section will include 'stats' and 'records_affected'. For example:

{

    "success": {
        "type": "ok",
        "msg": "Successfully completed your request."
    },
    "info": {
        "records_affected": [
            {
                "id": "MT3UV6WPDAT9", // unique id assigned to this manual time
                "request_id": "BASDFdslf",
                "pid": "R7W6UNSE",
                "tag": "00002",
                "name": "Bob Smith",
                "gender": "M",
                "bib": "2",
                "status": {
                    "success": {
                        "type": "updated",
                        "msg": "Set Time to at START-H to 09:21:20.21."
                    }
                }
            },
            {
                "request_id": "BASDF1233",
                "status": {
                    "error": {
                        "type": "no_results",
                        "msg": "Participant not found."
                    }
                }
            }
        ]
    }
}