Guides

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

  1. Go to Settings → Webhooks
  2. Click Add Endpoint
  3. Enter your HTTPS endpoint URL
  4. Choose a notification level (which events trigger this webhook)
  5. Save — xcelera generates a signing secret for verifying payloads

You can create up to 10 webhook endpoints per organization.

Webhook URLs must use HTTPS.

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:

HeaderDescription
X-Xcelera-EventThe event type (e.g. score_regressed)
X-Xcelera-TimestampUnix timestamp (seconds) when the request was signed
X-Xcelera-SignatureHMAC-SHA256 signature for verification
Content-Typeapplication/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:

  1. Read the X-Xcelera-Timestamp and X-Xcelera-Signature headers
  2. Compute HMAC-SHA256(secret, "{timestamp}.{body}")
  3. 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.

Help