XFlux
Webhook signatures

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. 1

    Copy the webhook secret

    Dashboard → the monitor’s webhook secret. Starter+ sends live hits; Free can send a test ping.

  2. 2

    Read the two headers

    x-xflux-timestamp and x-xflux-signature (value starts with sha256=).

  3. 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).

Verify Twitter Webhook Signatures — HMAC-SHA256 | XFlux