Webhooks

Webhooks allow your application to receive real-time notifications when events occur in Rhizome. To create and configure a webhook, visit: /s/Webhook+Configuration

Configuration

The form requires two main inputs:

  • Payload URL — The endpoint on your server that will receive webhook POST requests.
  • Events — Which events the webhook subscribes to. By default, all events are selected.

You can also provide custom request headers under the Custom Headers section at the bottom of the form. This is useful for sending Bearer tokens or other authentication values.

Testing

After saving a webhook configuration, click the "Send Test Webhook" button to verify your setup. The test payload will be sent with the event type test.

PII & Payload Format

Personally identifiable information (PII) is not included in webhook payloads. You can retrieve it separately using the Rhizome API.

To receive JSON responses, append .json to any URL or include the following headers in your request:

  • Content-Type: application/json
  • Accept: application/json

Payload Verification (HMAC Signature)

If you specify a Secret when configuring your webhook, each payload will include an X-Webhook-Signature header containing an HMAC-SHA256 signature. You can use this to verify that the payload is tamper-proof and originated from Rhizome.

Below are examples for verifying the signature in common languages:

Python

import hmac import hashlib # 'secret' should be your string key #
    'request_body' must be bytes (the raw body) computed_signature = hmac.new(
    secret.encode('utf-8'), request_body, hashlib.sha256 ).hexdigest() #
    Compare with the header is_valid = hmac.compare_digest( computed_signature,
    request.headers.get('X-Webhook-Signature') )

Javascript (Node.js)

const crypto = require("crypto"); // 'secret' is your string key //
    'requestBody' should be the raw string or Buffer of the body const
    computedSignature = crypto .createHmac("sha256", secret)
    .update(requestBody) .digest("hex"); // Use timingSafeEqual for security
    (requires both to be Buffers) const signatureHeader =
    request.headers["x-webhook-signature"]; const isValid =
    crypto.timingSafeEqual( Buffer.from(computedSignature),
    Buffer.from(signatureHeader), );

Ruby (Rails)

is_valid = OpenSSL::HMAC.hexdigest( "SHA256", secret, request.body.read )
    == request.headers['X-Webhook-Signature']

PHP

// 'secret' is your string key // 'requestBody' is the raw input stream
    (php://input) $computedSignature = hash_hmac('sha256', $requestBody,
    $secret); $signatureHeader = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE']; //
    hash_equals protects against timing attacks $isValid =
    hash_equals($computedSignature, $signatureHeader);