Webhooks
Receive real-time notifications when content is published
Overview
Webhooks allow your application to receive real-time HTTP POST notifications when content is published or unpublished in FlareBuilder. Each webhook request is signed with HMAC-SHA256 for security verification.
Available Events
| Event | Trigger |
|---|---|
content.published | When content item is published or updated |
content.unpublished | When published content is unpublished |
Payload Format
All webhook requests send a JSON payload with the following structure:
{
"event": "content.published",
"timestamp": "2025-12-05T10:30:00Z",
"tenant_id": "abc123",
"data": {
"id": "content-uuid",
"title": "Sample Event",
"type": "Event",
"status": "published",
"date_published": "2025-12-05T10:30:00Z",
"description": "Event description",
"sections": {
"location": "123 Main St",
"event_start": "2025-12-10T18:00:00Z",
"event_end": "2025-12-10T21:00:00Z"
},
"tags": ["community", "event"],
"url": "https://tenant.flarebuilder.com/p/content-uuid"
}
}
Signature Verification
All webhook requests include an X-Webhook-Signature header containing an
HMAC-SHA256 signature of the payload. Verify this signature to ensure the request
originated from FlareBuilder.
const crypto = require('crypto');
// Express.js middleware example
function verifyWebhookSignature(req, res, next) {
const signature = req.headers['x-webhook-signature'];
const secret = process.env.WEBHOOK_SECRET;
// Get raw body
const payload = JSON.stringify(req.body);
// Compute HMAC
const hmac = crypto.createHmac('sha256', secret);
hmac.update(payload);
const expectedSignature = hmac.digest('hex');
// Constant-time comparison
if (crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
)) {
next();
} else {
res.status(401).json({ error: 'Invalid signature' });
}
}
// Usage
app.post('/webhook',
express.json(),
verifyWebhookSignature,
(req, res) => {
const { event, data } = req.body;
// Process webhook
processWebhook(event, data).catch(console.error);
res.status(200).json({ received: true });
}
);
import hmac
import hashlib
import os
from flask import Flask, request, jsonify
def verify_webhook_signature(payload, signature):
secret = os.environ.get('WEBHOOK_SECRET')
expected_signature = hmac.new(
secret.encode('utf-8'),
payload.encode('utf-8'),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected_signature)
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-Webhook-Signature')
payload = request.get_data(as_text=True)
if not verify_webhook_signature(payload, signature):
return jsonify({'error': 'Invalid signature'}), 401
data = request.get_json()
process_webhook.delay(data['event'], data['data'])
return jsonify({'received': True}), 200
<?php
function verifyWebhookSignature($payload, $signature) {
$secret = getenv('WEBHOOK_SECRET');
$expectedSignature = hash_hmac('sha256', $payload, $secret);
return hash_equals($expectedSignature, $signature);
}
$payload = file_get_contents('php://input');
$headers = getallheaders();
$signature = $headers['X-Webhook-Signature'] ?? '';
if (!verifyWebhookSignature($payload, $signature)) {
http_response_code(401);
echo json_encode(['error' => 'Invalid signature']);
exit;
}
$data = json_decode($payload, true);
processWebhook($data['event'], $data['data']);
http_response_code(200);
echo json_encode(['received' => true]);
?>
Delivery Behavior
- Success: HTTP 2xx response within 5 seconds
- Timeout: Requests timeout after 5 seconds
- Single Attempt: Webhooks are delivered once with no automatic retries
- Monitoring: Check your webhook's last delivery status in your dashboard
Best Practices
- Always verify the signature before processing the payload
- Respond with HTTP 200 immediately, process asynchronously if needed
- Use HTTPS endpoints for security
- Store your webhook secret securely (environment variables, secrets manager)
- Implement idempotency - handle duplicate events gracefully
Managing Webhooks
You can manage webhooks (create, update, delete) from your FlareBuilder dashboard. The maximum number of webhooks per organization is 3.