Verify a Twitter account-alert webhook signature
XFlux signs live monitor webhooks so your server can reject forgeries. Compute HMAC-SHA256 over {timestamp}.{raw body} and compare to x-xflux-signature. This is not official X Account Activity CRC. Discord and Slack Incoming Webhooks do not use this header.
Raw body, then JSON
Hash the exact bytes you received. Parsing JSON first changes the string and breaks the signature.
Five-minute window
Header x-xflux-timestamp is unix seconds. Reject if it is more than 300 seconds from now.
HTTPS endpoints only
Slack and Discord URLs are formatted for those apps. Custom servers use the signed JSON and this check.
Check a delivery
- 1
Copy the webhook secret
Dashboard → the monitor’s webhook secret. Starter+ sends live hits; Free can send a test ping.
- 2
Read the two headers
x-xflux-timestamp and x-xflux-signature (value starts with sha256=).
- 3
Compare in constant time
Expected digest is HMAC-SHA256 of timestamp + "." + raw body. Deduplicate on tweet id + monitor id.
Node check
Full Express example: /docs/webhooks. Python: /twitter-webhook-python.
import crypto from "crypto";
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
const ok = crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
);FAQ
- Is this the official X CRC challenge?
- No. Official Account Activity API uses a CRC handshake. XFlux uses HMAC-SHA256 on monitor.hit POSTs. See /twitter-account-activity-api.
- Do Slack and Discord need this?
- No. Those URLs get an app-specific body. Verify HMAC on your own HTTPS endpoint.
- Where is the secret?
- On the monitor in the Dashboard. Reference: /docs/webhooks.
Related guides
Try account monitors free
Free includes 1 monitor and Dashboard hit history. Live webhook delivery starts on Starter ($19/mo).