Webhooks | Parallel Developer Documentation
This is documentation for Parallel Developer Documentation Legacy – v1.x, which is no longer actively maintained.
For up-to-date documentation, see the latest version (Current – v2.x).
Version: Legacy – v1.x
Caution
If you are a Case Management partner but are using legacy webhooks documented here, you should migrate to webhooks as described in our V2 documentation. Refer to the Migration Guide for more information.
As part of OAuth Client configuration, you can specify a webhook URL to receive updates on connected individuals and businesses. Updates are sent when there is a change in accreditation status, an identity information submission, changes in a user profile or a potential risk monitor match.
Configuring Webhooks
You can manage OAuth2 Clients and configure webhooks to receive updates by:
- Logging into your Parallel Markets account,
- Selecting a business in the top-right dropdown, and
- Clicking on the "Integrations & Exports" item under the "Settings" item in the menu bar.
Request Details
Parallel will send an HTTP POST to the endpoint you specify whenever an event occurs (see the list of possible events here). Any configured webhook URL must accept a JSON POST request and return HTTP status 200 OK within 5 seconds. See the Request Format page for payload formats.
Caution
If a successful response isn't received, we will automatically retry up to 3 additional times at 60 second intervals. Once three retries have failed, additional requests for the given event will not be sent. Subsequent accreditation status changes will trigger a new request with up to 3 retries.
Testing Webhooks
After configuring a webhook URL for an OAuth2 Client, click "Send Test Payload" to send a POST request from our servers, with "test" as the entity id. You'll see a success message for a 200 response or an error message with debugging information.
The body that is posted to your webhook will be:
{
"entity": {
"id": "test",
"type": "individual"
},
"event": "data_update",
"scope": "accreditation_status"
}
Deleting Webhooks
Webhooks will be delivered to the configured URL for all OAuth2 Clients, even if the OAuth2 Client is disabled. To stop delivery of webhooks, click "Delete" next to the webhook URL to be deleted. You will be asked to confirm the deletion. Once the webhook URL is deleted, webhooks will no longer be delivered to the specified URL.
Verifying Webhook Authenticity
Parallel can optionally sign all webhook requests with a shared secret key, allowing you to verify that the webhook call was actually made by Parallel and not by a third party. After creating an OAuth Client with "Sign Webhook Requests" enabled, we will generate and display a unique "Webhook Key" for the client. The text we show for the key is a Base64-encoded representation of a secret key that will be used to sign any requests sent to webhooks you create for that OAuth Client.
To verify a signature, you should first extract the values of two custom headers that will be sent with the request:
Parallel-Timestamp: This contains the Unix timestamp when the request was madeParallel-Signature: This contains the request signature
The header value with the request signature will be a Base64-encoded HMAC SHA256 signature of the concatenation of the timestamp and webhook POST body. This can be represented in pseudocode with:
desbase64(HMACSHA256(WEBHOOK_KEY, TIMESTAMP_HEADER + BODY)))
Here's a full example in NodeJS showing signature verification:
const crypto = require('crypto')
function isValidSignature(webhookKey, signatureHeader, timestampHeader, body) {
const decodedWebhookKey = Buffer.from(webhookKey, 'base64')
const hmac = crypto.createHmac('sha256', decodedWebhookKey)
const sig = hmac.update(timestampHeader + body).digest('base64')
return Buffer.from(signatureHeader).equals(Buffer.from(sig))
}
// The 'Webhook Key' copied from the OAuth Client config.
// The value is a Base64-encoded representation of the key used in the HMAC.
const webhookKey = 'fKYatxi3x9lI4Zsn31P1sF238a+WUlv/76sJSodYwEbtA=='
// Value of the 'Parallel-Signature' header in the webhook call
const signatureHeader = 'bmnNmLqONdxl/BP/t14rb71tkSO5EgIPyfvhIdbRJ1o='
// Value of the 'Parallel-Timestamp' header in the webhook call
const timestampHeader = '1669748474'
// Raw POST body in the webhook call
const body = '...'
const result = isValidSignature(webhookKey, signatureHeader, timestampHeader, body)
The timestamp value can be used to mitigate a replay attack, a case where an attacker intercepts a valid payload and its signature and retransmits them. In addition to ensuring the signature is correct, you may also verify the provided timestamp is within the last few seconds to prevent such a replay attack.