Skip to main content

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 includes flap_count, stable_fingerprint, and alt_fingerprint.
    • cert.flapping.resolve – Triggered once when the certificate fingerprint has been stable for a full hour after a flapping episode. The payload includes stable_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

  1. Extract the t (timestamp) and v1 (signature) values from the X-Webhook-Signature header.
  2. Build the signing payload by concatenating the timestamp, a period (.), and the raw request body: {t}.{body}
  3. Compute the HMAC-SHA256 of the signing payload using your webhook's Signing Secret.
  4. Compare your computed signature with the v1 value from the header.
  5. 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:

  1. Parse the t and v1 values from the X-Webhook-Signature header.
  2. Compute: HMAC-SHA256(key=signing_secret, message="{t}.{raw_body}").
  3. Compare your computed hex digest with v1 using a constant-time comparison.
  4. Optionally check that t is 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.