Webhooks

This PI platform uses notification webhooks to communicate status changes to external systems.


Definition and Purpose

A webhook is a common industry practice to allow one system to communicate changes to another system using an ordinary HTTP POST sent from the "changing" system to the "listening" system. Some refer to a Webhook as a "reverse API" because APIs require the curious system to actively ask for data to be returned but when using a Webhook the curious system is passively listening for an incoming notification from the changing system.

For a Webhook relationship to function, the "changing" system must know the URL at which the "listening" system would like to receive change notifications. The URL of the listening system's preferred entry point is known as the Webhook URL or sometimes simply the Webhook.

The term "Webhook" is sometimes spelled "web hook" or WebHook.

The Predictive Index API currently uses Webhook URLs for sending notifications regarding the final status of assessments.

Setting Webhooks - Default or Single

There are two ways to define a Webhook using the PI system:

  1. Single: assessmentStatusWebHook parameter - defined when creating each individual assessment via the API
  2. Default: Default Assessment Status Webhook URL - defined one time per PI client account in the General Settings area within PI software Administration

The Default Assessment Status Webhook URL will be used for all assessments from all sources: 

  • Email Invitation sent from within the PI Software
  • Open Invitation Link assessments (from Classic or new PI software)
  • API-originated assessments without a defined value for the assessmentStatusWebHook property. If this property is defined, the Default Assessment Status Webhook URL will be ignored and the assessment property URL used instead.

When a webhook is defined in either the Default setting or via an API property, all of the general information below applies.

Defining a Webhook URL

A Webhook URL defines the web address of a listener service belonging to the integration solution. The listener must expect to receive POST requests from the PI platform containing information about completion or other status changes in an assessment. 

For example, the listener address provided as your Webhook value might look like this:

  • https://integration.somedomain.com/listeners/predictiveindex/assessmentstatus

Requirements

  • HTTPS- The Webhook URL must be accepting SSL-secured requests. Any webhook that does not use https:// will be rejected and will not be used to make calls.
  • Maximum Length - The maximum length allowed for the Webhook URL setting or parameter is 255 characters.

Basic Authentication Credentials - optional

If your listener service requires Basic Authentication, you can embed the username and password directly into the URL you pass as the value for this parameter. There is no other place to store webhook credentials and no other protocol supported other than Basic Authentication.
Note: this support exists for both Behavioral and Cognitive assessments.

If your username is "user" and password is "password", your listener URL with embedded credentials would look like this:
https://user:password@server.domain.com/listener/

If your username contains an @ symbol, like "user@group" and password is "password", you would URL encode the username first (replacing the @ with %40), and then your listener URL with embedded credentials would look like this:
https://user%40group:password@server.domain.com/listener/

URL Parameters - optional

If you wish to store values with the assessment order that you would like to receive back through your listener, you can embed unique values in the URL as query string variables, for example:
https://server.domain.com/listener?jobid=12345&department=123

Receiving Calls at Your Webhook Listener

Content Type

The POST request sent from the PI platform and received by the listener service will use this content-type defined in the request header:

application/x-www-form-urlencoded

Body

The body of the request will contain four property/value pairs using these names:

  • assessmentId - this is the GUID belonging to the assessment whose status is being reported
  • assessmentState - a numerical value representing the new status of the assessment. see Assessment Statuses below
  • externalId(optional) - if this value was defined as a parameter in the original POST behavioralassessments or POST cognitiveassessments call which created this assessment, it is included as a POST variable. This is useful for matching the PI assessment with the receiving system's identifier for the same assessment
  • assessmentSource - contains a string indicating whether the assessment originated from an Email Invitation, an Open Invitation, or another source (this variable was added 05 Jan 2018). If the API is used to generate a new assessment, the returned value will be Email Invitation.

If you view the raw content of the body, it would look something like this:

assessementId=xxx-xxxx-xxxx-xxxx&assessmentState=40&externalId=ABC123&assessmentSource=EmailInvitation

Here is a mock request that is just like those sent from the PI system to your Webhook listener:

curl -X POST \
  https://username:password@somedomain.com/listener \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d 'assessmentId=xxx-xxxx&assessmentState=40&externalId=ABC123&assessmentSource=EmailInvitation'

Developer Note: Be sure that you do NOT write code that assumes the exact format and variable sequence of the sample body content above. Always use a library method that parses form variables and provides access to them by key name. Your code should not break if future webhook body content includes additional form variable key-value pairs. 

IP Whitelisting

If your listener system implements some kind of filtering strategy that only allows calls from a designated list of IP Addresses, the current list of possible addresses from which The Predictive Index systems will deliver outbound webhook callsnt is the following:

191.236.19.222
191.236.19.242
191.236.21.165
191.236.18.160
23.96.14.211
23.96.10.216
23.96.14.86
23.96.12.109

Which Statuses?

The assessmentStatusWebHook URL will be sent a POST message for the final status changes in assessment status, not for every assessment status change.

Statuses that are NOT delivered via a webhook call: 

  • 10 - Sent
  • 20 - Opened
  • 30 - Started
  • 50 - Expired 
  • 65 - Aborted

Statuses that ARE delivered via a webhook call:

  • 40 - Completed - called immediately upon completion
  • 60 - Failed (Cognitive only) - called immediately upon failure of the software to correctly process the assessment

HTTP Response and Retry Strategy

If your listener receives the content of the Webhook POST request and completes whatever decision-making or processing is appropriate, your listener should respond with an HTTP code of 200 or 201. When the PI system receives a 200-class response, no retry of the same webhook call will be performed.

The Predictive Index system will call a Webhook URL up to 18 times for a given status change using an exponential back-off algorithm spanning up to 5 days until it either receives an HTTP response code of 200 (OK) or the retry maximum is reached.

If your listener fails to completely process the Webhook POST request due to some database connectivity issue, unexpected exception, or other condition where it would be helpful for the PI system to try again, your listener should respond with an HTTP response code in the 400 or 500 range. When the PI system receives a 400 or 500 class response, the retry cycle will begin and the same Webhook POST will be re-attempted until a 200-class response is received or until the retry cycle is exhausted.

Do not send a 400 or 500 class response in an attempt to "report back" to the PI system any actionable details concerning some abnormal condition in your data or an unexpected data element in the POST request -- these are issues for your listener to handle and for you to follow up appropriately. The PI webhook sender will ignore anything you send in the response apart from the response code. If you send a 400 or 500 class response, you will receive the same notification data again in a retry cycle. If you send a 200 response, no more attempts will be made to deliver the Webhook POST to your URL. 

For example, if you receive a webhook request and your listener code determines that the assessmentId and externalId sent in the request body are not recognized as a match to your system's data, DO NOT send a 400 or 500 response code with a message like "assessmentId not found". Instead, you should send a 200 OK because you successfully received the message -- even though it is useless to you. This type of situation might be logged by you and followed up by your developers, but the PI system does not need to resend something that you have already processed and found to be useless, so there is no need to send a 400 or 500 response code. If your code has done all it can do with the data received, send a 200 response code

Determining Assessment Type

Assessment status Webhook requests contain several important facts, but do not indicate whether the assessment status represents a Behavioral or a Cognitive assessment. Only the assessmentId and externalId values are given in the request. It is up to the developer to decide among several strategies for determining which assessment type is being reported:

  1. Separate Listeners - you may wish to set up two different listener services with different endpoints, one for each assessment type. For example: /listener/predictiveindex/cognitiveassessment and /listener/predictiveindex/behavioralassessment. This strategy will only work with API assessmentStatusWebHook parameters, not with the Default Webhook setting.
  2. URL Parameters - you may append a parameter of your choosing to the end of the Webhook URL. For example: /listener/predictiveindex?type=cognitive. This strategy will only work with assessmentStatusWebHook parameters, not with the Default Webhook setting.
  3. External ID Suffix - you may construct an externalId value to describe the individual assessment by concatenating a string value indicating the assessment type with some unique value for the assessment user or the assessment order. For example, you might combine the candidate ID of 123456 with "BA" for behavioral and get the following value for externalId: "123456;BA". This strategy will only work with assessmentStatusWebHook parameters, not with the Default Webhook setting.
  4. Test AssessmentID with Both - you may take the assessmentId value sent in the POST request body and try finding it using a GET behavioralassessments/{id} method, and then if nothing is found, try finding it using a GET cognitiveassesments/{id} method. This method will work with both the assessementStatusWebHook parameter for individual assessment orders and also with the Default Assessment Status WebHook URL general setting.
  5. Wait for Enhancement - the current product road map includes adding an additional key/value pair to the POST request that will specify which assessment type is being reported. The exact design of this feature is not yet determined and the delivery date is not known.