Camera and Alarms Triggered Dispatches and Workflow Executions

The TrackTik API has all the endpoints and webhook capabilities you need for a successful bi-directional trigger -> dispatch -> workflow -> resolution workflow.

In the TrackTik ecosystem, the central data entities for a camera based triggers to dispatches flow are:

  • Client Sites (a kind of Account, the physical location that needs a guard dispatched to)
  • Task Types (Job Types, a kind of high level categorization of the reason for the dispatch) 
  • Report Templates (key historical information for the guard and to enrich the dispatch's metadata)
  • Dispatch Tasks (Dispatches)
  • Dispatch Task Notes (optional, extra ad-hoc notes for the dispatcher and the guard)
  • Workflows (templates that define the steps to execute during a dispatch)
  • Workflow Instances (instances of a workflow template, one of these per dispatch)
  • Workflow Instance Logs (the logs of a workflow instance's execution: assigned-> on the way -> on site -> done)

From Your System Towards TrackTik

In the below diagram, you see a uni-directional flow from a camera based incident based trigger mechanism that then creates Dispatch Tasks in the Trackforce application via its API.

2026-06-05 11_15_20-Partnership Integration - Local Security - Custom Integrations - Trackforce — Mo.png

Every TrackTik Web Portal has Different Data

When planning an architecture to deploy your integration to multiple different TrackTik portals (domains), you need to consider in your data and identifiers lookups and mapping strategies that every portal has a different database, and therefore different configurations and unique identifiers (like the IDs of Dispatches, Client Sites, Report Templates etc.) 

One TrackTik portal might allow the customization of the field clients.customId, while another may not. 

One administrative team of a TrackTik portal might be ok with an integration having its own Report Templates, while another will require that you add extra fields to their existing ones. 

One TrackTik portal might have a regional tree that 5 nodes deep before the Client Sites you intend to work with are seated, so then you have to plan for your solution's UX "how do I handle a regional tree if wanting to provide a Client Site selection tool?" Or another instance might have no regions at all.

Some TrackTik portals can have tens of thousands of Client Sites. How will your UX handle that? What kind of search mechanism will you employ? 

A TrackTik portal may have 60 Report Templates, or 600. Will your solution and possibly UX be scalable?

Luckily, you don't have to pre-map everything and create too many lattices. There is a way to discover the landscape and dynamically get to the minimums of what you need. We'll discuss that next. 

Data/Mapping Prerequisites

To make full use of the API for a Dispatch based integration with any TrackTik portal, you'll need to be able to verify the existence of (and for some, map) the following:

  • Client Sites (sometimes called an "account") (API /clients) exist 
  • Job Types (API /task-types) exist
  • A Report Template exists for the Dispatch Task (API /report-templates), and a report Template has 1:many children of Report Template Fields (API /report-template-fields)
  • A Workflow exists (API /workflows), and when a Dispatch is created, its the template used to spawn Workflow Instances (API /workflow-instances), and the steps of that Workflow Instance that get performed by a guard during a Dispatch will spawn Workflow Instance Logs (API /workflow-instance-logs)
  • OPTIONAL for analytics: an Incident Category (API /report-flags) exists

Regional Context

Almost everything in a TrackTik web portal will be linked to a Region, either directly (like a Job Type), or as a parent to something (like a Client Site that is multiple levels down in a Regional tree, including a parent of Multi-Site with sub-sites). 

2025-08-04 15_24_29-Operation Dashboard — Mozilla Firefox.png

When designing your solution, you need to discover and possibly coordinate if the target Client Sites being dispatched to will all exist in the same region, or be anywhere under the web portal's Regional Tree.

Here are the immediate parent items of your Data/Mapping Prerequisites for awareness and potential filtering by region:

  • Job Type aka Task Type (belongs to a region, but may be set to Global for the web app/mobile app)
  • Report Template (can belong to a region, but may be set to Global for the web app/mobile app)
  • Report Template Field (belongs to a Report Template)
  • Client Site (belongs to a region and possibly also a multi-site).
  • Workflow (can belong to a Job Type aka Task Type)

Here's a comparison of a complex Regional structure (left) vs a simple one (right):

2025-08-04 16_33_32-Dispatch Data Dependencies - Miro — Mozilla Firefox.png

NB: Report Templates can be stand alone or used for multiple purposes, like for Job Types. These multi-purpose report templates are indicated in grey. 

When navigating records in the API, you will typically be able to know which item is "parent" to another when there is a "region", "client" or "account" key in the response. E.g. a /clients record has a "region" key. A /task-types record has a "region" key. 

The Ideal Approach for ID/Mapping discovery

Once you've negotiated the Regional scope during the Business Analysis phase of your approach, you will find that you can start with the Job Types/task-types and derive the most important relationships and data dependencies for creating Dispatches. 

E.g. Regional scope is "all/any", which means no filtering for regions

  1. Obtain a list of task-types in full, or based on a naming convention the Business layer might provide you:
    GET /task-types
    OR with filter
    GET /task-types?name:contains=pattern    OR   GET /task-types?customId:contains=pattern
     
  2. Each of the records in the responses of #1 will have the ID of the Report Template. You can get the IDs of the report-template-fields by iterating through those:
    GET /report-templates/{id}?include=reportFields
     
  3. If the Business layer has told you to expect Report Templates that have a field for an Incident Category (report-flags), then you can get the ID of the report-flag within the reportFields JSON sub-object from step #2, or if they give you a name of a particular report-flag, you can look up its ID directly:
    GET /report-flags?name:contains=name_of_flag
     
  4. If you intend to map to the list of Client Sites in the TrackTik portal, you would get that list like these examples:
    GET /clients
    OR with a naming convention:
    GET /clients?name:contains=pattern OR GET /clients?customId:contains=pattern

NB: Your solution will not need to retrieve a list of Workflows. When a Dispatch gets created, a Workflow Instance is created, and you'll be more interested in the evolution of that workflow being executed,  with the data being found in /workflow-instance-logs . TrackTik's cloud infrastructure can push these out to you via POST method to an API endpoint/webhook you control. That will be discussed later.

After all the above, if your solution is based on a list of predetermined ID numbers or it searches dynamically with patterns, you'll still meet all the data dependencies required to create Dispatch Tasks.

Mapping Opportunities

Whenever two systems are talking to each other, they need an awareness of each other's identifiers in order to match and pair. Through architectural domain management, you'll feel a pressure to want to put your identifiers/foreign keys into the TrackTik application, but as of this writing, the opportunities are not ideal. Many data entities have a field called "customId" which can be used for mapping your identifiers, but these are editable fields to the web application and administrators can edit them if their training or attention paid aren't adequate. Many past partnerships and integrations have used these to great success, but they're not protected fields.

Primary Keys: id

The first thing to know is that any data entity accessible via the API with an "id" key, is the primary key from the database, so it's unique and immutable. You can depend on these.

But remember that each TrackTik web app has its own database, so instance to instance, they will differ. So it might be worth taking the web app's domains into account. If you're integrating with a company.staffr.net and a company2.staffr.ca, the employee.id=12 value of one site won't be the same person as the next. 

Task Types

Task Types have an "id" value, and also a "name" and "prefix" (prefix works like a customId, a string code). You can analyze the business needs vs best approach and negotiate with the TrackTik site administrator about naming conventions and if you can dedicate your solution's identifier to "type of event the camera detected" to the task-types.customId field.

Report Templates

Report Templates have an "id" value, and a "name" and "customId" as well. Same as before, analyze the business needs, what's in use, and what you can use for your solution including the usual talks about naming conventions. This one is less important because if you discover records down from Task Types to their associated Report Templates, there's already a top-down 1:1 made with Task Types. 

Client Sites, Regions, and Accounts (Clients and Regions are types of Accounts, views of Accounts)

For Clients and Regions, you have "id", "company", or "name", but customId is less available. The customId values of these entities tend to already be in use, or are not user editable if the TrackTik web app has been configured to self-manage these.

Regional trees exist but you don't need to map them in most solutions. A dispatch is linked to a Client Site as 1:1, and its data requirements of Task Type and Report are 1:1, and each of those are 1:1 with a region. But verify the business requirements if you need to build a UX with any regional selection, and to validate how the data will be organized within the TrackTik portal. 

Creating a Dispatch Task

You can see that the first API call is to create a Dispatch Task like this:

POST /dispatch-tasks

{
  "priority": "URGENT",
  "client":50,
  "report": {
    "reportTemplate": 28,
    "account": 50,
    "geoLocation": {"latitude" : 45.508, "longitude" : -73.56},
    "reportFields": [
      {"field": 29, "value": "12:30"},
      {"field": 31, "value": "Something undesirable has occurred"},
      {"field": 30, "value": "Interior Patrol"}
    ]
  },
  "startedOn": "20220331122600",
  "taskType": 9,
  "locationType": "ACCOUNT_ADDRESS"
}

NB: In the above the "geoLocation" was added as an example optional extra data (showing that /reports endpoint schema fields are allowed, but it's not required.

In the above payload you can see the integer indexes pointing to the dependencies mentioned previously:

Basic Data

  • Client Site 50 (/clients/50)
  • priority URGENT (an enum, see the API specification documentation)
  • startedOn is a datetime serial of yyyymmddhhiiss (NB: ISO standard, where i is minutes)
  • taskType 9 (/task-types/9)
  • locationType ACCOUNT_ADDRESS (an enum, see the API specification documentation)

Dispatch Task Report (business value information)

  • Report Template 28 (/report-templates/28)
  • Account (report record repeat of Client Site, so /clients/50)
  • Report Template 28 fields list with 1 value for each (/report-template-fields?reportTemplate=28)

More on Report Templates and Their Fields

The TrackTik Guarding Suite application has a Settings section, and Report Template section for creating or editing Report Templates to meet our business needs of initial information collection that should be associated with a Dispatch Task. Just above a reference was made to the report template who's ID is 28. Let's took a look at that:

GET /report-templates/28

{
"name": "Mobile Patrol Report",
"details": "Used to record the details of a completed Mobile Patrol task",
"tag": "",
"adminOnly": false,
"id": 28,
"defaultLanguage": "EN_US",
"translatable": true
}

The data seems small and doesn't mention the list of fields, because this is just the metadata for the Report Template. The fields can be seen through a different endpoint:

GET /report-template-fields?reportTemplate=28

{
            "reportTemplate": 28,
            "parent": {
                "type": "report-templates",
                "object": 28
            },
            "id": 29,
 ==>        "label": "Arrival Time:",
            "name": "f_29",
 ==>        "type": "TIME",
            "required": false,
            "adminOnly": false,
            "displayOrder": 100,
            "extra": "",
            "isDispatcherField": false,
            "fieldTag": "",
            "confidential": false
        },
        {
            "reportTemplate": 28,
            "parent": {
                "type": "report-templates",
                "object": 28
            },
            "id": 30,
==>         "label": "Activity Performed:",
            "name": "f_30",
==>         "type": "LIST_MULTIPLE",
            "required": false,
            "adminOnly": false,
            "displayOrder": 98,
            "extra": "Interior Patrol\nExterior Patrol\nStationary Post\nLocation Inspection",
            "list": [
                "Interior Patrol",
                "Exterior Patrol",
                "Stationary Post",
                "Location Inspection"
            ],
            "listItems": [
==>             "Interior Patrol",
                "Exterior Patrol",
                "Stationary Post",
                "Location Inspection"
            ],
            "isDispatcherField": false,
            "fieldTag": "",
            "confidential": false
        }
  ...etc.

In the above JSON response we see two (of several not shown) fields defined in the Report Template. The first is of type TIME with label/prompt "Arrival Time", and the second is a drop-down list (type LIST_MULTIPLE) to pick a value from a list with label/prompt "Activity Performed".

The "value" key in the Dispatch Task Report section would be a time value (hh:ii) for the first field, and the string "Interior Patrol" (if chosen) would be the value for the second.

You should look at other report-template-fields in your web portal's records to see other types that are possible and familiarize yourself.

Workflows

When you create a Dispatch Task an instance of its Workflow (if one is configured for the Task Type) is also created. The Workflow Instance that gets created can be looked up as a relation list of Dispatch Task:

GET /dispatch-tasks/653?include=workflowInstance

{
        "customId": "2024-12-13-15-37",
        "taskType": 3,
        "priority": "URGENT",
        "priorityRating": 2,
        "taskInstructions": "",
        "scheduled": "NOW",
        "startedOn": "2024-12-13T20:31:00+00:00",
        "startDateTime": "2024-12-13T20:31:00+00:00",
        "endedOn": null,
        "endDateTime": null,
        "plannedDurationInMinutes": null,
        "reminderInMinutes": null,
        "reminderAt": null,
        "alarmOrganization": null,
        "client": 687,
        "account": 687,
        "priceTier": null,
        "status": "OPEN",
        "active": "ACTIVE",
        "assignedUser": null,
        "assignedGroup": null,
        "assignedGroupResource": null,
        "assignedVendor": null,
        "reportTemplate": 28,
        "report": 6180,
        "location": 78,
        "locationType": "ACCOUNT_ADDRESS",
        "closedOn": null,
        "parentDispatchTask": null,
        "alarm": null,
        "id": 653,
 ==>    "workflowInstance": {
            "currentStatus": 11,
            "workflow": 2,
            "modifiedOn": "2024-12-13T20:39:52+00:00",
            "startedOn": "2024-12-13T20:39:52+00:00",
            "dispatchTask": 653,
==>         "id": 590
        }
    }
  

The Workflow Instance who's ID is 590 in the sample payload above is the ID to retain to be able to follow the journey of the Dispatch Task through its Workflow Instance's steps.

These steps are accessible like this:

GET /workflow-instance-logs?workflowInstance=590&include=status

{
            "user": 1002,
            "timeZone": "America/New_York",
            "createdOn": "2024-12-13T16:01:14+00:00",
            "workflowInstance": 590,
            "id": 2181,
            "status": {
                "name": "New Alarm",
                "tag": "New Alarm",
                "workflow": 2,
                "formatBackgroundColor": "Black",
                "formatTextColor": "WHITE",
                "warningThresholdInMinutes": 1,
                "alertThresholdInMinutes": 5,
                "id": 11
            }
        },
        {
            "user": 1002,
            "timeZone": "America/New_York",
            "createdOn": "2024-12-13T16:04:36+00:00",
            "workflowInstance": 590,
            "id": 2182,
            "status": {
                "name": "Assigned",
                "tag": "Assigned",
                "workflow": 27,
                "formatBackgroundColor": "red",
                "formatTextColor": "black",
                "warningThresholdInMinutes": 1,
                "alertThresholdInMinutes": 5,
                "id": 12
            }
        }
  

This hopping through Dispatch Task -> Workflow Instance -> Workflow Instance Logs is important to understand when deciding to use the API to advance a Workflow through additional transitions (if you need to do that procedurally instead of as manual tasks performed by guards and administrators), and/or if you intend to make call-outs back to your system using a webhook -- more on that later in the section titled From TrackTik Towards Your System.

Creating Workflows and Transitions

Workflows are the sequence of possible steps a guard assigned to a Dispatch Task will follow (in part or in full). The TrackTik web application offers an easy to use graphical interface based approach to creating these, but they can be created with the API as well.

See this guide: https://support.tracktik.com/hc/en-us/articles/23863495183511-Workflows-and-Transitions-Create#workflows-and-transitions-create-0-0

Advancing Workflows

Normally it's administrators and guards that advance steps through a workflow to its termination (early or after full completion), but the transitions and workflow steps can be triggered by API as well.

See this guide: https://support.tracktik.com/hc/en-us/articles/23795058188439-Dispatch-Tasks-Workflow-Subscriptions-Advancing-a-Workflow-Adding-a-Note#Advancing-a-workflow-to-another-step

From TrackTik Towards Your System

So far we've looked at the flow of information and executing steps that advance business processes that are administered from and within the TrackTik software. But for your System to participate in the process AFTER the creation of a Dispatch Task (or other step), you need to be able to monitor the evolution of a dispatch/response and that is done by receiving data from TrackTik.

TrackTik can send information to an API webhook that you define and control, as an inherent feature of your system or middleware software that you write yourself (by hand, cloud service, whatever your preferred architecture.) Whatever solution your system uses, it must be a webhook that is REST API based and can receive POST methods with JSON payloads.

The TrackTik service that makes POST/call-out calls to your REST API webhook is called Events Subscriptions. There is a dedicated API endpoint for configuring these call-outs in terms of client ID and secret, email notifications, triggers, filters, payload shaping and the retry mechanism.

Consult the Events Subscription guide ( https://support.tracktik.com/hc/en-us/articles/24446820229911-Events-Subscriptions-aka-Call-outs-Webhooks ) to become familiar with its full capabilities before continuing with the rest of this guide.

Two Strategies

When you create a Dispatch Task, and its Task Type creates an instance of its assigned Workflow, and you want to capture data related to the journey of the steps that Workflow follows in your own system as a call-out to your webhook, you need to make an implementation strategy decision:

(A) I want to have a separate Events Subscription for each Workflow Instance, making sure to create the subscription myself, collect its data like the Dispatch Task and Workflow Instance and Workflow Instance Logs by using a filter on Dispatch Task and Workflow Instance IDs, until the Workflow Instance completes its journey, and then retire/halt the Events Subscription.

OR

(B) I want to subscribe to ALL Workflow Instance lots via a single Events Subscription, and I'll aggregate data in my system on the Dispatch Task ID, Workflow Instance ID and Workflow Instance Logs IDs."

Most of our partners who configure an Events subscription don't want the overhead of having to create/retire Events Subscriptions over and over again because the administration and recovery complexity is much more complex because there are so many different subscriptions.

Almost everyone chooses approach (B), and it's also what we recommend.

Best Strategy: subscribe once, capture all, aggregate in your own system

To subscribe to all workflow-instance-logs and then link the Dispatch Task and its Workflow Instance on your system's end, you will need to monitor its created and updated triggers.

An example configuration you can POST to the /events-subscriptions endpoint is below:

{
        "customId": "WFI-ANY",
        "name": "Steps progression of any Workflow Instance",
        "events": [
            "entity:workflow-instance-logs:created",
            "entity:workflow-instance-logs:updated"
        ],
        "entityResponse": {
            "include": [
                "status",
                "user",
                "workflowInstance"
            ]
        },
        "contextFilters": {
            "filters": [
                {
                    "tag": "context.*",
                    "includeChildren": true
                }
            ]
        },
        "url": "https://webhook.site/fd152...",
        "failureEmail": "fd152...@email.webhook.site",
        "secretHeaderName" : "TrackTik-subscription-secret-without-spaces",
        "secret" : "B2C6011...."
    }
  

The "what triggers a call-out to my system" portion are:

"events": [ "entity:workflow-instance-logs:created", "entity:workflow-instance-logs:updated" ]

And the include object is merely to add detail (via 3 relation lists, like joined sub-queries) to the payload to include more information that isn't provided by default.

context.region.* is to tell the subscription to commmunicate all events that occur under all regions, otherwise the * would be the region.id value to restrict the call-outs to just events from that region.

includeChildren is to tell the subscription to also trigger for all events for children regions under its parental context.

customId and name are descriptive field you can decide.

url is the address of your webhook/listener.

failureEmail is where error messages should be sent to.

secretHeaderName and secret are for authentication with your webhook/listener.

For additional configuration of the events subscription, refer to the stand-alone guide mentioned earlier.

OPTIONAL:

  • If you want to monitor the parent Dispatch Task for any updates, you can create a second Events Subscription for entity:dispatch-tasks:updated, or include it as a relation list within the subscription of the workflow-instance-logs by adding another line to the includes array by using a dot member like workflowInstance.dispatchTask

Common Problems and Solutions

You're having difficulty retrieving the list of Task Types or Report Templates

This means you've applied a regional filter that is omitting what you need, or the data you're working with has not been organized (via regional contexts) in a way that your solution expects. 

Discuss what regions the data dependencies belong to with the Business layer, with administrators who configure the TrackTik portal. 

You need to supply more information in the Dispatch Task Report than the Report Template allows

First, you'll know exactly how many fields you have and their ID numbers by having Business folks tell you which Task Types to use, which have data that list the 1:1 connection to a Report Template. And like it's described earlier in this guide, you can lookup its total number of fields and their datatypes with:

GET /report-templates/{id}?include=reportFields

You can work with the Business layer, and administrators of the TrackTik portal, to extend the current templates to accommodate more data, or they can help set up a new Report Template that is more dedicated to your solution.

 

Was this article helpful?
0 out of 0 found this helpful

Articles in this section