API
LiveTrack24 API v2 Index
- LiveTrack24 API v2 intro
- LiveTrack24 API v2 details
- LiveTrack24 API v2 - One Lazy Step
- Calling sequence
- Pseudo code new simplified version
- Deeper understanding of OTP
- Working source code in PHP
- Live Info sub-API
- Track Data sub-API
- Competition sub-API
Samples in PHP - external links
Note: Always make sure you are reading the latest version of this manual.
LiveTrack24 API v2 intro
Obtaining your API Keys
To use the LiveTrack24 API you need to have an application key (appKey) and a secret key (appSecret).
Both are supplied by LiveTrack24 on request free of charge.
LiveTrack24 OTP Authentication Sessions
LiveTrack24 API v2 uses an OTP (One-Time-Password) authentication. It is an OTP-question / OTP-answer procedure, in which the server gives a question and you have to give the right answer.
This means that in each data or action request to the server you also add your appKey and the OTP-answer to the previous OTP-question and in each reply additionally to the data the server will give you a new OTP-question.
If your OTP-answer is not correct or if it is your first request, the server will give you a new OTP-question to answer and an error message indicating what is wrong.
In PHP the otpReply function is like this:
function otpReply($question) { $vc = substr( hash_hmac("sha256", $question, LT24_appSecret), 0, 16); return "/ak/" . LT24_appKey . "/vc/" . $vc; }
LiveTrack24 API v2 details
=> The API URL format is this:
http://api.livetrack24.com/api/v2/op/{op_code}/{parameters}/{OTP-answer} {op_code} = operation code, it can be numeric or string {parameters} = key1/value1/key2/value2/key3/value3/... {OTP-answer} = in PHP that is: otpReply($question);
<= LiveTrack24 API v2 returns data in JSON format and it can be returned in a gzip compressed string with the /gzip/1 parameter.
Example:
=> request a test "ping"
http://api.livetrack24.com/api/v2/op/ping/ak/00DE262/vc/2d12585900bc8359Explanation:
http://api.livetrack24.com/api/v2 /op/ping /ak/00DE262 /vc/2d12585900bc8359
http://api.livetrack24.com/api/v2 : API url base op : operation code ak : appKey vc : validation code (the OTP-answer)<= server's reply with data
{ "ip": "188.40.246.133", "qwe": "5558e1573243c4b3" }
ip : requested data for the given op code qwe : OTP-question for your next request<= server's reply with error
{ "qwe": "0400e4d5b20b7bb4", "newqwe": 1, "error": "Server refused the connection." }
qwe : OTP-question for your next request newqwe : you need to reply the new OTP-question error : error message
Notes:
- The value of "qwe" will be an empty string if the given appKey is wrong or missing.
- "qwe" will not be present if the given op code is not valid.
- Always calculate the "vc" based on the "qwe" you have, if the "qwe" you have has expired or is empty (your first call ever) the call will fail but you will get a fresh "qwe" to retry.
- When you get a "newqwe:1" you will need to add the user token "ut" (see bellow) and the device ID "di" (see next) to the reply.
- The device ID (for mobile devices) or browser ID is an MD5 string of yours, in combination with the IP it is used to detect account misuses and password leakages.
LiveTrack24 API v2 - One Lazy Step
Most applications will need to access LiveTrack24 on behalf of a user, this user needs to be logged in.
Step 1 - Use the API assuming everything is ready
Usually that will be enough.
Example of a "ping" call:http://api.livetrack24.com/api/v2 /op/ping /ak/00DE262/vc/91c08766d5135759
(the URL above is split in 3 parts to increase readability, the "ak" and "vc" values should be replaced with yours)
If you do not get "reLogin:1" or "newqwe:1" you are done with the call.
The reply will contain "reLogin:1" if the user was not previously logged in, or in case of password change, or in (rare) case of a change in the protocol.
Step 2 - if you get "reLogin:1"
(Re)login with LiveTrack24 user credentials.
Example:
http://api.livetrack24.com/api/v2 /op/6/username/gust/passe/LCw4pRTGsdflMqCn /ak/00DE262/vc/91c08766d5135759=> Parameters
op : 6 or login username : user name pass : password in plain text, or passe : encrypted password, in PHP: encryptWithKey($password, LT24_appSecret); //(see bellow for the function)<= Returns:
{ "qwe": "d029563294f33703", "error": "", "userID": "11401", "username": "GUST", "displayName": "GUST - Kostas Proitsakis", "country": "GR", "ut": "1324d2e3a4d5c6a7f7e8f91324de2a3d", }Special reply parameter:
ut : user token, handles automatic re-login, you should save this and pass it back to the server only if you get a "newqwe:1" or "reLogin:1", your initial ut can be any valid string like "0", "hello", "123", "ok", etc.
Step 3 - if you get "reLogin:1" during login
The user needs to edit his/her username and/or password.
Calling sequence
Let's say we want the result of "tasksList/tasksToGet/5" which will return info about the latest 5 competition tasks.
- we assume everything is ready, we call the server and store the special result values for the next call
- if there is not special result like "newqwe" or "reLogin" we return to the caller
- if there is "reLogin:1" we call "login" and then we go to step 1 (but only once per call from step 3)
- if there is "newqwe:1" we go to step 1 (but only once per call from step 4)
Pseudo code
result = callLiveTrack24("tasksList/tasksToGet/5")begin function callLiveTrack24(params, calledSelf = 0) URL = "http://api.livetrack24.com/api/v2/op/" + params + "/ak/" + saved_appKey + "/vc/" + substr( hash_hmac('sha256', saved_qwe, saved_appSecret), 0, 16) if ( calledSelf ) URL = URL + "/di/" + saved_myDeviceID + "/ut/" + saved_ut reply = getURLcontents(URL) if URL contains '/gzip/1' then reply = gzdecode(reply) res = JSON.parse(reply) if res contains "ut" then save it to saved_ut if res contains "qwe" then save it to saved_qwe if NOT calledSelf if res contains "newqwe:1" res = callLiveTrack24(params, 1) if res contains "reLogin:1" res = callLiveTrack24("login/username/" + saved_username + "/pass/" + saved_password, 1) if res contains "reLogin:1" // "You need to enter your LiveTrack24 login credentials" // get from the user the saved_username and saved_password // and retry return callLiveTrack24(params, 1) end if end if end if return res end function callLiveTrack24
Deeper understanding of OTP
To the server your OTP answer is a key to a short lived user session cache block which is time expired and deleted or copied to a new block and the old one is deleted after one use (in reality that is after three uses to allow up to 3 parallel calls but you should tread it as one). You should always save the qwe you are getting and use it to generate the OTP reply (the vc) for your next call.
That user session block contains all the needed information for the server and it belongs to a guest until a user is logged in with it.
When you get "Wrong OTP" it means your OTP answer (the /vc ) does not (longer) correspond to a user session block in the cache and the server notifies you about it with newqwe:1
When you get "No user logged in" it means you are doing a call on behalf of a user while the user session block you are referring does not belong to a logged in user and the server notifies you about it with reLogin:1
Working source code in PHP
define("LiveTrack24_API", "http://api.livetrack24.com/api/v2/op/"); // test key and secret, will be valid for limited time // define("LT24_appSecret", "83523469867234672146"); // !!!!!!!!! replace it with yours define("LT24_appKey", "00DE262"); // !!!!!!!!! replace it with yours // if you cannot get the device id create a random one once! // if ( !myRead('deviceID') ) myWrite('deviceID', md5( microtime(true) . rand() ) ); // replace this function with one of yours that reads data (client side) from cookies/session/storage/db // function myRead($name) { return ( array_key_exists($name, $_SESSION) ) ? $_SESSION[$name] : 0; } // replace this function with one of yours that writes data (client side) to cookies/session/storage/db // function myWrite($name, $val) { return $_SESSION[$name] = $val; } // http://php.net/manual/en/function.hash-hmac.php // function otpReply($question) { return "/ak/" . LT24_appKey . "/vc/" . substr( hash_hmac('sha256', $question, LT24_appSecret), 0, 16); } // You call this and it handles the (re)Login and the OTP for you. // // e.g.: callLiveTrack24old('status'); // function callLiveTrack24($params, $calledSelf = 0) { $url = LiveTrack24_API . $params . otpReply( myRead('qwe') ); // on "reLogin:1" or "newqwe:1" we need to add our deviceID and the saved user token to the URL if ( $calledSelf ) $url .= "/di/" . myRead('deviceID') . "/ut/" . myRead('ut'); // get the result from the server $reply = file_get_contents( $url ); $onError = $reply; // handle gzip if ( strpos($url, '/gzip/1') ) $reply = @gzdecode($reply); // try to decode the JSON result $res = @json_decode($reply, TRUE); // if there is something wrong and we did not get a valid JSON reply return to the caller if ( !is_array($res) ) return ( strlen($res) ) ? $res : $onError; // we have got our valid reply: // save the user token if we get one if ( array_key_exists('ut', $res) ) myWrite('ut', $res['ut']); // save the OTP-question if we get one if ( array_key_exists('qwe', $res) ) myWrite('qwe', $res['qwe']); if ( !$calledSelf ) { // try once more on 'newqwe' it may catch up and login with the user token ut if ( array_key_exists('newqwe', $res) ) $res = callLiveTrack24($params, 1); // check if we need to re-login if ( is_array($res) && array_key_exists('reLogin', $res) ) { // try to re-login if ( myRead('LT24_username') && myRead('LT24_password') ) { $res = callLiveTrack24('login/username/' . urlencode(myRead('LT24_username')) . '/passe/' . myRead('LT24_password'), 1); } // check if we need to edit username and or password if ( is_array($res) && array_key_exists('reLogin', $res) ) { $res['askForLoginInfo'] = "You need to enter your LiveTrack24 login credentials"; } else { // re-login was successful, now call LiveTrack24 again with the given params return callLiveTrack24($params, 1); } } } return $res; } // encryptWithKey($str,$key) is used to encrypt passwords. // It supports character codes from 32 (inclusive) to 224 (exclusive). // For key you should use your appSecret and it returns the encrypted string in URL-friendly base64 format. // function encryptWithKey($str,$key) { $offset = rand(0,255); $multi = rand(0,255); $final= chr($offset) . chr($multi); $helpKey = '!' . $key; for($i = 0; $i < strlen($str) ; $i++ ) { $keypos = ( $i * $multi + $offset ) % strlen($key); // if the previous digit from the key is odd, 1 , else -1 $sign = ( ord($helpKey[$keypos]) & 1 ) ? 1 : -1; $final .= chr( ord($str[$i]) + ( ord($key[$keypos]) & 0x3f ) * $sign ); } return rtrim(strtr(base64_encode($final), '+/=', '-_,'), ','); } function decryptWithKey($str,$key) { $str = base64_decode(strtr($str, '-_,', '+/=')); $final=""; $offset = ord($str[0]); $multi = ord($str[1]); $str = substr($str, 2); $helpKey = '!' . $key; for($i=0; $i< strlen($str); $i++ ) { $keypos = ( $i * $multi + $offset ) % strlen($key); // if the previous digit from the key is odd, 1 , else -1 $sign = ( ord($helpKey[$keypos]) & 1 ) ? 1 : -1; $goodCode = ord($str[$i]) - ( ord($key[$keypos]) & 0x3f ) * $sign ; $final.=chr($goodCode); } return $final; }
Back to the the API index.