Twitter Webhook Integration
Receive signed HTTP POST requests when a monitor detects a new tweet. Available on Starter and above — limited-time 30-day free Starter trial (card required), then $19/mo. For a product overview, see Twitter webhook integration. Discord routing: Discord alerts. Make.com setup: Connect XFlux to Make.
Setup
- Start the limited-time free Starter trial (or upgrade to Starter+) from Billing
- Dashboard → Monitors → expand Webhook section on a monitor
- Enter your HTTPS endpoint URL and save — Discord or Slack incoming webhook URLs are supported directly (we adapt the payload)
- Copy the signing secret shown once — store it securely
- Click Test webhook to verify connectivity
Delivery
When a new hit is recorded, XFlux POSTs JSON to your URL with these headers:
Content-Type: application/json
X-XFlux-Event: monitor.hit
X-XFlux-Timestamp: 1710000000
X-XFlux-Signature: sha256=<hex>
User-Agent: XFlux-Webhook/1.0Hit payload
{
"event": "monitor.hit",
"monitor": {
"id": "clx...",
"targetUsername": "elonmusk",
"keywords": null
},
"tweet": {
"id": "1234567890",
"text": "Hello world",
"authorUsername": "elonmusk",
"createdAt": "2026-06-14T12:00:00.000Z"
},
"detectedAt": "2026-06-14T12:00:05.000Z"
}Test payload
{
"event": "monitor.test",
"monitor": {
"id": "clx...",
"targetUsername": "elonmusk",
"keywords": null
},
"test": true
}Verify signatures
Compute HMAC-SHA256 over {timestamp}.{raw_body} using your webhook secret. Reject requests older than 5 minutes. Always verify against the raw request body before JSON.parse.
import crypto from "crypto";
function verify(secret, timestamp, rawBody, signatureHeader) {
const ageSec = Math.abs(Date.now() / 1000 - Number(timestamp));
if (!Number.isFinite(ageSec) || ageSec > 300) return false;
const expected = "sha256=" + crypto
.createHmac("sha256", secret)
.update(`${timestamp}.${rawBody}`)
.digest("hex");
try {
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signatureHeader)
);
} catch {
return false;
}
}
// Express example — must use raw body
app.post("/webhooks/xflux", express.raw({ type: "application/json" }), (req, res) => {
const timestamp = req.headers["x-xflux-timestamp"];
const signature = req.headers["x-xflux-signature"];
const rawBody = req.body.toString("utf8");
if (!verify(WEBHOOK_SECRET, timestamp, rawBody, signature)) {
return res.status(401).send("Invalid signature");
}
const event = JSON.parse(rawBody);
// Deduplicate on tweet.id + monitor.id if you may see replays
res.status(200).send("ok");
});Idempotency
Treat tweet.id + monitor.id as a unique key. Store processed keys for at least 24 hours so accidental duplicate POSTs do not double-fire alerts or trades.
Retries & logs
Each delivery attempt is logged in Dashboard (status code, latency, error message). Failed deliveries are not automatically retried in the current version — fix your endpoint, then use Test webhook, or read hits from the Dashboard / GET /api/v1/monitors/:id/hits as a fallback.
Event types
monitor.hit— new tweet matched the monitor (optional keyword filter applied)monitor.test— manual ping from Dashboard
Security
Always verifyX-XFlux-Signature before processing. Use HTTPS endpoints only. Rotate the secret from the Dashboard if compromised.FAQ
Which plans include live webhooks?
Starter and above deliver live monitor.hit events. Limited-time: eligible accounts get a 30-day free Starter trial, then $19/mo. Free can save a URL and send test pings only.
How do I verify X-XFlux-Signature?
Compute HMAC-SHA256 over `{timestamp}.{raw_body}` with your webhook secret and compare to the X-XFlux-Signature header using a timing-safe equality check. Reject timestamps older than five minutes.
Are failed deliveries retried automatically?
Failed deliveries are logged in the Dashboard with status and latency. Automatic retries are not guaranteed in the current version — fix your endpoint and use Test webhook, or poll Dashboard hit history as a fallback.
How do I route webhooks to Discord?
Paste a Discord Incoming Webhook URL (Channel → Integrations → Webhooks) into the monitor — XFlux auto-formats Discord embeds/content. You can also use Make.com or your own bot. See /twitter-discord-alerts.