Webhooks Paid
Webhooks let you receive real-time HTTP notifications when audit events occur. Use them to integrate xcelera with Slack, PagerDuty, custom dashboards, or any system that accepts HTTP callbacks.
For an overview of notification types and levels, see Notifications.
Creating a webhook endpoint
- Go to Settings → Webhooks
- Click Add Endpoint
- Enter your HTTPS endpoint URL
- Choose a notification level (which events trigger this webhook)
- Save — xcelera generates a signing secret for verifying payloads
You can create up to 10 webhook endpoints per organization.
Notification level filtering
Each webhook endpoint has its own notification level, independent of your email notification preferences. This lets you route different event types to different systems — for example, send all events to a logging service but only failures to PagerDuty.
See Notifications for the full list of levels and what events they include.
Payload format
Webhook requests are sent as POST with a JSON body:
{
"version": "v1",
"event": "score_regressed",
"timestamp": "2025-01-15T10:30:00Z",
"data": {
"page": {
"id": "clx...",
"name": "Homepage",
"url": "https://example.com"
},
"auditId": "clx1abc23def",
"current": {
"categories": {
"performance": 72,
"accessibility": 95,
"bestPractices": 90,
"seo": 100
},
"audits": {
"lcp": 2400,
"tbt": 150,
"cls": 0.05,
"fcp": 1200,
"si": 2000
}
},
"previous": {
"categories": {
"performance": 85
}
},
"insights": [
{
"id": "render-blocking-insight",
"title": "Eliminate render-blocking resources",
"metricSavings": { "FCP": 200, "LCP": 350 }
}
]
}
}The event field is one of: audit_completed, score_regressed, or audit_failed. For failed audits, data.error contains the error code and message. The insights array is present when Lighthouse detects performance issues with potential savings.
Request headers
Each webhook request includes these headers:
| Header | Description |
|---|---|
X-Xcelera-Event | The event type (e.g. score_regressed) |
X-Xcelera-Timestamp | Unix timestamp (seconds) when the request was signed |
X-Xcelera-Signature | HMAC-SHA256 signature for verification |
Content-Type | application/json |
Verifying signatures
Every webhook request is signed so you can verify it came from xcelera. The signature is an HMAC-SHA256 hash of the timestamp and request body, using your endpoint's signing secret.
To verify:
- Read the
X-Xcelera-TimestampandX-Xcelera-Signatureheaders - Compute
HMAC-SHA256(secret, "{timestamp}.{body}") - Compare your computed signature with the header value
import crypto from 'node:crypto'
function verifyWebhook(body, secret, timestamp, signature) {
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${body}`)
.digest('hex')
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))
}See Security best practices for more on webhook verification.
Slack integration
xcelera automatically detects Slack webhook URLs and formats the payload as a Slack message with rich formatting — no middleware needed.
Failure handling
If a webhook delivery fails (non-2xx response or timeout after 10 seconds), xcelera tracks consecutive failures. After 5 consecutive failures, the endpoint is automatically disabled to prevent further errors.
You can re-enable a disabled endpoint from Settings → Webhooks after fixing the issue.
Disabled endpoints stop receiving all notifications. Check your webhook settings if you notice missing notifications.