
HaloCRM Guides
Custom Integrations/Runbooks
In this guide we will cover:
- Building blocks of runbooks
- Runbook Statistics
- Worked Example
- Actions that can be completed through the API
- Using Previous output variables in subsequent steps
The Building Blocks of Runbooks
Authentication an triggering a runbook
Head to Configuration > Integrations > Custom Integrations > Integration Runbooks and create a new runbook. When creating a new runbook, you will be prompted to input a name for the runbook.
You can then set the 'Runbook Start Access' this will determine where this runbook can be started (triggered) from.
Can only be started from Halo - Choose this option when you would like the runbook to only be able to be started from an even that occurs within this Halo instance, such as using an action, event or workflow in Halo).
Can only be started from Halo and from a public endpoint - Choose this option when you would like the runbook to only be able to be started (triggered) by an event that occurs within Halo, but you would also like events from other applications to be able to trigger this runbook.
Triggering Runbooks
Runbooks triggers control when a chosen runbook will be 'triggered' to run and have it's flow begin. There are various ways to trigger runbooks.
Starting Runbooks from a Public Endpoint
When this option is selected as the 'Runbook Start Access' it can be triggered when an external application posts to the given URL. When enabled you will be provided with the URL that the POST most be sent to to trigger this runbook.
Fig 1. URL to post to to start this runbook
When starting runbooks this way (externally), you can choose how the incoming request is authenticated using the "Authentication" field.
- No Authentication: Anyone will be able to trigger this runbook by posting to this URL (not recommended)
- Basic Authentication: Enter a username and password against the runbook in Halo, the incoming request to trigger this runbook must contain this username password in order to be authenticated.
- Validate Signature using signature key: Allows you to authenticate the runbook using a signature and secret key. You will need to enter the details of the secret key and signature in Halo, using the fields shown in figure 2.
- Halo API Bearer Token: Allows you to authenticate the runbook using a bearer token.
- Secret in Header: Allows you to authenticate the runbook using a parameter and secret value.
- Secret in URI Parameter (v2.210.1+): Works similarly to webhook authentication within Integrations. Allows you to authenticate the runbook using a parameter and secret value.
Fig 2. Fields to allow runbook start to be authenticated using secret key
You can specify request headers to include in the signature when validating an inbound payload to start a Runbook. Any header names can be added here and they will be pre-pended to the payload when verifying the signature.
You can also use a timestamp to authorise the request starting this runbook. The request will need to contain a timestamp in RFC1123 date standard format (E.G "Tue, 29 Apr 2025 11:25:12 GMT"). specify the name of the request header this timestamp is contained in in the 'Timestamp header name' field in Halo. Halo will then validate that header is present and the value has is a valid timestamp which is within 1 minute, only then will the request be authenticated.
Trigger based on an event in Halo
To have a runbook triggered automatically when a certain event occurs in Halo you will need to set an 'Event' against the runbook.
Scroll down to the 'Events' section within the runbook details. Here you can add an event to the table to determine which event will trigger this runbook.
Fig 3. Runbook events.
Once you have chosen an event additional criteria can be added to narrow down when the runbook is triggered. In the figure 4 example the runbook will only trigger when a new ticket is logged and the primary asset linked to the ticket includes one of the selected assets.
Fig 4. Example trigger criteria.
Trigger from an Action
To have a runbook trigger when a particular action is used on a ticket you will need to configure an action with the system use 'Send Webhook/Queue Integration Runbook'. Useful when you would like to manually run the runbook.
Head to Configuration > Tickets > Actions > new, set the system use to 'Send Webhook/Queue Integration Runbook' then choose which runbook you would like to be triggered when this action is used.
Fig 5. Action to trigger runbook.
Now just ensure you add this action to the relevant workflows.
Trigger from a Custom Button (v2.212+)
From v2.212+ (Beta) and v2.208.61 (Stable) custom buttons can be configured to start a runbook. Allowing you to manually trigger a runbook outside a ticket. This is supported for custom buttons for the following entities: Client, Site, User, Device, Quotation, Purchase Order, Invoice. From v2.208.91 (Stable) or v2.214 (Beta) this is also supported for custom button for Sales Orders.
Head to Configuration > Custom Objects > Custom Buttons > New, when creating the button set the 'Button Use' to 'Start a Runbook'. Then choose the runbook to start.
Fig 6. Custom button to start a runbook.
Step Setup
Once you have saved your Custom Integration, the flow chart tab will become available.
The flow chart tab will contain each step of your runbook, each step will control which action is carried out and when, the outcome of the step will then determine which step will be executed next.
When adding a step you will need to choose the 'Type' of step it is.
Fig 7. Step type
Condition - Will allow you to configure a step that evaluates data. If the condition is met the runbook will move to step x, if not met it will move to step y.
Action - Will allow you to configure a step that carries out an action. Various actions can be executed, this could be making a POST/GET request to a specified endpoint.
Halo API Actions
We have some pre-configured actions available for you to use in Runbooks out of the box, these are called 'HaloAPI' actions. These are used to make requests in your own Halo instance, useful for obtaining data from your instance or updating your instance. When using these actions you do not need to setup any additional authentication as this is built into the actions.
To use these actions set the step type to be 'Action' and the 'Action type' to be Halo API Action'. You will then be given a choice of actions that can be used in the 'Action' field.
Fig 8. Halo API actions
'Create' actions - Will make a new entry for the entity specified. For example when 'Create Ticket' is chosen a new ticket will be created in your instance with the specified information.
'Update/Edit' actions - Will make changes to an existing instance of the entity specified. For example, when 'Edit Site' is chosen an existing site will be updated with the specified information.
'Get' actions - Will retrieve data from your database for the entity specified. For example, 'Get Customer' will get all the information from the Clients endpoint of the Halo API. This data can then be stored as output variables to be used in later steps of the Runbook.
When an action is chosen that is creating/updating/editing an entity, you will be provided with a default JSON body.
Fig 9. Default JSON body for Halo API Action to update a ticket
This provides a template for the request the action will make. You will need to edit the body here in line with the request you would like to make. For example, if you would like a specific field on the ticket to be updated with a set value, the JSON key for this field and the value will need to be included in the request.
To find out which JSON key is needed to update the desired fields, checkout our API documentation, found under configuration > Integrations > Halo API > API Documentation.
Fig 10. Access API documentation
Halo API actions are useful for completing straightforward requests into your own instance. If you are looking to make a request elsewhere, you will need to configure an integration method.
Methods
Methods define a series of different API requests that can be made for a given custom integration. Each Method allows you to
- specify a HTTP Method (GET, POST, PUT etc..)
- Send requests to a particular endpoint.
- Include Query Parameters for the requested resource.
- Include request headers, and a request body (if the HTTP method permits).
- Specify Output variables, which can be used further on down the road.
Fig 11. Method
In the below example, I am making a request to the Completions endpoint of OpenAI's API. Authentication is already handled by the fact that I have selected my 'Integration' as 'OpenAI' (& already added in the bearer token in the previous step). As I am making a POST Request, I am permitted to include a Request Body.
Fig 12. Request body example
Click 'Test' to make sure you get a successful response & to check the response body.
Fig 13. Response body following test
Output Variables
The chances are you are not going to want the entire response body, but only particular parts of the response. In the above example, I'm really only concerned with the 'Text', within the 'Choices' array.
Output variables can be used, to define a particular part of a response body. Variables can either be setup at the runbook level, or at the method (step) level.
Runbook level variables are setup under the 'Details' tab of the runbook, here variables can be configured using data that is available when the runbook is triggered. Method level variables are configured against the method used by the runbook, here variables can be configured using data that is obtained from the method at this same step.
Fig 14. Output variables example
There are some details in this window outlining the required syntax, the key points are:
- Variables must start with response.
- Child properties are referenced using ^
- Arrays can be indexed using [x]
- Conditions can be added to return a specific object in an array where prop=value via [prop=value], i.e: response[id=123]
- Append ! to your variable value to remove the leading/trailing " character from the value.
Continuing with the above example, I am looking to return the 'Text' from the 'Choices' array of the response. So my output variable would look like:
response^choices[0]^text
Now when testing my method, I will also be able to see what my Output Variable returns.
Fig 15. Output variable in response body
Runbook methods can support responses that are plain text. If the response is not JSON or XML, then it is treated as plain text.
These plain text responses can also be used in lookups by setting the lookup field to "response".
Fig 16. Lookup from a runbook.
Filtering output variables for greater than, less than and contains
You can apply greater than, less than and contains conditions to output variables. Output variables can be filtered further to find a specific object in an array based on the property containing a specified value, being greater than a specified value or less than a specified value. This allows you to obtain an object relative to set values.
[prop>value] and [prop<value] can be used to find a specific object in an array based on a property being greater than or less than a value. For example, <<response^user[id > 50 ]>> will only return users in the response that have an ID above 50.
[prop contains value] and [prop !contains value] can be used to find a specific object in an array based on a property containing or not containing a value. For example, <<response^customfields[name contains Additional Info]>>. This will return the custom field(s) in the response that contain the string 'Additional Info' in their name.
See runbook level variables in the UI (v2.200+)
From v2.200+ the current value of a persistent runbook variable can now be seen and reset from the runbook variable configuration screen. Useful to store and reference information about this runbook.
This functionality can be enabled against each runbook level variable, as shown in figure 17.
Fig 17. Option to persist the value of this variable between runs of this runbook
When enabled, the value of this variable during the last run of the runbook will be visible from here.
Triggering Multiple instances of the same runbook - Runbook Execution modes
If your runbook is triggered multiple times in a short space of time, that is the next instance of the runbook will be triggered before the previous instance has finished it's run/completed, you will need to consider the execution mode of your runbook.
On versions prior to v2.190 runbooks will always run in parallel. This means if the same runbook is triggered again before the previous run is finished, the next run will begin at the same time. Two or more instances of the same runbook will execute in parallel.
On versions v2.190+ you can choose whether runbooks instances execute in series or in parallel. Navigate to the details tab within the runbook > advanced section > see 'Runbook execution mode'.
Fig 18. Runbook execution mode
Parallel - When selected if the same runbook is triggered again before the previous run is finished, the next run will begin at the same time. Two or more instances of the same runbook will execute in parallel.
Series - When selected if the same runbook is triggered again before the previous run is finished, the next run will not begin until the previous run has finished. Two or more instances of the same runbook will not run at the same time, they will run in the order they were triggered. This should be used when the runbook relies on a previous result of a previous run.
There is another option here to auto-disable the runbook if it fails a certain number of times in a row. This is enabled per runbook, and defaults to be disabled. It is recommended to set this to 3-5 times so if the runbook is misconfigured, it does not continue to loop.
Fig 19. Auto-disable threshold.
Runbooks can also send a notification or email when they fail. Upon enabling the runbook notification, agents with the preference to be sent error notifications will receive these, and an additional option to send an email will show as of v2.204.1+. This can be set to "Don't Send", or an agent can be set here to receive the email.
Fig 20. Runbook failure notification.
Runbook Statistics
Each runbook will have a number properties tracked, these statistics will be visible under the details of the runbook.
Fig 21. Runbook statistics
Average steps executed - This is the average (mean) number of steps within the runbook that have been executed (successfully or not) within the last 30 days.
Maximum steps executed- This is the most number of steps within this runbook that have been executed in one run in the last 30 days.
Average execution time - This is the average time the runbook took to execute within the last 30 days.
Maximum execution time - This is the longest time the runbook took to execute within the last 30 days.
Runs in the last day - The number of times the runbook has run in the last 24 hours.
Runs in the last week - The number of times the runbook has run in the last week.
Statistics per run
Statistics are also available per instance of the runbook (each time it is triggered). You can currently see statistics for the number of steps that were executed in this run and the time it took to execute.
To see these statistics head to the 'Log' tab of the runbook select the log that corresponds to the instance/run of the runbook you would like to review. Select the log entry > Log tab > statistics are visible here.
Fig 22. Statistics for individual runbook instance
Worked Example- Post a response from ChatGPT into the ticket
Now we have an understanding of the building blocks towards creating a 'Custom Integration' (i.e.: we can make requests to protected endpoints and create output variables from response data), let's look at tying multiple methods together via Runbooks.
Runbooks are similar to Ticket Workflows, in that you have a flow chart composed of 'Steps'. The core difference is instead of each step containing Ticket Actions, they contain Custom Integration Methods.
Let's build on the previous example to create the following functionality:
"I want to create an Action - 'Ask ChatGPT a Question' - that takes the contents of the note field from the action as the question/prompt and posts ChatGPT's response back to the Ticket"
Functionally, this would be composed of 2 Methods:
- An initial POST to OpenAI's API
- We will want to do this from a Ticket via an Action & set the Prompt based on the Action text.
- A Post back to our own API
- This Post should create an Action on the same ticket with the text being OpenAI's response text to our Prompt.
We have already seen how to create the first request, the only difference would be that our prompt should now take the note of the Action it will be triggered from. This can be handled by using a variable for the 'Prompt'.
Fig 23. using variable for prompt
To POST back "ChatGPT's" response to the Ticket in question, you would have to create a 'Custom Integration' to your own instance's API.
Fig 24. create new custom integration
The method required for this example would be a POST request to '/api/actions', passing in the Ticket ID as a variable & utilising the previously created Output Variable - 'ResponseText'.
Fig 25. Method required
So we now have the two methods required for our 'Integration', next is to tie them together in a Runbook.
Head to the 'Integration Runbooks' section of the Custom Integration configuration. Upon creating a new Runbook, you will first be presented with the 'Details' tab. In here, you can establish a 'Runbook Start Access' & specify events that can occur in Halo that would trigger the Runbook.
Fig 26. Runbook start access
These trigger events have been added:
- Feedback Added
- Stock Received
- Stock Removed
- Recurring Invoice Created
- Recurring Invoice Updated
- Recurring Invoice Deleted
Runbook Start Access has two options:
- Can only be Started from Halo - This option will mean that Runbooks can only be triggered from an Action, Event or Workflow.
- Can only be Started from Halo and from a public Endpoint - When this option is selected, some new configuration options will be presented.
Fig 27. Runbook can only be Started from Halo and from a public Endpoint
Firstly, a URL will be presented. This is the URL that would need to be called, if triggering the runbook from outside of Halo. this URL will only accept POST requests. Note: If triggering a runbook from an external source, Ticket variables cannot be used.
You can also specify an authentication method required for the POST to this endpoint. Current methods include Basic Auth & Signature Validation via Secret Key. Below this Authentication option, you will see an 'Input Variables' table - this table will allow you to create variables from the initial payload of the POST request, that can be used in subsequent methods within the Runbook (the variables established here are only valid when the Runbook is triggered from the external source).
You will also see a 'Flow Chart' tab - this is where you construct the Runbook logic. Similar to Ticket Workflows, the Flow Chart of a Runbook is composed of 'Steps', where each Step corresponds to a Condition or Integration method. Conditions being met or integration Methods returning successful responses can then move the runbook to a new step in the flow chart.
Lets look at the Runbook Flow Chart for our Custom Integration.
Fig 28. Runbook flow chart
Again, our custom Integration is composed of two methods:
- An initial POST to OpenAI
- A POST back to our own API with ChatGPT's response.
So we can see here that our initial step, 'Ask Question', is configured such that we are executing an Integration Method - Post Completions. If we get a successful response, we then move on to our next step.
Fig 29. Step example
In the next step, we are executing a different method - 'Post ChatGPT Action to Ticket'.
Finally, we need to see how the Runbook is actually triggered. In this example, we are Triggering the Runbook from an Action in Halo. The Action is configured such that the System Use is 'Queue Webhook/runbook', at which point you can select the Runbook to queue.
Fig 30. Runbook trigger
Halo API Actions
Direct changes can be made to your Halo instance via runbooks. The following can be achieved by using the Halo API action on a runbook step:
These are the actions which can be added to a runbook
- Create Customer
- Edit Customer
- Create site
- Edit Site
- Create User
- Edit User
- Create Asset
- Edit Asset
- Create Lookup
- Edit Lookup
- Create Knowledge Base Article
- Edit Knowledge Base Article
- Edit Custom Table Data
- Create Ticket rule
- Edit Ticket Rule
- Get Control (Global Settings)
Action Configuration
This can be configured within the runbook step by using the following.
Fig 31. Action configuration
After the action has been set on the single select field "Create Customer" The name can be added to the JSON (The JSON will auto populate based on the action chosen)
The next step is to create an action to execute the runbook (make sure to add this to the workflow if your ticket contains one, or add it to the Allowed actions if there are restrictions set on actions).
Fig 32. Action to execute Runbook
Then this can be actioned from a ticket to create the customer.
Fig 33. Using action to execute runbook
Checking our customer list, we can see that the new customer is there.
Fig 34. New customer made
Another type of action that can be achieved could be the one explained in the rising tide video on this guide, it covers "Marking a ticket as spam via a runbook". This is achieved using the "Update Ticket" action shown in the Halo API actions list above.
All of the keys that can be added to the "Actions" JSON Body can be found in the dev tools using "Fn + F12".
Fig 35. Keys visible in dev tools
An example JSON Body for creating an action via a runbook, as you can see the "note_html" on the dev tools is shown on the JSON Body as well, this is where the note would go for the action being created.
Fig 36. Example JSON body for creating action via runbook
Use Previous output variables in subsequent steps
There is the ability to use previous output variables from custom integration methods, as part of the subsequent steps.
Set up a custom integration runbook and create a method for it. Then use this variable in a subsequent method of the runbook. Adding the custom integration method's variable here.
Fig 29. Custom integration method's variable
Then use the custom integration variable as part of the next method.
Fig 37. Variable being used in following method
Encryption (v2.208+)
New features have been introduced to Custom integrations and Runbooks to handle sensitive data like passwords and secrets more securely. These are used when building a custom authentication method for an integration as it allows authentication tokens/keys to be stored more securely.
Disclaimer: We always recommend configuring a custom integration to authenticate requests where possible as this is more secure than implementing your own authorisation flow.
1. Encrypt Custom Integration method Query Params, Headers, and Body Mappings
Custom integration methods will now have an "Encrypt?" checkbox in the tables for Query Params, Headers, and Body Mappings (for x-www-form-urlencoded). Checking this will encrypt the value in the database and not reveal it in the client. It's value will also be obfuscated in the request logs and runbook logs.
Fig 38. Encrypt Query Parameter
The method's base Resource URL is a factor in the encryption, meaning that changing the URL will invalidate all encrypted values for optimal security.
2. Encrypt the Response body on Custom Integration Methods, Halo API Actions, and Execute SQL Actions
The "Encrypt response body" option will show on the Advanced tab of a Custom integration method.
Fig 39. Encrypt response body
The same option also shows when configuring Halo API Actions or Execute SQL options.
Fig 40. Encrypt response body
When this is active the Response body of the request will be encrypted in the database and no longer show in the Request logs or Runbook logs. Additionally, any Runbook-level variables that use encrypted responses will also be encrypted in the database and no longer show in the Request logs or Runbook logs. Any subsequent requests that use an encrypted response variable will have their Request Headers and Request Body removed from the logs.
3. Encrypt the Request body of the Request that triggers the Runbook
The "Encrypt the Request Body and Headers" checkbox now shows on the Runbook configuration screen when the Runbook can be started from a public endpoint.
Fig 41. Encrypt the request body and headers
When enabled this will remove the Request headers from the log, and encrypt the Request body in the database. Additionally, any Runbook variables that are calculated from the initial request body will also be encrypted in the database and no longer show in the Request logs or Runbook logs. Any subsequent requests that use the <<request>> variable will have their Request Headers and Request Body removed from the logs.
4. Encrypt a Runbook-level Variable
Individual Runbook-level variables now have an "Encrypt?" option.
Fig 42. Encrypt runbook level variable
This can be used when a Runbook-level variable holds information that is constant. There is no need to set this unless the variable itself holds a password/secret by default - if the variable gets set based on the request/response from a method that has it's body encrypted then it follows that the runbook-level variable will be encrypted automatically without this option enabled (from features 2 and 3).
It encrypts the value in the database and prevents it from being shown in config, and any requests that use an encrypted variable will have their Request Headers and Request Body removed from the logs.
Fig 43. Encrypted request
Fig 44. Encrypted response
Popular Guides
- Asset Import - CSV/XLS/Spreadsheet Method
- Call Management
- Creating Agents and Editing Agent Details
- Creating API Applications
- Departments and Teams
- Halo Integrator
- Importing Data
- Multiple New Portals with different branding for one customer [Hosted]
- NHServer Deprecation User Guide
- Organisation Basics
- Organising Teams of Agents
- Step-by-Step Configuration Walk Through



