Stream Order Activity Markers via Webhooks

Use webhooks to ingest live location as well as activity, outage, trip, geotag, and geofence markers generated by your devices from HyperTrack to your server end point. This can allow you to implement real-time application workflows on your server.

Use status updates and markers to power your application workflows

Your webhook integration with HyperTrack can empower you to handle application workflows on your server in real-time as soon as your app user's devices generate location data. You can ingest the following webhook updates posted to your server:

Outage notifications

Inactive device status

"device_status": {
  "data": {
    "recorded_at": "2019-09-03T16:39:35.326000Z",
    "reason": "tracking_stopped"
  },
  "value": "inactive"
}

The device is not sending location updates and in that case, the device_status.data object is contains reason property`. These reasons can be one of the following below:

  • airplane_mode_detected
  • location_permissions_denied
  • location_services_disabled
  • low_battery
  • motion_activity_permissions_denied
  • motion_activity_services_disabled
  • motion_activity_services_unavailable
  • push_token_missing_to_start_tracking
  • tracking_stopped
  • tracking_service_terminated
  • deleted
  • uninstalled
  • location_unavailable
  • location_unavailable_battery_saver
  • location_unavailable_provisional_authorization
  • sdk_killed_low_memory
  • sdk_killed_by_user
  • sdk_killed_by_app_update
  • sdk_killed_by_permissions_activity
  • sdk_killed_by_permissions_location
  • sdk_killed_by_os_update
  • sdk_killed_by_os_reboot
  • sdk_killed_by_low_power
  • storage_unavailable
  • network_limit_reached
  • location_permission_asked_in_background
  • location_permission_restricted
  • motion_activity_permission_not_determined
  • motion_activity_permission_asked_in_background
  • location_permission_not_determined
  • location_permission_imprecise

Note that this is an embeddable dashboard view that you can implement in minutes for your ops managers as explained in this guide.

Disconnected device status

"device_status": {
  "data": {},
  "value": "disconnected"
}

Connection with the device was lost unexpectedly (no data received for over an hour). In that case, the device_status.data object is empty.

Geotags

Geotags are generated when your app users take action in the app as described in the track work day with geotags guide as well as in track actual distance between geotags guide.

Integrate geotags in real-time with your app backend via webhooks

If your app business workflow requires real-time integration of app user's notes as they take place, please review an example payload as shown below.

You can see that not only you get back payload data your app user generated from the mobile app, but also route_to data which contain distance in meters, duration in seconds, start_location from the previous geotag event for which distance and duration is generated, as well as recorded_at timestamp which captures the time this app event was received from your user's app.

Plus, you get location that HyperTrack captures for you when your app user generates a note in the app.

{
  "created_at": "2019-07-01T14:01:00.000000Z",
  "recorded_at": "2019-07-01T14:00:00.000000Z",
  "data": {
    "metadata": {
      "product_id": "Kent Ace",
      "action": "sold",
      "quantity": 5,
      "customer_name": "Amit K"
    },
    "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": "geotag",
  "version": "2.0.0"
}

Get geotag distances in real-time via webhooks

Please review an example payload as shown below.

You can see that not only you get back payload data your app user generated from the mobile app, but also route_to data which contain distance in meters, duration in seconds, start_location from the previous app event for which distance and duration is generated, as well as recorded_at timestamp which captures the time this app event was received from your mobile app.

Lastly, but not least importantly, you get location that HyperTrack captures for you when your app user generates an app event.

{
  "created_at": "2019-07-01T14:01:00.000000Z",
  "recorded_at": "2019-07-01T14:00:00.000000Z",
  "data": {
    "metadata": {
      "Route type": "Car",
      "Station Id": "1BCX",
      "Package Id": "1WUXZ1393",
      "Route Id": "2248311",
      "Action Type": "Reached Doorstep"
    },
    "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": "geotag",
  "version": "2.0.0"
}

Route status

In your business workflow, you may need to take actions depending on the status of the route you created for your app user. HyperTrack provides real-time updates for your app that deliver to you important events associated with your route.

Route events are posted whenever a route is started, a specified device enters or exits the destination, a route with a scheduled arrival is estimated to be delayed, and when a route is completed. Events provide the device triggering the event, the route, event type (dispatch, destination enter, destination exit, delay, or completion), and route metadata defined during start.

Currently, HyperTrack will send notifications triggered by:

  • Route created: For every new route, created events are posted.
  • Route dispatched: For every dispatched route, dispatched events are posted.
  • Route estimate: For every Create Route Estimate API call, Estimate events are posted.
  • Route completion: For every completed route, completion events are posted.

All route updates will include the update type, created_at, device_id, route_handle and metadata at the very least.

It is up to you to decide how to utilize route updates. To give you an idea, the following can be done:

  • complete route based on custom logic
  • update database records of route
  • send mobile device notifications
  • update real-time views and maps
  • start custom processes (training of AI models, send custom emails, etc)

Trigger notifications based on route activity

A common use case is to leverage route events to trigger contextual, location-aware notifications in web or native applications. To make these types of notifications possible, you should maintain a list of devices (users), a list of route, and notification templates for route events (created, dispatched, completion) to be used as notification message.

It is suggested to leverage device metadata that can be set either through mobile SDKs or through Devices API in combination with route metadata to establish all relevant information in order to send highly contextualized notifications.

More context is provided based on the update type. Please take a look at the route webhooks references for more details.

Route created

Please see an example for the route created webhook payload. Once the route is created, you may be able to get Route API to receive route estimate and expected route to the destination.

{
   "created_at":"2021-01-01T14:01:00.000000Z",
   "recorded_at":"2021-01-01T14:00:00.000000Z",
   "device_id":"00112233-4455-6677-8899-AABBCCDDEEFF",
   "account_id":"6784e919-7168-4f61-b686-2020f547637f",
   "type":"route",
   "data":{
      "value":"created",
      "route_handle":"4359cc65-90dd-4b2b-875b-26e6d2eba11d",
      "status":"planned",
      "embed_url":"https://embed.hypertrack.com/trips/4359cc65",
      "metadata":{
         "storeId":"123490809808",
         "customerName":"Andrew"
      }
   },
   "version":"3.0.0"
}

Route dispatched

Please see an example for the route dispatched webhook payload. Once the route is dispatched, you may be able to get Route API to receive route estimate and expected route to the destination.

{
   "created_at":"2021-01-01T14:01:00.000000Z",
   "recorded_at":"2021-01-01T14:00:00.000000Z",
   "device_id":"00112233-4455-6677-8899-AABBCCDDEEFF",
   "account_id":"6784e919-7168-4f61-b686-2020f547637f",
   "type":"route",
   "data":{
      "value":"created",
      "route_handle":"4359cc65-90dd-4b2b-875b-26e6d2eba11d",
      "status":"planned",
      "embed_url":"https://embed.hypertrack.com/trips/4359cc65",
      "metadata":{
         "storeId":"123490809808",
         "customerName":"Andrew"
      }
   },
   "version":"3.0.0"
}

Route Estimate Generated

When the Create Route Estimate API is called, Estimate events are posted, you will receive the route estimate generated webhook.

{
   "created_at":"2021-01-01T14:01:00.000000Z",
   "recorded_at":"2021-01-01T14:00:00.000000Z",
   "device_id":"00112233-4455-6677-8899-AABBCCDDEEFF",
   "account_id":"6784e919-7168-4f61-b686-2020f547637f",
   "type":"route",
   "data":{
      "value":"estimate_generated",
      "route_handle":"4359cc65-90dd-4b2b-875b-26e6d2eba11d",
      "status":"planned",
      "embed_url":"https://embed.hypertrack.com/trips/4359cc65-90dd-4b2b-875b-26e6d2eba11d?publishable_key=lujVNBunxFFHBQ2gk980UqQ3KQemmKRsqlATo4nes959pKEo9nAqxv60Sk1r1HR_KSpdZ0feR4FLajKuw",
      "estimate":{
				"distance": 7382,
				"duration": 1263,
				"start_by": "2021-01-01T14:05:00.000Z"
			}
			"metadata":{
         "storeId":"123490809808",
         "customerName":"Andrew"
      }
   },
   "version":"3.0.0"
}

Route completion

When the route is completed, you will receive the route completion webhook. Key metrics such as distance or duration is part of the payload.

{
   "created_at":"2021-01-01T14:01:00.000000Z",
   "recorded_at":"2021-01-01T14:00:00.000000Z",
   "device_id":"00112233-4455-6677-8899-AABBCCDDEEFF",
   "account_id":"6784e919-7168-4f61-b686-2020f547637f",
   "type":"route",
   "data":{
      "value":"completed",
      "route_handle":"4359cc65-90dd-4b2b-875b-26e6d2eba11d",
      "status":"completed",
			"distance": 6278,
			"duration": 1273,
      "embed_url":"https://embed.hypertrack.com/trips/4359cc65",
			"metadata":{
         "storeId":"123490809808",
         "customerName":"Andrew"
      }
   },
   "version":"3.0.0"
}

Geofence markers

HyperTrack provides the capability to send you geofence visit markers from your HyperTrack SDK integration.

Webhook payload is following this data structure:

{
    "created_at": "2019-07-01T14:01:00.000Z",
    "recorded_at": "2019-07-01T14:00:09.000Z",
    "data": {
      "arrival": {
        "location": {
          "coordinates": [
            -123.45677,
            12.34567,
            12.34
          ],
          "type": "Point"
        },
        "recorded_at": "2019-07-01T14:00:00.000Z"
      },
      "duration": 9,
      "exit": {
        "location": {
          "coordinates": [
            -111.11111,
            22.222222,
            12.34
          ],
          "type": "Point"
        },
        "recorded_at": "2019-07-01T14:00:09.000Z"
      },
      "geofence_id": "fed594a1-10c7-47e3-8aa3-f5fcaa265bdb",
      "geofence_metadata": {"station": "B"}
      "geometry": {
        "coordinates": [
          -101.625463,
          32.347361
        ],
        "type": "Point"
      },
      "marker_id": "123e4567-e89b-12d3-a456-426614174000",
      "route_to": {
        "distance": 1234,
        "duration": 930,
        "idle_time": 12
      },
      "trip_id": "01380bff-5b72-4ae6-a8c5-71e694b1c3c9",
      "value": "exit"
    },
    "location": {
        "type": "Point",
        "coordinates": [-111.11111,22.222222,12.34]
    },
    "device_id": "321E4567-AAAA-12D3-A456-42661417400",
    "account_id": "111e3322-e89b-12d3-a456-426614174000",
    "type": "geofence",
    "version": "2.0.0"
}

In the example, you can see that device_id with value 321E4567-AAAA-12D3-A456-42661417400 exited the geofence with geofence_id fed594a1-10c7-47e3-8aa3-f5fcaa265bdb.

:::note
The field geofence_metadata is optional and present when the geofence associated with the geofence marker has metadata.
:::

For further reference, you may visit this guide to receive and process geofence visit events.

Battery status changes

Battery status changes include values such as low, normal and charging

"battery": "normal"

Device objects contain a battery property to indicate the state of the device battery. The property can take one of the following values: low, normal, or charging

:::tip
If you would like to receive battery state updates as they come in, it is recommended to use battery updates webhooks. This enables reacting to low battery risks as they happen.
:::

{
    "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"
}

HyperTrack sends battery updates to indicate the battery health. These events include details on charge, discharge and low battery.

:::info
Battery updates can be combined with outages as a leading indicator for tracking outages.
:::

Identifying devices by name and metadata in webhook payloads

Optionally, webhook payload can also contain name and metadata associated with the device as shown in the example below with name and metadata keys.

{
	"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": "Alex",
    "metadata": {
      "store_manager_id": 1
    }
}

:::note
Device name and metadata addition to webhook payloads is in limited Beta with select customers. Please contact us to get access.
:::

Nearby API request completion

In addition to GET /devices/nearby API, you will also get notified about the completion of a request via webhook notification with below payload example structure. To see how Nearby API works, please see this guide.

Notification payload for Nearby API completion will look like this:

 {
    "created_at": "2020-04-29T02:25:59.906839Z",
    "type": "nearby_devices_request",
    "data": {
        "value": "completed",
        "request_id": "09f63b10-9bbc-4b24-af1a-d8ac84644fcc",
        "location": {
                "coordinates": [
                  -122.402007, 37.792524
                ],
                "type" : "Point"
            },
        "metadata": {
            "team": "san_francisco",
            "gig_type": "delivery"
        }
        "radius": 1000
    },
    'version': '2.0.0'
 }

Webhooks setup

To get started with webhook integration, the HyperTrack dashboard allows you add your webhook URL on the Setup page.

Just enter your webhook URL and click on Add Webhook. Once entered, it will immediately change to Receiving markers and location update if Include location updates option is selected.

πŸ“˜

If you select to receive location updates from devices in your account, it will increase number of webhooks by 10-40x. Please use this option only if your business use case requires real-time location update stream from all locations from all tracked devices.

You may be able to opt-in later to receive location updates should your requirements change. Please note it takes up to 10 minutes for your configuration changes to take effect.

Validate webhook notifications

Your webhook payload can be optionally validated to confirm as being sent by HyperTrack.

All webhook payloads sent to your server contain x-hypertrack-signature header. This header is an HMAC-SHA1 signature generated using your webhook request payload and your account's secret key. Your secret key can be found in your account's dashboard setup page as SecretKey.

Please review code examples below for guidance on how to perform signature verification.

πŸ“˜

Please ensure to process raw body from the HTTP POST request to validate the contents of the webhook payload.

const crypto = require('crypto');

// Get webhook payload as received by your server end point. It needs to be the raw payload coming from the HTTP POST body that came to your server end point. 

const webhook_payload = '[{"created_at": "2020-06-09T22:44:29.554924Z", "device_id": "ABCD182-6998-4686-AB2E-CF8F998A1EB6", "recorded_at": "2020-06-09T22:44:25.999000Z", "type": "location", "data": {"geometry": {"type": "Point", "coordinates": [-122.294112, 37.864945, 15.14]}, "speed": 1.003556110578331, "accuracy": 14.733237162224144, "bearing": 179.2877726443533}, "version": "2.0.0"}]'

// Get your SecretKey from the setup page in your account dashboard
const signatureKey = '{your_secret_key}'

const hmac = crypto.createHmac('sha1', signatureKey);
hmac.update(webhook_payload);
const signature = hmac.digest('hex');

// Verify signature from `x-hypertrack-signature` header
const webhook_payload_signature = '{signature_value}'

if (signature === webhook_payload_signature) {
  console.log('Verification is successful');
} else {
  console.log('Verification failed');
}


import hashlib
import hmac

# Get webhook payload as received by your server end point. This needs to be the raw payload that comes from your
# end point from HTTP POST body.
# For example:
# webhook_payload = request.body

webhook_payload = '[{"created_at": "2020-06-09T22:44:29.554924Z", "device_id": "ABCD182-6998-4686-AB2E-CF8F998A1EB6", "recorded_at": "2020-06-09T22:44:25.999000Z", "type": "location", "data": {"geometry": {"type": "Point", "coordinates": [-122.294112, 37.864945, 15.14]}, "speed": 1.003556110578331, "accuracy": 14.733237162224144, "bearing": 179.2877726443533}, "version": "2.0.0"}]'
encoded_webhook_payload = webhook_payload.encode('utf-8')

# Get your SecretKey from the setup page in your account dashboard

secret_key = '{your_secret_key}'
encoded_secret_key = secret_key.encode('utf-8')
signature = hmac.new(encoded_secret_key, encoded_webhook_payload, hashlib.sha1)

# Verify signature from `x-hypertrack-signature` header

webhook_payload_signature = '{signature_value}'
if signature.hexdigest() == webhook_payload_signature:
    print("Verification is successful")
else:
    print("Verification failed")

Troubleshooting webhook integration

Please review common issues below for suggestions on how to resolve them.

Webhooks payloads are not sent to your server

To confirm if your webhook server is working as expected, you may send a test event by clicking on three dots on the webhook setup screen and and then clicking on Send test event option.

You will receive a webhook test payload that will be like this:

[
  {
    "recorded_at": "2019-02-27T22:50:24.538000Z",
    "data": {
      "altitude": 495.2,
      "bearing": 90,
      "location": {
        "coordinates": [
          -6.2755,
          57.6398983
        ],
        "type": "Point"
      },
      "location_accuracy": 14.087,
      "speed": 0
    },
    "device_id": "TEST_DEVICE_ID",
    "type": "location",
    "account_id": "0"
  }
]

If you have not received the request, then you may want to verify if your server is reachable by making a POST request with a tool of your choice to your webhook server URL. Otherwise, your server will be receiving webhooks from HyperTrack once devices under your account generate location data.

πŸ“˜

You will likely not receive webhooks right away. We offer the capability to send test events (upon click on the three dots on the screen above). This will allow you to test your implementation.

Multiple webhook payloads received for the same event

When you observe multiple webhook payloads received for the same event, for example, a trip completion event, you need to check if your URL end point returns a successful and timely response for each webhook HTTP POST request sent to your server.

Otherwise, HyperTrack will attempt to re-send the same request up to three times before giving up.