Beszel
Send Beszel server alerts to Uptimeify Incident Management through a Shoutrrr generic webhook, with host, link, severity and automatic recovery for every Beszel alert type.
Beszel notifies through Shoutrrr URLs. Its generic webhook sends only a title and a message, with no status field and no alert id. The Beszel preset reads everything it needs from the title: whether the alert fires or recovers, which system it is about, and which earlier alert a recovery closes. Checked against the alert texts of Beszel 0.21.
1. Create the alert source in Uptimeify
Go to Incident Management → Alert Sources → New, pick the Beszel preset, name it, and create it. The success screen shows a ready-made notification URL for Beszel:
generic://<your-domain>/api/im/ingest/<token>?template=jsonIt is shown once and never displayed again in cleartext. If you lose it, rotate the token from the source's Settings tab and build the URL again from the new ingest URL: replace https:// with generic:// and append ?template=json.
template=json is required. Without it Beszel sends plain text instead of { "title", "message" }, and the preset has nothing to read.
2. Add the URL in Beszel
- In Beszel, open Settings → Notifications.
- Under Webhook / Push notifications, add the URL from step 1 and save. Test URL sends a test notification. It arrives as an open alert titled
Test Alert; resolve it by hand. - In the systems table, open the bell icon of each system and enable the alerts you want (status, CPU, memory, disk, and so on).
Beszel sends one notification when an alert fires and one when it recovers. Both reach the same Uptimeify alert, so the recovery resolves it.
Supported alert types
| Beszel alert | Firing title | Recovery title |
|---|---|---|
| CPU, memory, disk, bandwidth, temperature, load, GPU | web-01 CPU above threshold | web-01 CPU below threshold |
| Battery (fires when low) | web-01 battery below threshold | web-01 battery above threshold |
| Status (connection) | Connection to web-01 is down 🔴 | Connection to web-01 is up ✅ |
| Container health | Unhealthy container db on web-01 🔴 or 3 unhealthy containers on web-01 🔴 | web-01 containers are healthy ✅ |
| systemd services | Failed services on web-01 🔴 | Services recovered on web-01 ✅ |
| Network monitor (packet loss) | Network monitor loss on web-01: 1.1.1.1:53 | Network monitor recovered on web-01: 1.1.1.1:53 |
| SMART | SMART failure on web-01: /dev/sda 🔴 | none |
| ZFS pool | Storage pool DEGRADED on web-01: tank | none |
Beszel sends no recovery for SMART and ZFS. Those alerts stay open until you resolve them in Uptimeify. Several unhealthy containers on one system share one alert, because Beszel's recovery also covers the whole system.
Default field mapping
| Beszel field | Normalized field |
|---|---|
title | Title, verbatim |
title | Status: below threshold (battery: above threshold), is up, recovered and containers are healthy resolve the alert, everything else keeps it open |
title | Host: the Beszel system name, also when it contains spaces |
title | Dedup key: system plus alert type, the same for the firing and the recovery notification |
message | Link back to the system in Beszel (the URL Beszel appends to every message) |
message | Custom field details, the message without the link (for example CPU averaged 91.20% for the previous 10 minutes.) |
Severity map
| Beszel alert | Uptimeify severity |
|---|---|
SMART failure, ZFS pool FAULTED, OFFLINE, UNAVAIL, REMOVED or SUSPENDED | sev1 |
Connection down, failed services, ZFS pool DEGRADED | sev2 |
| SMART warning | sev3 |
| Everything else | The source's default severity |
Sample payload
{
"title": "backend1 CPU above threshold",
"message": "CPU averaged 91.20% for the previous 10 minutes.\n\nhttps://beszel.example.com/system/x8k2m4p9q1w7e3r"
}You can send this exact payload against your source's mapping from the Payload Mapping tab in the dashboard to verify the setup before enabling alerts in Beszel.
Beszel by email instead
If Beszel can only reach you by email (SMTP under Settings → Notifications), use an Email source instead. Beszel's email subject is the same title, and the body is the message followed by the link. Set these emailSelectors through the Alert Sources API to get the same behavior as the webhook preset:
{
"emailSelectors": {
"title": "subject",
"severity": "subject =~ /^SMART (failure) on / || subject =~ /^Storage pool (FAULTED|OFFLINE|UNAVAIL|REMOVED|SUSPENDED) on / || subject =~ /^Connection to .+ is (down)\\b/ || subject =~ /^(Failed) services on / || subject =~ /^Storage pool (DEGRADED) on / || subject =~ /^SMART (warning) on /",
"status": "subject =~ / (battery (?:above|below)) threshold/ || subject =~ / (above|below) threshold/ || subject =~ /^Connection to .+ is (down|up)\\b/ || subject =~ /^Network monitor (loss|recovered) on / || subject =~ /^Services (recovered) on / || subject =~ /containers are (healthy)\\b/",
"host": "subject =~ /^(.+?) (?:\\d+m load|\\S+) (?:above|below) threshold/ || subject =~ /^Connection to (.+) is (?:down|up)\\b/ || subject =~ /^Network monitor (?:loss|recovered) on (.+?): / || subject =~ /^(?:Failed services|Services recovered) on (.+) \\S+$/ || subject =~ /^(?:Unhealthy container \\S+|\\d+ unhealthy containers) on (.+) \\S+$/ || subject =~ /^(.+) containers are healthy\\b/ || subject =~ /^SMART \\S+ on (.+?): / || subject =~ /^Storage pool \\S+ on (.+?): /",
"dedupKey": "subject =~ /^(.+) (?:above|below) threshold/ || subject =~ /^(Connection to .+) is (?:down|up)\\b/ || subject =~ /^Network monitor (?:loss|recovered) (on .+)$/ || subject =~ /^(?:Failed services|Services recovered) (on .+) \\S+$/ || subject =~ /^(?:Unhealthy container \\S+|\\d+ unhealthy containers) on (.+) \\S+$/ || subject =~ /^(.+) containers are healthy\\b/ || subject =~ /^(SMART \\S+ on .+?) \\S+$/ || subject =~ /^(Storage pool .+)$/",
"severityMap": { "failure": "sev1", "FAULTED": "sev1", "OFFLINE": "sev1", "UNAVAIL": "sev1", "REMOVED": "sev1", "SUSPENDED": "sev1", "down": "sev2", "Failed": "sev2", "DEGRADED": "sev2", "warning": "sev3" },
"resolveValues": ["below", "battery above", "up", "recovered", "healthy"],
"custom": { "details": "body =~ /^(.*?)\\s*https?:\\/\\/\\S+\\s*$/s || body" }
}
}The webhook preset is the better choice where it works: it also stores the Beszel link as the incident's link.
Sentry
Send Sentry issue alerts to Uptimeify Incident Management via an internal integration webhook, mapped from the event's level, message, and environment.
Custom webhook
Send alerts from any tool that can POST JSON to Uptimeify Incident Management, and define your own field mapping in the dashboard.