Intégrations
Webhook
Chaque alerte en JSON signé dans votre outil, ou en message dans Slack, Discord et Teams.
Le régler
Dans Alertes, section « Où prévenir », collez l’adresse de votre outil dans « Webhook », puis cliquez sur « Tester » : Kelva envoie un message de test et dit ce que votre outil a répondu. Le webhook est inclus à partir de l’offre Solo.
Une adresse de Slack, de Discord ou de Microsoft Teams (un flux Workflows) reçoit un message mis en forme pour lui : le titre de l’alerte, sa phrase et son lien. Toute autre adresse reçoit le corps JSON ci-dessous.
Le corps du message
Un POST en JSON, à l’ouverture d’une alerte (alert.opened), à sa résolution (alert.resolved), quand l’agent d’une machine est désinstallé (machine.uninstalled) et pour « Tester » (test, sans machine ni alerte). Les clés sont en anglais, les phrases en français, comme dans l’application.
{ "type": "alert.opened", "id": "0b6f3c1e-8d2a-4c55-9a51-2f1f2c9d7e10", "timestamp": "2026-10-09T07:41:00.000Z", "organization": { "id": "org_1", "name": "Atelier Morel" }, "url": "https://app.kelva.sh/alerts?machine=00000000-0000-4000-8000-000000000001", "machine": { "id": "00000000-0000-4000-8000-000000000001", "hostname": "srv-fichiers" }, "group": { "id": "4f0c2a9e-7d1b-4e3a-9b6c-5a2d8e1f0c3b", "name": "Cabinet Durand" }, "alert": { "id": "00000000-0000-4000-9000-000000000001", "rule": "disk_full", "severity": "warning", "title": "Disque D: à 92 %", "text": "Le disque D: de srv-fichiers est rempli à 92 % (80 Go libres).", "subject": "D:", "openedAt": "2026-10-09T07:41:00.000Z", "resolvedAt": null, "facts": { "mountpoint": "D:", "usedPercent": 92, "freeBytes": 85899345920, "peakPercent": 92, "unreported": false } }}idest le même à chaque nouvel essai d’un même message : servez-vous-en pour ne le traiter qu’une fois.groupest le dossier de la machine, ounullquand elle n’en a pas. La clé est toujours là dans un message d’alerte ; le message de test n’en a pas, ni les messages mis en forme pour Slack, Discord et Teams.machine.uninstalledaalertànullet une cléuninstall:title,text,uninstalledAtetpurge(truequand la clé de la machine a aussi été révoquée). Liseztypeavantalert.rulevautmachine_offline,disk_full,cpu_highouservice_stopped;severity,warningoucritical.factsdonne les mesures propres à chaque règle.
La signature
Chaque message est signé selon la spécification Standard Webhooks, avec le secret affiché sous le champ du webhook (« Copier le secret »). Trois en-têtes l’accompagnent :
webhook-id, l’identifiant du message ;webhook-timestamp, l’heure d’envoi, en secondes Unix ;webhook-signature,v1,suivi de la signature.
Vérifiez le corps tel qu’il arrive, avant de le lire, avec la bibliothèque Standard Webhooks de votre langage. En JavaScript :
// npm install standardwebhooksimport { Webhook } from "standardwebhooks";const payload = new Webhook(process.env.KELVA_WEBHOOK_SECRET).verify(rawBody, request.headers);En Python :
# pip install standardwebhooksimport osfrom standardwebhooks.webhooks import Webhookpayload = Webhook(os.environ["KELVA_WEBHOOK_SECRET"]).verify(raw_body, request.headers)La vérification échoue si la signature ne correspond pas ou si l’heure d’envoi est à plus de 5 minutes. Sans bibliothèque : la signature est le HMAC-SHA256, en base64, de <webhook-id>.<webhook-timestamp>.<corps>, avec pour clé la partie du secret après whsec_, décodée du base64. Comparez-la en temps constant.
« Renouveler le secret » en crée un nouveau : les messages suivants sont signés avec lui. Mettez votre outil à jour dans la foulée.
Répondre
Répondez par un statut 2xx en moins de 10 secondes. Kelva réessaie après un 408, un 429 ou un 5xx, ou sans réponse ; pas après un autre statut. Il ne suit pas les redirections et n’envoie qu’à une adresse en HTTPS.