Webhooks — Real-time Event Notifications

Webhooks notify your application in real-time when email events occur — deliveries, bounces, opens, clicks, and more. Instead of polling the API, your server receives HTTP POST requests instantly.

Supported Events

Event Description When It Fires
delivered Email delivered to recipient Recipient’s mail server accepted the email
bounced Email bounced Recipient address invalid (hard) or mailbox full (soft)
opened Email opened Recipient opened the email (tracking pixel loaded)
clicked Link clicked Recipient clicked a tracked link
complained Spam complaint Recipient marked the email as spam
failed Delivery failed Email could not be sent after all retry attempts

Setting Up Webhooks

  1. Go to https://platform.cyberpersons.com/email/webhooks/
  2. Click Create Webhook
  3. Enter your endpoint URL (must be HTTPS in production)
  4. Select which events to subscribe to
  5. Click Create — note the signing secret for verification

Webhook Payload

Each webhook sends a JSON POST request to your endpoint:

{
  "event": "delivered",
  "timestamp": "2026-02-23T10:30:02Z",
  "data": {
    "message_id": "[email protected]",
    "from": "[email protected]",
    "to": "[email protected]",
    "subject": "Order Confirmation",
    "tags": ["order"],
    "metadata": {"order_id": "12345"}
  }
}

For bounce events, additional fields are included:

{
  "event": "bounced",
  "data": {
    "message_id": "...",
    "bounce_type": "hard",  // "hard", "soft", or "complaint"
    "error_message": "550 User not found"
  }
}

Security: Verifying Webhook Signatures

Every webhook request includes an X-Webhook-Signature header with an HMAC-SHA256 signature. Always verify this to confirm the request came from CyberPanel.

Python

import hmac, hashlib

def verify_signature(payload_body, signature, secret):
    expected = hmac.new(
        secret.encode(),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

Node.js

const crypto = require('crypto');

function verifySignature(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expected), Buffer.from(signature)
  );
}

PHP

function verifySignature($body, $signature, $secret) {
    $expected = hash_hmac('sha256', $body, $secret);
    return hash_equals($expected, $signature);
}

Retry Policy

  • If your endpoint returns a non-2xx status, we retry with exponential backoff
  • After 10 consecutive failures, the webhook is automatically disabled
  • You can re-enable disabled webhooks from the dashboard
  • Use the Test button in the dashboard to send a test event to your endpoint

Related Guides

← Back to Documentation Hub

Table of Contents