Webhooks API

Webhooks are used by organizations to keep other applications in sync with their ITRP accounts. Scripts that are published on public web servers (i.e. servers that can be accessed from the internet) can be called by webhooks in near real-time to collect data from ITRP and to use this data to update an external application (or to perform an update in ITRP itself).

What are webhooks?

Webhooks are a way to tell ITRP to call a script on a web server whenever a given event occurs in ITRP. A script is typically developed to execute specific actions for an organization that uses ITRP. The organization for which such a script was developed normally hosts it on one of its own web servers.

Some possible uses for webhooks include:

Registering webhooks

Webhooks can be created in an organization’s ITRP account by going to SettingsWebhooks in the ITRP application, or with the ITRP Webhooks API.

Select the event that needs to be listened to from the select box, and enter the URI that needs to receive the call from the webhook.

Once a webhook has been registered, ITRP issues an HTTP POST call to the URI specified in the webhook every time the selected event occurs.

Webhooks are asynchronous events. They usually get sent quickly, but sometimes there can be a small delay.

ITRP calls the specified URI every time the event happens. This means that if, for example, a bulk-upload of 1,000 tasks is performed, the webhook is called 1,000 times if its selected event is task.create.

Webhook contents

Webhooks are sent as HTTP POST calls to URIs with a form-encoded body (with Content-Type: application/x-www-form-urlencoded) for easy parsing in almost any programming language. All webhook callback bodies contain the following parameters:

webhook_id
The ID of the webhook registered in ITRP.
account
The url of your organization’s ITRP account.
name
The name of the webhook that got fired.
event
The event of the webhook that got fired.
object_id
The id of the ITRP record that triggered the event. Use this id to make an ITRP API call to retrieve further details if needed.
person_id
The id of the person that triggered the event. This field is empty if the trigger was caused by a system event.
person_name
The name of the person that triggered the event. This field is empty if the trigger was caused by a system event.
payload[audit_line_id]
The ID of the audit entry that ITRP generated for the creation or update of the ITRP record that triggered the event. This parameter is included only when the event caused an audit entry to be generated. The addition of a note, or specifying a value in the Time spent field, does not cause an audit entry to get generated.
payload[source]
The source of the ITRP record that triggered the event. This parameter is not included if the Source field of the ITRP record that triggered the event does not contain a value.
payload[sourceID]
The source ID of the ITRP record that triggered the event. This parameter is not included if the Source ID field of the ITRP record that triggered the event does not contain a value.
payload[status]
The status of the ITRP record that triggered the event. This parameter is not included if the ITRP record that triggered the event does not have a Status field.
payload[previous_status]
The status of the ITRP record before its status was updated, causing the event to be triggered. This parameter is included only for the events request.status-changed, problem.status-changed, change.status-changed and task.status-changed.
payload[team][id]
The ID of the team that is linked to the ITRP record that triggered the event. This parameter is not included if the type of ITRP record that triggered the event cannot be assigned to a team.
payload[team][name]
The name of the team that is linked to the ITRP record that triggered the event. This parameter is not included if the type of ITRP record that triggered the event cannot be assigned to a team.
payload[team][sourceID]
The source ID of the team that is linked to the ITRP record that triggered the event. This parameter is not included if the Source ID field of this team does not contain a value.
payload[team][disabled]
The Disabled checkbox value of the team that is linked to the ITRP record that triggered the event. This parameter is not included if this team is enabled.
payload[team][account][id]
The account ID of the team that is linked to the ITRP record that triggered the event. This parameter is included whenever the ITRP record that triggered the event can be assigned and has a value in its Team field.
payload[team][account][name]
The name of the account of the team that is linked to the ITRP record that triggered the event. This parameter is included whenever the ITRP record that triggered the event can be assigned and has a value in its Team field.
payload[member][id]
The ID of the person who is selected in the Member field of the ITRP record that triggered the event. This parameter is included whenever the ITRP record that triggered the event has a value in its Member field.
payload[member][name]
The name of the person who is selected in the Member field of the ITRP record that triggered the event. This parameter is included whenever the ITRP record that triggered the event has a value in its Member field.
payload[member][sourceID]
The source ID of the person who is selected in the Member field of the ITRP record that triggered the event. This parameter is not included if the Source ID field of this person does not contain a value.
payload[member][disabled]
The Disabled checkbox value of the person who is selected in the Member field of the ITRP record that triggered the event. This parameter is not included if this person is enabled.
payload[member][account][id]
The account ID of the person who is selected in the Member field of the ITRP record that triggered the event. This parameter is included whenever the ITRP record that triggered the event has a value in its Member field.
payload[member][account][name]
The name of the account of the person who is selected in the Member field of the ITRP record that triggered the event. This parameter is included whenever the ITRP record that triggered the event has a value in its Member field.

In addition references to URIs of interest are provided via the Link http header. The following relation types might be received:

canonical
URI to the affected resource viewable via the ITRP UI application.
resource
URI to the affected resource viewable via the ITRP API.
related
URI to a related affected resource viewable via the ITRP API. For example, if a note was added to a request, then this points to the note details. The link with relation type resource points to the request in this example.

Request

POST /mywebhook HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: myserver.example.com
User-Agent: ITRP/1.0 (https://developer.itrp.com/v1/webhooks)
Link: <https://mycompany.itrp.com/requests/219>; rel="canonical",
      <https://api.itrp.com/v1/requests/219>; rel="resource",
      <https://api.itrp.com/v1/requests/219/notes/3455>; rel="related"
webhook_id=945&account=https%3A%2F%2Fmycompany%2Eitrp%2Ecom&event=request%2Enote-added&object_id=219&person_id=8543&person_name=Howard%20Tanner&payload[source]=self%20service&payload[status]=change_pending&payload[team][id]=372&payload[team][name]=End-User%20Support%2C%20Houston&payload[member][id]=8529&payload[member][name]=Tom%20Edwards

which in JSON format equals:

{
  "webhook_id": 945,
  "account": "https://mycompany.itrp.com",
  "name": "Note added to Request of mycompany",
  "event": "request.note-added",
  "object_id": 219,
  "person_id": 8543,
  "person_name": "Howard Tanner",
  "payload[source]": "self service",
  "payload[member][name]": "Tom Edwards",
  "payload[member][id]": 8529,
  "payload[status]": "change_pending",
  "payload[team][id]": 372,
  "payload[team][name]": "End-User Support, Houston"
}

Expected response

Make sure the status code of the response is between 200 and 299 ( preferably 200 OK ) which indicates success. ITRP simply discards the rest of the results of the webhook.

The webhook request to the web server on which the script is hosted times out after 10 seconds. Move long running processes (e.g. PDF generation) into an asynchronous background task and make sure that the script responds immediately to the ITRP server.

Failed callbacks

If ITRP receives anything other than a 2xx HTTP response code (likely meaning that the script has been moved, is non-existent, or misconfigured) or requests to the web server times out, ITRP retries the HTTP POST call periodically. After several failures, the message is dropped and no further delivery attempts are made. Email notifications are sent out for these exceptions. By default, these exception notifications are sent to each person who has the Account Administrator role of the account in which the webhook is registered.

Automatic disabling

A webhook can be temporarily disabled. In addition, ITRP automatically disables a webhook when there have been 20 consecutive failures for the exact same webhook over a period longer than a week. The details of the disabled webhook (viewable via the ITRP application or via the Webhooks API) then include the last error as received by ITRP.

Security considerations

As ITRP needs to call a script on a server of a different organization via a publicly available connection, there is a potential vulnerability to hacks on that server.

Verifying a webhook

The easiest way to verify a webhook is by adding a secret query parameter to the URI, and then to have this parameter checked by the script.

In addition, it is possible to use basic http authentication by providing the username:password in the webhook URI, like this:

https://myuser:mylogin@myserver.example.com/mywebhook

Lastly, ITRP always sends the ID of the webhook as part of the response, which could also be used in a verification step. The ID of a webhook can be found by selecting the webhook in the ITRP application and looking at the number that is visible in the address bar of the browser, and/or via the ITRP Webhooks API.

Testing webhooks

Testing that a webhook works can be a bit of a challenge. Thanks to RequestBin this has been made quite simple.

Setting up

First, be sure to have the Account Administrator role within the ITRP application.

Then visit RequestBin and click “Create a RequestBin”. Copy the URL that is then shown in the header:

RequestBin created

Within the ITRP application go to SettingsWebhooks. Add a new Webhook, select for example “request.update” from the Event select box, and paste the RequestBin URL into the URI field:

Webhooks form

Save this webhook.

Testing the webhook is fired

To test that the webhook fires simply create a request and update it. Check if the webhook fired by refreshing the RequestBin page:

Webhooks form

Example conversation

In the example below a webhook test is performed using the command line tool curl. This example shows how to test a webhook without actually modifying any data in ITRP.

Setting up

First create a webhook:

$ curl -v -u "API-TOKEN:x" -X POST \
       -d '{"event":"request.create", "uri":"http://requestb.in/nlety4nl"}' \
       https://api.itrp.com/v1/webhooks/
Status: 201 Created
Location: https://wdc.itrp.com/webhooks/2
{
  "id": 2,
  "name": "Request created in WDC",
  "event": "request.create",
  "uri": "http://requestb.in/nlety4nl",
  "created_at": "2016-01-27T20:38:32-06:00",
  "updated_at": "2016-01-27T20:38:32-06:00"
}

Then test the webhook that was just created:

$ curl -v -u "API-TOKEN:x" -X POST https://api.itrp.com/v1/webhooks/2/test
Status: 204 No Content

Refresh the RequestBin page. It should show a new event posted for the event request.create that triggered the webhook with webhook_id 2.