Skip to main content

Webhooks

Webhooks let you subscribe to events happening in the k-ID Engine as they happen, as opposed to polling an API to see if data is available.

What are webhooks?

Webhooks can be used for a variety of purposes, such as:

  1. Handling challenge completion results
  2. Handling age verification results
  3. Handling changes in the k-ID Session

Setting up webhooks

Webhooks are configured in the Compliance Studio, by specifying a URL that the k-ID Engine calls when an event occurs. The URL must be a secure HTTPS URL. The k-ID Engine sends a POST request to the URL with a JSON payload that contains the event data.

info

Webhooks are associated with individual Products. You can use the same endpoint for all of your k-ID Products if you have more than one, but it's important to note that you must retrieve the correct Product-specific k-ID API Key to make API calls (for example /session/get).

Webhooks can be configured in the Developer Settings section of your product in the Compliance Studio.

Webhook Publisher Dashboard

Webhook event structure

The JSON payload sent to the webhook URL contains the following fields:

  • eventType - The type of event that occurred.
  • data - The data associated with the event.

An X-Event-Type header is also sent with the event type.

Validating webhook requests

Webhooks are sent over the public internet, so it's important to validate that the requests are coming from k-ID. This is done by verifying the event payload signature by using the configured webhook secret.

All requests include the following headers:

  • X-Signature-Timestamp - The timestamp of the request, in UNIX epoch seconds.
  • X-Signature-Hmac-Sha256 - The HMAC SHA-256 keyed-hash of the UTF-8 encoded timestamp and request body concatenated together, using the webhook secret as the key, encoded as a lowercase hexadecimal string.

If the signature is invalid, the request should be rejected with a 401 status code. Webhook requests with validated signatures can be processed and accepted with a 200 status code.

Example validation code

const crypto = require("crypto");

// Your webhook secret, configured in the [Compliance Studio](/compliance-studio/products/creating-new-product).
const SECRET = "your-secret";

const timestamp = req.get("X-Signature-Timestamp");
const signature = req.get("X-Signature-Hmac-Sha256");
const body = req.rawBody; // Raw request body, as a string.

// Compute the expected signature.
const hmac = crypto.createHmac("sha256", SECRET);
hmac.update(timestamp + body);
const expectedSignature = hmac.digest("hex");

// Compare signatures securely.
if (
!crypto.timingSafeEqual(
Buffer.from(signature, "hex"),
Buffer.from(expectedSignature, "hex")
)
) {
return res.status(401).end("Unauthorized");
}

Event types

Event TypeDescription
Challenge.StateChangeEmitted when a parental consent challenge changes state
Verification.ResultEmitted with the result of a verification attempt
Account.DeleteEmitted when an account is deleted
AgeAssurance.ResultEmitted with the result of an Age Assurance evaluation (deprecated, replaced by Verification.Result)
ParentalConsent.GrantedEmitted when parental consent is granted
Session.ChangePermissionsEmitted when session permissions are modified by a parent
Session.DeleteEmitted when a session is deleted
TestUsed to verify that the webhook is working correctly