Using Web Hooks
Webhooks provide real-time programmatic event notifications for your monitoring services, billing, and account status. For detailed information about webhook schema's and formatting, see the Webhooks section of the API documentation.
Adding a Webhook
To add a new Webhook, click Add Webhook from the the Development ➡️ Webhooks section of the Portal, and provide a Display Name, the publicly accessible HTTP(s) URL for your webhook endpoint, and select one or more Events to trigger your webhook.

Webhooks are triggered using application/json POSTs to your endpoint.
Events
Each webhook can be configured to receive one or more Events from our platform, currently available in the following categories:
-
Billing Events – provides billing related event data, including payment alerts, renewal notices, and more.
billing.balance.alert– Triggered when your account balance goes below your alert threshold.billing.recharge.success– Triggered when an auto-recharge is successful.billing.recharge.failed– Triggered when an auto-recharge attempt fails.billing.renewal.success– Triggered when your billing package is successfully renewed.billing.renewal.failed– Triggered when a package renewal attempt fails.expiring.card.alert– Triggered when one of your credit cards is about to expire.expiring.plan.alert– Triggered when your monthly plan is set to expire and auto-renewal is disabled.
-
RBL Monitoring Events – provides real-time RBL monitoring event data, related to hosts being monitored on your account.
rbl.host.check.started– Triggered when a check is started for one of your hosts.rbl.host.check.completed– Triggered when a check completes for one of your hosts.rbl.host.listed– Triggered when one of your hosts becomes listed.rbl.host.delisted– Triggered when one of your hosts becomes delisted.
-
Certificate Monitoring Events – provides real-time certificate monitoring event data, related to monitors configured on your account.
cert.expiration.trigger– Triggered when a certificate expiration threshold is crossed.cert.expiration.resolve– Triggered when an expiring certificate is renewed.cert.error.trigger– Triggered when new certificate errors are detected.cert.error.resolve– Triggered when previously detected certificate errors are resolved.cert.changed– Triggered when a certificate changes without a renewal.cert.flapping– Triggered once when three or more certificate fingerprint changes are detected within a one-hour window. This typically indicates that CDN or load-balancer nodes are serving different certificates. The payload includesflap_count,stable_fingerprint, andalt_fingerprint.cert.flapping.resolve– Triggered once when the certificate fingerprint has been stable for a full hour after a flapping episode. The payload includesstable_fingerprint.
-
Agent Events – provides real-time event data related to monitoring agents configured on your account.
agent.timeout– Triggered when a persistent monitoring agent instance stops checking in and exceeds its configured timeout threshold. The payload includes the agent name and SID, the instance identifier and IP addresses, the last check-in timestamp, and the configured timeout in minutes.agent.timeout.resolve– Triggered when a monitoring agent instance that had timed out resumes checking in. The payload includes the agent name and SID, and the instance identifier and IP addresses.
New event types are regularly added to the system to provide real-time data related to your account.
Verifying Webhook Signatures (Optional)
Each webhook is assigned a unique Signing Secret, visible in the Edit Webhook panel of the Portal. You can use this secret to verify that incoming requests were sent by our platform and have not been tampered with.
Every webhook request includes an X-Webhook-Signature header in the format:
X-Webhook-Signature: t=1738900000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd
Where t is the Unix timestamp of when the request was sent, and v1 is the HMAC-SHA256 signature.
How Verification Works
- Extract the
t(timestamp) andv1(signature) values from theX-Webhook-Signatureheader. - Build the signing payload by concatenating the timestamp, a period (
.), and the raw request body:{t}.{body} - Compute the HMAC-SHA256 of the signing payload using your webhook's Signing Secret.
- Compare your computed signature with the
v1value from the header. - Optionally, check that the timestamp is within an acceptable window (e.g., 5 minutes) to prevent replay attacks.
Verification with Official SDKs
Our official SDKs provide a Webhook.verify() helper that handles header parsing, HMAC computation, constant-time comparison, and timestamp tolerance checking. This is the recommended approach.
PHP
use GeneratorLabs\Webhook;
$header = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$body = file_get_contents('php://input');
try {
$payload = Webhook::verify($body, $header, $signing_secret);
// $payload contains the decoded event data
} catch (GeneratorLabs\Exception $e) {
http_response_code(403);
}
Python
from generatorlabs import Webhook
header = request.headers.get('X-Webhook-Signature', '')
body = request.get_data(as_text=True)
try:
payload = Webhook.verify(body, header, signing_secret)
# payload contains the decoded event data
except Exception:
return jsonify({'error': 'Invalid signature'}), 403
Node.js
import { Webhook } from 'generatorlabs';
const header = req.headers['x-webhook-signature'];
const body = req.body; // raw string body
try {
const payload = Webhook.verify(body, header, signingSecret);
// payload contains the decoded event data
} catch (error) {
res.status(403).json({ error: 'Invalid signature' });
}
Go
import generatorlabs "github.com/generator-labs/go-sdk"
header := r.Header.Get("X-Webhook-Signature")
body, _ := io.ReadAll(r.Body)
payload, err := generatorlabs.VerifyWebhook(string(body), header, signingSecret, generatorlabs.DefaultWebhookTolerance)
if err != nil {
http.Error(w, "Invalid signature", http.StatusForbidden)
return
}
// payload contains the decoded event data
Ruby
require 'generatorlabs'
header = request.env['HTTP_X_WEBHOOK_SIGNATURE'] || ''
body = request.body.read
begin
payload = GeneratorLabs::Webhook.verify(body, header, signing_secret)
# payload contains the decoded event data
rescue GeneratorLabs::Error
halt 403, { error: 'Invalid signature' }.to_json
end
All SDKs default to a 5-minute timestamp tolerance window. You can customize this (in seconds) via an optional parameter, or pass 0 to disable timestamp checking.
Each SDK repository includes a complete webhook verification example in the examples/ directory. See the SDK README for your language for details.
Manual Verification
If you prefer not to use an SDK, you can verify signatures manually:
- Parse the
tandv1values from theX-Webhook-Signatureheader. - Compute:
HMAC-SHA256(key=signing_secret, message="{t}.{raw_body}"). - Compare your computed hex digest with
v1using a constant-time comparison. - Optionally check that
tis within an acceptable time window.
$header = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$body = file_get_contents('php://input');
// Parse the header
preg_match('/t=(\d+),v1=([a-f0-9]+)/', $header, $matches);
$timestamp = $matches[1] ?? '';
$signature = $matches[2] ?? '';
// Check timestamp tolerance (5 minutes)
if (abs(time() - intval($timestamp)) > 300) {
http_response_code(403);
exit;
}
// Compute and compare the signature
$expected = hash_hmac('sha256', $timestamp . '.' . $body, $signing_secret);
if (hash_equals($expected, $signature)) {
$payload = json_decode($body, true);
// Signature is valid, process the event
}
Regenerating a Signing Secret
You can regenerate a webhook's Signing Secret at any time from the Edit Webhook panel. After regeneration, the previous secret will no longer produce valid signatures — make sure to update your application with the new secret.
Testing
You can test your Webhook configuration by clicking on the Send Test link on the desired Webhook, and selecting the event type from the Event drop-down.
After you click the Sent Test Request button on the testing dialog, you'll receive test results, including response code and timing, TLS information, and response headers.