Skip to main content

Webhooks Integration Overview

Webhook integrations notify you when a verified privacy request is ready for processing. This enables you to manage the request within your infrastructure or pass it to a third-party system, allowing you to handle the request and confirm its completion via the provided callback URL.

Configure a Webhook Endpoint

The initial step in setting up a webhook integration involves creating a webhook endpoint. The endpoint will allow DataGrail to send notifications about incoming requests. Webhook notifications will be sent as HTTP POST requests with a JSON body to the configured webhook endpoint.

Depending on the request type, DataGrail will send one of the following notification types to your webhook endpoint:

  • Health Check - Test the readiness of the webhook endpoint.
  • Access - Send the details of an access request to be processed.
  • Deletion - Send the details of a deletion request to be processed.
  • Opt-Out - Send the details of an opt-out request to be processed.

Headers

DataGrail will include two custom headers in the webhook request for identification and security purposes.

NameDescription
X-Webhook-SignatureHMAC-SHA256 signature to verify the request originated from DataGrail.
X-Webhook-TimestampTimestamp of when the request was sent.

Example Headers

{
"X-Webhook-Timestamp": "1757462400",
"X-Webhook-Signature": "kecgzfKH7/rUIns3tA1V4xDo9g/8k+aaClx9osgcpfg=",
"Accept": "application/json",
"Content-Type": "application/json",
"User-Agent": "dgclient/1.0"
}

Body

The webhook body will be sent as a JSON object, where the structure of the body will depend on the notification type.

Common Request Body Parameters

For all webhook requests, the body will contain the below common parameters.

NameDescription
integration_namestring
The integration display name in the DataGrail application.
integration_kindstring
The integration kind, which will always be webhook.
webhook_request_idstring(UUID)
A unique identifier for the webhook request.
request_typeenum(RequestType)
The action to perform (privacy request type, or health check).

Health Check Body

The Health Check notification body will only contain the Common Body Parameters.

Health Check Example Body
{
"request_type": "health_check",
"integration_name": "Webhook Integration",
"integration_kind": "webhook",
"webhook_request_id": "3aa32ca6-e60d-4b71-981a-d1ba258fd712"
}

Access, Deletion, and Opt-Out Body Parameters

In addition to the Common Body Parameters, the Access, Deletion, and Opt-Out notification bodies will include the following specific parameters:

NameDescription
topicenum(Topic)
The type of request notification.
identifiersobject(Identifiers)
The data subject identifiers associated with the request.
webhook_callback_urlstring
The URL to callback to once the request is complete.
privacy_request_idstring(UUID)
The UUID of the privacy request (36-character string).
integration_idstring(UUID)
The UUID of the integration (36-character string).
Access Request Example Body
{
"request_type": "access",
"integration_name": "Webhook Integration",
"integration_kind": "webhook",
"topic": "privacy_request:create",
"identifiers": {
"email": [ { "email": "john@example.com" } ],
"user_id": [ { "user_id": "100101" } ]
},
"webhook_callback_url": "https://acme.datagrail.io/api/v2/webhooks/callback",
"privacy_request_id": "4b7a02e2-361e-4957-9d69-b381e3f47758",
"integration_id": "4b7a02e2-361e-4957-9d69-b381e3f47758",
"webhook_request_id": "3aa32ca6-e60d-4b71-981a-d1ba258fd712"
}

Validation

For security purposes, we strongly recommend implementing a mechanism to validate the DataGrail webhook.

First obtain a Webhook Secret generated by DataGrail on the webhook integration connection page.

To validate the webhook request, follow these steps:

  1. Fetch the webhook timestamp from the request header X-Webhook-Timestamp (e.g. $TIMESTAMP).
  2. Fetch the webhook body (e.g. $PAYLOAD).
  3. Concatenate the timestamp and body to a single string (e.g. $TIMESTAMP:$PAYLOAD).
  4. Calculate the HMAC-SHA256 signature for the string, using the Webhook Secret.
  5. Convert the signature to the printable ASCII characters (base64).
  6. Compare the signature with the webhook signature from the request header X-Webhook-Signature.

Here are a few webhook validation examples for the Health Check notification:

#!/bin/bash
trap 'rm -f /tmp/payload.txt /tmp/original_signature.bin /tmp/computed_signature.bin' EXIT

read -p "Enter payload: " PAYLOAD
read -p "Enter timestamp: " TIMESTAMP
read -p "Enter signature: " SIGNATURE
read -sp "Enter secret key: " SECRET_KEY

printf "$TIMESTAMP:$PAYLOAD" > /tmp/payload.txt
printf "$SIGNATURE" | base64 -d > /tmp/original_signature.bin

openssl dgst -sha256 -mac HMAC -macopt key:"$SECRET_KEY" -binary /tmp/payload.txt > /tmp/computed_signature.bin
cmp -s /tmp/original_signature.bin /tmp/computed_signature.bin && printf "\nSignature is valid\n" || printf "\nSignature is not valid\n"

Expected Responses

DataGrail expects a 201 Created HTTP response when a request has been created successfully. If the request has not been created, DataGrail expects an appropriate 4xx or 5xx HTTP response code. An error description is not required, but will aid in request debugging.

Error Response Body Examples

401 Unauthorized
{
"error": "Invalid request signature"
}
400 Bad Request
{
"error": "Invalid request type"
}

Callbacks

Once the request has been processed, you must notify DataGrail of completion by sending a callback to the provided Callback URL.

URL

The callback URL is included in the webhook_callback_url parameter of the webhook notification body.

API Key

The callback request must include an API key with the Webhook Callback scope. You can create an API key in DataGrail by navigating to Settings > API Keys > Create API Key.

Body

The webhook callback body will be sent as a JSON object, where the structure of the body will depend on the notification type.

Common Callback Body Parameters

For all webhook callbacks, the body will contain the below common parameters.

NameDescription
webhook_request_idstring
A unique identifier for the webhook request.
request_typeenum(RequestType)
The notification type.
statusenum(Status)
The status of the request.

Access Callback Body Parameters

Access callback bodies will also include the following fields:

NameDescription
privacy_request_idstring
The UUID of the privacy request (36-character string).
integration_idenum(RequestType)
The UUID of the integration (36-character string).
resultsobject(Files or FileRefs)
The status of the request.
note

Max upload limit of all files is 200 MB.

Example Access Body with Files
{
"webhook_request_id": "3aa32ca6-e60d-4b71-981a-d1ba258fd712",
"request_type": "access",
"privacy_request_id": "4b7a02e2-361e-4957-9d69-b381e3f47758",
"integration_id": "4b7a02e2-361e-4957-9d69-b381e3f47758",
"status": "completed",
"results": {
"files": [
{ "contacts_data.txt": "cHJpdmFjeSBkYXRhIGZvciBzb21lIHVzZXI=" },
{ "events_data.txt": "cHJpdmFjeSBkYXRhIGZvciBzb21lIHVzZXIgKGV2ZW50cyk=" }
]
}
}
Example Access Body with FileRefs
{
"webhook_request_id": "3aa32ca6-e60d-4b71-981a-d1ba258fd712",
"request_type": "access",
"privacy_request_id": "4b7a02e2-361e-4957-9d69-b381e3f47758",
"integration_id": "4b7a02e2-361e-4957-9d69-b381e3f47758",
"status": "completed",
"results": {
"file_refs": [
"api_integration_files_sync/{privacy_request_id_}/{integration_id}/*"
]
}
}

Deletion Callback Body Parameters

Deletion callback bodies will also include the following fields:

NameDescription
privacy_request_idstring
The UUID of the privacy request (36-character string).
integration_idenum(RequestType)
The UUID of the integration (36-character string).
Example Deletion Callback Body
{
"webhook_request_id": "8cf283d3-b9d3-4f93-8195-55948c43d625",
"request_type": "deletion",
"privacy_request_id": "9b8d61c7-8432-4e7a-bc2d-7ae17232979c",
"integration_id": "716cde3d-3136-407a-bb32-dba2b4dcf1d9",
"status": "completed"
}

Opt Out Callback

Opt-out callback bodies will also include the following fields:

NameDescription
opt_out_request_idstring
The UUID of the opt-out request (36-character string).
integration_idenum(RequestType)
The UUID of the integration (36-character string).
Example Opt-Out Body
{
"webhook_request_id": "9bfacff3-c454-4212-9417-88e246e1798f",
"request_type": "opt_out",
"opt_out_request_id": "206356d2-80de-492c-bd34-b0093b6f5d25",
"integration_state_id": 786,
"status": "completed"
}

Expected Responses

See the API documentation for updating a privacy request integration.


Objects

Identifiers

An object containing key-value pairs of all identifiers for the request.

NameDescription
<identifier_api_name>[]object(Identifier)
The key-value pairs of the identifier category and identifier value.

Identifier

An individual identifier object.

NameDescription
<identifier_category_api_name>string
The identifier value.

Files

A list of objects containing key-value pairs of file names and file contents to upload.

NameDescription
files[]object(File)
An array of File objects.

File

An individual file and its contents.

NameDescription
<file_name>string
The file to upload. Files must be converted to printable ASCII characters (Base64).

FileRefs

A list of file paths in your cloud storage to sync.

NameDescription
file_refs[]string
An array of file paths in your cloud storage.

The file paths must be located in the bucket that is integrated with DataGrail, and must use the following file path format:
api_integration_files_sync/{privacy_request_id}/{integration_id}/*

Enums

RequestType

The action to perform.

EnumDescription
health_checkstring
The request is for a health check
accessstring
The request is for access.
deletionstring
The request is for deletion.
opt_outstring
The request is for opt-out

Topic

The request notification type.

EnumDescription
privacy_request:createstring
The request is to create a new privacy request.
privacy_request:reminderstring
The request is a reminder of an incomplete privacy request.
opt_out_request:createstring
The request is to create a new opt-out request.
opt_out_request:reminderstring
The request is a reminder of an incomplete opt-out request.

Status

The status that is set for an integration on a privacy request.

EnumDescription
completedstring
The integration for the request should be marked as completed.
ignoredstring
The integration for the request should be marked as ignored.

 

Need help?
If you have any questions, please reach out to your dedicated Account Manager or contact us at support@datagrail.io.

Disclaimer: The information contained in this message does not constitute as legal advice. We would advise seeking professional counsel before acting on or interpreting any material.