Track Visits with Geofences

Introduction

Geofences help automate productivity. Geofence visits measure how time is being spent on the field, at places of interest and on the way to those places. This further helps answer questions about whether time is productively spent relative to outputs from those places and teams. Geofences are used to automate attendance, time sheets, customer surveys, visit notes, behavior analysis, worker safety, route efficiency and more.

Use Geofences to automatically track app users visiting places of interest. Frequently visited places such as offices, partners, merchants, branches, field assets, or rest areas may be set as geofences. These geofences may be applied to all app users in the account, or users grouped by their profile metadata, or a specific user.

App users' visits (arrival to exit) at applicable geofences are accurately and automatically tracked in real-time. Each visit marker includes information about the the visit, route to the visit, and idle time on the way to the visit. This information is available through real-time webhooks, map views, scoreboards, and insights.

Create geofences

Geofences may be created by calling the Geofences API. Places may be set as a geoJSON point location with radius, or as a polygon location. GeoJSON.io has a useful tool to draw polygons. Also, HyperTrack Playground has tools to create geofences on a map.

For all app users

Set geofences for all app users when you expect any user in the account to visit from a fixed set of places like offices or warehouses. As the number of users get larger, in hundreds or more, it is advisable to create geofences by groups to avoid generating noisy data.

To create geofences for all app users, use the Geofences POST API as shown in the example below. Note that you may pass an array of geofences in one API call.

The API supports both Point and Polygon type geofences.

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

curl -X POST \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences

In the payload below, you are creating two geofences of Point and Polygon type for all devices under your account. Your account is automatically identified through your AccountId credential supplied in the API call.

{
"geofences": [
{
"geometry": {
"type": "Point",
"coordinates": [-122.395223, 37.7947633]
},
"metadata": {
"station": "A"
},
"radius": 50
},
{
"geometry": {
"type": "Polygon",
"coordinates": [[
[-122.395237, 37.7947693],
[-122.402321, 37.794374],
[-122.401371, 37.790205],
[-122.389450, 37.791271],
[-122.395237, 37.7947693]
]]
},
"metadata": {
"dropoff": "1ABC"
}
}
]
}

Once the call is made successfully, you will get back an HTTP 201 response with this payload below. Make a note of geofence_id returned below as you will need it to delete this geofence once you no longer need it. You may also use geofence_id to get the details of geofence back as described below.

[
{
"geometry":{
"type":"Point",
"coordinates": [
122.395223,
37.7947633
]
},
"metadata":{
"station": "A"
},
"radius":50,
"single_use": false,
"geofence_id":"000111-4047-4b28-a6ec-f934e870c425"
},
{
"geometry":{
"type":"Polygon",
"coordinates": [[
[-122.395237, 37.7947693],
[-122.402321, 37.794374],
[-122.401371, 37.790205],
[-122.389450, 37.791271],
[-122.395237, 37.7947693]
]]
},
"metadata":{
"dropoff": "1ABC"
},
"single_use": false,
"geofence_id":"00002222-3738-1c11-f2ef-a213e641a342"
}
]

For groups of app users

To set geofences for groups of app users, you must first set app user profiles using device metadata and then use it as a filter to apply the geofence to that user group.

To create geofences for groups of app users, use the Geofences POST API as shown in the example below. Note that you may pass an array of geofences in one API call.

The API supports both Point and Polygon type geofences.

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

curl -X POST \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences

In the payload below, you are creating two geofences of Point and Polygon type, both accessible by app users that have the "foreman" as "Bruce Lee". Your account is automatically identified through your AccountId credential supplied in the API call.

{
"geofences": [
{
"geometry": {
"type": "Point",
"coordinates": [-122.395223, 37.7947633]
},
"metadata": {
"station": "A"
},
"radius": 50
},
{
"geometry": {
"type": "Polygon",
"coordinates": [[
[-122.395237, 37.7947693],
[-122.402321, 37.794374],
[-122.401371, 37.790205],
[-122.389450, 37.791271],
[-122.395237, 37.7947693]
]]
},
"metadata": {
"dropoff": "1ABC"
}
}
],
"metadata_filter": {"foreman": "Bruce Lee"}
}

Once the call is made successfully, you will get back an HTTP 201 response with this payload below. Make a note of geofence_id returned below as you will need it to delete this geofence once you no longer need it. You may also use geofence_id to get the details of geofence back as described below.

[
{
"geometry":{
"type":"Point",
"coordinates": [
122.395223,
37.7947633
]
},
"metadata":{
"station": "A"
},
"radius":50,
"single_use": false,
"geofence_id":"000111-4047-4b28-a6ec-f934e870c425",
"metadata_filter": {"foreman": "Bruce Lee"}
},
{
"geometry":{
"type":"Polygon",
"coordinates": [[
[-122.395237, 37.7947693],
[-122.402321, 37.794374],
[-122.401371, 37.790205],
[-122.389450, 37.791271],
[-122.395237, 37.7947693]
]]
},
"metadata":{
"dropoff": "1ABC"
},
"single_use": false,
"geofence_id":"00002222-3738-1c11-f2ef-a213e641a342",
"metadata_filter": {"foreman": "Bruce Lee"}
}
]

For specific app users

Set user-specified geofences for places like home, work location assigned to a user, or any other place of individual interest. This helps understand when users leave or re-enter these places during work hours, and power automations that use this information.

To create geofences for specific app users, use the Geofences POST API with the corresponding device_id.

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

In the payload below, you will notice the device_id field where device F3DF6D4F-6A06-4883-8201-D767EA408030 will be tracked for the two geofences created.

{
"device_id": "F3DF6D4F-6A06-4883-8201-D767EA408030",
"geofences": [
{
"geometry": {
"type": "Point",
"coordinates": [-122.395223, 37.7947633]
},
"metadata": {
"station": "A"
},
"radius": 50
},
{
"geometry": {
"type": "Polygon",
"coordinates": [[
[-122.395237, 37.7947693],
[-122.402321, 37.794374],
[-122.401371, 37.790205],
[-122.389450, 37.791271],
[-122.395237, 37.7947693]
]]
},
"metadata": {
"dropoff": "1ABC"
}
}
]
}

Once the call is made successfully, you will get back an HTTP 201 response with this payload below. Make a note of geofence_id returned below as you will need it to delete this geofence once you no longer need it. You may also use geofence_id to get the details of geofence back as described below.

[
{
"geofence_id":"000111-4047-4b28-a6ec-f934e870c425",
"device_id": "F3DF6D4F-6A06-4883-8201-D767EA408030",
"geometry":{
"type":"Point",
"coordinates": [-122.395223, 37.7947633]
},
"metadata":{
"station": "A"
},
"radius":50,
"single_use": false,
},
{
"geofence_id":"00002222-3738-1c11-f2ef-a213e641a342",
"device_id": "F3DF6D4F-6A06-4883-8201-D767EA408030",
"geometry":{
"type":"Polygon",
"coordinates": [[
[-122.395237, 37.7947693],
[-122.402321, 37.794374],
[-122.401371, 37.790205],
[-122.389450, 37.791271],
[-122.395237, 37.7947693]
]]
},
"metadata":{
"dropoff": "1ABC"
},
"single_use": false,
}
]
important

You need to make a note of geofence_id of geofences you created via Geofences API. The geofence_id is the primary handle to get visit markers, modify geofence profiles, delete geofences and more.

Geofence Hit Clusters

Start and stop tracking

Tracking geofence visits requires that you track the user's device using the Devices API. To protect user privacy, and maximize tracking rate, it is important to be mindful about when you start and stop tracking the user. Start tracking when the user starts working and stop when user stops working. The start and end of work is usually determined by login/logout, clock in/out, working hours, work assignment/completion and similar workflows. If this is determined from the backend, it is advisable to also provide the user a way to manually clock in and out from the app as a fallback.

Devices APIs give you the power to reliably control tracking on app user devices from the backend. This requires a completed SDK setup with quiet push notifications. Review the respective Install SDK instructions to complete the setup. This is automatically set up in case you are using the HyperTrack Visits app from the stores.

Start tracking

Call Devices API with the app user's device_id to start tracking.

// 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
});

Stop tracking

In order to protect the privacy of workers using your app, you are strongly encouraged to stop tracking when the user stops working. This will positively impact your tracking rate because users will trust the system and not try to kill tracking in the app through the smartphone or OS. Call Devices API with the app user's device_id to stop tracking.

// 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 started
})
.catch(error => {
// Error handling
});

Get app user's device ID

The SDK should have added a device name and metadata upon initialization in the user's app (iOS, Android).

If you have already sent and stored this information to your servers, get the user's device ID from your application database. Else, get the list of registered devices from the Devices API and use the device name or metadata to identify the user(s) you want to track.

HyperTrack views and developer integrations rely on the device names and metadata for filtering, selection, and more. Customizing these device properties makes navigation and identification of users easier. Developers often add unique identifiers, grouping information, or annotations that are frequently accessed for devices.

Device name and custom metadata
{
"name": "Alex’s Phone",
"metadata": {
"customer_id": "ABC123"
}
}

By default, the property name is set to the name of the device as configured in the device settings. With the SDK, you can set and customize this name. Additionally, the Devices API provides you an ability to update device name and metadata via an HTTP PATCH.

note

The Devices API is authoritative when it comes to setting the device name and/or metadata. Once you have updated the device name by invoking the Devices API above, the HyperTrack mobile SDK will not be able to make subsequent changes to the device name. Similarly, if you update the device metadata via the Devices API call, the HyperTrack mobile SDK will not be able to make changes as well.

Using geofence visits

As app users visit geofences, HyperTrack generates visit markers that include information about the visit, the route to the visit, and the idle time (stops) before getting there. The visit marker is created upon arrival at the geofence, and updated with visit information upon exit. The next section covers how you can receive geofence arrivals and exits over webhooks, query recent visits to the geofence, and add metadata to a visit marker.

Inside each visit, you will find arrival and exit objects that get created and updated upon arrival and exit respectively. Each visit is tagged with a unique marker_id so that you can differentiate them from each other.

When your users arrive at a geofence, an object called route_to will be initialized if there was a previous geofence that they came from. Inside the route_to object you'll find attributes duration and distance that give metrics on how long and how far the journey was. Please note that a geofence will be initialized with a route_to object even if the previous geofence has not been exited.

After your user leaves the geofence, the marker will be updated with its own duration attribute for how they spent inside.

View timeline with visits

Timeline with Geofence VisitsApp user's timeline with geofence visits as they happen

Get arrival and exit webhooks

By subscribing to geofence webhooks, you can receive a real-time stream of your app user's geofence arrivals and exits. This helps automate workflows such as attendance, time sheets, customer notifications, app notifications, exception handling, and more.

The webhook payload has the following data structure to represent geofence arrivals and exits. Note that the webhook payload can contain multiple entries, each with type geofence. Each geofence marker payload inside webhook has a data object containing a an arrival or exit corresponding to the state of the geofence. arrival will be shown by default, as a visit starts when a device enter a geofence. exit will be included when the user leaves that geofence.

[
{
"device_id": "F3DF6D4F-6A06-4883-8201-D767EA408030",
"data": {
"geofence_id": "00001111-4047-4b28-a6ec-f934e870c425",
"marker_id": "00001111-3767-2c12-f4ad-e213c130b321",
"metadata": null,
"geofence_metadata": {
"station": "A"
},
"geometry": {
"type":"Point",
"coordinates": [-122.395223, 37.7947633]
},
"radius":50,
"arrival": {
"location": {
"type":"Point",
"coordinates": [-122.394223, 37.792763]
},
"recorded_at": "2019-07-01T13:45:00.000000Z"
},
"exit": {},
"duration": null,
"route_to": {
"duration": 3600,
"distance": 2374
},
"value": "entry"
},
"location": {
"type": "Point",
"coordinates": [-122.394223, 37.792763]
},
"recorded_at": "2019-07-01T13:45:00.000000Z",
"created_at": "2019-07-01T13:46:00.000000Z",
"version": "2.0.0",
"type": "geofence"
}
]
note

The value attribute in the data object is a legacy field and contains some inconsistent terminology to what is currently given in the response. The value of entry corresponds to the arrival object. The value of exit is unchanged and corresponds to its exit.

Geofence Hit Real Time with Metadata

View visit scoreboards

Geofence scoreboards show a running scores of the day's KPIs compared to the past 7 or 30 days, and help understand day-wise trends of time spent on the field. Scores for geofence visits include total visits, average visit time, average idle time, average route time, and average route distance. Scoreboard views may be filtered by region or app user profile.

Scoreboards for Geofence VisitsScoreboard view of geofence visits for the last 30 days.

View visit insights

Geofence insights show visits data organized by app users, average durations, and visit outcomes. This information may be grouped by visit marker metadata and filtered by region or app user profile. Reports may be downloaded as CSV. Interactive map views help identify how time is spent on the field.

Get visits for a geofence

Query the Geofence API with the geofence_id to get all visits for the geofence.

GET   https://v3.api.hypertrack.com/geofences/visits?geofence_id={geofence_id}

curl -X GET \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences/visits?geofence_id={geofence_id}

The JSON response contains two keys data and links, where data contains an array of markers ordered in descending time, and links contains a url to retrieve the next page of results. If there is not a next page found, the next object will be null.

{
"data": [
{
"geofence_id": "00001111-4047-4b28-a6ec-f934e870c425",
"device_id": "F3DF6D4F-6A06-4883-8201-D767EA408030",
"marker_id": "00001111-3767-2c12-f4ad-e213c130b321",
"metadata": null,
"geofence_metadata": {
"station": "A"
},
"geometry": {
"type":"Point",
"coordinates": [-122.395223, 37.7947633]
},
"radius":50,
"arrival": {
"location": {
"type":"Point",
"coordinates": [-122.394223, 37.792763]
},
"recorded_at": "2019-07-01T13:45:00.000000Z"
},
"exit": {
"location": {
"type":"Point",
"coordinates": [-122.154223, 37.132763]
},
"recorded_at": "2019-07-01T13:50:00.000000Z"
},
"duration": 900,
"route_to": {
"duration": 3600,
"distance": 2374
},
"value": "exit"
},
{
"geofence_id": "00001111-4047-4b28-a6ec-f934e870c425",
"device_id": "A2DA5B2A-1B23-1244-1235-A134BD212415",
...
}...
],
"links": {
"next": 'https://v3.api.hypertrack.com/geofences/visits?geofence_id=00001111-4047-4b28-a6ec-f934e870c425&pagination_token=eyJhY2NvdW50X2lkIj'
}
}
note

The value attribute in the data object is a legacy field and contains some inconsistent terminology to what is currently given in the response. The value of entry corresponds to the arrival object. The value of exit is unchanged and corresponds to its exit.

Get visits for a user

Query the Geofence API with the device_id to get all visits for the app user.

GET   https://v3.api.hypertrack.com/geofences/visits?device_id={device_id}

curl -X GET \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences/visits?device_id={device_id}

The JSON response contains two keys data and links, where data contains an array of markers ordered in descending time, and links contains a url to retrieve the next page of results. If there is not a next page found, the next object will be null.

{
"data": [
{
"geofence_id": "00001111-4047-4b28-a6ec-f934e870c425",
"device_id": "F3DF6D4F-6A06-4883-8201-D767EA408030",
"marker_id": "00001111-3767-2c12-f4ad-e213c130b321",
"value": "exit",
"metadata": null,
"geofence_metadata": {
"station": "A"
},
"geometry": {
"type":"Point",
"coordinates": [-122.395223, 37.7947633]
},
"radius":50,
"arrival": {
"location": {
"type":"Point",
"coordinates": [-122.394223, 37.792763]
},
"recorded_at": "2019-07-01T13:45:00.000000Z"
},
"exit": {
"location": {
"type":"Point",
"coordinates": [-122.154223, 37.132763]
},
"recorded_at": "2019-07-01T13:50:00.000000Z"
},
"duration": 900,
"route_to": {
"duration": 3600,
"distance": 2374
}
},
{
"geofence_id": "00002222-3738-1c11-f2ef-a213e641a342",
"device_id": "F3DF6D4F-6A06-4883-8201-D767EA408030",
...
}...
],
"links": {
"next": 'https://v3.api.hypertrack.com/geofences/visits?device_id=F3DF6D4F-6A06-4883-8201-D767EA408030&pagination_token=eyJhY2NvdW50X2lkIj'
}
}
note

The value attribute in the data object is a legacy field and contains some inconsistent terminology to what is currently given in the response. The value of entry corresponds to the arrival object. The value of exit is unchanged and corresponds to its exit.

Change visit metadata

Visit metadata represents the outcome of the visit and helps measure productivity. Visit duration, route and idle time may be correlated with outcomes scores from your application. This information shows up in views and becomes available as filters in insights.

To change visit metadata, it is important to store the visit marker IDs in your system. Use the Geofences PATCH API to modify visit metadata at any time.

PATCH   https://v3.api.hypertrack.com/geofences/visits/{marker_id}

payload='{
"metadata": {
"message": "Package left at the door",
"tracking_id": "384748984"
}
}'
curl -X PATCH \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences/visits/{marker_id}
-H 'Content-Type: application/json' \
-d $payload

Managing geofences

Use these APIs to get active geofences, change geofence metadata, and delete geofences.

Get geofence setting

You may be able to retrieve geofence data for a particular geofence_id like so:

GET   https://v3.api.hypertrack.com/geofences/{geofence_id}

curl -X GET \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences/{geofence_id}
[
{
"geofence_id": "00001111-4047-4b28-a6ec-f934e870c425",
"device_id": "F3DF6D4F-6A06-4883-8201-D767EA408030",
"geofence_metadata": {
"station": "A"
},
"geometry": {
"type":"Point",
"coordinates": [122.395223, 37.794763]
}
"radius":50
}
]

Get account geofences

This API currently returns all active geofence IDs set for account-wide, viz. applicable to all users in the account. We are modifying this API to return all active geofence IDs, whether account-wide, group-wide or user-specific.

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

curl -X GET \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences/

The JSON response contains two keys data and links, where data contains an array of geofence objects, and links contains a url to retrieve the next page of results. If there is not a next page found, the next object will be null.

{
"data": [
{
"geofence_id": "00001111-4047-4b28-a6ec-f934e870c425"
"geofence_metadata": {
"station": "A"
},
"geometry": {
"type":"Point",
"coordinates": [122.395223, 37.794763]
}
"radius":50,
"single_use": false
}
],
"links": {
"next": 'https://v3.api.hypertrack.com/geofences/?pagination_token=eyJhY2NvdW50X2lkIj'
}
}

To access the next page of data, simply perform another GET request to the next url provided in the JSON response:

GET   https://v3.api.hypertrack.com/geofences/?pagination_token=eyJhY2NvdW50X2lkIj

Get app user geofences

This API currently returns all active geofence IDs set for a user, viz. set for specific app user. We are modifying this API to return all active geofence IDs applicable to the app user, whether set as account-wide, group-wide or user-specific.

GET   https://v3.api.hypertrack.com/geofences/?device_id={device_id}

curl -X GET \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences/?device_id={device_id}

The JSON response is the same as the object listed above with data and links keys. You can paginate through this response's pages using the same method described previously.

Changing geofence metadata

Over the course of a geofence's lifetime, you may want to change its attributes to reflect changes in your application data.

You can use the Geofences PATCH API to modify any geofence at any time after its creation. Metadata for this geofence will be changed and visible across all HyperTrack views. Please note that previous metadata will be erased after you update it.

GET   https://v3.api.hypertrack.com/geofences/{geofence_id}

payload='{
"metadata": {
"Assign": "Riley Davis",
"Note": "Access from the back parking lot"
}
}'
curl -X PATCH \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences/visits/{marker_id}
-H 'Content-Type: application/json' \
-d $payload

Delete geofences

User this API to delete geofences that are no longer needed. Visit markers for deleted geofences will remain in the sytem and show up across interfaces—views, APIs, exports and insights. Deleted geofences will stop generating new visit markers after the time of deletion.

You can use Geofences DELETE API to delete a geofence as shown in an example below. Please note you will need to use a specific geofence_id to delete the entry. If the call is successful, you will get HTTP 200 response back.

curl -X DELETE \
-u {AccountId}:{SecretKey} \
https://v3.api.hypertrack.com/geofences/{geofence_id}

Questions?

If your business can benefit from tracking geofence visits to places of interest, or if you have feeedback and comments, please do not hesitate to contact us.