What's new
Panelica Community Forum

Welcome to the official Panelica Community Forum — the central hub for server administrators, developers, and hosting professionals. Register a free account today to access technical discussions, product announcements, feature requests, and direct support from the Panelica team. Be part of the growing community shaping the future of server management.

Webhooks --- Complete Guide

admin

Administrator
Staff member
Webhooks --- Complete Guide​

This guide covers everything about Panelica's webhook system --- creating webhooks, subscribing to events, configuring destinations (HTTP, Telegram, Slack, Discord), verifying signatures, monitoring deliveries, and handling retries.

What Are Webhooks?​

Webhooks are automated HTTP callbacks that notify your application when events happen on your Panelica server. Instead of constantly polling the API to check for changes, webhooks push notifications to your endpoint in real-time.

Example: When a new domain is created, Panelica instantly sends a POST request to your configured URL with the domain details.

Supported Destinations:
  • HTTP/HTTPS --- Send JSON payloads to any URL
  • Telegram --- Receive notifications in a Telegram chat or group
  • Slack --- Post messages to a Slack channel
  • Discord --- Send embeds to a Discord channel

---

Accessing Webhook Management​

Go to Developer > Webhooks in the panel navigation.

The page has 4 sections:

SectionDescription
Webhooks ListAll your configured webhooks with status and stats
Delivery LogsHistorical delivery attempts with request/response details
Event CategoriesBrowse all 160+ available events organized by category
StatisticsSuccess rate, average response time, delivery metrics

---

Creating a Webhook​

Step 1: Click Create Webhook.

Step 2: Fill in the general settings:

FieldRequiredDescription
NameYesA descriptive name (e.g., "Slack Domain Alerts", "Billing Webhook")
DescriptionNoOptional notes about this webhook's purpose
ActiveNoEnable/disable the webhook (default: active)

Step 3: Configure the destination (see destination-specific sections below).

Step 4: Select events to subscribe to (see Event Categories section).

Step 5: Configure retry settings:

FieldDefaultDescription
Retry Count3Maximum number of retry attempts on failure
Retry Delay60 secondsBase delay between retries (exponential backoff applied)
Timeout30 secondsMaximum time to wait for a response

Step 6: Click Create.

Step 7: Copy the webhook secret! A secret is generated:
Code:
whsec_a1b2c3d4e5f6789...
This secret is used to verify that incoming payloads are genuinely from Panelica. It is shown only at creation time and when regenerated.

---

Destination: HTTP/HTTPS​

Send JSON payloads to any HTTP endpoint.

Configuration:
FieldRequiredDescription
URLYesThe endpoint URL (must be HTTPS for production)
MethodNoHTTP method: POST (default), PUT, or PATCH
Custom HeadersNoAdditional headers to include in each request
TimeoutNoRequest timeout in seconds (default: 30)

Headers Sent with Each Request:
Code:
Content-Type: application/json
X-Panelica-Signature: sha256=a1b2c3d4e5f6...
X-Panelica-Event: domain.created
X-Panelica-Delivery: 550e8400-e29b-41d4-a716-446655440000
User-Agent: Panelica-Webhook/1.0

Payload Format:
Code:
{
 "event_type": "domain.created",
 "event_id": "evt_550e8400-e29b-41d4-a716-446655440000",
 "timestamp": "2026-03-07T12:00:00Z",
 "webhook_id": "uuid-of-webhook",
 "data": {
 "id": "domain-uuid",
 "domain": "example.com",
 "php_version": "8.4",
 "status": "active",
 "created_by": "admin"
 },
 "_meta": {
 "user_id": "user-uuid",
 "source_ip": "192.168.1.100"
 }
}

SSRF Protection: Panelica validates webhook URLs to prevent Server-Side Request Forgery:
  • Localhost and loopback addresses are blocked (127.0.0.1, ::1, 0.0.0.0)
  • Private network ranges are blocked (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
  • Link-local, multicast, and reserved ranges are blocked
  • DNS resolution is validated (hostname must resolve to a public IP)

---

Verifying Webhook Signatures​

When you receive a webhook, verify the X-Panelica-Signature header to ensure it's genuinely from Panelica.

How it works:
  1. Take the raw request body (JSON string)
  2. Compute HMAC-SHA256 using your webhook secret
  3. Compare with the X-Panelica-Signature header value (after removing the sha256= prefix)

Python Example:
Code:
import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_your_secret_here"

@app.route('/webhook', methods=['POST'])
def handle_webhook():
 # Get the signature from headers
 signature = request.headers.get('X-Panelica-Signature', '')
 if signature.startswith('sha256='):
 signature = signature[7:]

 # Compute expected signature
 body = request.get_data()
 expected = hmac.new(
 WEBHOOK_SECRET.encode(),
 body,
 hashlib.sha256
 ).hexdigest()

 # Constant-time comparison
 if not hmac.compare_digest(signature, expected):
 abort(401, 'Invalid signature')

 # Process the event
 payload = request.get_json()
 event_type = payload['event_type']

 if event_type == 'domain.created':
 domain = payload['data']['domain']
 print(f"New domain created: {domain}")
 elif event_type == 'backup.failed':
 print(f"Backup failed! Details: {payload['data']}")

 return '', 200

Node.js Example:
Code:
const crypto = require('crypto');
const express = require('express');
const app = express();

const WEBHOOK_SECRET = 'whsec_your_secret_here';

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
 const signature = req.headers['x-panelica-signature'] || '';
 const sig = signature.replace('sha256=', '');

 const expected = crypto
 .createHmac('sha256', WEBHOOK_SECRET)
 .update(req.body)
 .digest('hex');

 if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
 return res.status(401).send('Invalid signature');
 }

 const payload = JSON.parse(req.body);
 console.log(`Event: ${payload.event_type}`, payload.data);

 res.status(200).send('OK');
});

app.listen(3000);

PHP Example:
Code:
<?php
$secret = 'whsec_your_secret_here';
$body = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_PANELICA_SIGNATURE'] ?? '';

// Remove 'sha256=' prefix
$sig = str_replace('sha256=', '', $signature);

// Compute expected signature
$expected = hash_hmac('sha256', $body, $secret);

// Constant-time comparison
if (!hash_equals($expected, $sig)) {
 http_response_code(401);
 die('Invalid signature');
}

$payload = json_decode($body, true);
$eventType = $payload['event_type'];

switch ($eventType) {
 case 'domain.created':
 // Handle new domain
 break;
 case 'ssl.expiring_soon':
 // Send alert
 break;
}

http_response_code(200);
echo 'OK';

---

Destination: Telegram​

Receive webhook notifications as Telegram messages.

Prerequisites:
  1. Create a Telegram bot via @BotFather and get the bot token
  2. Add the bot to your group/channel or start a direct chat
  3. Get the chat ID (use @userinfobot or the Telegram API)

Configuration:
FieldRequiredDescription
Bot TokenYesToken from @BotFather (e.g., 123456:ABC-DEF...)
Chat IDYesTarget chat/group/channel ID
Parse ModeNoHTML (default), Markdown, or MarkdownV2
Disable NotificationsNoSend silently without notification sound

Message Format:
Panelica formats events as readable Telegram messages with HTML formatting:
Code:
 Panelica Webhook: domain.created

Event Details:
{
 "domain": "example.com",
 "php_version": "8.4",
 "status": "active"
}

---

Destination: Slack​

Post webhook notifications to a Slack channel.

Prerequisites:
  1. Go to your Slack workspace settings
  2. Create an Incoming Webhook (Apps > Incoming Webhooks)
  3. Select the target channel and copy the webhook URL

Configuration:
FieldRequiredDescription
Webhook URLYesSlack incoming webhook URL
ChannelNoOverride the default channel (e.g., #alerts)
UsernameNoOverride the bot username
Icon EmojiNoOverride the bot icon (e.g., :bell:)

Message Format:
Slack messages use Markdown formatting with code blocks:
Code:
* Panelica Webhook: domain.created*

```json
{
 "domain": "example.com",
 "php_version": "8.4"
}
```

---

Destination: Discord​

Send webhook notifications as Discord embeds.

Prerequisites:
  1. In your Discord server, go to Channel Settings > Integrations > Webhooks
  2. Create a webhook and copy the URL

Configuration:
FieldRequiredDescription
Webhook URLYesDiscord webhook URL
UsernameNoOverride the bot username
Avatar URLNoOverride the bot avatar image

Embed Colors:
Discord embeds are color-coded by event type:
  • Green --- Success events (created, started, issued, renewed)
  • Blue --- Update events (updated, changed, synced)
  • Red --- Delete/failure events (deleted, failed, expired)
  • Yellow --- Warning events (warning, expiring_soon, brute_force)
  • Gray --- Other events

---

Event Categories​

Panelica supports 160+ webhook events across 27 categories. Here are the most commonly used:

User Events
EventTriggered When
user.createdA new user account is created
user.updatedUser profile is updated
user.deletedUser account is deleted
user.suspendedUser account is suspended
user.unsuspendedUser account is unsuspended
user.loginSuccessful login
user.login_failedFailed login attempt
user.password_changedPassword changed
user.2fa_enabledTwo-factor authentication enabled
user.2fa_disabledTwo-factor authentication disabled
user.role_changedUser role changed (e.g., USER to RESELLER)

Domain Events
EventTriggered When
domain.createdNew domain added
domain.updatedDomain settings changed
domain.deletedDomain removed
domain.suspendedDomain suspended
domain.unsuspendedDomain activated
domain.php_updatedPHP version changed
domain.webserver_changedWeb server switched (Nginx/Apache)

SSL Events
EventTriggered When
ssl.issuedNew SSL certificate issued
ssl.renewedCertificate renewed
ssl.expiredCertificate expired
ssl.expiring_soonCertificate expiring within 14 days
ssl.auto_renew_failedAuto-renewal failed

Security Events
EventTriggered When
security.ip_blockedIP address blocked (manual or Fail2ban)
security.brute_force_detectedBrute force attack detected
security.modsec_triggeredModSecurity WAF rule triggered
security.malware_detectedClamAV found malware
security.ssh_loginSSH login detected

Backup Events
EventTriggered When
backup.createdBackup completed successfully
backup.failedBackup failed
backup.restoredBackup restored
backup.uploaded_remoteBackup uploaded to remote storage

System Events
EventTriggered When
system.service_startedA system service started
system.service_stoppedA system service stopped
system.service_failedA system service failed
system.disk_warningDisk usage exceeds threshold
system.cpu_warningCPU usage exceeds threshold
system.memory_warningMemory usage exceeds threshold
system.update_availablePanel update available

Quota Events
EventTriggered When
quota.disk_warningDisk quota approaching limit
quota.disk_exceededDisk quota exceeded
quota.bandwidth_warningBandwidth approaching limit
quota.bandwidth_exceededBandwidth exceeded
quota.domain_limit_reachedMaximum domain count reached

Monitoring Alerts
EventTriggered When
monitor.alert_triggeredMonitoring alert threshold exceeded
monitor.alert_resolvedAlert condition resolved
monitor.service_downMonitored service went down
monitor.service_upMonitored service recovered
monitor.domain_downWebsite unreachable
monitor.domain_upWebsite recovered

Additional Categories:
  • DNS Events --- zone creation/deletion, record changes, propagation
  • Subdomain Events --- creation, update, deletion
  • Database Events --- database/user creation, deletion, backup, import
  • Email Events --- account creation, quota warnings, forwarding changes
  • FTP Events --- account creation, login attempts
  • Cron Events --- job creation, execution, failures
  • File Events --- uploads, deletions, permission changes
  • Docker Events --- container creation, start, stop, deletion
  • WordPress Events --- installation, uninstallation
  • CloudFlare Events --- DNS sync, domain sync
  • Migration Events --- started, completed, failed
  • SSH Events --- session start/end, login success/failure
  • Terminal Events --- session management
  • Plan Events --- plan creation, user assignment
  • API Events --- key creation, rate limit exceeded
  • Antivirus Events --- scan completed, threat detected
  • Snapshot Events --- creation, restoration, deletion

---

Delivery & Retry System​

Processing Architecture:
  • Asynchronous --- Events are queued and processed by a worker pool (5 workers)
  • Non-blocking --- Event queue holds up to 1,000 events
  • Parallel --- Multiple webhooks for the same event are delivered concurrently

Retry Strategy (Exponential Backoff):

AttemptDelayDescription
1st attemptImmediateFirst delivery attempt
1st retry1 minuteFirst retry after failure
2nd retry5 minutesSecond retry with increased delay
3rd retry30 minutesFinal retry attempt

After 3 failed retries, the delivery is marked as permanently failed.

Success Criteria:
  • HTTP 2xx status code = Success
  • Any other status code (3xx, 4xx, 5xx) = Failure (triggers retry)
  • Connection timeout = Failure
  • DNS resolution failure = Failure

---

Delivery Logs​

Every webhook delivery attempt is logged with full details.

Log Entry Fields:
FieldDescription
Event TypeThe event that triggered the delivery
Event IDUnique event identifier (evt_uuid)
Statuspending, success, or failed
Status CodeHTTP response status code
Response TimeTime to receive response (milliseconds)
Request PayloadFull JSON payload sent
Response BodyResponse received (max 10KB)
Error MessageError details if delivery failed
Retry CountNumber of retry attempts made
Next Retry AtScheduled time for next retry
Created AtWhen the delivery was initiated

Actions:
  • View Details --- See full request payload and response body
  • Retry --- Manually retry a failed delivery
  • Filter --- Filter by event type, status, or date range

---

Statistics Dashboard​

The statistics section provides an overview of webhook health:

  • Total Webhooks --- Number of configured webhooks
  • Active Webhooks --- Currently enabled webhooks
  • Deliveries (24h) --- Total deliveries in the last 24 hours
  • Success Rate (24h) --- Percentage of successful deliveries
  • Failed Deliveries (24h) --- Number of failed deliveries
  • Average Response Time --- Mean response time in milliseconds

---

Managing Webhooks​

Available Actions:

ActionDescription
EditUpdate name, destination, events, retry settings
Toggle ActiveEnable or disable the webhook
TestSend a test event to verify the endpoint works
Regenerate SecretGenerate a new signing secret (old one invalidated)
View LogsSee delivery history for this specific webhook
DeleteRemove the webhook permanently

Testing a Webhook:
  1. Click the Test button on any webhook
  2. A test event is sent with sample data
  3. Check the delivery logs to verify it was received
  4. For Telegram/Slack/Discord: check the target channel for the test message

---

Common Use Cases​

1. Billing Integration (WHMCS/Blesta)
Subscribe to user and domain events to sync with your billing system:
Code:
Events: user.created, user.deleted, user.suspended,
 domain.created, domain.deleted,
 plan.user_assigned, plan.user_changed

2. Security Monitoring
Get instant alerts for security events:
Code:
Events: security.ip_blocked, security.brute_force_detected,
 security.modsec_triggered, security.malware_detected,
 user.login_failed

3. SSL Certificate Monitoring
Never miss an SSL expiration:
Code:
Events: ssl.expiring_soon, ssl.expired,
 ssl.auto_renew_failed, ssl.renewed

4. Backup Monitoring
Ensure backups are running successfully:
Code:
Events: backup.created, backup.failed,
 backup.restored, backup.uploaded_remote

5. Server Health Alerts (Telegram)
Real-time server status in your Telegram group:
Code:
Events: system.service_failed, system.disk_warning,
 system.cpu_warning, system.memory_warning,
 monitor.service_down, monitor.service_up

6. DevOps Notifications (Slack)
Development team notifications:
Code:
Events: domain.created, domain.deleted,
 database.created, system.update_available,
 docker.container_started, docker.container_stopped

---

Permissions (RBAC)​

FeatureROOTADMINRESELLERUSER
Create webhooksYesYesYesYes
View all webhooksAllOwn chainOwnOwn
Event subscriptionsAll eventsFilteredFilteredOwn events only
View delivery logsAllOwnOwnOwn
View statisticsGlobalOwnOwnOwn

---

Troubleshooting​

Problem: Webhook not receiving events
  • Check the webhook status is "Active" (not "Inactive" or "Failed")
  • Verify the subscribed events match the events you expect
  • Check delivery logs for error messages
  • Test the webhook manually using the Test button

Problem: Signature verification failing
  • Ensure you're using the correct webhook secret
  • Read the raw body before parsing (don't parse then re-serialize)
  • Use constant-time comparison for the signature check
  • Check that you're removing the sha256= prefix from the header

Problem: Deliveries failing with timeout
  • Ensure your endpoint responds within the configured timeout (default 30s)
  • Return HTTP 200 immediately, then process the event asynchronously
  • Check network connectivity between your server and the endpoint

Problem: Telegram messages not arriving
  • Verify the bot token is correct (test with Telegram API directly)
  • Ensure the bot is added to the target chat/group
  • Check the chat ID is correct (use @userinfobot)
  • For groups: make sure the bot has permission to send messages

Problem: Duplicate events received
  • This can happen during retries --- use the event_id field for deduplication
  • Store processed event IDs and skip duplicates in your handler

---

Best Practices​

  1. Respond quickly --- Return HTTP 200 within 5 seconds. Process heavy tasks asynchronously after acknowledging
  2. Always verify signatures --- Don't trust webhook payloads without verifying the HMAC signature
  3. Use HTTPS endpoints --- Always use HTTPS URLs for HTTP webhook destinations
  4. Implement idempotency --- Handle duplicate events gracefully using event_id
  5. Monitor delivery logs --- Check for failed deliveries regularly
  6. Subscribe selectively --- Only subscribe to events you actually need
  7. Rotate secrets periodically --- Use the Regenerate Secret feature to rotate webhook secrets
  8. Use Telegram/Slack for alerts --- Quick setup for instant notifications without building an endpoint

---

Related Topics​

 
Last edited:
Back
Top