Webhooks¶
On an alert Vesana sends a JSON POST to a URL of your choice. Use it to connect your own ticket system, n8n, Node-RED and the like. PagerDuty, Opsgenie, ntfy, Pushover, Telegram and the chat services have channel types of their own (see Notification channels).
Configuration¶
Alerting → Channels → New Channel → type Webhook:
| Field | Value |
|---|---|
| Name | e.g. "Ticket webhook" (required) |
| Tenant | only selectable when creating |
| Webhook URL | http:// or https:// (required) |
That's all: no method choice (always POST, Content-Type: application/json), no custom headers, no payload template, no signature. To protect the receiver, put a secret token in the URL (e.g. https://tickets.example.com/hook?token=…) and use HTTPS; the URL is stored encrypted and shown masked when editing.
Targets inside the Vesana server's internal network (loopback, link-local, cloud metadata, the stack's containers) are rejected; addresses in your own LAN are allowed.
Payload¶
{
"type": "alert",
"host_name": "web01.acme.local",
"host_ip": "10.10.5.13",
"service_name": "Disk /var",
"status": "CRITICAL",
"previous_status": "WARNING",
"message": "Disk usage 96.4%",
"triggered_at": "2026-10-19T10:15:30+00:00",
"tenant_name": "Acme GmbH",
"dashboard_url": "https://vesana.example.com/hosts/…",
"duration_seconds": 320,
"extra_data": { }
}
type: among othersalert,recoveryandtest(the Send test button).duration_secondsandextra_dataare left out when there is nothing to report.dashboard_urlis the link to the affected check or device in Vesana; empty if the instance does not know its own address (BASE_URLor agent server URL).
Grouped messages¶
If grouping is enabled in the alert rule, one POST per group arrives. The individual entries are then in extra_data:
"extra_data": {
"grouped": true,
"alerts": [
{ "host": "web01", "service": "Disk /var", "status": "CRITICAL", "message": "…", "timestamp": "…" }
],
"total_alert_count": 12,
"overflow_count": 2,
"hosts": ["web01"]
}
alerts holds at most 10 entries, the rest is counted in overflow_count. A receiver should tell single and grouped messages apart (extra_data.grouped).
Delivery and retries¶
Any response from HTTP 400 up, a timeout (10 s) or a connection error counts as a failure. Vesana retries with growing intervals (10 s, 30 s, 1 min, 2 min, 5 min, 10 min …, up to 8 attempts in total); after that the message counts as finally failed and shows up as such in the channel's delivery journal. A receiver may therefore get a message more than once.
Test¶
Send test on the channel row sends a test message ("type": "test", host test-host, status CRITICAL). If the receiver answers with an error, the HTTP status and the start of the response appear right on the channel.