Webhook Security
Sydx AI handles two types of webhooks, both secured with industry-standard cryptographic verification.
Inbound Webhooks (Meta → Sydx AI)
What Are Inbound Webhooks?
When a customer sends a WhatsApp message, Meta's Cloud API sends an HTTP POST request to Sydx AI's server. These are inbound webhooks — data flowing into Sydx AI.
How They're Secured
1. Initial Verification (Handshake)
When you configure the webhook URL in the Meta Developer Console, Meta sends a verification request:
- Meta sends a
GETrequest with ahub.verify_tokenparameter - Sydx AI validates the token matches the configured verify token
- If valid, Sydx AI responds with the
hub.challengevalue - This proves Sydx AI owns the endpoint
2. Payload Verification (Every Message)
Every incoming webhook from Meta includes a cryptographic signature:
- Meta signs the request body using HMAC-SHA256 with your App Secret
- Sydx AI recalculates the signature and compares it
- If the signatures don't match, the request is rejected
- This prevents unauthorized parties from sending fake events
Outbound Webhooks (Sydx AI → Your Server)
What Are Outbound Webhooks?
When events occur in Sydx AI (new message, new contact, etc.), Sydx AI sends HTTP POST requests to URLs you configure. These are outbound webhooks — data flowing from Sydx AI to your servers.
How They're Secured
1. HMAC-SHA256 Signing
Every outbound webhook delivery is signed:
- Sydx AI generates a unique secret for each webhook (starts with
whsec_) - Before sending, the payload is signed using HMAC-SHA256 with this secret
- The signature is included in the
X-Sydx-Signatureheader - Your server should verify this signature to ensure the request is genuine
2. How to Verify the Signature
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your handler:
const signature = req.headers['x-sydx-signature'];
const isValid = verifySignature(req.body, signature, YOUR_WEBHOOK_SECRET);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
3. Security Headers
Every outbound delivery includes these headers:
| Header | Purpose |
|---|---|
X-Sydx-Signature | HMAC-SHA256 signature for verification |
X-Sydx-Event | Event type (e.g., message.received) |
X-Sydx-Timestamp | ISO 8601 timestamp of the event |
User-Agent | SydxAI-Webhook/1.0 — identifies the sender |
4. Secret Rotation
If you suspect your webhook secret has been compromised:
- Go to Settings → Outbound Webhooks
- Click "Rotate Secret" on the webhook
- A new secret is generated instantly
- Update the secret in your receiving application
- The old secret is immediately invalidated
General Security Measures
| Measure | Inbound (Meta → Sydx) | Outbound (Sydx → You) |
|---|---|---|
| HMAC-SHA256 Verification | ✅ | ✅ |
| HTTPS Required | ✅ | ✅ |
| Retry on Failure | Meta handles | 3 retries with exponential backoff |
| Secret Rotation | Via Meta Console | Via Sydx AI Settings |
| Audit Logging | ✅ Request logs | ✅ Delivery logs with status |
| Error Isolation | Errors don't crash services | Per-webhook error handling |
Best Practices
- Always verify signatures — Never process a webhook without checking the signature first
- Use HTTPS endpoints — Never use HTTP for webhook URLs
- Rotate secrets regularly — Change your webhook secrets every 90 days
- Respond quickly — Return
200 OKwithin 5 seconds; process data asynchronously - Implement idempotency — Handle duplicate deliveries gracefully
- Monitor delivery logs — Check the Delivery Logs tab regularly for failures
- Never log secrets — Don't print webhook secrets or API keys in your application logs