Every webhook delivery from Settlx is signed using HMAC-SHA256 with a timestamped, Stripe-style signature scheme. You must verify this signature before processing any event — unsigned, tampered, or replayed payloads must be rejected.
The result is sent in the X-Webhook-Signature header in this format:
X-Webhook-Signature: t=1735689600,v1=a3f1c9b...
Where:
t=<unix_seconds> — the timestamp the signature was generated (UTC, integer seconds since epoch).
v1=<hex> — the lowercase hex HMAC-SHA256 digest. The v1 prefix is the scheme version, kept stable so the verification algorithm can evolve without breaking integrators.
To verify, parse the header, recompute the HMAC on your side using the raw request body (before any JSON parsing), and compare it against the v1 value using a timing-safe comparison. You must also reject signatures whose timestamp is outside a tolerance window (5 minutes recommended) to prevent replay attacks.
Always sign over the raw bytes of the request body. Re-serializing the JSON before computing the HMAC will fail because object key ordering and whitespace are not canonical.
Always use a timing-safe comparison function. A standard === or == string check is vulnerable to timing attacks that can leak your secret.
Replay protection is built directly into the signature scheme. The t= value inside X-Webhook-Signature is the canonical signing timestamp — your verifier MUST reject any delivery whose timestamp is more than 5 minutes from your server’s current time.The examples above all enforce this with a TOLERANCE_SECONDS = 300 check before the HMAC comparison. Without that check, a single captured webhook could be replayed against your endpoint indefinitely.We also send an informational X-Webhook-Timestamp header containing the same moment in ISO 8601 format. It is for human readability only — always use the t= value from X-Webhook-Signature for verification, never the standalone header.
Settlx may deliver the same event more than once — for example if your server acknowledges after a retry was already in flight. Use the eventId field to deduplicate.
Return any 2xx status within 30 seconds. 200, 201, and 204 are all accepted. Any non-2xx response or a timeout triggers a retry.See Webhook Overview for the full retry schedule.