XFlux

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

  1. Start the limited-time free Starter trial (or upgrade to Starter+) from Billing
  2. Dashboard → Monitors → expand Webhook section on a monitor
  3. Enter your HTTPS endpoint URL and save — Discord or Slack incoming webhook URLs are supported directly (we adapt the payload)
  4. Copy the signing secret shown once — store it securely
  5. 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.0

Hit 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 verify X-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.

Webhook API Reference — Events, Signatures & Verification