Date: | 19 Feb 2016 |
Version: | 2.0.3 (this is a beta under consideration) |
Author: | Kostas Proitsakis |
Email: | tech@livetrack24.com |
Additions: | 7 Feb 2014 - DeviceID in common URL parts. |
3 Mar 2014, 30 Apr 2014 - updateProfile clarification - how profile 99 works. | |
22 May 2014 - added POST support. | |
19 Feb 2016 - corrected altitude requirement - WGS84 Geoid | |
LiveTrack24 LiveTracking API v2
The new LiveTrack24 LiveTracking API:
http://[server].livetrack24.com/api/[dataFormat]/lt/[OpCode]/[AppKey]
/[AppVersion]/[SessionID]/[UserID]/[PasswordToken]/[OpCodeParameters]
/[OptionalParameters]
http://[server].livetrack24.com/api/[dataFormat]/lt?op=[OpCode]&ak=[AppKey]
&vr=[AppVersion]&sid=[SessionID]&uid=[UserID]&pt=[PasswordToken]
{[OpCodeParameters]}{[OptionalParameters]}
Part | Value | POST | Short description |
1 | http:// | “As is” part. | |
2 | [server] | t0 => Testing server t2 => Production server | |
3 | .livetrack24.com | “As is” part. | |
4 | /api | “As is” part. | |
5 | [dataFormat] | see below | |
6 | /lt | “As is” part. | |
7 | [OpCode] | op | getUserID or updateProfile or getProfiles or track or trackEnd |
8 | [AppKey] | ak | Your LiveTrack24 AppKey (obtained from LiveTrack24, unique per App, send the name of your App to request a new AppKey from here). e.g: WhudO |
9 | [AppVersion] | vr | String of your App version, e.g: 1.0.3 |
10 | [DeviceID] | di | A device identifier, it can be any URL friendly string but zero and has to be unique per App. Good example is the serial number of the device or the IMEI. In this document, for DeviceID we use the: unique_device_id |
11 | [SessionID] | sid | It can be 0 for some op codes, otherwise must be a random 32 bit unsigned integer, unique per session (track), e.g: 605419896 |
12 | [UserID] | uid | The user ID of the user who the track is for, e.g: 11401 see below |
13 | [PasswordToken] | pt | see below |
14 | [OpCodeParameters] | Op code specific parameters | |
N | [OptionalParameters] | A number of optional key/value extra parameters [/key1/value1][/key2/value2][...] e.g.: cat/1/phone/Lenovo P780/equipment/AXIS Mercury |
<code>;<message>
[<content in multiple lines>]
code is 0
message is OK
content the rest of the reply if needed.
Example response on success:
0;OK
11401
where 0;OK means no error and at the next line 11401 is the returned user id.
code is not 0
message is the error message
content is extra information about the error to help the developer.
Example response on error:
20;Unknown user
where 20 is the error code and the ; separates it from the error message.
t 'text' plain text values, single or multiple values with no compression or delta
d 'delta' Delta, RLE, GBase64 packed (see below)
z 'compressed' Can be used with delta to further compress [NOT YET IMPLEMENTED]
b 'binary' BIT STREAM highly compressed [NOT YET IMPLEMENTED]
Example:
http://t2.livetrack24.com/api/t/...
where t means plain text values
A unique per session (track) password token. That is a URL safe base64 string based on the SessionID (it can be 0 for some op codes), the user password and your AppSecret (obtained from LiveTrack24, unique per App).
$lowerPassMD5 = md5(strtolower($plainTextPassword)); // hex MD5
$tokenString = md5($lowerPassMD5 . $sessionID ); // hex MD5
$tokenString = $tokenString . $lowerPassMD5 . $appSecret;
$base64Token = base64_encode(md5($tokenString, true)); // binary MD5!!!
$passwordToken = strtr($base64Token, '+/=', '-_,'); // URL safe
$passwordToken = rtrim($passwordToken, ','); // beautify
PasswordToken maker - Working sample in PHP for quick testing and verification.
$plainTextPassword = 'thisIsMyPass';
$appSecret = 'This-Is-An-App-Secret';
$sessionID = 605419896;
xjFqBpRZR2trZltB5C2pRg
Example: (the URL below is split in 2 rows for easier reading)
http://t2.livetrack24.com/api/t/lt/trackEnd/WhudO/1.0.3/unique_device_id
/605419896/11401/xjFqBpRZR2trZltB5C2pRg/...
where xjFqBpRZR2trZltB5C2pRg is the password token for user with ID 11401 and this track with SessionID 605419896.
Op code getUserID is used to get the user id for a user.
/[Username]
Part | Value | POST | Short description |
11 | 0 | sid | SessionID can be 0 in getUserID |
12 | 0 | uid | UserID can be 0 |
14 | [Username] | usr | The username we want the user id for. |
Example: (the URL below is split in 2 rows for easier reading)
http://t2.livetrack24.com/api/t/lt/getUserID/WhudO/1.0.3/unique_device_id
/0/0/xjFqBpRZR2trZltB5C2pRg/testUser
where /0/0 is used instead of sessionID and userID and testUser is the username we want the user id for.
Example response on success:
0;OK
11401
where 0;OK means no error and at the next line 11401 is the returned user id.
Example response on error:
20;Unknown user
where 20 is the error code and the ; separates it from the error message.
Password Notice: The user may change his/her password on the server at anytime, to ensure an App has the correct password, the App has to verify it periodically by calling getUserID and / or by checking the response of any other call for error: 22;Wrong password
Important: Because getUserID is used to detect the correctness of the credentials and possible password change, should be called:
Users can have multiple tracking profiles with activity, equipment, alerts, submission and privacy settings stored in the server. Any of these will have ProfileID from 1 to 98 and can be used by you, the app.
3 Mar 2014 Update: There is also a special app defined user profile with ProfileID 99 which is handled by you and can be updated to the server. This profile is not listed server side. Kind of:
"select one of your predefined profiles:
1. Public Paraglider ← profile names
2. Public Running
or use these settings:
privacy: [Private] ← selectable
equipment type: [Car] ← selectable
equipment name: [TUCSON] ← writable or selectable
"
Op code updateProfile is used to update the app defined user profile 99 to the server. It should be called when the profile 99 settings are changed in the app and when starting a new track which uses the profile 99 and.
/[Privacy]/[TrackCategory]/[EquipmentName]/[DeviceModel]
Part | Value | POST | Short description |
11 | 0 | sid | SessionID must be 0 in updateProfile |
14 | [Privacy] | pvc | 0 => Public 1 => Private 2 => Visible to friends only |
15 | [TrackCategory] | cat | 1 => "Paraglider" 2 => "Flex wing FAI1" 4 => "Rigid wing FAI5" 8 => "Glider" 16 => "Paramotor" 32 => "Trike" 64 => "Powered flight" 128 => "Hot Air Balloon" 16385 => "Walk" 16386 => "Run" 16388 => "Bike" 16400 => "Hike" 16401 => "Cycle" 16402 => "Mountain Bike" 16403 => "Motorcycle" 16500 => "Windsurf" 16501 => "Kitesurf" 16502 => "Sailing"
16600 => "Snowboard" 16601 => "Ski" 16602 => "Snowkite" 17100 => "Car" 17101 => "4x4 Car" |
16 | [EquipmentName] | equ | URL encoded Equipment brand and model. |
17 | [DeviceModel] | dm | URL encoded Device / phone model as it is acquired from a system call. |
Example: (the URL below is split in 3 rows for easier reading)
http://t2.livetrack24.com/api/t/lt/updateProfile/WhudO/1.0.3/unique_device_id
/0/11401/Yu6a78WAjCl8GL-e2MWRgg
/0/16/Gradient Avax%20SR23/Lenovo%20P780
where the 0 in the 3rd row means visible to all (public) and the 16 is the vehicle type for paramotor.
Privacy Notice: Changing the privacy settings during a LiveTracking session will result to unspecified behavior and thus it should not be implemented by the App.
Op code getProfiles is used to get the list of the user’s profile ids and names separated by newline (\n) char. It is recommended to check the existence of the selected profile with this before starting a new track. Profile 99 is not returned here.
Part | Value | POST | Short description |
11 | 0 | sid | SessionID can be 0 in getProfiles |
Example: (the URL below is split in 2 rows for easier reading)
http://t2.livetrack24.com/api/t/lt/getProfiles/WhudO/1.0.3/unique_device_id
/0/11401/Yu6a78WAjCl8GL-e2MWRgg
Example response on success with profiles:
0;OK
1;Public Paragliding
2;Private Paragliding
5;Public Running
7;Private Running
19;Car
45;Testing
where 0;OK means no error and at the next lines contain the user profiles.
response on success without profiles:
0;OK
where 0;OK means no error but there are no profile results because the user does not have any.
Part | Value | POST | Short description |
14 | [Privacy] | pvc | This can be 0-3 or 9, see the combinations below. |
15 | [ProfileID] | prf | This can be 99 or 1-98, or 0, see the combinations below. |
16 | [PacketID] | pid | The packet number of each packet, we start with 1 for each track and increase with each packet send either with GPS data or the end of the track, e.g: 1 |
Privacy | ProfileID | Short description |
0 => public 1 => private 2 => friends only | 99 | Use the app defined profile.
|
9 => from profile | 1-98 | Set this as default profile and use it with its privacy settings. If the ProfileID given is not found on the server, the Track will be displayed with the default profile that the user has set on his/her account on the website. This must be avoided by checking the existence of the selected ProfileID with getProfiles op code before starting a new Track. |
9 => from profile | 0 | Use the default profile defined in the user’s account |
Privacy Notices:
Op code track is used to send GPS point(s).
/[TimeList]/[LatList]/[LonList]/[AltList]/[SOGlist]/[COGlist](/[TrackInfo])?
Part | Value | POST | Short description |
17 | [TimeList] | tm | The Unix timestamps in GMT of the GPS time, not the phone's time, e.g: 1387259187 |
18 | [LatList] | lat | Latitudes in decimal notation, use negative numbers for west, e.g: 40.62302 |
19 | [LonList] | lon | Longitudes in decimal notation, use negative numbers for south, e.g: 22.96950 |
20 | [AltList] | alt | Altitudes in meters above the MSL (WGS84 Geoid, orthometric height if it is possible), no decimals, e.g: 89 |
21 | [SOGlist] | sog | Speed Over Ground in km/h no decimals. Give 0 if you have NODATA. |
22 | [COGlist] | cog | Course Over Ground in degrees 0-360, no decimals. 0 is North, 90 is East. Give 0 if you have NODATA. |
23 | [TrackInfo] | tki | The first packet should contain track info, e.g.: 16:Gradient Avax SR23:Lenovo P780 see below. |
This applies to the 1st packet of the track ( PacketID = 1 ). Depending on the ProfileID we send the following “:” separated URL encoded information:
IF ProfileID = 99 THEN
[TrackCategory]:[EquipmentName]:[DeviceModel]
ELSE
[DeviceModel]
TrackInfo encoding in PHP:
$TrackInfo = $TrackCategory // this is an integer no encoding
. ":" . urlencode($EquipmentName) // URL encoded string
. ":" . urlencode($DeviceModel); // URL encoded string
Examples: (the URLs below are split in 4 rows for easier reading)
http://t2.livetrack24.com/api/t/lt/track/WhudO/1.0.3/unique_device_id
/605419896/11401/xjFqBpRZR2trZltB5C2pRg
/0/99/1/1387259187/40.62302/22.96950/89/34/145
/16:Gradient%20Avax%20SR23:Lenovo%20P780
in the above, PacketID = 1, ProfileID = 99, we send complete track info.
http://t2.livetrack24.com/api/t/lt/track/WhudO/1.0.3/unique_device_id
/605419896/11401/xjFqBpRZR2trZltB5C2pRg
/9/2/1/1387259187/40.62302/22.96950/89/34/145
/Lenovo%20P780
above, PacketID = 1, ProfileID != 99, we send the device model only.
http://t2.livetrack24.com/api/t/lt/track/WhudO/1.0.3/unique_device_id
/605419896/11401/xjFqBpRZR2trZltB5C2pRg
/0/99/2/1387259187/40.62302/22.96950/89/34/145
above, PacketID > 1, we send no track info.
Example response on success:
0;OK
where 0;OK means no error.
Op code trackEnd is used to send the end of a track reporting the status of the user.
/[ProblemID]/[Submit]
Part | Value | POST | Short description |
17 | [ProblemID] | prid | The status of the user: 0 => "Everything OK" 1 => "Need retrieve" 2 => "Need some help, nothing broken" 3 => "Need help, maybe something broken" 4 => "HELP, SERIOUS INJURY" |
18 | [Submit] | sbm | Submit can be 0 or 1 |
Example: (the URL below is split in 3 rows for easier reading)
http://t2.livetrack24.com/api/t/lt/trackEnd/WhudO/1.0.3/unique_device_id
/605419896/11401/xjFqBpRZR2trZltB5C2pRg/3
/0/99/2156/0/1
Let’s assume the App has the following details:
appKey = WhudO
appSecret = This-Is-An-App-Secret
appVersion = 1.0.3
and runs on a device with id: unique_device_id
The App asks the user within a login page for:
when the user clicks Login the App calculates the password token with:
sessionID = 0
plainTextPassword = thisIsMyPass
appSecret = This-Is-An-App-Secret
let’s assume the result is: A-Password-Token
the userID is still unknown, so we use userID = 0
The App gets the userID by calling:
http://t2.livetrack24.com/api/t/lt/getUserID/WhudO/1.0.3/unique_device_id/0/0/A-Password-Token/testUser
The reply on error may be:
22;Wrong password
The App should ask the user for the correct username and password.
The reply on success will be:
0;OK
11401
where 11401 is the userID, the App stores that.
Get profile details, update profile
The App asks the user within a settings page for:
and gets the phone model DeviceModel for the system, let’s say it is a Lenovo P780)
When the user click OK the App updates the app profile on the server by calling:
http://t2.livetrack24.com/api/t/lt/updateProfile/WhudO/1.0.3/unique_device_id/0/11401
/A-Password-Token/0/16/Gradient Avax SR23/Lenovo P780
A LiveTracking session
The user selects Start LiveTracking.
The App generates a new random 32 bit unsigned integer for sessionID, let’s say 605419896 and calculates the sessioned password token for our example with:
sessionID = 605419896
plainTextPassword = thisIsMyPass
appSecret = This-Is-An-App-Secret
let’s assume the result now is: This-Is-A-Password-Token
// The App can send a single GPS Point ( in the 1st packet we append the track info )
http://t2.livetrack24.com/api/t/lt/track/WhudO/1.0.3/unique_device_id/605419896/11401
/This-Is-A-Password-Token/0/99/1/1387259187/40.62302/22.96950/89/34/145
/16:Gradient%20Avax%20SR23:Lenovo%20P780
// Or several GPS Points together, here are 4
http://t2.livetrack24.com/api/t/lt/track/WhudO/1.0.3/unique_device_id/605419896/11401
/This-Is-A-Password-Token/0/99/2/1387259189,1387259191,1387259193,1387259195
/40.62301,40.62303,40.62300,40.62297/22.96949,22.96950,22.96948,22.96949/91,90,92,90
/38,37,36,35/147,150,149,151
The App is sending points until the the user selects Stop LiveTracking, then it asks the user if everything is OK and reports to the server, e.g.:
// END OF TRACK, reporting “Everything OK” and Submit
http://t2.livetrack24.com/api/t/lt/trackEnd/WhudO/1.0.3/unique_device_id/605419896/11401
/This-Is-A-Password-Token/0/99/3/0/1
This is a Delta, RLE, GBase64 packed URL friendly text format:
Lats and Lons are converted to integer degrees (see below),
parts 17-22 of /track are packed GBase64 integers,
only the differences to the previous values are sent (delta),
RLE ‘compressed’ by default.
In JavaScript: coordInt = ~~( coord * 60000 );
In PHP: coordInt = intval( coord * 60000 );
Sending 32 GPS Points can look like that:
http://t2.livetrack24.com/api/d/lt/track/WhudO/1.0.3/unique_device_id/605419896/11401
/xjFqBpRZR2trZltB5C2pRg/0/99/426/1iKrdi$u3/one0d!C!1d*4!C*n/c]uJa:1v!1v*4:C*j!j*3
/pw_21*o!1*3/4!3*t/0*u
1iKrdi$u3 equals:
1387901778,1387901781,1387901784,1387901787,1387901790,1387901793,1387901796,
1387901799,1387901802,1387901805,1387901808,1387901811,1387901814,1387901817,
1387901820,1387901823,1387901826,1387901829,1387901832,1387901835,1387901838,
1387901841,1387901844,1387901847,1387901850,1387901853,1387901856,1387901859,
1387901862,1387901865,1387901868
It’s ‘delta’ equals:
1387901778:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3:3
It’s RLE equals:
1387901778$31:3
In GBase64 becomes:
1iKrdi$u3
For a working example of int GBase64 and deltaRLE library in JavaScript see: