Skip to main content
Every webhook request from Leaf includes an X-Leaf-Signature header. This header contains a base64-encoded HMAC SHA-256 digest of the request body, signed with the secret you provided when creating the webhook. Verify this signature before processing any payload.

How signature verification works

  1. Read the raw request body as bytes. Do not parse or reformat it first.
  2. Compute an HMAC SHA-256 digest of those bytes using your webhook secret as the key.
  3. Base64-decode the value from the X-Leaf-Signature header.
  4. Compare the two digests using a constant-time comparison function.
The signed content is a compact JSON string without extra line breaks or spaces (other than spaces after : and ,).

Code examples

import hmac
import base64
import json

def verify_leaf_signature(raw_body: bytes, secret: str, signature_header: str) -> bool:
    expected_sig = hmac.digest(
        msg=raw_body,
        key=secret.encode("utf-8"),
        digest="sha256"
    )
    request_sig = base64.b64decode(signature_header)
    return hmac.compare_digest(expected_sig, request_sig)

Example payload

If you receive a fieldCreated event, the signed body looks like:
{"source": "REST", "leafUserId": "uuid", "fieldId": "uuid", "timestamp": "2024-06-15T14:30:00.000000Z", "type": "fieldCreated"}
Compute the HMAC of this exact byte string with your secret to get the expected signature.

IP addresses

Leaf uses cloud infrastructure and does not have a fixed range of IP addresses for webhook delivery. If your network architecture requires allow-listing, consider placing a load balancer or reverse proxy in a DMZ to receive webhook traffic and forward it to your internal systems.
Using an X-CompanyName-Signature header for webhook verification is an industry-standard pattern also used by Twilio, Slack, and Stripe.

What to do next

Last modified on March 19, 2026