Navbar
👋 Have a question? Ask us!
cURL NodeJS Python Java PHP Ruby Swift ObjC

References

references > APIs

HyperTrack APIs allow to manage devices and trips using an HTTP-based RESTful interface with JSON format. HyperTrack APIs are mainly used to integrate with the HyperTrack platform through your backend server. Using the APIs allows you to obtain the full state of all tracked devices and trips.

HyperTrack REST APIs can be consumed through HTTP requests. Please follow the guidelines below to ensure a working server setup.

Authentication

HTTP 401 - Unauthorized

{
  "message": "Unauthorized"
}

API requests require Basic Authentication to succeed. Failing to set the Authorization header in the right format with correct credentials will result in errors.

A sample Authorization header looks like this:

Authorization: Basic V3AxTGdWTjNZSGFmOHVRcE9qalTNTMm5BaEF1RA==

Generating Basic Auth header

credentials="$(echo -n "{AccountId}:{SecretKey}" | base64)"
header="Authorization: Basic $credentials"
const auth =
  "Basic " + new Buffer("{AccountId}" + ":" + "{SecretKey}").toString("base64");
const header = { Authorization: auth };
base64string = base64.encodestring('%s:%s' % ('{AccountId}', '{SecretKey}')).replace('\n', '')
header = ("Authorization: Basic %s" % base64string)
String authString = "Authorization: Basic " +
                Base64.getEncoder().encodeToString(
                        String.format("%s:%s", "{AccountId}","{SecretKey}")
                                .getBytes()
                );
<?php

$header = "Authorization: Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

?>
$header = 'Authorization: Basic ' + Base64.encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp
let base64encoded = "{AccountId}:{AccountId}".data(using: .isoLatin1)?.base64EncodedString() ?? ""
urlRequest.addValue("Basic \(base64encoded)", forHTTPHeaderField: "Authorization")
[request addRequestHeader:@"Authorization"
                    value:[NSString stringWithFormat:@"Basic %@",
                           [ASIHTTPRequest base64forData:
                            [[NSString stringWithFormat:@"%@:%@", "{AccountId}", "{SecretKey}"]
                             dataUsingEncoding:NSUTF8StringEncoding]]]];

The header should be constructed as followed:

With authentication in place, you should be able to make successful HTTP requests to HyperTrack APIs.

HTTPS Methods

Depending on the HyperTrack API and endpoint, your server should support the following HTTPS methods: GET, POST, and DELETE.

HTTP Response Codes

HyperTrack APIs implement appropriate HTTP response codes to indicate how the HTTP request was processed. In success cases, you will receive the expected JSON payload. However, API requests can fail due to client or server errors. We adopted the RFC 7807 standard for our error messages. Please ensure your implementation handles error messages for all HTTP requests.

JSON Payload

The payload you will receive with HTTPS requests is formatted in JSON. You need to implement the capability to parse JSON objects in order to leverage the HTTP response body content.

You should use a JSON parser that handles converting the escaped representation of control characters back to their ASCII character values (for example, converting \n to a newline character).

The HyperTrack APIs make use of GeoJSON and ISO 8601 timestamp formats, which you should handle appropriately as well.

Base URL and endoints

All HyperTrack APIs have are available on the same base URL:

https://v3.api.hypertrack.com/

However, each API is reachable on a different endpoint:

Path Parameters

Path parameters are used to accomplish querying, filtering, searching, sorting, and for pagination.

Query Trips API by trip_id

curl \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/{trip_id}
const request = require("request");

const options = {
  url: "https://v3.api.hypertrack.com/trips/{trip_id}",
  auth: {
    user: "{AccountId}",
    password: "{SecretKey}"
  }
};

request(options, (err, res, body) => {
  console.dir(err, res, body);
});
import requests

response = requests.get("https://v3.api.hypertrack.com/trips/{trip_id}", auth=("{AccountId}", "{SecretKey}"))

print(response.text)
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/{trip_id}")
  .get()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/{trip_id}');
$request->setMethod(HTTP_METH_GET);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/{trip_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

Querying

HyperTrack APIs support querying to request a single resource using the respective identifier:

Filtering

Filter Trips API sample URLs

# reduce result set size to 5 trips
GET https://v3.api.hypertrack.com/trips?limit=5

# find trips with status "completed"
GET https://v3.api.hypertrack.com/trips?status=completed

It is planned to provide filtering capabilities to ...

Pagination

Coming soon: Trips API pagination parameters

# get items 180-200 form entire result set
https://v3.api.hypertrack.com/trips?offset=180&limit=20

The APIs utilize token-based pagination, which will allow to control how many items should be skipped in the returned result set.

The links section of the response provides a next link to request the next page of results.

Postman Collection

We published a Postman Collection to make it easier and faster to experiment with the HyperTrack APIs. Postman Collections lists all available API endpoints, allow making API requests instantly (with Basic Auth), and can generate reusable code snippets to make API requests using the programming language of your choice.

Try it out yourself:

Run in Postman

Payload and Headers

The responses will always include a set of headers. Please review them carefully when implementing the APIs.

Content-Type

The body payload sent by the server is in application/json, which means that the JSON format is enforced for the payload by default. Please ensure you handle JSON appropriately before processing the data.

Pagination

The payload structure of responses is change as follows.

{
  "data": [
    // trip objects
  ],
  "links": {
    "next": "https://v3.api.hypertrack.com/trips/?pagination_token=abc"
  }
}
Name Type Description
links reference object Object with references to use for pagination
links.next URL URL with pointer to the next page

The links object will include all pagination and filtering properties to navigate through result sets with the same query as initiated. You should use the links properties and prefix them with the API base URL to make consecutive API calls when scrolling through the result set.

The easiest way to identify the end of the pagination is to look for the existence of the links.next property. If it doesn’t exist, you completed the pagination.

Processing States

HTTP 202 - Trip completion processing payload

{
  "message": "pending completion for trip '00112233-4455-6677-8899-AABBCCDDEEFF'"
}

In some scenarios, API requests cannot be fully processed before an API response has to be issued. An example of this is the completion of a trip. The request needs to be processed on the platform and trip completion needs to be confirmed on the mobile SDK of the device. To handle the processing, the API will respond with a processing state (e.g. processing_completion for trips).

To handle the processing state, you should anticipate the response to be in a different format (see the message property).

After processing the request on the HyperTrack platform, a webhook will be sent out and the requested resource will be available through the API. For trip completion, you will receive a completed trip webhook. After the webhook arrival, you can also call the Trips API to retrieve the trip resource using the trip_id.

Errors

HTTP 401 - Trip not found error payload

{
  "status": 404,
  "code": "trip_not_found",
  "title": "Trip could not be found",
  "type": "https://docs.hypertrack.com/#trips-api-trip-not-found",
  "detail": "Trip with the id '00112233-4455-6677-8899-AABBCCDDEEFF' does not exist"
}

We are adopting the RFC 7807 standard for API error messages.

The standard requires at least the type property. Everything else is optional. For HyperTrack, we always send title, detail, status, and code in addition. To detail out some errors (for instance multiple invalid fields), additional properties will be available.

Parameter Type Description
status Number HTTP status code
code String Error class code
title String Brief summary of the error class
type URL URL to the respective error page (about:blank if none is provided)
detail String Detailed description of the error instance
invalid_params Object A list of invalid parameters to review (options)

Please review the reference page to see all possible HTTP errors returned by the HyperTrack APIs.

references > apis > Devices

Use the HyperTrack API to track and manage devices with installed app(s) built with the HyperTrack SDK.

references > apis > devices > Start tracking

Device start tracking example:

curl -X POST \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/devices/{device_id}/start
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);
// Use Node.js helper library method to start tracking
hypertrack.devices.startTracking(deviceId).then(() => {
  // Tracking started
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

hypertrack.devices.start_tracking({device_id})
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/devices/{device_id}/start")
  .post(null)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/devices/{device_id}/start');
$request->setMethod(HTTP_METH_POST);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/devices/{device_id}/start")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

HTTP 200 - Tracking command was sent (no content)

Start tracking a device with the API.

POST /devices/{device_id}/start

Authentication: Basic Auth

Path Parameters

device_id - a string representing the ID of device, case sensitive

references > apis > devices > Stop tracking

Device stop tracking example:

curl -X POST \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/devices/{device_id}/stop
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);
// Use Node.js helper library method to stop tracking
hypertrack.devices.stopTracking(deviceId).then(() => {
  // Tracking stopped
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

hypertrack.devices.stop_tracking({device_id})
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/devices/{device_id}/stop")
  .post(null)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/devices/{device_id}/stop');
$request->setMethod(HTTP_METH_POST);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/devices/{device_id}/stop")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

HTTP 200 - Tracking command was sent (no content)

Stop tracking a device with the API.

POST /devices/{device_id}/stop

Authentication: Basic Auth

Path Parameters

device_id - a string representing the ID of device, case sensitive

references > apis > devices > Set device name and metadata

Set device name and metadata example:

payload='{
  "name": "Alex’s Phone",
  "metadata": {
    "customer_id": "ABC123"
  }
}'

curl -X PATCH \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/devices/{device_id} \
  -H 'Content-Type: application/json' \
  -d $payload
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

// Change device name
hypertrack.devices.changeName(deviceId, "Test Name").then(() => {
  // Name changed
}).catch(error => {
  // Error handling
})

// Change device metadata
let metadata = {
    customer_id: "ABC123"
};

hypertrack.devices.patchMetadata(deviceId, metadata).then(() => {
  // Metadata set
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

# Change device name
hypertrack.devices.change_name({device_id}, "Test name")


# Change metadata
metadata = {
  "customer_id": "ABC123"
}

hypertrack.devices.patch_metadata({device_id}, metadata)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n  "
    + "\"name\": \"Alex’s Phone\",\n "
    + "  \"metadata\": {\n"
    + "    \"customer_id\": \"ABC123\"\n"
    + "  }\n"
    + "}");

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "4IZ7fWXxRmmxFL4RWcAgxrPWBD8","rXc40pSVlYkhJsNkcQCncp-c5CVxQeRi6s6bAWXM6T76bWwUlaUMlQ")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/devices/{device_id}")
  .patch(body)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/devices/{device_id}');
$request->setMethod(HTTP_METH_PATCH);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

$request->setBody('{
  "name": "Alex’s Phone",
  "metadata": {
    "customer_id": "ABC123"
  }
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/devices/{device_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp
request.body = {
  "name": "Alex’s Phone",
  "metadata": {
    "customer_id": "ABC123"
  }
}.to_json

response = http.request(request)
puts response.read_body

HTTP 204 - Device updated (no content)

Update the name and/or metadata for a device.

PATCH /devices/{device_id}

Authentication: Basic Auth

Path Parameters

device_id - a string representing the ID of a tracked device, case sensitive

Request Body

Request body must be a JSON formatted string. In order to patch name and/or metadata for the device, you must include name and/or metadata as keys inside this JSON object. Note that metadata needs to be a valid JSON object.

references > apis > devices > Get device list

Get device list example:

curl \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/devices/
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.devices.getAll().then(devices => {
  // Process devices list
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

"""
Arguments:
 - pagination: bool flag to enable or disable pagination. False by default
 - pagination_token: string token received from previous call to request next page
"""
devices = hypertrack.devices.get_all()
print(devices)
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/devices/")
  .get()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/devices/');
$request->setMethod(HTTP_METH_GET);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/devices/")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

HTTP 200 - Devices payload

[
  {
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "location": {
        "speed": 4.20,
        "accuracy": 14.09,
        "bearing": 193.12,
        "geometry": {
        "type": "Point",
        "coordinates": [
            35.1016383,
            47.8391314,
            65.40
        ]
        },
        "recorded_at": "2019-07-18T18:01:59.064000Z",
    },
    "device_status": {
        "data": {
        "recorded_at": "2019-07-30T01:38:45.610000Z",
        "activity": "stop"
        },
        "value": "active"
    },
    "views": {
        "share_url":"https://trck.at/abcdef",
        "embed_url":"https://embed.hypertrack.com/devices/00112233-4455-6677-8899-AABBCCDDEEFF?publishable_key=abc"
    },
    "battery": "normal",
    "device_info": {
        "timezone": "America/Los_Angeles",
        "os_name": "iOS",
        "device_brand": "Apple",
        "sdk_version": "3.3.2",
        "device_model": "iPhone X",
        "network_operator": "T-Mobile",
        "name": "Alex’s Phone",
        "os_version": "12.4"
    },
    "registered_at": "2019-07-10T01:38:45.610000Z",
    "metadata": { ... }
  },
  ...
]

Get list of devices in your account (excludes deleted devices)

GET /devices

Get all tracked devices.

Authentication: Basic Auth

Response Attributes

Name Type Description
device_id string Unique device identifier, case sensitive
location object (optional)
location.data.speed float (optional) speed in m/s
location.data.accuracy float (optional) accuracy in m
location.data.bearing float (optional) bearing in degrees starting at due north and continuing clockwise around the compass
location.data.geometry object Location in GeoJSON format
location.data.geometry.type string As of right now, only Point is supported
location.data.geometry.coordinates array Array of longitude, latitude and optional altitude
location.recorded_at string ISO 8601 date when the location was recorded
device_status object Device status.
device_status.value string Can be one of active, inactive and disconnected. Please read here to understand how HyperTrack tracks device status.
device_status.data object Extra information about device status
device_status.data.recorded_at string ISO 8601 date when the device status was recorded (optional)
device_status.data.activity string Device activity (optional). If available, can be one of stop, walk, or drive
device_status.data.reason string For inactive devices only.

Can be one of:

location_permissions_denied,
location_services_disabled,
motion_activity_permissions_denied,
motion_activity_services_disabled,
motion_activity_services_unavailable,
stopped_programmatically,
tracking_service_terminated,
unexpected
views object
views.embed_url string Embeddable view URL
views.share_url string Sharable view URL
battery string Battery status, can be one of low, normal, or charging
device_info object Device information
device_info.timezone string The timezone on the device in TZ format
device_info.os_name string The operating system of the device, can be one of iOS or Android
device_info.device_brand string The brand of the device
device_info.sdk_version string The HyperTrack SDK version on the device. Can be reviewed here: Android, iOS, React Native
device_info.device_model string The device model
device_info.network_operator string The network operator for the device
device_info.os_version string The version of the operating system on the device
metadata object Device metadata submitted via Mobile SDKs (Android, iOS) or Devices API
registered_at string ISO 8601 date when the device was registered
name object The name of the device submitted via Mobile SDKs (Android, iOS) or Devices API

references > apis > devices > Get device location and status

Get device location and status example:

curl \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/devices/{device_id}
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.devices.get(deviceId).then(device => {
  // Process device
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

device = hypertrack.devices.get({deviceId})
print(device)
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/devices/{device_id}")
  .get()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/devices/{device_id}');
$request->setMethod(HTTP_METH_GET);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/devices/{device_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

HTTP 200 - Single device payload

{
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "location": {
    "speed": 4.20,
    "accuracy": 14.09,
    "bearing": 193.12,
    "geometry": {
      "type": "Point",
      "coordinates": [
        35.1016383,
        47.8391314,
        65.40
      ]
    },
    "recorded_at": "2019-07-18T18:01:59.064000Z",
  },
  "device_status": {
    "data": {
      "recorded_at": "2019-07-30T01:38:45.610000Z",
      "activity": "stop"
    },
    "value": "active"
  },
  "views": {
    "share_url":"https://trck.at/abcdef",
    "embed_url":"https://embed.hypertrack.com/devices/00112233-4455-6677-8899-AABBCCDDEEFF?publishable_key=abc"
  },
  "battery": "normal",
  "device_info": {
    "timezone": "America/Los_Angeles",
    "os_name": "iOS",
    "device_brand": "Apple",
    "sdk_version": "3.3.2",
    "device_model": "iPhone X",
    "network_operator": "T-Mobile",
    "name": "Alex’s Phone",
    "os_version": "12.4"
  },
  "registered_at": "2019-07-10T01:38:45.610000Z",
  "metadata": { ... }
}

Get live location and status of a device. GET /devices/{device_id}

Authentication: Basic Auth

Path Parameters

device_id - a string representing the ID of a tracked device, case sensitive

Response Attributes

Name Type Description
device_id string Unique device identifier, case sensitive
location object (optional)
location.data.speed float (optional) speed in m/s
location.data.accuracy float (optional) accuracy in m
location.data.bearing float (optional) bearing in degrees starting at due north and continuing clockwise around the compass
location.data.geometry object Location in GeoJSON format
location.data.geometry.type string As of right now, only Point is supported
location.data.geometry.coordinates array Array of longitude, latitude and optional altitude
location.recorded_at string ISO 8601 date when the location was recorded
device_status object Device status.
device_status.value string Can be one of active, inactive and disconnected. Please read here to understand how HyperTrack tracks device status.
device_status.data object Extra information about device status
device_status.data.recorded_at string ISO 8601 date when the device status was recorded (optional)
device_status.data.activity string Device activity (optional). If available, can be one of stop, walk, or drive
device_status.data.reason string For inactive devices only.

Can be one of:

location_permissions_denied,
location_services_disabled,
motion_activity_permissions_denied,
motion_activity_services_disabled,
motion_activity_services_unavailable,
stopped_programmatically,
tracking_service_terminated,
unexpected
views object
views.embed_url string Embeddable view URL
views.share_url string Sharable view URL
battery string Battery status, can be one of low, normal, or charging
device_info object Device information
device_info.timezone string The timezone on the device in TZ format
device_info.os_name string The operating system of the device, can be one of iOS or Android
device_info.device_brand string The brand of the device
device_info.sdk_version string The HyperTrack SDK version on the device. Can be reviewed here: Android, iOS, React Native
device_info.device_model string The device model
device_info.network_operator string The network operator for the device
device_info.os_version string The version of the operating system on the device
metadata object Device metadata submitted via Mobile SDKs (Android, iOS) or Devices API
registered_at string ISO 8601 date when the device was registered
name object The name of the device submitted via Mobile SDKs (Android, iOS) or Devices API

references > apis > devices > Get device history

Get single device history example:

curl \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/devices/{device_id}/history/{date}
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.devices.getHistory(deviceId, "2020-03-17").then(history => {
  // Process device history
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

"""
Arguments:
 - device_id: string
 - history_date - may be string in format "YYYY-mm-dd or python date/datetime object"
"""
device_history = hypertrack.devices.get_history(device_id, "2020-03-17")
print(device_history)

OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/devices/{device_id}/history/{date}")
  .get()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/devices/{device_id}/history/{date}');
$request->setMethod(HTTP_METH_GET);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/devices/{device_id}/history/{date}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

HTTP 200 - Single device history response

{
    "distance": 14,
    "duration": 86400,
    "started_at": "2020-02-24T00:00:00+00:00",
    "completed_at": "2020-02-25T00:00:00+00:00",
    "locations": {
        "type": "TimeSeriesLine",
        "coordinates": [
            {
                "type": "Point",
                "coordinate": [
                    35.185475,
                    47.7785621,
                    55.9566650390625
                ],
                "timestamp": "2020-02-24T22:22:36.631000Z"
            }
        ]
    },
    "markers": [
        {
            "type": "device_status",
            "data": {
                "value": "inactive",
                "start": {
                    "recorded_at": "2020-02-24T22:23:55.993000Z",
                    "location": {
                        "geometry": {
                            "type": "Point",
                            "coordinates": [
                                35.185475,
                                47.7785621
                            ]
                        },
                        "recorded_at": "2020-02-24T22:22:36.631000Z"
                    }
                },
                "end": {
                    "recorded_at": "2020-02-25T00:00:00Z",
                    "location": {
                        "geometry": {
                            "type": "Point",
                            "coordinates": [
                                35.185475,
                                47.7785621
                            ]
                        },
                        "recorded_at": "2020-02-24T22:22:36.631000Z"
                    }
                },
                "reason": "stopped_programmatically",
                "duration": 5764,
                "__typename": "DeviceStatusMarkerData"
            }
        }
    ],
    "device_id": "F6BED2D5-82FF-36D7-91F9-5C6C2749FD1A"
}

Get location history of device organized by activity and outage segment markers.

GET /devices/{device_id}/history/{date}

Authentication: Basic Auth

Path Parameters

device_id - a string representing the ID of a tracked device, case sensitive
date - a string representing specific date in UTC format YYYY-MM-DD

The response includes next data:

Name Type Description
locations object Object representing the location time series of the trips. Follows GeoJSON geometry of type LineString
locations.type string As of right now, only LineString is supported
locations.coordinates array Array of coordinates arrays; each item follows [longitude, latitude, elevation, timestamp]; elevation can be null
distance int Distance in meters
duration int Duration in seconds
started_at string ISO 8601 history start date
completed_at string ISO 8601 history end date
device_id string Unique identifier of the device, case sensitive
markers array Array of markers
markers[].type string Marker type; can be one of device_status, geofence or trip_marker
markers[].data object Marker data; dependent on marker type

references > apis > devices > Export account data

Export account data example:

curl \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/devices/history/{date}
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.devices.getAccountHistory("2020-03-17", "blob", "json", "km").then(history => {
  // Process history
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

"""
Arguments:
  - history_date: string date in format "YYYY-mm-dd or python date/datetime object"
  - response: string `blob` or `file`. `blob` by default
  - response_type: string `json` or `csv`. `json` by default`
  - unit: string `km` or `mi`. `km` by default
"""
account_history = hypertrack.devices.get_account_history("2020-03-17", "blob", "json", "km")
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/devices/history/{date}")
  .get()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/devices/history/{date}');
$request->setMethod(HTTP_METH_GET);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/devices/history/{date}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

Get data for all tracked devices for a specified day. Data is available for the the last 60 days.

GET /devices/history/{date}

HTTP 200 - Devices history response

[
    {
        "active_duration": 221186,
        "inactive_duration": 115,
        "inactive_count": 1,
        "disconnected_duration": null,
        "disconnected_count": null,
        "stop_duration": 194697,
        "stop_count": 48,
        "walk_distance": 7222,
        "walk_duration": 6187,
        "walk_count": 5,
        "drive_distance": 222217,
        "drive_duration": 21418,
        "drive_count": 14,
        "trip_marker_route_to_distance": null,
        "last_updated": "2020-03-06T16:08:27.614750+00:00",
        "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
        "device_info": {
            "app_name": "io.hypertrack.SendETA-iPhone",
            "app_version_string": "",
            "app_version_number": "4.1.0",
            "device_hardware": "",
            "device_brand": "Apple",
            "device_meta": "",
            "device_model": "iPhone 11 Pro Max",
            "name": "Yar's iPhone",
            "network_operator": "AT&T",
            "os_hardware_identifier": "54ECE003-2708-49D3-A211-548BSD590612",
            "os_name": "iOS",
            "os_version": "13.3.1",
            "play_services_version": "",
            "recorded_at": "2020-03-03T16:39:17.944Z",
            "sdk_version": "4.0.2-rc.3",
            "timezone": "America/Los_Angeles"
        },
        "trips_count": 2,
        "trips_links": [
            "https://embed.hypertrack.com/trips/f8fd3af4-ca1a-11e9-8e88-1a94e0b3a523?publishable_key=abc",
            "https://embed.hypertrack.com/trips/ks838ks9-ca93-12j2-8e88-3mdki37asj47?publishable_key=abc"
        ],
        "geofences_visited_duration": 99,
        "geofences_route_to_distance": 88430
    },
    {
        "active_duration": 68842,
        "inactive_duration": null,
        "inactive_count": null,
        "disconnected_duration": null,
        "disconnected_count": null,
        "stop_duration": 68842,
        "stop_count": 22,
        "walk_distance": null,
        "walk_duration": null,
        "walk_count": null,
        "drive_distance": null,
        "drive_duration": null,
        "drive_count": null,
        "trip_marker_route_to_distance": null,
        "last_updated": "2020-03-06T16:08:27.614770+00:00",
        "device_id": "00112233-4455-6677-8899-AABBCCDDEEDD",
        "device_info": {
            "app_name": "com.hyperTrack.core.sdk.test.app",
            "app_version_string": "",
            "app_version_number": "4.0.2",
            "device_hardware": "",
            "device_brand": "Apple",
            "device_meta": "",
            "device_model": "iPhone 6",
            "name": "Yar’s iPhone 6",
            "network_operator": "Kyivstar",
            "os_hardware_identifier": "54ECE003-2708-49D3-A211-548BSD590613",
            "os_name": "iOS",
            "os_version": "12.4.4",
            "play_services_version": "",
            "recorded_at": "2020-03-05T13:58:24.964Z",
            "sdk_version": "4.0.2-rc.3",
            "timezone": "Europe/Kyiv"
        },
        "trips_count": 0,
        "trips_links": []
    }
]

Authentication: Basic Auth

Path Parameters

date - a string representing specific date in UTC format YYYY-MM-DD

Query Parameters

response - response object can be one of: blob or file

     blob response object is a binary large object, has JSON format and returned in the response.

     file response object is a link to a temporary S3 bucket with JSON file and can be downloaded.

type - response type can be one of: json or csv

unit - metric or imperial system: km or mi

If query parameters are omitted, the default response object is blob, type is json and unit is km

Query Example

GET /devices/history/{date}?response=blob&type=json&unit=km

Response Attributes

Name Type Description
device_id string Unique device identifier, case sensitive
active_duration int Active duration in seconds
inactive_duration int Inactive duration in seconds
inactive_count int Inactive events count
disconnected_duration int Disconnected duration in seconds
disconnected_count int Disconnect events count
stop_duration int Stop duration in seconds
stop_count int Stop events count
walk_distance int Walk distance in meters
walk_duration int Walk duration in seconds
walk_count int Walk events count
drive_distance int Drive distance in meters
drive_duration int Drive duration in seconds
drive_count int Drive events count
trip_marker_route_to_distance int Route to trip markers in meters
last_updated string Timestamp of the latest device information update
device_info object Device information
device_info.app_name string Application name
device_info.app_version_string string Application version
device_info.app_version_number string Application version number
device_info.device_hardware string The hardware of the device
device_info.device_brand string The brand of the device
device_info.device_meta string Device meta data
device_info.device_model string The device model
device_info.name string Name of the device
device_info.network_operator string The network operator for the device
device_info.os_hardware_identifier string The operating system hardware identifier
device_info.os_name string The operating system of the device, can be one of iOS or Android
device_info.os_version string The version of the operating system on the device
device_info.play_services_version string Play services version of the device
device_info.recorded_at string Timestamp of the latest device_info update
device_info.sdk_version string The HyperTrack SDK version on the device. Can be reviewed here: Android, iOS, React Native
device_info.timezone string The timezone on the device in TZ format
trips_count int Trips count
trips_links array Array of trips embed view URLs
geofences_visited_duration int Duration of visit to the geofences in seconds (optional)
geofences_route_to_distance int Route to geofences in meters (optional)

references > apis > devices > Delete device

Delete single device example:

curl -X DELETE \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/devices/{device_id}
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.devices.delete(deviceId).then(() => {
  // Device deleted
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

hypertrack.devices.delete({deviceId})
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/devices/{device_id}")
  .delete(null)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/devices/{device_id}');
$request->setMethod(HTTP_METH_DELETE);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/devices/{device_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Delete.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

Delete a device. Once deleted, the device will not be able send location data again. Deleted devices cannot be undeleted.

DELETE /devices/{device_id}

HTTP 204 - Device removed (no content)

Authentication: Basic Auth

Path Parameters

device_id - a string representing the ID of a tracked device, case sensitive

references > apis > Trips

Manage Trips on the HyperTrack platform. With Trips API, you may be able a trip with destination, and a trip with geofences, or without either a destination or geofence.

references > apis > trips > Start trip with destination

Trip with destination request example:

payload='{
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "destination": {
    "geometry": {
      "type": "Point",
      "coordinates": [-122.3980960195712, 37.7930386903944]
    },
    "scheduled_at": "2022-05-03T06:25:51.238000Z"
  },
  "metadata": {
    "shift_id": "ABC123"
  }
}'

curl -X POST \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/ \
  -H 'Content-Type: application/json' \
  -d $payload
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

let tripData = {
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "destination": {
    "geometry": {
      "type": "Point",
      "coordinates": [35.10747945667027, 47.8565694654932]
    },
      "radius": 50
  }
};

hypertrack.trips.create(tripData).then(trip => {
  // Trip created
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

trip_data = {
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "destination": {
    "geometry": {
      "type": "Point",
      "coordinates": [35.10747945667027, 47.8565694654932]
    },
      "radius": 50
  }
}

trip = hypertrack.trips.create(trip_data)
print(trip)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,"{\n" +
        "  \"device_id\": \"00112233-4455-6677-8899-AABBCCDDEEFF\",\n" +
        "  \"metadata\": {\n" +
        "    \"shift_id\": \"ABC123\"\n" +
        "  }\n" +
        "}");

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "4IZ7fWXxRmmxFL4RWcAgxrPWBD8","rXc40pSVlYkhJsNkcQCncp-c5CVxQeRi6s6bAWXM6T76bWwUlaUMlQ")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/")
  .post(body)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/');
$request->setMethod(HTTP_METH_POST);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

$request->setBody('{
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "metadata": {
        "shift_id": "ABC123"
    }
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp
request.body = {
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "metadata": {
        "shift_id": "ABC123"
    }
}.to_json

response = http.request(request)
puts response.read_body

Start a new trip for a device with a destination.

POST /trips

Authentication: Basic Auth

Trip with destination request attributes

Name Type Description
device_id string Unique identifier representing a device, case sensitive
destination object Definition of a trip destination (optional)
destination.geometry object GeoJSON geometry of type Point
destination.geometry.type string As of right now, only Point is supported
destination.geometry.coordinates array Array of longitude and latitude (in that order)
destination.radius int Defines the radius (in meters) of a circular trip destination (optional, default is 30)
destination.scheduled_at string Timestamp for scheduled arrival (optional)
metadata object Optional JSON metadata you want to assign to this trip

HTTP 201 - New trip with destination

{
  "completed_at": null,
  "status": "active",
  "views": {
    "embed_url": "https://embed.hypertrack.com/dkdkddnd",
    "share_url": "https://trck.at/abcdef"
  },
  "destination": {
    "geometry": {
      "type": "Point",
      "coordinates": [
        -122.3980960195712,
        37.7930386903944
      ]
    },
    "radius": 30,
    "scheduled_at": null,
    "arrived_at": null,
    "exited_at": null
  },
  "estimate": {
    "arrive_at": "2019-05-03T06:25:51.238000Z",
    "route": {
      "distance": 14666,
      "duration": 2884,
      "remaining_duration": 1560,
      "start_place": "Mannat Manzil #48,2nd cross, 3rd Main,Amrita Nagar, 3rd Phase, Choodasandra, Bengaluru, Karnataka 560035, India",
      "end_place": "4, Muniswamy Garden, A - Block, Bengaluru, Karnataka 560025, India",
      "polyline": {
        "type": "LineString",
        "coordinates": [
          [ -122.3980960195712, 37.7930386903944 ]
          , ... ]
      }
    }
  }
}

Trip with destination response attributes

Name Type Description
trip_id string Unique identifier of the newly created trip, case sensitive
device_id string Unique identifier of the device associated with the trip, case sensitive
started_at string Timestamp for trip starting time
completed_at string Timestamp of trip completion time (only set when trip is completed), can be null
status string Trip status, can be active, completed or processing_completion
views.embed_url string Embeddable trip view
views.share_url string Shareable trip view
destination object Defined trip destination
destination.geometry object GeoJSON geometry of type Point for destination point
destination.radius int Radius (in meters) of a circular trip destination
destination.scheduled_at string Timestamp for scheduled arrival
destination.arrived_at string Timestamp first enter to destination
destination.exited_at string Timestamp first exit from destination
estimate object Estimates (route and arrival time) Only available for active trips.
estimate.arrive_at string Timestamp for estimated arrival
estimate.route objects Planned route segments to destination
estimate.route.distance int Route distance in meters
estimate.route.duration int Route duration in seconds
estimate.route.remaining_duration int Remaining route duration in seconds, can be null
estimate.route.start_place string Start place for segment start
estimate.route.end_place string End place for segment end
estimate.route.polyline object GeoJSON geometry of type LineString
metadata object Metadata provided at trip start

Please keep in mind that new trips do not have the summary property (outlining the trip history). The summary is only provided upon completion of a trip.

This API returns HTTP 201 once the trip is successfully created. If a trip with same destination and metadata already exists, the API will return existing trip with HTTP status 200.

references > apis > trips > Start trip with geofences

Trip with geofences example:

payload='{
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "geofences": [
    {
      "geometry": {
        "type": "Polygon",
        "coordinates": [
            [-121.3980960195712, 38.7940386903944],
            [-121.3990960195712, 38.7940386903944],
            [-121.3990960195712, 38.7930386903944],
            [-121.3980960195712, 38.7930386903944]
          ]
      },
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office"
      }
    },
    {
      "geometry": {
        "type": "Point",
        "coordinates": [-121.3980960195712, 38.7930386903944]
      },
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office"
      }
    }
  ],
  "metadata": {
    "shift_id": "ABC123"
  }
}'

curl -X POST \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/ \
  -H 'Content-Type: application/json' \
  -d $payload
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

let tripData = {
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "geofences": [
    {
    "geometry": {
      "type": "Polygon",
      "coordinates": [
          [-121.3980960195712, 38.7940386903944],
          [-121.3990960195712, 38.7940386903944],
          [-121.3990960195712, 38.7930386903944],
          [-121.3980960195712, 38.7930386903944]
        ]
    },
    "metadata": {
      "stop_id": "12345XYZ",
      "stop_name": "SF office 2"
    }
  },
  {
    "geometry": {
      "type": "Point",
      "coordinates": [35.105761016637075, 47.856801319070776]
    },
    "radius": 65,
    "metadata": {"id": "MAIN dec43d3c-766c-4f6a-bd78-dfe873556782"}
    }]
};

hypertrack.trips.create(tripData).then(trip => {
  // Trip created
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

trip_data = {
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "geofences": [
    {
      "geometry": {
        "type": "Polygon",
        "coordinates": [
            [-121.3980960195712, 38.7940386903944],
            [-121.3990960195712, 38.7940386903944],
            [-121.3990960195712, 38.7930386903944],
            [-121.3980960195712, 38.7930386903944]
          ]
      },
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office 2"
      }
    },
    {
      "geometry": {
        "type": "Point",
        "coordinates": [-121.3980960195712, 38.7930386903944]
      },
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office"
      }
    }
  ],
  "metadata": {
    "shift_id": "ABC123"
  }
}


trip = hypertrack.trips.create(trip_data)
print(trip)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,"{\n" +
        "  \"device_id\": \"00112233-4455-6677-8899-AABBCCDDEEFF\",\n" +
        "  \"geofences\": [\n" +
        "    {\n" +
        "      \"geometry\": {\n" +
        "        \"type\": \"Polygon\",\n" +
        "        \"coordinates\": [\n" +
        "            [-121.3980960195712, 38.7940386903944],\n" +
        "            [-121.3990960195712, 38.7940386903944],\n" +
        "            [-121.3990960195712, 38.7930386903944],\n" +
        "            [-121.3980960195712, 38.7930386903944]\n" +
        "          ]\n" +
        "      },\n" +
        "      \"metadata\": {\n" +
        "        \"stop_id\": \"12345XYZ\",\n" +
        "        \"stop_name\": \"SF office 2\"\n" +
        "      }\n" +
        "    },\n" +
        "    {\n" +
        "      \"geometry\": {\n" +
        "        \"type\": \"Point\",\n" +
        "        \"coordinates\": [-121.3980960195712, 38.7930386903944]\n" +
        "      },\n" +
        "      \"metadata\": {\n" +
        "        \"stop_id\": \"12345XYZ\",\n" +
        "        \"stop_name\": \"SF office\"\n" +
        "      }\n" +
        "    }\n" +
        "  ],\n" +
        "  \"metadata\": {\n" +
        "    \"shift_id\": \"ABC123\"\n" +
        "  }\n" +
        "}");

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "4IZ7fWXxRmmxFL4RWcAgxrPWBD8","rXc40pSVlYkhJsNkcQCncp-c5CVxQeRi6s6bAWXM6T76bWwUlaUMlQ")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/")
  .post(body)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/');
$request->setMethod(HTTP_METH_POST);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

$request->setBody('{
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "geofences": [
        {
          "geometry": {
            "type": "Polygon",
            "coordinates": [
                [-121.3980960195712, 38.7940386903944],
                [-121.3990960195712, 38.7940386903944],
                [-121.3990960195712, 38.7930386903944],
                [-121.3980960195712, 38.7930386903944]
              ]
          },
          "metadata": {
            "stop_id": "12345XYZ",
            "stop_name": "SF office 2"
          }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [
                    -121.3980960195712,
                    38.7930386903944
                ]
            },
            "metadata": {
                "stop_id": "12345XYZ",
                "stop_name": "SF office"
            }
        }
    ],
    "metadata": {
        "shift_id": "ABC123"
    }
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp
request.body = {
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "geofences": [
        {
          "geometry": {
            "type": "Polygon",
            "coordinates": [
                [-121.3980960195712, 38.7940386903944],
                [-121.3990960195712, 38.7940386903944],
                [-121.3990960195712, 38.7930386903944],
                [-121.3980960195712, 38.7930386903944]
              ]
          },
          "metadata": {
            "stop_id": "12345XYZ",
            "stop_name": "SF office 2"
          }
        },
        {
            "geometry": {
                "type": "Point",
                "coordinates": [
                    -121.3980960195712,
                    38.7930386903944
                ]
            },
            "metadata": {
                "stop_id": "12345XYZ",
                "stop_name": "SF office"
            }
        }
    ],
    "metadata": {
        "shift_id": "ABC123"
    }
}.to_json

response = http.request(request)
puts response.read_body

Start a new trip for a device with geofences.

POST /trips

Authentication: Basic Auth

Trips with geofences request attributes

Name Type Description
device_id string Unique identifier representing a device, case sensitive
geofences array Array of geofence objects (optional)
geofences[].geometry object GeoJSON geometry of type Point or Polygon
geofences[].geometry.type string Either Point or Polygon
geofences[].geometry.coordinates array Array of longitude and latitude in case of Point type; Polygon type contains array of positions (First and last positions need to be same to complete the loop
geofences[].radius int Defines the radius (in meters) of a circular geofence (optional, default is 30)
geofences[].metadata object Any metadata you want to assign to this geofence (optional)
metadata object Any metadata you want to assign to this trip (optional)

HTTP 201 - New trip with geofences

{
  "completed_at": null,
  "status": "active",
  "views": {
    "embed_url": "https://embed.hypertrack.com/dkdkddnd",
    "share_url": "https://trck.at/abcdef"
  },
  "geofences": [
     {
      "geometry": {
        "type": "Polygon",
        "coordinates": [
            [-121.3980960195712, 38.7940386903944],
            [-121.3990960195712, 38.7940386903944],
            [-121.3990960195712, 38.7930386903944],
            [-121.3980960195712, 38.7930386903944]
          ]
      },
      "radius": 30,
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office 2"
      },
      "arrived_at": null,
      "exited_at": null
    },
    {
      "geometry": {
        "type": "Point",
        "coordinates": [-121.3980960195712, 38.7930386903944]
      },
      "radius": 30,
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office"
      },
      "arrived_at": null,
      "exited_at": null
    }
  ]
}

Trip with geofences response attributes

Name Type Description
trip_id string Unique identifier of the newly created trip, case sensitive
device_id string Unique identifier of the device associated with the trip, case sensitive
started_at string Timestamp for trip starting time
completed_at string Timestamp of trip completion time (only set when trip is completed), can be null
status string Trip status, can be active, completed or processing_completion
views.embed_url string Embeddable trip view
views.share_url string Shareable trip view
geofences array Array of geofence objects (optional)
geofences[].geometry object GeoJSON geometry of type Point
geofences[].geometry.type string As of right now, only Point is supported
geofences[].geometry.coordinates array Array of longitude and latitude
geofences[].radius int Defines the radius (in meters) of a circular geofence (optional, default is 30)
geofences[].metadata object Any metadata you want to assign to this geofence (optional)
geofences[].arrived_at string Timestamp first enter to geofence
geofences[].exited_at string Timestamp first exit from geofence
metadata object Metadata provided at trip start

Please keep in mind that new trips do not have the summary property (outlining the trip history). The summary is only provided upon completion of a trip.

This API returns HTTP 201 once the trip is successfully created. If a trip with same destination and metadata already exists, the API will return existing trip with HTTP status 200.

references > apis > trips > Start trip

Create new trip request (no destination or geofences included in the request data):

payload='{
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "metadata": {
    "shift_id": "ABC123"
  }
}'

curl -X POST \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/ \
  -H 'Content-Type: application/json' \
  -d $payload
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

const tripData = {
  device_id: "00112233-4455-6677-8899-AABBCCDDEEFF",
  metadata: {
    shift_id: "ABC123"
  }
};

hypertrack.trips.create(tripData).then(trip => {
  // Trip created
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

trip_data = {
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "metadata": {
    "shift_id": "ABC123"
  }
}

trip = hypertrack.trips.create(trip_data)
print(trip)

OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,"{\n" +
        "  \"device_id\": \"00112233-4455-6677-8899-AABBCCDDEEFF\",\n" +
        "  \"metadata\": {\n" +
        "    \"shift_id\": \"ABC123\"\n" +
        "  }\n" +
        "}");

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "4IZ7fWXxRmmxFL4RWcAgxrPWBD8","rXc40pSVlYkhJsNkcQCncp-c5CVxQeRi6s6bAWXM6T76bWwUlaUMlQ")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/")
  .post(body)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/');
$request->setMethod(HTTP_METH_POST);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

$request->setBody('{
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "metadata": {
        "shift_id": "ABC123"
    }
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp
request.body = {
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "metadata": {
        "shift_id": "ABC123"
    }
}.to_json

response = http.request(request)
puts response.read_body

Additionally, you can start a new trip for a device without either destination or geofence. Once the call to start a trip is made, HyperTrack platform starts tracking on the device if it was not started already. The device will continue generating location data for the trip until the trip is marked as completed.

POST /trips

Authentication: Basic Auth

Trip request attributes

Name Type Description
device_id string Unique identifier representing a device, case sensitive
metadata object Any metadata you want to assign to this trip (optional)

HTTP 201 - New trip payload

{
  "completed_at": null,
  "status": "active",
  "views": {
    "embed_url": "https://embed.hypertrack.com/dkdkddnd",
    "share_url": "https://trck.at/abcdef"
  },
  "metadata": {
    "customer_id": "ABC123"
  },
  "device_info": {
    "sdk_version": "3.3.2",
    "os_version": "12.4"
  },
}

Trip request response attributes

Name Type Description
trip_id string Unique identifier of the newly created trip, case sensitive
device_id string Unique identifier of the device associated with the trip, case sensitive
started_at string Timestamp for trip starting time
completed_at string Timestamp of trip completion time (only set when trip is completed), can be null
status string Trip status, can be active, completed or processing_completion
views.embed_url string Embeddable trip view
views.share_url string Shareable trip view
metadata object Metadata provided at trip start

Please keep in mind that new trips do not have the summary property (outlining the trip history). The summary is only provided upon completion of a trip.

This API returns HTTP 201 once the trip is successfully created. If a trip with same destination and metadata already exists, the API will return existing trip with HTTP status 200.

references > apis > trips > Complete trip

Complete trip example:

curl -X POST \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/{trip_id}/complete
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.trips.complete(tripId).then(() => {
  // Complete procedure initiated
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

hypertrack.trips.complete({tripId})
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "4IZ7fWXxRmmxFL4RWcAgxrPWBD8","rXc40pSVlYkhJsNkcQCncp-c5CVxQeRi6s6bAWXM6T76bWwUlaUMlQ")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/{trip_id}/complete")
  .post()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/{trip_id}/complete');
$request->setMethod(HTTP_METH_POST);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'

url = URI("https://v3.api.hypertrack.com/trips/{trip_id}/complete")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

Complete an ongoing trip.

POST /trips/{trip_id}/complete

The request will start the procedure and confirm a pending completion with a trips webhook. Until the completion is done, the trip will have the status processing_completion.

Authentication: Basic Auth

HTTP 202 - Trip completion initiated

{
  "message": "pending completion for trip '00112233-4455-6677-8899-AABBCCDDEEFF'"
}

Path Parameters

trip_id - a string representing the ID of a trip, case sensitive

Completion finished

As soon as the trip was completed on HyperTrack systems, it will be extended with a summary property.

Completed trips do not have an estimate property because routing was completed.

HTTP 200 - Completed trip payload

{
  "trip_id": "aabb2233-8899-4455-3210-aabbccddeeff",
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "started_at": "2019-05-03T06:25:51.238000Z",
  "completed_at": "2019-05-03T06:25:51.238000Z",
  "status": "completed",
  "views": {
    "embed_url": "https://embed.hypertrack.com/dkdkddnd",
    "share_url": "https://trck.at/abcdef"
  },
  "metadata": {
    "customer_id": "ABC123"
  },
  "device_info": {
    "sdk_version": "3.3.2",
    "os_version": "12.4"
  },
  "destination": {
    "geometry": {
      "type": "Point",
      "coordinates": [
        -122.3980960195712,
        37.7930386903944
      ]
    },
    "radius": 30,
    "scheduled_at": "2019-05-03T06:25:51.238000Z",
    "arrived_at": "2019-05-03T06:25:51.238000Z"
  },
  "summary": {
     ...
  }
}

Response Attributes

Name Type Description
trip_id string Unique identifier of the newly created trip, case sensitive
device_id string Unique identifier of the device associated with the trip, case sensitive
started_at string Timestamp for trip starting time
completed_at string Timestamp of trip completion time (only set when trip is completed), can be null
status string Trip status, can be active, completed or processing_completion
views.embed_url string Embeddable trip view
views.share_url string Shareable trip view
destination object Defined trip destination
destination.geometry object GeoJSON geometry of type Point for destination point
destination.radius int Radius (in meters) of a circular trip destination
destination.scheduled_at string Timestamp for scheduled arrival
destination.arrived_at string Timestamp first enter to destination
destination.exited_at string Timestamp first exit from destination
geofences array Array of geofence objects (optional)
geofences[].geometry object GeoJSON geometry of type Point
geofences[].geometry.type string As of right now, only Point is supported
geofences[].geometry.coordinates array Array of longitude and latitude
geofences[].radius int Defines the radius (in meters) of a circular geofence (optional, default is 30)
geofences[].metadata object Any metadata you want to assign to this geofence (optional)
geofences[].arrived_at string Timestamp first enter to geofence
geofences[].exited_at string Timestamp first exit from geofence
summary object Trip summary
metadata object Metadata provided at trip start

references > apis > trips > Get trips

Get all trips example:

curl \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.trips.getAll().then(trips => {
  // Process trips
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

"""
Arguments:
 - trip_status: string status `active` or `completed` or `processing_completion`. `completed` by default
 - pagination_token: string token received from previous call to request next page
"""
trips = hypertrack.trips.get_all()
print(trips)
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/")
  .get()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/');
$request->setMethod(HTTP_METH_GET);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

Get all trips in your account. Returns ongoing trips by default.

GET /trips

Authentication: Basic Auth

Query Parameters

status - (optional) a string representing the trip status to filter by. Default is active.

HTTP 200 - Trips payload

{
  "data":[
    {
      "trip_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
      "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
      "started_at": "2019-05-03T06:25:51.238000Z",
      "completed_at": null,
      "status": "active",
      "views": {
          "embed_url": "https://embed.hypertrack.com/dkdkddnd",
          "share_url": "https://trck.at/abcdef"
      },
      "metadata": {
          "customer_id": "ABC123"
      },
      "destination": {
          "geometry": {
          "type": "Point",
          "coordinates": [
              -122.3980960195712,
              37.7930386903944]
          },
          "radius": 30,
          "scheduled_at": "2019-05-03T06:25:51.238000Z",
          "arrived_at": null,
          "exited_at": null
      },
      "geofences": [{
          "geometry": {
              "type": "Point",
              "coordinates": [-121.3980960195712, 38.7930386903944]
          },
          "radius": 30,
          "metadata": {
              "stop_id": "12345XYZ",
              "stop_name": "SF office"
          },
          "arrived_at": null,
          "exited_at": null
      }],
      "estimate": {
          "arrive_at": "2019-05-03T06:25:51.238000Z",
          "route": {
              "distance": 14666,
              "duration": 2884,
              "remaining_duration": 1560,
              "start_place": "Mannat Manzil #48,2nd cross, 3rd Main,Amrita Nagar, 3rd Phase, Choodasandra, Bengaluru, Karnataka 560035, India",
              "end_place": "4, Muniswamy Garden, A - Block, Bengaluru, Karnataka 560025, India",
              "polyline": {
                  "type": "LineString",
                  "coordinates": [
                  [ -122.3980960195712, 37.7930386903944 ]
                  , ... ]
              }
          }
      }
    },
    {
      "trip_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
      "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
      "started_at": "2019-05-03T06:25:51.238000Z",
      "completed_at": "2019-05-03T06:25:51.238000Z",
      "status": "completed",
      "views": {
          "embed_url": "https://embed.hypertrack.com/dkdkddnd",
          "share_url": "https://trck.at/abcdef"
      },
      "metadata": {
          "customer_id": "ABC123"
      },
      "destination": {
          "geometry": {
          "type": "Point",
          "coordinates": [
              -122.3980960195712,
              37.7930386903944]
          },
          "radius": 30,
          "scheduled_at": "2019-05-03T06:25:51.238000Z",
          "arrived_at": "2019-05-03T06:25:51.238000Z"
      },
      "summary": {
          ...
      }
    }, ...
  ],
  "links":{
    "next": "https://v3.api.hypertrack.com/trips/?pagination_token=abc"
  }
}

Response Attributes

Name Type Description
trip_id string Unique identifier of the newly created trip, case sensitive
device_id string Unique identifier of the device associated with the trip, case sensitive
started_at string Timestamp for trip starting time
completed_at string Timestamp of trip completion time (only set when trip is completed), can be null
status string Trip status, can be active, completed or processing_completion
views.embed_url string Embeddable trip view
views.share_url string Shareable trip view
destination object Defined trip destination
destination.geometry object GeoJSON geometry of type Point for destination point
destination.radius int Radius (in meters) of a circular trip destination
destination.scheduled_at string Timestamp for scheduled arrival
destination.arrived_at string Timestamp first enter to destination
destination.exited_at string Timestamp first exit from destination
geofences array Array of geofence objects (optional)
geofences[].geometry object GeoJSON geometry of type Point and Polygon
geofences[].geometry.type string Either Point or Polygon
geofences[].geometry.coordinates array Array of longitude and latitude in case of Point or array of positions in case if Polygon (First and last positions need to be same to complete the loop)
geofences[].radius int Defines the radius (in meters) of a circular geofence (optional, default is 30) for type Point
geofences[].metadata object Any metadata you want to assign to this geofence (optional)
geofences[].arrived_at string Timestamp first enter to geofence
geofences[].exited_at string Timestamp first exit from geofence
estimate object Estimates (route and arrival time). Only available for active trips.
estimate.arrive_at string Timestamp for estimated arrival
estimate.route objects Planned route segments to destination
estimate.route.distance int Route distance in meters
estimate.route.duration int Route duration in seconds
estimate.route.remaining_duration int Remaining route duration in seconds, can be null
estimate.route.start_place string Start place for segment start
estimate.route.end_place string End place for segment end
estimate.route.polyline object GeoJSON geometry of type LineString
summary object Trip summary. Available for completed trips as well as for ongoing trips for a given trip_id
metadata object Metadata provided at trip start

references > apis > trips > Get trip summary

Get trip summary example:

curl \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/{trip_id}
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.trips.get(tripId).then(trip => {
  // Process trip
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

trip = hypertrack.trips.get({tripId})
print(trip)
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/{trip_id}")
  .get()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/{trip_id}');
$request->setMethod(HTTP_METH_GET);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/{trip_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp

response = http.request(request)
puts response.read_body

Get summary for a trip. Available for both ongoing and completed trips.

GET /trips/{trip_id}

Authentication: Basic Auth

Path Parameters

trip_id - a string representing the ID of a trip, case sensitive

HTTP 200 - Completed trip payload

{
  "trip_id": "aabb2233-8899-4455-3210-aabbccddeeff",
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "started_at": "2019-05-03T06:25:51.238000Z",
  "completed_at": "2019-05-03T06:25:51.238000Z",
  "status": "completed",
  "views": {
    "embed_url": "https://embed.hypertrack.com/dkdkddnd",
    "share_url": "https://trck.at/abcdef"
  },
  "metadata": {
    "customer_id": "ABC123"
  },
  "device_info": {
    "sdk_version": "3.3.2",
    "os_version": "12.4"
  },
  "destination": {
    "geometry": {
      "type": "Point",
      "coordinates": [
        -122.3980960195712,
        37.7930386903944
      ]
    },
    "radius": 30,
    "scheduled_at": "2019-05-03T06:25:51.238000Z",
    "arrived_at": "2019-05-03T06:25:51.238000Z"
  },
  "summary": {
     ...
  }
}

Response Attributes

Name Type Description
trip_id string Unique identifier of the newly created trip, case sensitive
device_id string Unique identifier of the device associated with the trip, case sensitive
started_at string Timestamp for trip starting time
completed_at string Timestamp of trip completion time (only set when trip is completed), can be null
status string Trip status, can be active, completed or processing_completion
views.embed_url string Embeddable trip view
views.share_url string Shareable trip view
destination object Defined trip destination
destination.geometry object GeoJSON geometry of type Point for destination point
destination.radius int Radius (in meters) of a circular trip destination
destination.scheduled_at string Timestamp for scheduled arrival
destination.arrived_at string Timestamp first enter to destination
destination.exited_at string Timestamp first exit from destination
geofences array Array of geofence objects (optional)
geofences[].geometry object GeoJSON geometry of type Point and Polygon
geofences[].geometry.type string Either Point or Polygon
geofences[].geometry.coordinates array Array of longitude and latitude in case of Point or array of positions in case if Polygon (First and last positions need to be same to complete the loop)
geofences[].radius int Defines the radius (in meters) of a circular geofence (optional, default is 30) for type Point
geofences[].metadata object Any metadata you want to assign to this geofence (optional)
geofences[].arrived_at string Timestamp first enter to geofence
geofences[].exited_at string Timestamp first exit from geofence
estimate object Estimates (route and arrival time). Only available for active trips.
estimate.arrive_at string Timestamp for estimated arrival
estimate.route objects Planned route segments to destination
estimate.route.distance int Route distance in meters
estimate.route.duration int Route duration in seconds
estimate.route.remaining_duration int Remaining route duration in seconds, can be null
estimate.route.start_place string Start place for segment start
estimate.route.end_place string End place for segment end
estimate.route.polyline object GeoJSON geometry of type LineString
summary object Trip summary. Available for completed trips as well as for ongoing trips for a given trip_id
metadata object Metadata provided at trip start

Trip summary

For completed and ongoing trips, the response will include summary object giving location and marker details about the full trip.

Trips API: Summary available for completed trips

{
  "summary": {
    "locations": {
      "type": "LineString",
      "coordinates": [
        [-122.3996, 37.79396136184457, 123, "2019-09-13T18:21:51.002000Z"],
        [
          -122.39982803643629,
          37.79423869055751,
          null,
          "2019-09-13T18:21:51.802000Z"
        ]
      ]
    },
    "distance": 1234,
    "duration": 9887,
    "started_at": "2019-09-13T18:04:20.467000Z",
    "completed_at": "2019-09-13T20:49:08.226000Z",
    "device_id": "FC772B07-2F27-4EB9-8A3B-F21D7F63A436",
    "markers": [
      {
        "type": "geofence",
        "data": {
          "arrival": {
            "location": {
              "geometry": {
                "type": "Point",
                "coordinates": [-122.3996, 37.7939]
              },
              "recorded_at": "2019-09-13T19:35:51.002000Z"
            }
          },
          "geofence": {
            "geometry": {
              "type": "Point",
              "coordinates": [-122.3996, 37.7939]
            },
            "geofence_id": "7159040c-ad03-4a49-9c1f-11f9763cdf9b",
            "radius": 30,
            "metadata": {
              "stop_id": 2937
            }
          },
          "route_to": {
            "duration": 120,
            "distance": 600,
            "start_location": {
              "geometry": {
                 "type": "Point",
                 "coordinates": [-122.3996, 37.7939]
              },
              "recorded_at": "2019-09-13T19:33:51.002000Z"
            }
          },
          "exit": {
            "location": {
              "geometry": {
                "type": "Point",
                "coordinates": [-122.3996, 37.7939]
              },
              "recorded_at": "2019-09-13T19:36:51.002000Z"
            }
          },
          "duration": 60
        }
      },
      {
        "type": "device_status",
        "data": {
          "value": "inactive",
          "start": {
            "recorded_at": "2019-09-13T19:40:51.002000Z",
            "location": {
              "geometry": {
                "type": "Point",
                "coordinates": [-122.3996, 37.7939]
              },
              "recorded_at": "2019-09-13T19:39:51.002000Z"
            }
          },
          "end": {
            "recorded_at": "2019-09-13T20:40:51.002000Z",
            "location": {
              "geometry": {
                "type": "Point",
                "coordinates": [-122.3996, 37.7939]
              },
              "recorded_at": "2019-09-13T20:40:52.002000Z"
            }
          },
          "reason": "stopped_programmatically"
        }
      },
      {
        "type": "trip_marker",
        "data": {
          "recorded_at": "2019-09-13T20:40:52.002000Z",
          "location": {
            "coordinates": [-122.3996, 37.7939],
            "type": "Point"
          },
          "metadata": {
            "id": "1235"
          },
          "route_to": {
            "duration": 2654,
            "distance": 377,
            "start_location": {
              "geometry": {
                 "type": "Point",
                 "coordinates": [-122.3996, 37.7939]
              },
              "recorded_at": "2019-09-13T19:33:51.002000Z"
            }
          }
        }
      }
    ]
  }
}
Name Type Description
summary.locations object Object representing the location time series of the full trip. Follows GeoJSON geometry of type LineString
summary.locations.type string As of right now, only LineString is supported
summary.locations.coordinates array Array of coordinates arrays; each item follows [longitude, latitude, elevation, timestamp]; elevation can be null
summary.distance int Distance for entire trip, in meters
summary.duration int Duration for entire trip, in seconds
summary.started_at string ISO 8601 date when the trip started
summary.completed_at string ISO 8601 date when the trip was completed
summary.device_id string Unique identifier of the device associated with the trip, case sensitive
summary.markers array Array of markers
summary.markers[].type string Marker type; can be one of device_status, geofence or trip_marker
summary.markers[].data object Marker data; dependent on marker type

Detailed description of device_status markers:

Name Type Description
end object End of the device status segment
end.location object Location object when the device_status changed
end.location.geometry object GeoJSON geometry of type Point
end.location.geometry.type string As of right now, only Point is supported
end.location.geometry.coordinates array Array of longitude and latitude
end.location.recorded_at string ISO 8601 date when the location was recorded
end.recorded_at string ISO 8601 date when the device status change was recorded
start object Start of the device status segment
start.location object Location object when the device_status changed
start.location.geometry object GeoJSON geometry of type Point
start.location.geometry.type string As of right now, only Point is supported
start.location.geometry.coordinates array Array of longitude and latitude
start.location.recorded_at string ISO 8601 date when the location was recorded
start.recorded_at string ISO 8601 date when the device status change was recorded
value string Device status. Can be one of active, inactive or disconnected

Detailed description of geofence markers:

Name Type Description
arrival object Object representing details about the geofence arrival
arrival.location object Location object that triggered geofence arrival
arrival.location.geometry object GeoJSON geometry of type Point
arrival.location.geometry.type string As of right now, only Point is supported
arrival.location.geometry.coordinates array Array of longitude and latitude
arrival.location.recorded_at string ISO 8601 date when the location was recorded
duration int Duration of time spent inside geofence, in seconds
exit object Object representing details about the geofence exit
exit.location object Location object that triggered geofence exit
exit.location.geometry object GeoJSON geometry of type Point
exit.location.geometry.type string As of right now, only Point is supported
exit.location.geometry.coordinates array Array of longitude and latitude
exit.location.recorded_at string ISO 8601 date when the location was recorded
geofence object Object representing the defined geofence
geofences.geometry object GeoJSON geometry of type Point
geofences.geometry.type string As of right now, only Point is supported
geofences.geometry.coordinates array Array of longitude and latitude
geofences.radius int Defines the radius (in meters) of a circular geofence (optional, default is 30)
geofences.metadata object Any metadata you want to assign to this geofence (optional)
geofence object Object representing the defined geofence
route_to object Object giving details about the route taken to this geofence
route_to.distance int Distance traveled from previous geofence (or fist location), in meter
route_to.duration int Duration traveled from previous geofence (or fist location), in seconds
route_to.start_location object Location object where route_to calculation is based on. Starting point of route to this geofence.
route_to.start_location.geometry object GeoJSON geometry of type Point of start location
route_to.start_location.geometry.type string As of right now, only Point is supported
route_to.start_location.geometry.coordinates array Array of longitude and latitude
route_to.start_location.recorded_at array ISO 8601 date when the start location was recorded

Detailed description of trip_marker markers:

Name Type Description
location object Location object where the trip marker was created
location.geometry object GeoJSON geometry of type Point
location.geometry.type string As of right now, only Point is supported
location.location.geometry.coordinates array Array of longitude and latitude
metadata object Any metadata assigned to this trip marker
recorded_at string ISO 8601 date when trip marker was recorded
route_to object Object giving details about the route taken to this trip marker
route_to.distance int Distance traveled from previous trip marker (or fist location), in meter
route_to.duration int Duration traveled from previous trip marker (or fist location), in seconds
route_to.start_location object Location object where route_to calculation is based on. Starting point of route to this trip marker.
route_to.start_location.geometry object GeoJSON geometry of type Point of start location
route_to.start_location.geometry.type string As of right now, only Point is supported
route_to.start_location.geometry.coordinates array Array of longitude and latitude
route_to.start_location.recorded_at array ISO 8601 date when the start location was recorded

references > apis > trips > Add more geofences

Add geofences to the trip:

payload='{
  "geofences": [{
    "geometry": {
      "type": "Point",
      "coordinates": [-121.3980960195712, 38.7930386903944]
    },
    "metadata": {
      "stop_id": "12345XYZ",
      "stop_name": "SF office"
    }
  }]
}'

curl -X POST \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/{trip_id}/geofences \
  -H 'Content-Type: application/json' \
  -d $payload
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

let geofences  = [{
  "geometry": {
    "type": "Point",
    "coordinates": [-121.3980960195712, 38.7930386903944]
  },
  "metadata": {
    "stop_id": "12345XYZ",
    "stop_name": "SF office"
  }
}];

hypertrack.trips.createGeofences(tripId, geofences).then(() => {
  // Geofences created
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

geofences  = [{
  "geometry": {
    "type": "Point",
    "coordinates": [-121.3980960195712, 38.7930386903944]
  },
  "metadata": {
    "stop_id": "12345XYZ",
    "stop_name": "SF office"
  }
}]

hypertrack.trips.create_geofences({tripId}, geofences)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,"{\n" +
        " \"geofences\": [{\n" +
        "   \"geometry\": {\n" +
        "    \"type\": \"Point\",\n" +
        "    \"coordinates\": [-121.3980960195712, 38.7930386903944]\n" +
        "  },\n" +
        "  \"metadata\": {\n" +
        "    \"stop_id\": \"12345XYZ\",\n" +
        "    \"stop_name\": \"SF office\"\n" +
        "  }\n" +
        " }]\n" +
        "}");

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "4IZ7fWXxRmmxFL4RWcAgxrPWBD8","rXc40pSVlYkhJsNkcQCncp-c5CVxQeRi6s6bAWXM6T76bWwUlaUMlQ")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/{trip_id}/geofences")
  .post(body)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/{trip_id}/geofences');
$request->setMethod(HTTP_METH_POST);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

$request->setBody('{
    "geofences": [{
      "geometry": {
        "type": "Point",
        "coordinates": [-121.3980960195712, 38.7930386903944]
      },
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office"
      }
    }]
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/{trip_id}/geofences")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp
request.body = {
    "geofences": [{
      "geometry": {
        "type": "Point",
        "coordinates": [-121.3980960195712, 38.7930386903944]
      },
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office"
      }
    }]
}.to_json

response = http.request(request)
puts response.read_body

Add more geofences to an ongoing trip, in addition to geofences you might have created when creating trip.

PATCH /trips/{trip_id}/geofences

HTTP 201 - New trip payload

{
  "geofences": [
    {
      "geometry": {
        "type": "Point",
        "coordinates": [-121.3980960195712, 38.7930386903944]
      },
      "radius": 30,
      "metadata": {
        "stop_id": "12345XYZ",
        "stop_name": "SF office"
      },
      "arrived_at": null,
      "exited_at": null
    }
  ]
}

HTTP 200 - trips updated geofences

Authentication: Basic Auth

Path Parameters

trip_id - a string representing the trip ID

references > apis > trips > Update geofence metadata

Patch trip geofence data

payload='{
  "metadata": {
    "geofence_stop_id": "ABC123"
  }
}'

curl -X PATCH \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/{trip_id}/geofence/{geofence_id} \
  -H 'Content-Type: application/json' \
  -d $payload
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

let geofenceMetadata = {
  "start_id": "321zz"
};

hypertrack.trips.patchGeofenceMetadata(tripId,geofenceId, geofenceMetadata).then(() => {
  // Geofence updated
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

geofence_metadata  = {
  "start_id": "321zz"
}

hypertrack.trips.patch_geofence_metadata({tripId}, {geofenceId}, geofence_metadata)
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType,"{\n" +
        "  \"metadata\": {\n" +
        "    \"geofence_stop_id\": \"ABC123\"\n" +
        "  }\n" +
        "}");

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "4IZ7fWXxRmmxFL4RWcAgxrPWBD8","rXc40pSVlYkhJsNkcQCncp-c5CVxQeRi6s6bAWXM6T76bWwUlaUMlQ")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/{trip_id}/geofences/{geofence_id}")
  .patch(body)
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/{trip_id}/geofences/{geofence_id}');
$request->setMethod(HTTP_METH_PATCH);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

$request->setBody('{
    "metadata": {
      "geofence_stop_id": "ABC123"
    }
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/{trip_id}/geofences/{geofence_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp
request.body = {
    "metadata": {
      "geofence_stop_id": "ABC123"
    }
}.to_json

response = http.request(request)
puts response.read_body

Update geofence metadata for geofences in a trip. Available for both ongoing and completed trips.

PATCH /trips/{trip_id}/geofence/{geofence_id}

This is an overwrite operation on the metadata, so be sure to form the entire object first. Use the get geofence call below to get existing metadata for the geofence.

HTTP 200 - trips geofence metadata is updated

Authentication: Basic Auth

Path Parameters

trip_id - a string representing the trip ID

geofence_id - a string representing the geofence ID for which metadata is being updated

references > apis > trips > Get geofence metadata

Get trip geofence data

curl -X GET \
  -u {AccountId}:{SecretKey} \
  https://v3.api.hypertrack.com/trips/{trip_id}/geofence/{geofence_id} \
  -H 'Content-Type: application/json'
// Instantiate Node.js helper library instance
const hypertrack = require('hypertrack')(accountId, secretKey);

hypertrack.trips.getGeofence(tripId, geofenceId).then(geofence => {
  // Process geofence
}).catch(error => {
  // Error handling
})
from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException

hypertrack = Client({AccountId}, {SecretKey})

geofence = hypertrack.trips.get_geofence({tripId}, {geofenceId})
print(geofence['metadata'])
OkHttpClient client = new OkHttpClient();

String authString = "Basic " +
  Base64.getEncoder().encodeToString(
    String.format("%s:%s", "{AccountId}","{SecretKey}")
      .getBytes()
  );

Request request = new Request.Builder()
  .url("https://v3.api.hypertrack.com/trips/{trip_id}/geofence/{geofence_id}")
  .get()
  .addHeader("Authorization", authString)
  .build();

Response response = client.newCall(request).execute();

System.out.println(response.body().string());
<?php

$request = new HttpRequest();
$request->setUrl('https://v3.api.hypertrack.com/trips/{trip_id}/geofences/{geofence_id}');
$request->setMethod(HTTP_METH_GET);

$basicAuth = "Basic " . base64_encode('{AccountId}' . ':' . '{SecretKey}');

$request->setHeaders(array(
  'Authorization' => $basicAuth
));

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

?>
require 'uri'
require 'net/http'
require 'base64'
require 'json'

url = URI("https://v3.api.hypertrack.com/trips/{trip_id}/geofences/{geofence_id}")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic ' + Base64.strict_encode64( '{AccountId}' + ':' + '{SecretKey}' ).chomp
response = http.request(request)
puts response.read_body

HTTP 200 - Geofence payload


{
    "created_at": "2019-12-19T21:36:06.259005+00:00",
    "geofence_id": "f558e8fe-b71f-4529-b94c-2b1f242de873",
    "device_ids": [
        "caeeecf9-6130-47c3-bef8-63ac27df3d51"
    ],
    "metadata": {
        "metadata_key": "value"
    },
    "geometry": {
        "type": "Point",
        "coordinates": [
            35.0380182196383,
            47.8208697707263
        ]
    },
    "radius": 30.0
}

Get geofence metadata. You may want to do this before updating geofence with new metadata because PATCH will overwrite the metadata object.

GET /trips/{trip_id}/geofence/{geofence_id}

Authentication: Basic Auth

Path Parameters

trip_id - a string representing the trip ID

geofence_id - a string representing the geofence ID to get

references > Helper libraries

Server-side helper libraries for Node.js and Python allow you to easily get started with HyperTrack API from your Node.js or Python applications. These libraries allow you to use Devices and Trips API.

references > helper-libraries > Python helper library

The Python helper library lets you write Python code to make HTTP requests to the HyperTrack API to manage device tracking and create trips.

The easiest way to install the library is from PyPi using pip, a package manager for Python. Simply run this in the terminal:

pip install hypertrack


In the code example below, you can initialize a Client class instance:

from hypertrack.rest import Client
# Your AccoundId from dashboard.hypertrack.com/setup page
account_id = "your_account_id"
# Your SecretKey from dashboard.hypertrack.com/setup page
secret_key  = "your_secret_key"
client = Client(account_id, secret_key);


Python help library will throw HyperTrackException exception if any error occurs during request. There are might be different error scenarios, please check HTTP Errors section to see all possible errors. As common practice you should use try except block to catch errors from help library, for example:

from hypertrack.rest import Client
from hypertrack.exceptions import HyperTrackException
client = Client(account_id, secret_key);

try:
  client.device.get("ID-OF-NOT-EXISTING-DEVICE")
except HyperTrackException as e:
  print(e.status) # ---> 404
  print(e.title)  # ---> Device could not be found
  print(e.code)   # ---> device_not_found


Please check API reference documentation for the Python helper library usage. To view code examples in the right column, make sure to select Python language switcher tab.

references > helper-libraries > Node.js helper library

The hypertrack-node helper library lets you write Node.js code to make HTTP requests to the HyperTrack API to manage device tracking and create trips.

The easiest way to get started is to use an npm command:

npm install hypertrack


In this sample below, this is how you can initialize HyperTrack helper library:

// Your AccoundId from dashboard.hypertrack.com/setup page
let accountId = 'test_account_id_value'
// Your SecretKey from dashboard.hypertrack.com/setup page
let secretKey = 'test_secret_key_value'
const hypertrack = require('hypertrack')(accountId, secretKey);


Please check API reference documentation for the Node.js helper library usage. To view code examples in the right column, make sure to select NodeJS language switcher tab.

references > Webhooks

Webhooks let you subscribe to a real-time stream of location, and trip status data generated by HyperTrack. Rather than making an API call, HyperTrack can send an HTTPS request to an endpoint that you specify. Events are published for all devices associated with the account.

The HyperTrack mobile SDKs send a time-series of events from the device to the HyperTrack server. These events are processed and then posted to your servers on Webhooks. A webhook is an HTTPS POST call from the HyperTrack servers to a configurable destination.

After receiving a webhook on your own server, you can trigger updates on your mobile or web apps in near real-time and implement your live location features.

Setting up HyperTrack Webhooks requires configurations on your server and the HyperTrack dashboard. Finally, you need to complete a one-time activation process to verify your identity as the subscriber of the endpoint set on the HyperTrack dashboard. Please ensure you follow all three guidelines to start receiving webhooks.

The server receiving webhooks needs to be configured appropriately to consume webhooks.

Static Endpoint URL

Your server needs to expose a public HTTPS endpoint capable of receiving external, incoming requests. It is important to have a static endpoint URL that will be accessible at all times.

HTTPS POST Method

Webhooks are realized through HTTPS POST requests to the configured endpoint. Your server needs to support this method and be able to parse the payload provided with the request.

JSON Payload

The payload you will receive with POST requests is formatted in JSON. You need to implement the capability to parse JSON objects in order to leverage the HTTP request body content.

You should use a JSON parser that handles converting the escaped representation of control characters back to their ASCII character values (for example, converting \n to a newline character). This is critical if you want to verify the signature of a webhook.

SSL Verification

By default, we verify the SSL certificate of your website when delivering webhook payloads. SSL verification helps ensure that webhooks are delivered to your endpoint URL securely. We only support HTTPS endpoints to ensure secure server-to-server communication.

Make sure that your endpoint has a server certificate from a trusted Certificate Authority (CA). Amazon SNS will only send messages to HTTPS endpoints that have a server certificate signed by a CA trusted by Amazon SNS.

Payload and Headers

Webhooks from HyperTrack will be sent with headers and a JSON payload. Please ensure to verify the headers and implement your server to handle these correctly.

Header: Content-Type

The header is set to text/plain for all webhooks. Please ensure to parse every webhook with this content type. The actual content is represented in JSON.

Header: x-amz-sns-message-type

The header is set to Notification for all webhooks.

Header: x-amz-sns-message-id

The header uniquely identified the webhook. It is important to keep track of the webhook ID because under some circumstances like retries, duplicated webhooks with the same ID could be sent to your server. It is suggested to log most recent webhook IDs to ensure you avoid processing the same update multiple times.

Header: x-amz-sns-subscription-arn

The ARN for the subscription to this URL endpoint. You received this with the subscription confirmation response in XML format during the one-time verification.

Responding to webhooks

Make sure to respond to HyperTrack webhooks with the appropriate status code. The connection will time out in 15 seconds. If your endpoint does not respond before the connection times out or if your endpoint returns a status code outside the range of 200–4xx, HyperTrack will consider the delivery of the webhook as a failed attempt and retry as described below.

Retry algorithm

If HyperTrack doesn't receive a successful response from your server, it attempts to deliver the webhook again. By default, if the initial delivery of the webhook fails, HyperTrack attempts up to three retries with a delay between failed attempts set at 20 seconds.

The retries will always refer to the same x-amz-sns-message-id. By comparing the IDs of the webhooks you have processed with incoming webhooks, you can understand whether the message is a retry attempt.

Order of webhooks

HyperTrack will attempt to deliver webhooks in the same order they were received. However, network issues could potentially result in out-of-order webhooks.

Before handling events, you should compare the recorded_at property of the JSON payload and ensure to store events in the order they were recorded as opposed to when they were received.

Webhook Payload

The overall POST payload has a static structure. The type of the webhook indicates the structure of the data object.

[{
  "created_at": "2019-02-27T22:50:29.000000Z",
  "data": { ... },
  "location": { ... },
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "recorded_at": "2019-02-27T22:50:24.000000Z",
  "type": "",
  "version": "2.0.0"
}]
Name Type Description
device_id string Unique device identifier, case sensitive
created_at string ISO 8601 date and time when webhook was sent (server timestamp)
recorded_at string ISO 8601 date and time when event was recorded (client timestamp). Not available for trip webhooks (e.g. start and completion)
type string Type of webhook data. Could be either location, device_status, battery or trip
data object Either location, device_status, battery or trip data, see details below.
location object GeoJSON object with type and coordinates. Provided as context to trip delay webhooks only
version string Version string of the webhook. Current version is "2.0.0"

Depending on the type of webhook, the JSON payload will vary. However, the overall structure is fixed.

Currently, the following types are supported:

Feature Type Description
Locations location Location stream
Device Status device_status Device status changes (active, inactive, disconnected and activity changes)
Battery battery Battery changes (low, normal and charging)
Trips trip Trip start, destination arrival, destination exit, trip delays, and trip completion events
Custom Markers custom_marker Custom markers stream

references > webhooks > Location Payload

{
    "created_at": "2019-07-01T20:00:01.247377Z",
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "recorded_at": "2019-07-01T20:00:00.000000Z",
    "type": "location",
    "data": {
        "accuracy": 9.64,
        "geometry": {
            "type": "Point",
            "coordinates": [
                -6.2755,
                57.6398983
                124
            ]
        },
        "speed": 0.0,
        "bearing": 313.94
    },
    "version": "2.0.0"
}
Name Type Description
data.geometry object Location in GeoJSON format
data.geometry.type string As of right now, only Point is supported
data.geometry.coordinates array Array of longitude, latitude and (optional) altitude (in m)
data.accuracy float (optional) accuracy in m
data.bearing float (optional) bearing in degrees starting at due north and continuing clockwise around the compass
data.speed float (optional) speed in m/s

references > webhooks > Device Status Payload

{
    "created_at": "2019-07-01T20:00:01.247377Z",
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "recorded_at": "2019-07-01T20:00:00.000000Z",
    "type": "device_status",
    "data": {
        "value": "active",
        "activity": "walk"
    },
    "location": {
        "type": "Point",
        "coordinates": [
                -6.2755,
                57.6398983
                124
            ]
    },
    "version": "2.0.0"
}
Name Type Description
data.value string Device status. One of active, inactive or disconnected. Please read here to understand how HyperTrack tracks device status.
data.activity string For active devices only, can be one walk,drive, or stop
data.reason string For inactive devices only.

Can be one of:

location_permissions_denied,
location_services_disabled,
motion_activity_permissions_denied,
motion_activity_services_disabled,
motion_activity_services_unavailable</code>,
stopped_programmatically,
tracking_service_terminated,
unexpected.
Please read here to understand how HyperTrack tracks device status.
location object Location in GeoJSON format
location.type string As of right now, only Point is supported
location.coordinates array Array of longitude latitude and (optional) altitude (in m)

references > webhooks > Battery Payload

{
    "created_at": "2019-07-01T20:00:01.247377Z",
    "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
    "recorded_at": "2019-07-01T20:00:00.000000Z",
    "type": "battery",
    "data": {
        "value": "low"
    },
    "location": {
        "type": "Point",
        "coordinates": [
                -6.2755,
                57.6398983
                124
            ]
    },
    "version": "2.0.0"
}
Name Type Description
data.value string Battery status. Values include low, normal and charging
location object Location in GeoJSON format
location.type string As of right now, only Point is supported
location.coordinates array Array of longitude latitude and (optional) altitude (in m)

references > webhooks > Trip Payload

{
  "created_at": "2019-07-01T14:00:00.000000Z",
  "data": {
    "value": "created",
    "trip_id": "123E4567-E89B-12D3-A456-426655440000",
    "trip_metadata": { "customer": "1234" }
  },
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "type": "trip",
  "version": "2.0.0"
}

If you start trips, you will receive trip events whenever ...

Name Type Description
data.value string One of: created, destination_arrival, destination_exit, geofence_enter, geofence_exit, delayed or completed
data.trip_id string Unique identifier of the trip, case sensitive
data.trip_metadata Object Metadata that you have assigned to this trip (optional)
data.geofence_metadata Object Metadata that you have assigned to the corresponding geofence, only available if value is geofence_enter or geofence_exit
data.arrive_at string Timestamp with new arrived date, only available if value is delayed

references > webhooks > Custom Marker Payload

{
  "created_at": "2019-07-01T14:01:00.000000Z",
  "recorded_at": "2019-07-01T14:00:00.000000Z",
  "data": {
    "metadata": { "orderId": "123490809808" },
    "route_to":{
      "distance": 238,
      "duration": 63,
      "start_location": {
        "geometry": {
            "coordinates": [
                -6.271,
                57.6398983
            ],
            "type": "Point"
        },
        "recorded_at": "2019-07-01T13:52:08.213000Z"
      }
    }
  },
  "location": {
      "type": "Point",
      "coordinates": [
              -6.2755,
              57.6398983
      ]
  },
  "device_id": "00112233-4455-6677-8899-AABBCCDDEEFF",
  "type": "custom_marker",
  "version": "2.0.0"
}
Name Type Description
data.metadata Object Metadata that you have assigned to this custom marker (optional)
location Object Location in GeoJSON format
location.type string As of right now, only Point is supported
location.coordinates array Array of longitude latitude and (optional) altitude (in m)
data.route_to Object Object describing the route since last custom marker (optional)
data.route_to.distance int Distance travelled since last custom marker
data.route_to.duration int Time since last custom marker
data.route_to.start_location Object Location object for last custom marker
data.route_to.start_location.geometry Object Location in GeoJSON format
data.route_to.start_location.recorded_at string Timestamp at which start_location was recorded

references > SDKs

references > sdks > Android

This reference shows methods available in the Android SDK. You can also review the generated JavaDoc files.

references > sdks > android > Initialize

Initialize the SDK with your activity and publishable key only.

HyperTrack sdkInstance = HyperTrack.getInstance(getApplicationContext(), 'your-publishable-key-here');
val sdkInstance = HyperTrack.getInstance(this as Context,  'your-publishable-key-here')
Parameter Type Description
context Context Application Context
publishableKey String Your publishable key from the dashboard

references > sdks > android > Check tracking status

Check tracking status.

boolean isTrackingServiceRunning = sdkInstance.isRunning();
val isTrackingServiceRunning = sdkInstance.isRunning()

references > sdks > android > Get device ID

Obtain device identifier.

String deviceID = sdkInstance.getDeviceId();
val deviceID = sdkInstance.getDeviceId()

references > sdks > android > Set name and metadata

Set name and metadata for device tracking data.

sdkInstance.setDeviceName("your-custom-device-name");

// create new metadata map
Map<String,Object> myMetadata = new HashMap<>();
// add external id to metadata
myMetadata.put("external-id", "your-external-id");

sdkInstance.setDeviceMetadata(myMetadata);
sdkInstance
  .setDeviceName("your-custom-device-name")
  .setDeviceMetadata(mapOf("external-id" to "your-external-id"))
Parameter Type Description
name String Custom device name
metaData Map or String Custom metadata as key-value pair or valid JSON String

references > sdks > android > Create trip marker

Create a trip marker with configurable payload. Please, bear in mind that this will be serialized as JSON.1

// create new marker payload
Map<String,Object> payload = new HashMap<>();

// add event details
payload.put("item", "Martin D-18");
payload.put("price", 7.75);

sdkInstance.addTripMarker(payload);
sdkInstance.addTripMarker(mapOf("item" to "Martin D-18", "price" to 7.75))
Parameter Type Description
payload Map or valid JSON string Trip marker data as key-value pair

references > sdks > android > Customize notification

HyperTrack tracking runs as a separate foreground service. When tracking is activated, users will see a persistent notification. By default, it displays the app icon with text {app name} is running. You can customize the notification appearance.

sdkInstance.setTrackingNotificationConfig(
        new ServiceNotificationConfig(
          title,
          body,
          R.drawable.small_notification_icon,
          R.drawable.large_notification_icon,
          pendingIntent
       )
);
sdkInstance.setTrackingNotificationConfig(
    ServiceNotificationConfig(
      title,
      body,
      R.drawable.small_notification_icon,
      R.drawable.large_notification_icon,
      pendingIntent
   )
)

You can use builder, if you only need to override some of default properties or service notification config constructor to define all of them. Config options follow:

Parameter Type Description
title String Title (optional). Set to null to keep the default title
body String Body (optional). Set to null to keep the default body
smallIconId int Notification large icon ID
largeIconId int Notification large icon ID
pendingIntent PendingIntent Pending intent for notification click action

references > sdks > android > Attach sdk events handler

If you want to be notified about significant events, that occur during SDK initialization / tracking, you should attach listener (delegate, handler) to sdk instance. E.g. common issue is when tracking was started, but no actual location data is received due to location service been disabled on a os wide level. To address such an issue you can attach following

sdkInstance.addTrackingListener(new TrackingStateObserver.OnTrackingStateChangeListener() {
    @Override public void onError(TrackingError trackingError) {
        if (trackingError != null && trackingError.code == TrackingError.GPS_PROVIDER_DISABLED_ERROR) {
            String contentTitle = "Tracking isn't working";
            String contentText = "Please enable location service for tracking";
            PendingIntent pendingIntent = PendingIntent.getActivity(
                    context, 42, new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS),
                    PendingIntent.FLAG_ONE_SHOT
            );
            sdkInstance.setTrackingNotificationConfig(
                new ServiceNotificationConfig.Builder()
                        .setContentIntent(pendingIntent)
                        .setContentText(contentText)
                        .setContentTitle(contentTitle)
                        .build()
            );
        }
    }

    @Override public void onTrackingStart() { }
    @Override public void onTrackingStop() { }
});
sdkInstance.addTrackingListener(object : TrackingStateObserver.OnTrackingStateChangeListener() {
    override fun onError(trackingError: TrackingError?) {
        trackingError?.let {
            when (trackingError.code) {
                TrackingError.GPS_PROVIDER_DISABLED_ERROR -> sdkInstance.setTrackingNotificationConfig(
                        ServiceNotificationConfig.Builder()
                                .setContentTitle("Tracking isn't working, please enable location services in settings")
                                .setLargeIcon(R.drawable.ic_green)
                                .build()
                )
                else -> Log.d(TAG, "Tracking failed with error code $it")
            }
        }            }

    override fun onTrackingStart() { }
    override fun onTrackingStop() { }
})
Parameter Type Description
trackingStateListener TrackingStateObserver.OnTrackingStateChangeListener Appropriate object methods would be called in case if significant event occurs

references > sdks > iOS

This reference shows methods available in the iOS SDK.

Refer to the integration guide for additional details.

references > sdks > ios > makeSDK(publishableKey:)

let publishableKey = HyperTrack.PublishableKey("PASTE_YOUR_PUBLISHABLE_KEY_HERE")!

switch HyperTrack.makeSDK(publishableKey: publishableKey) {
case let .success(hyperTrack):
  // Use `hyperTrack` instance
case let .failure(fatalError):
  // Handle errors, for example using switch
}
NSString *publishableKey = @"PASTE_YOUR_PUBLISHABLE_KEY_HERE";

HTResult *result = [HTSDK makeSDKWithPublishableKey:publishableKey];
if (result.hyperTrack != nil) {
  // Use `hyperTrack` instance from `result.hyperTrack`
} else {
  // Handle errors, for example using switch:
  switch ([result.error code]) {
    case HTFatalErrorProductionLocationServicesUnavalible:
    case HTFatalErrorProductionMotionActivityServicesUnavalible:
      // Handle a case where device is fully untrackable (either iPhone 5 or lower
      // or not an iPhone
      break;
    case HTFatalErrorProductionMotionActivityPermissionsDenied:
      // Handle motion permissions denied error. Enabling permissions will
      // restart the app
    default:
      // Other errors should only happen during development
      break;
  }
}

Creates and returns an SDK interface or FatalError if there are blockers to successful initialization.

Multiple interfaces can be created without duplicating memory and resources.

Put the initialization call inside your AppDelegate's application:didFinishLaunchingWithOptions: method.

Parameter Type Description
publishableKey struct struct containing a non-empty string of publishable key provided in HyperTrack's dashboard setup page.

Returns: A Result with an instance for HyperTrack SDK or an error of type FatalError if there is a development or production blocker to SDK initialization.

references > sdks > ios > init(publishableKey:)

let publishableKey = HyperTrack.PublishableKey("PASTE_YOUR_PUBLISHABLE_KEY_HERE")!

if let hyperTrack = try? HyperTrack(publishableKey: publishableKey) {
  // Use `hyperTrack` instance
}
NSString *publishableKey = @"PASTE_YOUR_PUBLISHABLE_KEY_HERE";

HTSDK *hyperTrack = [[HTSDK alloc] initWithPublishableKey:publishableKey];
if (hyperTrack != nil) {
  // Use `hyperTrack` instance
}

Creates an interface for the SDK.

Multiple interfaces can be created without duplicating memory and resources.

Parameter Type Description
publishableKey struct struct containing a non-empty string of publishable key provided in HyperTrack's dashboard setup page.

Throws: An error of type FatalError if there is a development or production blocker to SDK initialization.

references > sdks > ios > isRunning

hyperTrack.isRunning
[hyperTrack isRunning];

Reflects tracking intent.

When SDK receives start command, it captures this intent. SDK tries to track until it receives a stop command or if it encounters one of the following errors: UnrestorableError.invalidPublishableKey, RestorableError.trialEnded, RestorableError.paymentDefault.

references > sdks > ios > deviceID

hyperTrack.deviceID
[hyperTrack deviceID]

A string used to identify a device uniquely.

references > sdks > ios > setDeviceName(_:)

Set name and metadata for device tracking data.

hyperTrack.setDeviceName("Device name")
hyperTrack.deviceName = @"Device name";
Parameter Type Description
deviceName String A human-readable string describing a device or its user.

references > sdks > ios > setDeviceMetadata(_:)

if let metadata = HyperTrack.Metadata(rawValue: ["key": "value"]) {
  hyperTrack.setDeviceMetadata(metadata)
} else {
  // Metadata can't be represented in JSON
}
NSDictionary *dictionary = @{@"key": @"value"};

HTMetadata *metadata = [[HTMetadata alloc] initWithDictionary:dictionary];
if (metadata != nil) {
  [self.hyperTrack setDeviceMetadata:metadata];
} else {
  // Metadata can't be represented in JSON
}

Sets the device metadata for the current device.

You can see the device metadata in device view in Dashboard or through APIs. Metadata can help you identify devices with your internal entities (for example, users and their IDs).

Parameter Type Description
metadata struct A Metadata struct that represents a valid JSON object.

references > sdks > ios > addTripMarker(_:)

if let metadata = HyperTrack.Metadata(rawValue: ["status": "PICKING_UP"]) {
  hyperTrack.addTripMarker(metadata)
} else {
  // Metadata can't be represented in JSON
}
NSDictionary *dictionary = @{@"status": @"PICKING_UP"};

HTMetadata *metadata = [[HTMetadata alloc] initWithDictionary:dictionary];
if (metadata != nil) {
  [self.hyperTrack addTripMarker:metadata];
} else {
  // Metadata can't be represented in JSON
}

Adds a new trip marker.

Use trip markers to mark a location at the current timestamp with metadata. This marker can represent any custom event in your system that you want to attach to location data (a moment when the delivery completed, worker checking in, etc.).

Parameter Type Description
marker struct A Metadata struct that represents a valid JSON object.

references > Views

references > views > Android

Android Views are implemented using GraphQL subscriptions and enable server-to-client communication without the need to integrate Webhooks on the backend.

The module handles websockets and provides easy-to-consume methods to retrieve device status and subscribe to programmatic notifications about key moments in the movement tracking of devices and trips, as they happen.

references > views > android > Get device status

// Get SDK instance with Context reference
// replace <PUBLISHABLE_KEY> with your own key
HyperTrackViews hypertrackView = HyperTrackViews.getInstance(this, <PUBLISHABLE_KEY>);

// replace <DEVICE_ID> with your device ID
hypertrackView.getDeviceMovementStatus(<DEVICE_ID>,
    new Consumer<MovementStatus>() {
        @Override
        public void accept(MovementStatus movementStatus) {
            Log.d(TAG, "Got movement status data " + movementStatus);
        }
    });
val hyperTrackView = HyperTrackViews.getInstance(this, PUBLISHABLE_KEY)
        hyperTrackView.getDeviceMovementStatus(DEVICE_ID)
        {Log.d(TAG, "Got movement status $it")}

Get device information by device ID. The callback receives a MovementStatus object describing the device.

Movement Status

The device movement status object encapsulates all data associated with a device, similar to the Device API. It provides the latest snapshot of the device state, including ...

references > views > android > get-device-status > Location Object
Location location = movementStatus.location;
if (location != null) {
  Log.d(TAG, "Got device location " + location +
  " with latitude " + location.getLatitude() +
  " and longitude " + location.getLongitude());
}
val location = movementStatus?.location
location?.let {
  Log.d(TAG, "Got device location $location " +
          "with latitude ${location.latitude}" +
          "and longitude ${location.longitude}")
Accessor method Type Description
getLatitude() double Latitude in degrees. Negatives are for southern hemisphere.
getLongitude() double Longitude in degrees. Negatives are for western hemisphere.
getAltitude() Double Altitude in m. Could be null, if value is not available.
getSpeed() Double Speed in m/s. Could be null, if device is stationary
getBearing() Double Bearing in degrees starting at due north and continuing clockwise around the compass
getAccuracy() Double Horizontal accuracy in m
getRecordedAt() String ISO 8601 date when the location was recorded
references > views > android > get-device-status > Device Status Object
DeviceStatus status = movementStatus.deviceStatus;
if (status != null) {
  Log.d(TAG, "Device is " + (status.isDisconnected() ? "disconnected" : "connected"));
}
val status = movementStatus?.deviceStatus
status?.let {
    Log.d(TAG, "Device is ${(if (status.isDisconnected) "disconnected"  else "connected")}")
}
Member Type Description
createdAt String ISO 8601 date when the device status was created
isActive() boolean Returns true if device is active (it's current location is known and updated) and false otherwise
isDisconnected() boolean Returns true if device is disconnected (it's location wasn't updated for a while) and false otherwise
isInactive() boolean Returns true if tracking data is unavailable because of lack of permissions or tracking was stopped intentionally and false otherwise
status int Property provides more extended description of current state, e.g. whether it it is driving, if active, etc. See JavaDoc for the list of possible values and their meaning.
references > views > android > get-device-status > Device Info Properties
DeviceInfo deviceInfo = movementStatus.deviceInfo;
if (deviceInfo != null) {
    Log.d(TAG, "Got status for device " + deviceInfo.name);
}
val deviceInfo = movementStatus?.deviceInfo
deviceInfo?.let {
    Log.d(TAG, "Status from device ${deviceInfo.name}")
}
Parameter Type Description
appName String Name of the hosting app
appVersionNumber String Version of the hosting app
appVersionString String Version of the hosting app
deviceBrand String The device brand
deviceModel String The device model
name String The name of the device
osName String The operating system of the device, can be one of iOS or Android
osVersion String The version of the operating system on the device
sdkVersion String The HyperTrack SDK version on the device. Can be reviewed here: Android, iOS, React Native
references > views > android > get-device-status > DeviceViewUrls Properties

This object incapsulates resources that could be used to open WebView Widget (embedded view) or for sharing location via link.

    String shareUrl = movementStatus.deviceViewUrls.embedUrl;
    Uri uri = Uri.parse(shareUrl + PUBLISHABLE_KEY);
    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
    val shareUrl = movementStatus.deviceViewUrls.embedUrl
    val uri = Uri.parse(shareUrl!! + PUBLISHABLE_KEY)
    val intent = Intent(Intent.ACTION_VIEW, uri)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
Parameter Type Description
embedUrl String Embeddable view URL
shareUrl String Sharable view URL
references > views > android > get-device-status > Trip Properties
Trip{
    tripId="3737e382-b251-11e9-a7f6-f6b591671d93",
    startedAt="2019-07-29T22:35:49.963554Z",
    completedAt="",
    status="active",
    destination=Destination{
        geometry=Geometry{
            coordinates=[-122.437941, 37.800563]
        },
        radius=30,
        scheduledAt=""
    },
    estimate=Estimate{ ... },
    metadata="",
    summary=""
}
Method Type Description
getTripId() String Unique identifier of the newly created trip, case sensitive
getStatus() String Trip status, can be either active or completed
getStartedAt() String Timestamp for trip starting time
getMetadata() String Metadata provided at trip start
getSummary() String Trip summary, only provided upon completion of a trip
getDestination() Trip.Destination Destination of the trip, or null if trip has no destination
getEstimate() Trip.Estimate Trip summary, only provided for trips with status active
getCompletedAt() String ISO 8601 date when the trips was completed or null if it haven't been completed
references > views > android > get-device-status > trip-properties > Trip Estimate Properties
Estimate{
    arriveAt="",
    route=Route{ ... }
}
Method Type Description
getArriveAt() String Timestamp for estimated arrival
getRoute() Trip.Route Planned route segments to destination
references > views > android > get-device-status > trip-properties > Trip Route Properties
Route{
    distance=210,
    duration=1720,
    startAddress="1 Embarcadero Center, San Francisco, CA, 94122",
    endAddress="353 Sacramento St, San Francisco, CA, 94122",
    polyline=Polyline{ ... }
}
Method Type Description
getDistance() Integer Timestamp for estimated arrival
getDuration() Integer Duration in seconds
getStartAddress() String Street address lookup for segment start
getEndAddress() String Street address lookup for segment end
getPoints() List of List of Double Planned route segments to destination, as array of longitude, latitude and altitude (optional) tuples
references > views > android > get-device-status > trip-properties > Trip Destination Properties
Destination{
    geometry=Geometry{ ... },
    radius=30,
    scheduledAt="2019-07-29T22:35:49.963554Z"
}
Method Type Description
getLatitude() Double Latitude coordinate of destination center point in degrees. Negatives are for southern hemisphere
getLongitude() Double Longitude coordinate of destination center point in degrees. Negatives are for western hemisphere
getRadius() Integer Radius (in meters) of a circular trip destination
getScheduledAt() String Timestamp for scheduled arrival

references > views > android > Subscribe to updates

// Get SDK instance with Context reference
// replace <PUBLISHABLE_KEY> with your own key
HyperTrackViews hypertrackView = HyperTrackViews.getInstance(this, <PUBLISHABLE_KEY>);

// replace <DEVICE_ID> with your device ID
hypertrackView.subscribeToDeviceUpdates(<DEVICE_ID>,
   new DeviceUpdatesHandler() {
       @Override
       public void onLocationUpdateReceived(@NonNull Location location) {
           Log.d(TAG, "onLocationUpdateReceived: " + location);
       }

       @Override
       public void onBatteryStateUpdateReceived(@BatteryState int i) {
           Log.d(TAG, "onBatteryStateUpdateReceived: " + i);
       }

       @Override
       public void onStatusUpdateReceived(@NonNull StatusUpdate statusUpdate) {
           Log.d(TAG, "onStatusUpdateReceived: " + statusUpdate);
       }

       @Override
       public void onTripUpdateReceived(@NonNull Trip trip) {
           Log.d(TAG, "onTripUpdateReceived: " + trip);
       }

       @Override
       public void onError(Exception e, String deviceId) {
           Log.w(TAG, "onError: ", e);
       }

       @Override
       public void onCompleted(String deviceId) {
           Log.d(TAG, "onCompleted: " + deviceId);
       }
   }
);

You can subscribe to receive device state changes as they come in. The DeviceUpdatesHandler should implement and override the following interface methods:

Method Parameter Description
onLocationUpdateReceived Location Location update
onBatteryStateUpdateReceived BatteryState Battery update, can be one of BATTERY_CHARGING, BATTERY_LOW, and BATTERY_NORMAL
onStatusUpdateReceived StatusUpdate Status update
onTripUpdateReceived Trip Trip update
onError Exception, Device ID (String) Error with exception details and device ID
onCompleted Device ID (String) Completion with Device ID

StatusUpdate Properties

StatusUpdate{
    value="WALK",
    hint="",
    recordedAt="2019-07-29T22:35:49.963554Z"
}
Parameter Type Description
value String Health event type, can be one of DRIVE, STOP, or WALK
hint String Health hint. Additional information about the health event
recordedAt String ISO 8601 date when the device status was recorded

references > views > android > Unsubscribe from updates

hypertrackView.stopAllUpdates();

You can stop receiving updates you are subscribed to.

references > Device Status

A device is either active or inactive at any given time.

references > device-status > Active

Location and activity data is tracking as expected.

references > device-status > Inactive

Location or activity data are not tracking. This could be due to one of a few reasons.

references > device-status > inactive > Reasons

Stopped programmatically: Tracking is stopped by the app. The app does not intend to track the device at this time.

Permissions disabled/denied: Location or activity permissions are disabled/denied by app user for all-apps/this-app.

Service unavailable on device: Location or activity services are unavailable, either due to OS terminating service for the app or hardware unavailability

Unexpected outage: Location or activity data from the device is missing, and no reason has been provided.

references > device-status > Disconnected

HyperTrack platform is unable to sync with the device.

HyperTrack is a cloud platform to track ground truth of the device. There are times when the platform goes out of sync with the device. If and when the connection between device and platform is restored, the platform syncs up offline data and updates it for consumption in the cloud.

In the event that the device never returns to sync with the platform (can happen when device is lost or app is uninstalled), the device status will remain disconnected.

To understand how tracking status is defined and used in HyperTrack API, please refer to the following:

references > GeoJSON

{
  "type": "Feature",
  "geometry": {
    "type": "Point",
    "coordinates": [125.6, 10.1, 123]
  },
  "properties": {
    "name": "Dinagat Islands"
  }
}

The GeoJSON format adopted by HyperTrack is based on the RFC 7946 specification. It is used as a generalized construct to encode geographic data structures using a JSON format. It supports a variety of types, with Point being the most commonly used.

references > HTTP Errors

We are adopting the RFC 7807 standard for our error messages.

{
  "status": 404,
  "code": "trip_not_found",
  "title": "Trip could not be found",
  "type": "https://docs.hypertrack.com/#trips-api-trip-not-found",
  "detail": "Trip with the id '00112233-4455-6677-8899-AABBCCDDEEFF' does not exist"
}

The standard requires at least the type property. Everything else is optional. For HyperTrack, we always send title, detail, status, and code in addition. To detail out some errors (for instance multiple invalid fields), the append additional properties as documented in the respective error section.

Parameter Type Description
status Number HTTP status code
code String Error class code
title String Brief summary of the error class
type URL URL to the respective error page (about:blank if none is provided)
detail String Detailed description of the error instance
invalid_params Object A list of invalid parameters to review (options)

references > http-errors > Trips API

The Trips API can return one of the following errors. Please review the reference carefully to understand the error reasons and potential steps to overcome the issues faced.

references > http-errors > trips-api > Wrong content-type

{
  "status": 400,
  "code": "wrong_content_format",
  "title": "Wrong content format",
  "type": "https://docs.hypertrack.com/#trips-api-wrong-content-type",
  "detail": "The content submitted in the request body is not in valid JSON format"
}

Potential reasons:

Potential actions: Please double check that the body you generate for the request is in valid JSON format. You can use this small tool to ensure your JSON is valid.

references > http-errors > trips-api > Trip not found

{
  "status": 404,
  "code": "trip_not_found",
  "title": "Trip could not be found",
  "type": "https://docs.hypertrack.com/#trips-api-trip-not-found",
  "detail": "Trip with the id '00112233-4455-6677-8899-AABBCCDDEEFF' does not exist"
}

Potential reasons:

Potential actions: Ensure that the right ID is used - with uppercase letters and no changes to the format(e.g. don't escape the -).

references > http-errors > trips-api > Device not found

{
  "status": 400,
  "code": "device_not_found",
  "title": "Device could not be found",
  "type": "https://docs.hypertrack.com/#trips-api-device-not-found",
  "detail": "Device with the id '00112233-4455-6677-8899-AABBCCDDEEFF' does not exist"
}

Potential reasons:

Potential actions:

references > http-errors > trips-api > Route not found

{
  "status": 400,
  "code": "route_not_found",
  "title": "Route could not be found",
  "type": "https://docs.hypertrack.com/#trips-api-route-not-found",
  "detail": "Could not generate a route from the device location to the set destination"
}

Potential reasons:

Potential actions:

references > http-errors > trips-api > Validation error

{
  "status": 400,
  "code": "validation_error",
  "title": "Trip request is malformed",
  "type": "https://docs.hypertrack.com/#trips-api-validation-error",
  "detail": "The request format does not have the correct format. Please review the invalid parameters",
  "invalid_params": [
    {
      "name": "destination.geometry.type",
      "reason": "Only supported type is 'Point'. Received 'Polygon' instead"
    }
  ]
}

Potential reasons:

Potential actions: Please review and fix the invalid parameters in invalid_params. You can also use this small tool to ensure your request body complies with our JSON schema for the API call.

references > http-errors > trips-api > Completion not possible

{
  "status": 400,
  "code": "completion_not_possible",
  "title": "Trip cannot be completed",
  "type": "https://docs.hypertrack.com/#trips-api-completion-not-possible",
  "detail": "Trip with the id '00112233-4455-6677-8899-AABBCCDDEEFF' cannot be completed"
}

Potential reasons:

Potential actions:

references > http-errors > trips-api > Unauthorized

// HTTP Status: 401
{
  "message": "Unauthorized"
}

Potential reasons:

Potential actions:

references > http-errors > trips-api > Route creation failed

{
  "status": 500,
  "code": "route_error",
  "title": "Failed to generate the route",
  "type": "https://docs.hypertrack.com/#trips-api-route-creation-failed",
  "detail": "Server could not complete the route generation"
}

Potential reasons:

Potential actions:

references > http-errors > Devices API

The Devices API can return one of the following errors. Please review the reference carefully to understand the error reasons and potential steps to overcome the issues faced.

references > http-errors > devices-api > Unauthorized

{
  "message": "Unauthorized"
}

HTTP 401 (Unauthorized)

Potential reason: The Authorization header in the request is invalid or missing.

Potential actions:

references > http-errors > devices-api > Device not found

{
  "status": 404,
  "code": "device_not_found",
  "title": "Device could not be found",
  "type": "https://docs.hypertrack.com/#devices-api-trip-not-found",
  "detail": "Device with the id '00112233-4455-6677-8899-AABBCCDDEEFF' does not exist"
}

HTTP 404 (Not Found)

Potential reasons:

Potential actions:

references > http-errors > devices-api > Method Not Allowed

{
  "status": 405,
  "code": "method_not_allowed",
  "title": "Method Not Allowed",
  "type": "https://docs.hypertrack.com/#devices-api-method-not-allowed"
}

HTTP 405 (Method Not Allowed)

Potential reasons:

Potential actions:

references > http-errors > devices-api > Validation Error

{
  "status": 400,
  "code": "validation_error",
  "title": "Device request is malformed",
  "detail": "The request format does not have the correct format. Please review the invalid parameters",
  "validation_errors": [
    {
      "field": "name",
      "message": "Name cannot be empty."
    }
  ],
  "type": "https://docs.hypertrack.com/#devices-api-validation-error"
}

HTTP 400 (Bad Request)

Potential reasons:

Potential actions:

references > http-errors > devices-api > Properties Cannot Be Patched

{
  "status": 400,
  "code": "cannot_patch_property",
  "title": "Properties cannot be patched",
  "detail": "The property {x} is immutable. You can only patch: name and metadata",
  "type": "https://docs.hypertrack.com/#devices-api-properties-cannot-be-patched"
}

HTTP 400 (Bad Request)

Potential reasons:

Potential actions:

references > http-errors > devices-api > Wrong content-type

{
  "status": 400,
  "code": "wrong_content_format",
  "title": "Wrong content format",
  "type": "https://docs.hypertrack.com/#devices-api-wrong-content-type",
  "detail": "The content submitted in the request body is not in valid JSON format"
}

Potential reasons:

Potential actions: Please double check that the body you generate for the request is in valid JSON format. You can use this small tool to ensure your JSON is valid.