Removal is slow: a broker can take days or weeks to act on a request, and removed data can come back later. Webhooks tell you when something changes for a user, instead of polling Get Profile Status.

Set up webhooks

Webhooks are configured by PureWL, not through the API:
  1. Send PureWL your webhook URL: the HTTPS endpoint where you want events delivered.
  2. PureWL configures the event subscription on that URL.
  3. PureWL shares the signing secret for that URL. Use it to verify every request.
Each webhook URL has its own signing secret. All event types configured on the same URL, including Dark Web Monitoring and Data Broker Opt-Out events, share that URL’s secret. Store the secret on your server, like your Secret Key, and never expose it in client-side code.

Events

Payload

All three events share the same payload.
string
Event type: scan.complete, removal.confirmed, or data.reappeared.
string
When the event occurred (ISO 8601, UTC).
object
object

rmd.scan.complete

A broker scan found this user’s data. The payload’s event field is scan.complete.
rmd.scan.complete

rmd.removal.confirmed

Removal verified: the broker replied and the reply was classified as a confirmed removal, or a re-scan after the opt-out no longer finds the record. The payload’s event field is removal.confirmed.
rmd.removal.confirmed

rmd.data.reappeared

The user’s data was found again at a broker that had already reached a confirmed removal in an earlier cycle — removed data has come back. Sent instead of rmd.scan.complete, never in addition. The payload’s event field is data.reappeared.
Expect this event to be rare. Build a handler for it, but do not treat its absence as a fault.
rmd.data.reappeared

Verify webhook signatures

Every webhook request is signed, so your endpoint can confirm it came from PureWL and was not altered. Accept a request only when its signature is valid. Reject any request with a missing or invalid signature. To verify a request:
  1. Compute the HMAC-SHA256 digest of the raw request body, using the signing secret as the key.
  2. Hex-encode the digest.
  3. Compare it with the value after v0= in the x-outpost-signature header.
  4. Use a constant-time comparison, to prevent timing attacks.
  5. Accept the request only if the two values match.
Compute the signature over the body exactly as received. If your framework parses the JSON first and you re-serialize it, the bytes can change and valid requests will fail verification.

Handling events

  • Accept HTTPS only, use an unguessable endpoint path, and verify the signature of every request.
  • Respond immediately, then process asynchronously, so slow handling is not mistaken for a failed delivery.
  • Expect duplicates and out-of-order delivery, and skip event types you do not recognize rather than erroring.
  • Re-fetch before acting — confirm against Get Profile Status before showing anything to the user.
  • Keep watching after a confirmed removal — rmd.data.reappeared can arrive long after a removal was reported complete.