MacDown logo

Hellotracks Jobs & Tracking API

Example Code: You can download a working implementation in Java here.

Endpoint

Every request is POST

    POST https://hellotracks.com/api/<action>

POST request data is in JSON format, consists of required auth attribute for authentication, required data attribute for additional action data, and an optional api-version attribute ver defaulting to the newest version. Current version is 2.

{ 
    auth: {
        <authentication-attributes>
    },
    data: {
        <data-attributes>
    },
    ver: 2
}

Response is in json format:

{ 
    status: <STATUSCODE>,
    <additional-response-attributes>
}

HTTP Status Code

Code Type Description
200 OK Request successfully responded.
500, 502, 503, 504 Server Errors Something went wrong on Hellotracks' end.

Authentication

usr, tok, pwd & key

Every request is validated and authenticated by the quintuple usr, tok, pwd, cts & key in the field auth in your request post-data as seen below.

{
   auth: {
        usr : "<your_username>",
        cts : <clock-unix-timestamp>
        tok : "<unique_token>",
        pwd : "<encoded_tok_secret>",
        key : "<API-KEY>"
   },
   data: { ... }
}

Creating pwd value

    pwd = md5(concat(tok,<password-for-usr>, cts))
    
    Example:
    cts: 1430580377
    tok: 1430580377123
    password-for-usr: secretpassword
    pwd = md5("1430580377123secretpassword1430580377") = d6448a9d9202d25dedfb160b2c080db2
    
    auth: {
        usr : "yourcompanyusername",        
        cts : 1430580377
        tok : "1430580377123", // note: this is a string
        pwd : "d6448a9d9202d25dedfb160b2c080db2",
        key : "E732313A399026C6143F4351D3A15E38"
    }

Example: Implementation in Java

// Create MD5 Hash
String plain = TOK + PASSWORD + CTS;
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(plain.getBytes());
byte[] md5 = md.digest();

// Create Hex String
StringBuilder hexBuilder = new StringBuilder();
for (int i = 0; i < md5.length; i++) {
    hexBuilder.append(Integer.toHexString(0xFF & md5[i]));
}
String pwd = hexBuilder.toString();

Job Actions Overview

Tracking Overview

Hellotracks Status Codes

Name Code Description
STATUS_OK 0 Everything worked as expected
ERROR_FORMAT -1 Input data could not be processed
ERROR_USERUNKNOWN -2 User in usr is unknown
ERROR_PASSWORDMISMATCH -3 pwd value incorrect
ERROR_USERALREADYEXISTS -4 Username is already taken
ERROR_NOPERMISSION -5 No permission for this request
ERROR_UNREGISTERED -6 Not registered for push notifications
ERROR_NOTREADY -7 System is not ready, try in a minute again
ERROR_INVALIDKEY -8 The API-KEY in auth.key is incorrect
ERROR_THROTTLING -9 Too many request for this API-KEY
ERROR_CLOCK -10 Clock value is severly out of sync
ERROR_UNKOWN -99 Unkown cause, please inform us

API Objects

Job API Object

Attribute Type R/W Description
id TEXT R Job unique ID
type INT RW Job Type: 0=Work, 1=Pickup, 2=Dropoff
teamId INT RW Team Id 0-6 (the number of the team). Defaults to 0 (no specific team).
destinationName TEXT RW Title of this job (1-line description)
destinationLat DOUBLE RW Latitude
destinationLng DOUBLE RW Longitude
destinationText TEXT RW Location Address
destinationUrl TEXT RW Location map URL
textDispatcher TEXT RW Dispatcher additional info text (multi-line)
textReceiver TEXT RW Worker's reply text
contactName TEXT RW Name of contact at job's location
conctactPhone TEXT RW Phone number of contact at job's location
day INT RW Date for job as YYYYMMDD or 0 (e.g. 20150530)
priority INT RW Priority min:0-max:10
number INT RW Sequence number for ordering
onSiteSeconds INT RW The assumed onsite-time in seconds (e.g. 10min on site: 600)
windowStart INT RW Format: HHMM or 0 (e.g 704 = 7:04am)
windowEnd INT RW Format: HHMM or 0 (e.g 1724 = 5:24pm)
orderId INT RW Optional Order ID as an integer number
dispatcherUid TEXT RW UID of dispatcher account
dispatcherName TEXT R Name of Dispatcher
dispatcherUrl TEXT R URL for dispatcher icon image
placeUid TEXT RW UID of place to visit or ""
placeName TEXT R Name of place/location
placeUrl TEXT R URL for place icon image
radius INT R Radius for check-in/out in meter (place-radius or default-radius)
worker TEXT RW User name of assigned worker
workerName TEXT R Full name of assigned worker

Job Status attributes (progress)

The job status attributes hold the timestamp when an event has occurred or 0 if it does not apply.

Note: Timestamps are milliseconds, between the current time and midnight, January 1, 1970 UTC (Java timestamps)

E.g.: 1430580377000 = Sat, 02 May 2015 15:26:17 GMT

Attribute Type R/W Description
tsCreated LONG RW Timestamp in millis for job creation
tsAccepted LONG RW Timestamp in millis for job accepted by worker
tsRejected LONG RW Timestamp in millis for job rejected by worker
tsDoneSuccess LONG RW Timestamp in millis for job marked as success by worker
tsDoneFailed LONG RW Timestamp in millis for job marked as issue by worker
tsCheckIn LONG RW Timestamp in millis for auto check-in by worker
tsCheckOut LONG RW Timestamp in millis for auto check-out by worker
tsCheckNFC1 LONG RW Timestamp in millis for first check with NFC
tsCheckNFC2 LONG RW Timestamp in millis for second check with NFC

Customizable Attributes:

Attributes Type R/W Description
custom_{text} TEXT R Custom field where {text} is the desired field name
extra_number_{x}_key TEXT R Worker input number field where {x} is 1-4
extra_number_{x}_val INT RW Worker input number value where {x} is 1-4
extra_text_{x}_key TEXT R Worker input text field where {x} is 1-4
extra_text_{x}_val TEXT RW Worker input text value where {x} is 1-4

Job Actions

Creating new jobs with createjobs

Request:

POST https://hellotracks.com/api/createjobs

{ 
    auth: { ... }
    data: {
        jobs: [ 
             { <job_1> },
             { <job_2> },
               ...
             { <job_n> }
         ]
    }
}

Response:

{ 
    status: 0,
    jobs : [
        { <job_1> },
        { <job_2> },
           ...
        { <job_n> }
    ]
}

status is guaranteed to be set, jobs is set if status: 0.

Note: Although optional, it is recommended to set uidSecondary on creating a new job. It will be guaranteed that only 1 job exists with this unique id. The value can be any kind of text, the only constraint is that it needs to be unique inside your company account.

Retrieving Jobs with getjobs

You can retrieve jobs by the following request:

POST https://hellotracks.com/api/getjobs

{ 
    auth: { ... }
    data: {
        day : 20150428,
        worker: "<worker-username>",
        team: <number> (optional),
        orderId: <number> (optional)
    }
}

Returns a list of jobs for a given day day and worker worker.

day is optional and defaults to today. To retrieve jobs with no date assigned, set day:0.

To retrieve jobs that are not assigned to a worker, set worker:"". To request all jobs for all workers for a specific date, set worker:"*".

team is an optional filter to only request jobs for a specific team. It defaults to 0 which means 'any team'.

orderId is an optional filter to request a specific job. It defaults to 0 which means 'any order id'.

Response:

{ 
    status: 0,
    jobs : [
        { <job_1> },
        { <job_2> },
           ...
        { <job_n> }
    ]
}

Edit Jobs

You can change job properties and update job status/progress with the following request:

POST https://hellotracks.com/api/editjobs

{ 
    auth: { ... }
    data: {
        jobs: { 
            "<job_id_1>" : { 
                "<attr_1>" : <value>,
                   ...
                "<attr_n>" : <value>,
            },
            "<job_id_2>" : { ... }, 
               ...
            "<job_id_n>" : { ... }
        },
        notify: <boolean>
    }
}

Compare Job API Object to see all modifiable attributes (all which are marked as RW in the column R/W. You are not able to change the id of a job, but most job properties are modifiable.

Set notify:true if you want to generate a notification in case the progress status of this job changed. To ommit creating notifications for this job modification, set notify:false. The notify attribute is optional and defaults to true.

Response:

{ 
    status: 0
}

Delete Jobs

You can delete jobs with the following request:

POST https://hellotracks.com/api/deletejobs

{ 
    auth: { ... }
    data: {
        jobs:  { 
            "<job_id_1>" : {},
            "<job_id_2>" : {},  
               ...
            "<job_id_n>" : {}
        }
    }
}

Response:

{ 
    status: 0
}

Distribute Jobs into Regions/Clusters

You can distribute say 100 jobs into e.g. 10 regions/clusters with the following request:

POST https://hellotracks.com/api/distributejobs

{ 
    auth: { ... }
    data: {
        jobs:  { 
            "<job_id_1>" : {},
            "<job_id_2>" : {},  
               ...
            "<job_id_n>" : {}
        },
        regions: <count>,
        optimize: <1-or-2>
    }
}

Response:

{ 
    status: 0,
    clusters: [
            { 
                "center_lat": <latitude>,
                "center_lng": <longitude>,
                "jobs" ["<job_id>",...,""<job_id>""],
            },
            ...
            { ... }
    ],
    maplink: "https://maps.google.com/maps/api/staticmap?center=&size=800x800&markers=color:0x8a2be2%7Clabel:1|37.4430274,-122.16563541|37.4430274,-122.16563541|37.4430274,-122.16563541|37.420177,-122.1437971|37.4147446,-122.1463464&markers=color:0xa52a2a%7Clabel:2|37.7802017,-122.39676012|37.7905151,-122.38908462|37.7766272,-122.39439722|37.7817018,-122.39590872|37.7766272,-122.39439722|37.801791,-122.4023092|37.7919951,-122.40063392|37.795274,-122.3931552|37.7537577,-122.42765022|37.7537577,-122.4276502&markers=color:0xdeb887%7Clabel:3|37.807671,-122.42129343|37.8083766,-122.41482783|37.8014285,-122.43308133|37.8067536,-122.43104083|37.8044073,-122.4267493&sensor=false&key=AIzaSyDI2RBDivFTcFSDa4s4SbV4kGJRpksB_eE"
            
}

Note: you can use the maplink for testing purposes to verify results

Set optimize:1 for optimizing for even cluster sizes, set optimize to 2 to allow uneven cluster sizes optimizing for distance.

3 regions optimized by even cluster size (optimize:1):

MacDown logo

3 regions optimimized by distance (optimize:2):

MacDown logo

Optimize a single-route by distance

You can optimize a route for a person per day. The optimization will be applied immediatebly (no saving or editing necessary) and the worker will be notified about the new order of jobs if the day field is set to today's value. The optimization is distance based and currently does not respect time windows and priorities. You can choose to include the company as start and finish locations to take into account for optimizing the route.

POST https://hellotracks.com/api/optimizeroute

{ 
    auth: { ... }
    data: {
        day: 20151125,
        account: <worker-username-or-uid>,
        includeCompany: <true-or-false> 
    }
}

Set includeCompany:true if your workers start and stop at your company's location, else false.

Response:

{ 
    status: 0,
    jobs: [{<job1>}, {<job2>} ... ]
    maplink: "https://maps.google.com/maps/api/staticmap?center=&size=800x800..."
}

Note: you can use the maplink for testing purposes to verify results

Tracking

Locating real-time position of an account with locate

Request:

POST https://hellotracks.com/api/locate

# by account uids:

{ 
    auth: { ... }
    data: {
        withAddress:    <true-or-false>,
        withDetails: <true-or-false>.
        accounts: [ 
            "<uid-or-username>" : {},
            "<uid-or-username>" : {},
               ...
            "<uid-or-username>" : {}
         ]
    }
}

# or by 1 or more teams:

{ 
    auth: { ... }
    data: {
        withAddress:    <true-or-false>,
        teams: [1, 2, ... , 6]
    }
}

Response:

{
   "accounts": [
      {
         "uid": "cubt5w",           // Worker UID
         "ts": 1396985826428,       // Timestamp in millis
         "dir": 10,                 // Direction heading
         "lng": -122.43143,         // Longitude
         "usr": "topservicesltd@gmail.com",
         "spd": 0,                  // Speed
         "elv": 20,                 // Elevetion
         "lat": 37.801205,          // Latitude
         "acc": 4,                  // Accuracy in meter
         "name": "John"             // Full name
         "bat": 78                  // battery level in percent
         "teams":[{"name":"Zone G","number":4}],
         // if withAddress:true    
         "address": "Chestnut Street, San Francisco",
         // if withDetails:true
         "connection_type":1,       // device's internet connection type
         "android_id":"aa819713c067792e",
         "loc_gps_on":true,         // Android setting if locating over GPS is activated (should be true)
         "loc_net_on":true,         // Android setting if locating over cell and wifi is activated (should be true)
         "tracking_status":true,    // if Hellotracks tracking switch is set to on or off
         "signal_ts": 1454894511000,// the timestamp in millis for the last signal (ping received)
      }
   ],
   "status": 0
}

Note: If you add "signal":"ping" as a parameter Hellotracks will send a signal to all devices. Devices that are logged in and do have internet connection will respond with updated data. signal_ts represents the last received ping signal from the device.

Note: Timestamps are milliseconds, between the current time and midnight, January 1, 1970 UTC (Java timestamps)

Retrieving tracks and mileage information with gettracks

Request:

POST https://hellotracks.com/api/gettracks

{ 
    auth: { ... }
    data: {
        from:   <timestamp-in-millis>,
        until:  <timestamp-in-millis>,
        accounts: [ 
            "<uid-or-username>" : {},
            "<uid-or-username>" : {},
               ...
            "<uid-or-username>" : {}
         ]
    }
}

Response:

{
   "status": 0,
   "accounts": {
      "daniel.bernoulli.ts": [
         {
            "lng_max": 0,
            "lng_min": 0,
            "owner_uid": "je7oc8",
            "start_ts": 1447018045000,
            "labels": 0,
            "altitude_min": -44,
            "altitude_loss": 159,
            "course_encoded": "cbveFpkgj...",
            "waypoint_count": 275,
            "kind": "track_entry",
            "altitude_max": 0,
            "start_lng": -122.43145,
            "short_encoded": "cbveFpkgjVc...",
            "id": 13787157,
            "distance": 3503.1265,
            "share_url": "https://hellotracks.com/!/@t/13787157",
            "end_lng": -122.43148,
            "speed_avg": 4.140268,
            "end_ts": 1447021091000,
            "lat_max": 0,
            "speed_max": 12,
            "altitude_gain": 166,
            "start_lat": 37.80146,
            "end_lat": 37.80122,
            "lat_min": 0
         },
         {
            ...
         }
      ]
   }
}

Webhooks

Hellotracks provides webhooks for job updates with custom callbacks. With webhooks you get immediately informed about updates which in the same time reduces unnecessary frequent polling.

Please let us know about your api-endpoint that Hellotracks should hit, we will set it up for your company: api@hellotracks.com

Job Updated Webhook

    POST http://<your-endpoint>/jobupdated

with a comma separated list of job-ids that changed as its content

    data=<job_id_1>,<job_id_2>,...<job_id_3>