Track Orders using Geofences

Introduction

Geofences help automate productivity tracking. Geofence visits measure how time is being spent by workers on the field, at places of interest and on the way to those places. This 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 river safety, route efficiency and more.

Use Geofences cloud to automatically track workers 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 workers in the account, or workers grouped by their profile metadata, or a specific worker. Geofences may be circular with a geofence radius around a point, or polygon with closed geofence coordinates.

Worker visits (arrival to exit) at applicable geofences are accurately and automatically tracked in real-time. Each visit marker includes information about 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.

How to create a Geofence

Geofences can be created from the dashboard using the Places Manager or by posting in the geofencing API called Geofences API.
Places may be set as a geoJSON point location with geofence radius, or as a polygon with geofence coordinates.

Places Manager

The Places Manager lets you manage all your places and their geofences.

Geofencing API

The API follows geojson format for geometries. GeoJSON.io has a useful tool to draw polygons.

For all workers

Set geofences for all workers when you expect any workers in the account to visit from a fixed set of places like offices or warehouses. Visits involve the worker having entered the geofence and optionally exited the geofence. As the number of workers get larger, in hundreds or more, it is advisable to create geofences by groups to avoid generating noisy data.

If you wish to get started with how to create a geofence for all workers, 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 workers 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, or else your app would have registered too many geofence visits. You may also use geofence_id to get the details of geofences exited and arrived 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 workers

To set geofences for groups of workers, you must first set worker profiles using worker profiles and then use it as a filter to apply the geofence to that group of workers.

To create geofences for groups of workers, 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 geofencing 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 workers 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 workers

Set worker-specified geofences for places like home, work location assigned to a worker, or any other place of individual interest. This may be as geofence radius or geofence coordinates. This helps understand when workers leave or re-enter these places during work hours, and power automations that use this information.

To create geofences for specific workers, use the Geofences POST API with the corresponding driver_handle.

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

In the payload below, you will notice the driver_handle 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,
    }
]

📘

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.

Start and stop tracking

Tracking visits requires that you track the worker's device using the Drivers API. To protect worker privacy, and maximize tracking rate, it is important to be mindful about when you start and stop tracking the worker. Start tracking when the worker starts working and stop when worker 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 worker a way to manually clock in and out from the app as a fallback.

The Drivers API gives you the power to reliably control tracking on worker 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.

Starting and stopping tracking

Call Drivers API with the worker's driver_handle and set tracking to TRUE to start tracking.

In order to protect the privacy of workers using your app, you are strongly encouraged to stop tracking when the worker stops working. This will positively impact your tracking rate because workers will trust the system and not try to kill tracking in the app through the smartphone or OS.

Call Drivers API with the worker's driver_handle and set tracking to FALSE to stop tracking.

Using geofence visits

As workers 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 inside the geofence radius or geofence coordinates, 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 workers 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.

📘

Note that exits can happen when:

  • Worker leaves the geofence. In this case, webhook payloads will have a location or
  • Outages (like permission denied; location services killed, etc.; or when order completed). In this case the webhook payloads do not have a location

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

View timeline with visits

Get arrival and exit webhooks

By subscribing to geofence webhooks, you can receive a real-time stream of your worker'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 a webhook has a data object containing an arrival or exit corresponding to the state of the geofence. arrival will be shown by default, as a visit starts when a device enters a geofence. exit will be included when the worker 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"
    }
]

📘

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.

View visit scoreboards

Geofence scoreboards show 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 worker profile.

View visit insights

Geofence insights show visits data organized by workers, average durations, and visit outcomes. This information may be grouped by visit marker metadata and filtered by region or worker 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'
    }
}

📘

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 worker

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

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'
    }
}

📘

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 geofence API currently returns all active geofence IDs set for account-wide, viz. applicable to all workers in the account. We are modifying this API to return all active geofence IDs, whether account-wide, group-wide or worker-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 worker specific geofences

This API currently returns all active geofence IDs set for a worker, viz. set for specific worker. We are modifying this API to return all active geofence IDs applicable to the worker, whether set as account-wide, group-wide or worker-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 place 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 places

Use this API to delete geofences that are no longer needed. Visit markers for deleted geofences will remain in the system and show up across interfaces—views, geofence 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 the HTTP 200 response back.

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

📘

After geofence deletion, historical visits data will continue to be available across all interfaces: views, geofence APIs, exports and insights.

Blogs