Webhooks
Webhooks allow you to receive real-time notifications when your dashboard generation completes, eliminating the need to poll the status endpoint.
Overview
If a webhook is configured (one per user) and the request used the API key, Alloy will POST a dashboard.ready event to your webhook URL when processing completes.
Configuration
Configure your webhook URL in the Alloy dashboard. Only one webhook URL can be configured per user account.
Security: Signature Verification
All webhook requests include a signature header that you must verify to ensure the request is authentic and hasn't been tampered with.
Always verify the signature before processing the webhook payload.
Signature Header
The request always includes:
X-Alloy-Signature: HMAC SHA256 signature of the raw JSON body, using the SHA256 hash of your API key as the secret.
The secret is calculated as:
secret = sha256(b"alloy_<your_key>").hexdigest()Webhook Payload
The webhook payload includes the following fields:
generation_id- The ID of the generation requestdashboard_id- The ID of the generated dashboarddataset_id- The ID of the uploaded datasettitle- The dashboard titleshare_link_id- The ID of the share linkshare_url- The URL to view the dashboard
Example Webhook Payload
{
"event": "dashboard.ready",
"timestamp": "2025-01-08T10:16:12.456Z",
"data": {
"generation_id": "af52d214-...",
"dashboard_id": "d6ad65c0-...",
"dataset_id": "1b0b7d3e-...",
"title": "Q3 Sales Overview",
"share_link_id": "4a5b...",
"share_url": "https://api.example.com/share/4a5b.../view/"
}
}Verifying the Signature
Python Example
import hashlib, hmac, json
payload_bytes = request.body # raw bytes
signature = request.headers.get("X-Alloy-Signature")
# Derive the secret Alloy used: sha256 of your API key string
api_key_hash = hashlib.sha256(b"alloy_yourapikey").hexdigest()
expected = hmac.new(
api_key_hash.encode("utf-8"),
payload_bytes,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(signature, expected):
raise ValueError("Invalid webhook signature")Node.js Example
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, apiKey) {
// Derive the secret: SHA256 hash of the API key
const secret = crypto
.createHash('sha256')
.update(`alloy_${apiKey}`)
.digest('hex');
// Calculate expected signature
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
// Use timing-safe comparison
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// Usage
const isValid = verifyWebhookSignature(
request.body,
request.headers['x-alloy-signature'],
'yourapikey'
);
if (!isValid) {
throw new Error('Invalid webhook signature');
}Best Practices
Testing Webhooks
You can test your webhook endpoint using tools like:
https://ngrok.com/ (ngrok) - Expose local server to the internet
https://webhook.site/ (webhook.site) - Temporary webhook testing service
https://www.postman.com/ (Postman) - API testing tool
Last updated