Learn
Webhook signing and verification
Verify that webhook payloads came from FluxyChat using HMAC-SHA256 signatures.
Why sign webhooks?
Webhooks allow FluxyChat to notify your backend about events like new messages, agent runs, or reactions. Without signature verification, an attacker could send fake webhook payloads to your endpoint.
FluxyChat signs every webhook with HMAC-SHA256 using a shared secret. Your backend must verify the signature before processing the payload.
Setting up webhook signing
- Generate a strong secret (32+ random bytes, base64-encoded)
- Set WEBHOOK_SECRET_ENCRYPTION_KEY in your worker env for at-rest encryption
- Each webhook subscription stores its own signing secret (encrypted in D1)
- The signature is sent in the X-FluxyChat-Signature header
Verifying signatures
The signature header contains the HMAC-SHA256 of the raw request body, hex-encoded. Compare it using a constant-time comparison to prevent timing attacks.
import crypto from "crypto";
function verifyWebhook(rawBody: Buffer, signature: string, secret: string): boolean {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature),
);
}Replay protection
Each webhook includes a timestamp in the X-FluxyChat-Timestamp header. Reject webhooks older than 5 minutes to prevent replay attacks. The timestamp is included in the signed payload.
Realtime chat on Vercel without Pusher or Ably
Vercel excels at HTTP and SSR. Long-lived WebSocket rooms belong on Cloudflare Workers + Durable Objects — keep your Next.js app on Vercel, run chat edge-native.
API Reference
REST endpoints on your FluxyChat Worker — auth, messages, rooms, agents, admin, and billing.