X-Sendmux-Signature-V2: v1=<hex> and X-Sendmux-Timestamp: <Unix seconds>. Verify the signature and timestamp before processing the event. The legacy X-Sendmux-Signature: sha256=<hex> header remains available.
What to sign
- Use the webhook signing secret returned when the subscription was created or rotated.
- Join
X-Sendmux-Timestamp, a literal full stop (.), and the raw request body bytes. - Compute HMAC-SHA256 and compare it with
v1in constant time. - Reject timestamps outside your freshness window. The example accepts at most 300 seconds of clock difference in either direction.
id; freshness checks do not prevent duplicates within the accepted window.
Example verifier
Common mistakes
- Reading parsed JSON instead of the raw body.
- Verifying only the body instead of the timestamp and body together.
- Accepting stale timestamps or keeping an inaccurate server clock.
- Using a normal string comparison for secrets.
- Processing retries without deduplicating the verified event ID.
Legacy verification
The legacyX-Sendmux-Signature value is sha256=<hex HMAC-SHA256> over the raw body bytes alone, using the same secret. It has no signed timestamp. Existing verifiers keep working; use V2 for freshness checks. A receiver configured for V2 should reject a missing or invalid V2 header instead of falling back to legacy verification.
Endpoint behaviour
Return a2xx status once the event is accepted. For longer processing, store the event first, return quickly, and process it after the response.
Sendmux retries non-2xx responses and timeouts. See Webhooks setup.