Zum Inhalt

Webhooks

Webhooks ermöglichen es, externe Systeme automatisch über Ereignisse in enconf zu informieren. Bei jedem konfigurierten Ereignis sendet das Panel eine HTTP-POST-Anfrage mit den Ereignisdaten an Ihre URL.

Typische Anwendungsfälle:

  • Automatische Deployment-Pipelines nach Website-Erstellung
  • Benachrichtigungen an Chat-Systeme (Slack, Microsoft Teams, Discord)
  • Synchronisierung mit Billing-Systemen
  • Monitoring und Logging in externe Plattformen

Funktionsweise

Ereignis im Panel → Webhook-Service → HTTP POST an Ihre URL
                                     ↓
                            Signatur (HMAC-SHA256) im Header
                                     ↓
                            Ihr Server verifiziert und verarbeitet
  1. Ein Ereignis tritt im Panel auf (z. B. Website erstellt)
  2. Das Panel findet alle aktiven Webhook-Endpoints, die auf dieses Ereignis abonniert sind
  3. Für jeden Endpoint wird ein HTTP-POST mit dem JSON-Payload gesendet
  4. Der Payload wird mit HMAC-SHA256 signiert
  5. Bei Fehlschlag wird ein automatischer Retry durchgeführt

Webhook-Endpoint erstellen

Über die API

POST /api/v1/webhooks
Authorization: Bearer <token>
Content-Type: application/json

{
  "url": "https://ihr-server.de/webhook",
  "secret": "IhrGeheimesWebhookSecret",
  "events": "site.created,site.deleted,backup.completed",
  "active": true
}
Feld Pflicht Beschreibung
url Ja Die URL, an die Ereignisse gesendet werden (muss HTTPS sein)
secret Ja Geheimer Schlüssel für die HMAC-SHA256-Signatur
events Ja Komma-getrennte Liste der gewünschten Ereignisse (oder * für alle)
active Nein Endpoint aktivieren/deaktivieren (Standard: true)

Über das Panel

  1. Navigieren Sie zu Einstellungen → Webhooks
  2. Klicken Sie auf Webhook erstellen
  3. Füllen Sie URL, Secret und Ereignisse aus
  4. Klicken Sie auf Erstellen

Verfügbare Ereignisse

Ereignis Beschreibung Payload-Daten
site.created Website wurde erstellt site_id, domain
site.deleted Website wurde gelöscht site_id, domain
domain.created Domain wurde hinzugefügt domain_id, name
domain.deleted Domain wurde entfernt domain_id, name
database.created Datenbank wurde erstellt database_id, name
database.deleted Datenbank wurde gelöscht database_id, name
email.created E-Mail-Postfach wurde erstellt mailbox_id, email
ftp.created FTP-Konto wurde erstellt ftp_account_id, username
backup.completed Backup wurde abgeschlossen schedule_id, name
subscription.created Abonnement wurde erstellt subscription_id, main_domain
subscription.suspended Abonnement wurde gesperrt subscription_id, main_domain
webhook.test Test-Ereignis (manuell ausgelöst) message

Wildcard-Abonnement

Verwenden Sie * als Ereignis, um alle Ereignisse zu empfangen:

{
  "events": "*"
}

Payload-Format

Jeder Webhook-Aufruf sendet einen JSON-Body mit folgendem Format:

{
  "event": "site.created",
  "timestamp": "2026-03-31T14:30:00Z",
  "data": {
    "site_id": 42,
    "domain": "meine-seite.de"
  }
}
Feld Typ Beschreibung
event String Name des Ereignisses
timestamp String Zeitpunkt des Ereignisses (RFC 3339, UTC)
data Object Ereignisspezifische Daten

HTTP-Header

Jede Webhook-Anfrage enthält folgende Header:

Header Beschreibung
Content-Type application/json
User-Agent NetCell-WebPanel-Webhook/1.0
X-Webhook-Event Name des Ereignisses (z. B. site.created)
X-Webhook-Signature HMAC-SHA256-Signatur (siehe unten)

HMAC-Signaturverifizierung

Jede Webhook-Anfrage wird mit HMAC-SHA256 signiert, damit Sie die Authentizität und Integrität des Payloads verifizieren können.

Signatur-Format

X-Webhook-Signature: sha256=<hex-encoded-hmac>

Verifizierungsschritte

  1. Lesen Sie den rohen Request-Body (als Byte-Array)
  2. Berechnen Sie HMAC-SHA256 mit Ihrem Secret als Schlüssel
  3. Vergleichen Sie das Ergebnis mit dem Wert aus X-Webhook-Signature
  4. Akzeptieren Sie die Anfrage nur bei Übereinstimmung

Beispiel: PHP

<?php
$secret = 'IhrGeheimesWebhookSecret';
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';

// Erwartete Signatur berechnen
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);

// Timing-sichere Vergleichsfunktion verwenden
if (!hash_equals($expected, $signature)) {
    http_response_code(403);
    die('Invalid signature');
}

// Payload verarbeiten
$data = json_decode($payload, true);
$event = $data['event'];

switch ($event) {
    case 'site.created':
        // Website wurde erstellt
        $siteId = $data['data']['site_id'];
        $domain = $data['data']['domain'];
        // Ihre Logik hier...
        break;

    case 'backup.completed':
        // Backup abgeschlossen
        break;
}

http_response_code(200);
echo json_encode(['status' => 'ok']);

Beispiel: Python

import hmac
import hashlib
import json
from flask import Flask, request, abort

app = Flask(__name__)
SECRET = 'IhrGeheimesWebhookSecret'

@app.route('/webhook', methods=['POST'])
def handle_webhook():
    # Signatur verifizieren
    signature = request.headers.get('X-Webhook-Signature', '')
    expected = 'sha256=' + hmac.new(
        SECRET.encode(),
        request.data,
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(expected, signature):
        abort(403, 'Invalid signature')

    # Payload verarbeiten
    data = request.json
    event = data['event']

    if event == 'site.created':
        site_id = data['data']['site_id']
        domain = data['data']['domain']
        # Ihre Logik hier...

    return {'status': 'ok'}, 200

Beispiel: Node.js

const crypto = require('crypto');
const express = require('express');
const app = express();

const SECRET = 'IhrGeheimesWebhookSecret';

app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webhook-signature'] || '';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', SECRET)
    .update(req.body)
    .digest('hex');

  if (!crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature)
  )) {
    return res.status(403).json({ error: 'Invalid signature' });
  }

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

  res.json({ status: 'ok' });
});

app.listen(3000);

Signatur immer prüfen

Verarbeiten Sie Webhook-Payloads niemals ohne Signaturprüfung. Ohne Verifizierung könnte ein Angreifer gefälschte Ereignisse an Ihre URL senden.

Timing-sichere Vergleiche

Verwenden Sie immer timing-sichere Vergleichsfunktionen (hash_equals in PHP, hmac.compare_digest in Python, crypto.timingSafeEqual in Node.js), um Timing-Angriffe zu verhindern.


Retry-Verhalten

Wenn Ihr Server nicht mit einem HTTP-Statuscode im Bereich 2xx antwortet, führt das Panel automatisch einen Retry durch:

Versuch Zeitpunkt
1. Versuch Sofort
2. Versuch (Retry) 2 Sekunden nach dem ersten Fehlschlag

Nach zwei Fehlversuchen wird die Zustellung als fehlgeschlagen markiert und im Delivery-Log protokolliert.

Timeout

Ihr Server muss innerhalb von 10 Sekunden antworten. Anfragen, die länger dauern, werden als fehlgeschlagen gewertet.

Empfehlungen für Ihren Webhook-Server

  • Antworten Sie sofort mit HTTP 200 und verarbeiten Sie den Payload asynchron
  • Implementieren Sie Idempotenz — derselbe Event kann doppelt zugestellt werden
  • Loggen Sie eingehende Webhooks für Debugging-Zwecke

Delivery-Logs

Das Panel speichert die letzten 100 Zustellversuche pro Webhook-Endpoint.

Logs abrufen

GET /api/v1/webhooks/:id/deliveries
Authorization: Bearer <token>

Log-Einträge

Feld Beschreibung
id Eindeutige ID des Zustellversuchs
event Ausgelöstes Ereignis
payload Der gesendete JSON-Payload
status_code HTTP-Statuscode der Antwort (0 bei Verbindungsfehler)
response Antwort-Body Ihres Servers (max. 4 KB)
success Ob die Zustellung erfolgreich war
duration_ms Dauer der Anfrage in Millisekunden
created_at Zeitpunkt des Zustellversuchs

Logs im Panel einsehen

  1. Navigieren Sie zu Einstellungen → Webhooks
  2. Klicken Sie auf einen Webhook-Endpoint
  3. Im Tab Zustellungen sehen Sie den Verlauf aller Zustellversuche

Test-Webhook senden

Um Ihre Integration zu testen, können Sie ein Test-Ereignis manuell auslösen:

POST /api/v1/webhooks/:id/test
Authorization: Bearer <token>

Dies sendet ein webhook.test-Ereignis mit Testdaten an die konfigurierte URL.

Oder im Panel:

  1. Öffnen Sie den Webhook-Endpoint
  2. Klicken Sie auf Test senden
  3. Prüfen Sie die Zustellung im Delivery-Log

Webhook verwalten

Endpoint aktualisieren

PUT /api/v1/webhooks/:id
Authorization: Bearer <token>
Content-Type: application/json

{
  "url": "https://neue-url.de/webhook",
  "events": "site.created,domain.created",
  "active": true
}

Endpoint löschen

DELETE /api/v1/webhooks/:id
Authorization: Bearer <token>

Endpoint deaktivieren

Setzen Sie active auf false, um einen Endpoint vorübergehend zu deaktivieren, ohne ihn zu löschen:

{
  "active": false
}

Best Practices

Empfehlung Beschreibung
HTTPS verwenden Nutzen Sie immer HTTPS für Ihre Webhook-URL
Signatur prüfen Verifizieren Sie jede Anfrage mit dem HMAC-Secret
Schnell antworten Antworten Sie innerhalb von 2 Sekunden, verarbeiten Sie asynchron
Idempotenz Rechnen Sie damit, dass Events doppelt zugestellt werden
Fehlertoleranz Loggen und monitoren Sie fehlgeschlagene Zustellungen
Secret rotieren Ändern Sie Ihr Webhook-Secret regelmäßig
IP-Whitelist Beschränken Sie den Zugriff auf Ihre Webhook-URL auf die Panel-IP