Docs / Monitoring & alerts
Receive alerts by webhook
15 minute read
A webhook channel sends every alert and recovery to your own URL as JSON, so you can open tickets, page someone on call or trigger automation. The URL must be https and reachable from the internet.
1. Add a webhook channel
Under Monitoring & alerts, Where alerts go, add a channel of type Webhook and paste your URL. SimpliCloud shows a signing secret once; store it with your receiver.
simplicloud alerts channels add webhook oncall --url https://ops.korafoods.ng/hooks/simplicloud# signing secret whsec_5f1d2c9a8b7e46e0a1c3 (shown once)
localhost and plain http are refused.2. Read the payload
Each event is a POST with Content-Type: application/json. Alerts and recoveries share one shape; type tells them apart.
{"id": "evt_9f2c41a0","type": "alert.fired","state": "alerting","org": "kora","project": "Production","resource": { "type": "server", "id": "reports-runner", "region": "lagos1" },"rule": {"id": "alr_51c07e","metric": "cpu","operator": "above","threshold": 80,"duration": "5m","text": "CPU above 80% for 5 minutes"},"value": 93,"unit": "percent","started_at": "2026-11-14T08:26:00Z","sent_at": "2026-11-14T08:31:02Z","url": "https://console.simplicloud.ai/#monitoring"}
| Field | Description |
|---|---|
id | Unique event ID. Use it to ignore repeats. |
type | alert.fired, alert.resolved or alert.test. |
state | alerting or ok after this event. |
resource | Type (server, app, database), name and region. |
rule | The rule that matched, with its threshold, duration and readable text. |
value, unit | The measured value when the event was sent. |
started_at | When the value first crossed the line (UTC). |
sent_at | When this delivery was made (UTC). |
url | Link to the resource in the console. |
3. Verify the signature
Each request carries X-SimpliCloud-Signature: sha256=<hex>, an HMAC-SHA256 of the raw body with your signing secret. Reject requests where it does not match.
import crypto from "node:crypto";import express from "express";const app = express();app.post("/hooks/simplicloud", express.raw({ type: "application/json" }), (req, res) => {const sent = req.get("X-SimpliCloud-Signature") || "";const mine = "sha256=" + crypto.createHmac("sha256", process.env.SIMPLICLOUD_WEBHOOK_SECRET).update(req.body).digest("hex");if (sent.length !== mine.length || !crypto.timingSafeEqual(Buffer.from(sent), Buffer.from(mine))) {return res.status(401).end();}const event = JSON.parse(req.body);console.log(event.type, event.resource.id, event.rule.text, event.value);res.status(204).end();});
4. Reply quickly and test
Return any 2xx status within 10 seconds and do slow work afterwards. Failed deliveries are retried with backoff for about an hour, with the same id, then the channel is marked Failing.
simplicloud alerts channels test oncall# Sent alert.test to https://ops.korafoods.ng/hooks/simplicloud · 204 in 182 ms