Webhooks
Subscribe to alert events and push them to your endpoint in real time.
MonPG posts a JSON payload to your endpoint every time an alert fires, resolves, or gets acknowledged. HMAC-SHA256 signature on every request — verify it before you trust the payload, especially if your endpoint is publicly reachable.
Setup
Settings → Notifications → Add channel → Webhook. Three fields: the URL, a secret (we generate a 32-byte one for you, used as the HMAC key), and an event filter (subset of alert.fired, alert.resolved, alert.acknowledged, alert.suppressed — most teams subscribe to the first three).
Payload
POST /your-endpoint HTTP/1.1
Content-Type: application/json
X-MonPG-Signature: sha256=<hex>
X-MonPG-Event: alert.fired
X-MonPG-Delivery: <uuid — unique per delivery>
{
"event": "alert.fired",
"delivery_id": "deliv_abc123",
"timestamp": "2026-04-24T19:45:12Z",
"alert": {
"id": "rh_xyz",
"rule_id": 42,
"rule_name": "Replication lag > 60s",
"server_id": 4,
"server_name": "prod-db-writer",
"severity": "warning",
"status": "firing",
"metric_value": 127,
"threshold": 60,
"triggered_at": "2026-04-24T19:45:12Z",
"url": "https://app.monpg.app/alerts/rh_xyz"
}
}
Verify the signature
// Node.js
const crypto = require('crypto');
const signature = req.headers['x-monpg-signature'];
const rawBody = await readRawBody(req);
const expected = 'sha256=' + crypto
.createHmac('sha256', process.env.MONPG_WEBHOOK_SECRET)
.update(rawBody)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).send('bad signature');
}
// process event...
The timingSafeEqual matters even if the consequence of a bad compare is small here — burned-in habit, costs nothing.
Delivery
Initial timeout 10 seconds. Retries on 5xx or timeout: 10 attempts with exponential backoff over 24 hours. 4xx responses other than 429 don't retry — we assume your endpoint has a permanent disagreement with the payload. 429 we respect with the Retry-After header.
Admin → Notification Queue shows pending and failed deliveries with the response code and body — when something's broken, that's the page that tells you.
Test delivery
The Webhook channel config has a "Send test" button. Fires a synthetic alert.fired with rule_name: "test". Use it to verify your endpoint responds 2xx before relying on real alerts to test it.