Zum Inhalt springen

Webhook-Events

Webhooks im Format JSON sind ein POST mit diesem Body. Einrichten: Webhooks.

{
"id": "…",
"event": "server.state_changed",
"createdAt": "2026-10-11T12:00:00Z",
"tenantId": "…",
"server": { "id": "…", "name": "DayZ" },
"data": { "state": "offline" }
}
Event data
server.state_changed { "state" }: nur running, offline oder installFailed, gesendet, sobald der Zustand 15 Sekunden lang besteht und sich vom zuletzt gesendeten unterscheidet. Für jede Änderung verwende den Konsolen-Stream.
server.created { "template", "node" }
server.deleted {}
server.install_finished { "succeeded", "exitCode" }
ping gesendet von Test
  • X-Panel-Event: das Event
  • X-Panel-Delivery: eine eindeutige ID; damit erkennst du wiederholte Zustellungen
  • X-Panel-Signature: t=1760184000,v1=<hex HMAC-SHA256(secret, "1760184000." + raw body)>
  1. Berechne den HMAC über t + "." + body neu, mit den Rohbytes, wie sie angekommen sind.
  2. Vergleiche in konstanter Zeit.
  3. Lehne Zeitstempel ab, die älter als ein paar Minuten sind.
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(secret, header, rawBody) {
const { t, v1 } = Object.fromEntries(header.split(',').map((p) => p.split('=')));
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
const expected = createHmac('sha256', secret).update(`${t}.`).update(rawBody).digest();
const given = Buffer.from(v1, 'hex');
return given.length === expected.length && timingSafeEqual(given, expected);
}
  • Jede Antwort 2xx gilt als zugestellt.
  • Sonst versucht es das Panel erneut nach 1, 2, 4 … bis 60 Minuten, insgesamt 8 Versuche.
  • Weiterleitungen werden nicht befolgt.