Webhooks for Slack, Discord and n8n, signed
Every action KLYRN VM records can be posted to your URL within a second, signed with HMAC-SHA256, or as a ready Slack or Discord message.
A virtualisation panel that only talks to its own browser tab makes everything around it poll. KLYRN VM now pushes: every action the Activity page records, and every task that finishes, can be posted to URLs you choose.
What is sent
{"id":"evt_3f2a...","event":"vm.create","result":"ok","target":"vm:41",
"actor":"ops@example.com","task_id":9001,"at":"2026-09-28T12:00:00Z",
"controller":"panel.example.com"}
Each webhook has a filter: everything (*), an exact code such as vm.create, or a family such as vm.*, node.* or backup.*. The codes are the same ones the Activity page shows, so there is one list to learn.
Slack and Discord without a relay
Choose Slack or Discord when adding a webhook and paste the incoming-webhook URL those services give you. KLYRN sends one readable line in the field each of them posts as a message, for example vm.create FAILED on vm:41 by ops@example.com. No middleware, no bot.
Signed, so your endpoint can trust it
Every request carries X-Klyrn-Signature: t=<unix time>,v1=<hex>, an HMAC-SHA256 of the timestamp, a dot and the body, keyed with a secret shown once when the webhook is created. Check it and reject a timestamp older than five minutes, and a replayed or forged event is refused.
const [t, v1] = sig.split(',').map((p) => p.split('=')[1])
const ok = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex') === v1
&& Date.now() / 1000 - Number(t) < 300
Delivery that never slows the panel
- Delivery is asynchronous: an endpoint that is slow or down delays only its own events.
- A network error, a 5xx, 408 or 429 is retried after 2 and after 10 seconds. Other 4xx answers are the endpoint saying no, so they are not retried.
- After 20 failures in a row the webhook switches itself off and says so on its row.
- The last 100 attempts per webhook are kept with the body and the answer, and a Test button sends one on demand.
- Link-local addresses such as the cloud metadata service at 169.254.169.254 are refused after DNS, and redirects are not followed.