Webhooks

The 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 completion status of assessments.

Setting Webhooks - Default or Single

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

  1. Single: assessmentStatusWebHookUrl parameter - defined when creating each individual behavioral or cognitive assessment via the API

  2. Default: Default Assessment Status Webhook URL - defined one time per PI client account in the Open APIs section under the Integrations tab within PI software Administration

The Default Assessment Status Webhook URL will be used for both the behavioral and cognitive assessments: 

  • Email Invitation sent from within the 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.

  • If both the default url and single url are applied to an individual cognitive or behavioral assessment, the single url will take precedence.

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/json

Body

General

All webhook events will share a common JSON body, however the eventDetails portion of the body will be different depending on the event in question.  The Content-Type header will be set as application/json.

The base body will look like this:

{
	"event": { 
		"action": "behavioralAssessmentCompleted",
		"id": "5a82af30-d2e2-43fe-9ec7-a42e7069acb3"
		"date": "2023-01-01T12:00:01Z"
	},
	"eventDetails": {
		// This section varies based on the type of event
	}
}
Fields
  • event

    • action : string : Initially this will be restricted to 2 possible values, behavioralAssessmentCompleted and cognitiveAssessmentCompleted, however other values may be added in the future.

    • id : string :  This represents a unique identifier for the event that is agnostic to the kind of event it is.  In the event of needing to open up a support call with PI, this ID will likely be requested to help facilitate looking at the specific event in question.

    • date : DateTime : Represents the initial date and time in UTC that this event was triggered.  In the scenario where a webhook has failed and is retried, this date and time will still be the original date and time of the event rather than the retried date and time.

  • eventDetails - This section is unique to each event and is described below, some of the objects within it are common between multiple kinds of events.

Behavoral Assessments

Completions

When a Behavioral Assessment is completed by a person and it has been successfully scored, the webhook platform will check first to determine if a webhook is to be sent.  This is based on if a webhook URL has been defined in 1 of 2 places (in this order):

  1. The assessmentStatusWebHookUrl property passed into the POST for behavioralassessment creation (see API docs).

  2. The Default Assessment Status Webhook Url in the Organization Settings -> Integrations section in Administration.

If it is determined that the webhook should be sent a HTTP POST will be initiated.  

The event type in the JSON body will be behavioralAssessmentCompleted.  A detailed list of what each field represents and, when appropriate what values might appear there, can be found in the appendix.

{
	"event": { 
		"action": "behavioralAssessmentCompleted",
 		"id": "5a82af30-d2e2-43fe-9ec7-a42e7069acb3"
 		"date": "2023-01-01T12:00:01Z"
	},
	"eventDetails": {
		"asssessmentId": "4ff0b326-e970-4907-98f3-11100bd235bb",
		"externalAssessmentId": "54321_B",
		"assessmentSentDateTime": "2024-02-27T18:01:46.774Z",
		"assessmentCompletedDateTime": "2023-01-01T12:00:01Z",
		"referenceProfileName": "Specialist",
		"referenceProfileNumber": 20,
		"languageLocale": "en-US",
		"redirectURL": "https://yourcompany.com/thankyou",
		"assessmentState": 40,
		"assessmentStateDescription": "Completed",
		"assessmentUrl" : "https://assessments.predictiveindex.com/4ff0b326-e970-4907-98f3-11100bd235bb",
 		"person": {
			"personId": "5968434a-5a75-4ae5-8dbe-3f32f1a0101d",
			"externalPersonId": "12345-C98_A",
			"email": "candidate@gmail.com",
			"firstName": "John",
			"lastName": "Smith",
			"middleName": "E",
			"gender": 1,
			"genderDescription": "Male",
			"isBookmarked": false
		},
		"administeredBy": {
			"email": "jane.doe.admin@company.com",
			"phone": "555-867-5309",
			"firstName": "Jane",
			"lastName": "Doe"
 		},
		// This will be set to null if the person is not a candidate for a Job in Hire.
		"job": { 
			"externalJobId": "55555-J123_B",
			"jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
			"title": "Sales Manager",
			"description": "Sales Manager"
		}
	}
}

Cognitive Assessment

Completions

When a Cognitive Assessment is completed by a person and it has been successfully scored, the webhook platform will check first to determine if a webhook is to be sent.  This is based on if a webhook URL has been defined in 1 of 2 places (in this order):

  1. The assessmentStatusWebHookUrl property passed into the POST for cognitiveassessment creation (see API docs).

  2. The Default Assessment Status Webhook Url in the Organization Settings -> Integrations section in Administration.

If it is determined that the webhook should be sent a HTTP POST will be initiated.  

The event type in the JSON body will be cognitiveAssessmentCompleted. A detailed list of what each field represents and, when appropriate what values might appear there, can be found in the appendix.

{
	"event": { 
		"action": "cognitiveAssessmentCompleted",
		"id": "5a82af30-d2e2-43fe-9ec7-a42e7069acb3"
		"date": "2023-01-01T12:00:01Z"
	},
	"eventDetails": {
		"asssessmentId": "4ff0b326-e970-4907-98f3-11100bd235bb",
		"externalAssessmentId": "54321_B",
		"assessmentSentDateTime": "2024-02-27T18:01:46.774Z",
		"assessmentCompletedDateTime": "2023-01-01T12:00:01Z",
		"cognitiveFitDescription": "Moderate Fit",
		"cognitiveScore": 300,
		"languageLocale": "en-US",
		"assessmentState": 40,
		"assessmentStateDescription": "Completed",
	"person": {
		"personId": "5968434a-5a75-4ae5-8dbe-3f32f1a0101d",
		"externalPersonId": "12345-C98_A",
		"email": "candidate@gmail.com",
		"firstName": "John",
		"lastName": "Smith",
		"middleName": "E",
		"gender": 1,
		"genderDescription": "Male",
		 "isBookmarked": false
	},
	"administeredBy": {
		"email": "jane.doe.admin@company.com",
		"phone": "555-867-5309",
		"firstName": "Jane",
		"lastName": "Doe"
	},
	"job": { 
		"externalJobId": "string",
		"jobId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
		"title": "string",
		"description": "string"
		}
	}
}

IP Allowed List

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

20.185.151.76

20.185.151.104 

20.185.151.105

Which statuses trigger webhooks?

The assessmentStatusWebHook URL will be sent a POST message for the completed 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 9 times for a completed assessment using an exponential back-off algorithm spanning up to 24 hours 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 of 408, 429, 500, 502, 503, or 504. When the PI system receives a response with the aforementioned codes, the retry cycle will begin and the same Webhook POST will be reattempted 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, respond with a 404 response code, This will ensure that no further attempts are made against the webhook for that assessment. 

In another example, if you receive a webhook request but it fails to process on your system in a way that indicates it can’t be retried return you should return an http status code indicating an error; excluding 408, 429, 500, 502, 503 or 504 as those will be retried.
The retry backoff timing is below for reference:

Retry Number

Next Retry In

Time Since First Attempt

1

0:00:09

0:00:09

2

0:00:21

0:00:30

3

0:01:09

0:01:39

4

0:04:21

0:06:00

5

0:17:09

0:23:09

6

1:08:21

1:31:30

7

4:33:09

6:04:39

8

18:12:21

24:17:00

Appendix

General

Field Definitions

  • person : Object containing properties related to a person in PI.

    • personId : string : PI generated ID for the person

    • externalPersonId : string(maxlength: 71) : Client provided ID when creating or updating a person via the API.

    • email : string(maxlength: 255) : Email address of the person.

    • firstName : string(maxlength: 255) : First Name of the person

    • lastName : string(maxlength: 255) : Last Name of the person

    • middleName : string(maxlength: 255) : Middle Name of the person

    • gender : smallint : Numerical representation of the gender of the person. 

      • Possible Values: 0 (Unknown), 1 (Male), 2 (Female)

    • genderDescription : string : The human readable representation of the gender of the person.

      • Possible Values: Unknown, Male, Female

    • isBookmarked : boolean : Indicates whether the person is bookmarked

  • administeredBy : Object containing properties related to who sent an assessment.

    • email : string(maxlength: 255) : Email address of the person.

    • firstName : string(maxlength: 255) : First Name of the person

    • lastName : string(maxlength: 255) : Last Name of the person

    • phone : string(maxlength: 255) : Phone number of the person

  • job : Object containing properties related to a job in PI.

    • jobId : string : PI generated ID for the job.

    • externalJobId : string(maxlength: 71) : Client provided ID when creating or updating a job via the API.

    • title : string(maxLength: 50) : Name of the Job

    • description : string : Description of the Job

Behavioral Assessments

Field Definitions

  • eventsDetails: Object containing properties specific to the Behavioral Assessment

    • assessmentId : string :  PI generated ID for the individual assessment.

    • externalAssessmentId : string(maxlength: 71) : Client provided ID when creating a new assessment

    • assessmentSentDateTime : DateTime : Date and Time in UTC that assessment was sent to the person.

    • assessmentCompletedDateTime : DateTime : Date and Time in UTC that assessment was completed.

    • referenceProfileName : string : The human readable reference profile value, rendered in English.  

      • Possible values are: Adapter, Venturer, Strategist, Analyzer, Controller, Specialist, Scholar, Individualist, Captain, Maverick, Persuader, Altruist, Collaborator, Promoter, Guardian, Operator, Craftsman

    • referenceProfileNumber : int : The integer reference profile value.  

      • Possible values are: 0 (Adapter), 8 (Venturer), 10 (Strategist), 12 (Analyzer), 14 (Controller), 20 (Specialist), 22 (Scholar), 24 (Individualist), 26 (Captain), 30 (Maverick), 36 (Persuader), 46 (Altruist), 54 (Collaborator), 56 (Promoter), 60 (Guardian),64 (Operator), 70 (Craftsman)

    • languageLocale : string : The language that the assessment was sent in.  The list of possible values can be fetched from here

    • redirectURL : string(maxlength: 500) : The URL that the assessment taker was redirected to upon completion of the assessment.

    • assessmentState : int : An integer representing the current state of the assessment.

      • Possible values are: 10 (Pending), 30 (Started), 40 (Completed), 50 (Expired), 60 (Failed), 65 (Aborted)

    • assessmentStateDescription : string : The human readable assessment state.

      • Possible values are:Pending, Started, Completed, Expired, Failed, Aborted

Cognitive Assessments

Field Definitions

  • eventDetails: Object containing properties specific to the Cognitive Assessment

    • assessmentId : string :  PI generated ID for the individual assessment.

    • externalAssessmentId : string(maxlength: 71) : Client provided ID when creating a new assessment

    • assessmentSentDateTime : DateTime : Date and Time in UTC that assessment was sent to the person.

    • assessmentCompletedDateTime : DateTime : Date and Time in UTC that assessment was completed.

    • languageLocale : string : The language that the assessment was sent in.  The list of possible values can be fetched from here

    • cognitiveFitDescription : string : General fit description based on the score vs the Job’s Cognitive Target. 

      • Possible Values: Moderate fit, Strong Fit, Cautionary fit

    • cognitiveScore : int : Cognitive Score on a scale of 100-450.

    • assessmentState : int : An integer representing the current state of the assessment.

      • Possible values are: 10 (Pending), 30 (Started), 40 (Completed), 50 (Expired), 60 (Failed), 65 (Aborted)

    • assessmentStateDescription : string : The human readable assessment state.

      • Possible values are:Pending, Started, Completed, Expired, Failed, Aborted