Skip to content

Alertmanager, Grafana and Zabbix

Notifly receives monitoring alerts natively — no webhook router and no parsing rules. Each source has its own receiver that understands its format, builds a readable title and text and turns the alert’s severity into the message priority:

SourceReceiver URLBody format
Prometheus AlertmanagerPOST /integrations/alertmanagerAlertmanager webhook (version 4)
Grafana AlertingPOST /integrations/alertmanagerwebhook contact point (version 1)
Zabbix (“Webhook” media type)POST /integrations/zabbixmedia type parameters as JSON

Authorisation is the channel token, same as for POST /message: the X-Notifly-Key header, Authorization: Bearer <token> or the ?token= parameter. In the admin UI (channel settings → the Sending tab → Receive from monitoring systems) the configuration snippets already contain the channel’s URL and token — just copy them.

Add a receiver to alertmanager.yml and reload the configuration (SIGHUP or POST /-/reload):

route:
receiver: notifly
group_by: ['alertname']
receivers:
- name: notifly
webhook_configs:
- url: https://api.notifly.ru/integrations/alertmanager
send_resolved: true
max_alerts: 50
http_config:
authorization:
type: Bearer
credentials: <channel token>

One message per Alertmanager notification, not per alert. Alertmanager already groups alerts by the route’s group_by — that is the unit of noise you chose: a storm of a hundred alerts in one group arrives as one message rather than a hundred pushes (and does not eat a hundred quota events). Want a message per alert — set group_by: ['...'] on the route.

Inside a notification alerts are split by status:

  • firing — a [FIRING:3] HighCPUUsage message (for a single alert — [FIRING] HighCPUUsage · node-1:9100). The priority is the highest across the group’s alerts;
  • resolved — a separate [RESOLVED] … message with priority 2: clients deliver it quietly, and escalation with a minimum priority ≥ 4 does not forward it.

So one request creates one or two messages. Notifly does not merge or deduplicate repeated notifications: Alertmanager repeats a notification every repeat_interval — that arrives as a new reminder message. Grouping and the reminder rate are controlled by the route’s group_wait, group_interval and repeat_interval.

The text is markdown: for every alert its name and severity, summary and description from the annotations, the start time (and the end time for resolved ones), the labels, and Source (generatorURL), Runbook (runbook_url) and Silence links (the silence form of the Alertmanager UI with matchers on the alert’s labels). The text lists the first 20 alerts of the group, the rest as a counter. Tapping the notification opens the alert’s source (the Alertmanager UI for a group).

The raw data is kept in the message extras: extras.alertmanager holds the status, groupKey, groupLabels, commonLabels, commonAnnotations, externalURL and up to 50 alerts with labels, annotations, startsAt/endsAt, fingerprint, generatorURL.

severity labelPriority
disaster10
critical, crit, page, emergency, emerg, alert, fatal9
error, err, high, major8
warning, warn, average, minor6
info, information, informational, notice, low3
none, debug1
no label or another valuethe channel default priority
resolved2

Values are case-insensitive. For a group of several alerts the highest priority wins.

A notifly_priority label (a number 0–10) sets the priority explicitly and overrides severity — handy when your rules use a non-standard severity scale.

The Grafana webhook contact point sends the same format as Alertmanager — use the same receiver:

  1. Alerting → Contact points → Add contact point, integration Webhook.
  2. URL — https://api.notifly.ru/integrations/alertmanager.
  3. Optional Webhook settings → Authorization Header - Scheme Bearer, Credentials — the channel token.

Links to the panel, dashboard and silence come from the panelURL, dashboardURL, silenceURL fields. Tapping a single-alert notification opens the panel (falling back to the dashboard or the source); for a group of alerts it opens the Grafana address from externalURL. The severity mapping, notifly_priority and the firing/resolved split are the same as for Alertmanager.

Receiving works through a media type of type Webhook (Zabbix 6.0 and later).

Alerts → Media types → Create media type: type Webhook, name Notifly. Parameters:

NameValue
notifly_urlhttps://api.notifly.ru/integrations/zabbix
notifly_token{ALERT.SENDTO}
subject{ALERT.SUBJECT}
message{ALERT.MESSAGE}
severity{EVENT.NSEVERITY}
status{EVENT.VALUE}
update{EVENT.UPDATE.STATUS}
event_id{EVENT.ID}
host{HOST.NAME}
trigger{EVENT.NAME}
trigger_id{TRIGGER.ID}
url{$ZABBIX.URL}/tr_events.php?triggerid={TRIGGER.ID}&eventid={EVENT.ID}
tags{EVENT.TAGSJSON}

Script:

var params = JSON.parse(value);
var url = params.notifly_url,
token = params.notifly_token;
delete params.notifly_url;
delete params.notifly_token;
var req = new HttpRequest();
if (typeof params.HTTPProxy === 'string' && params.HTTPProxy.trim() !== '') {
req.setProxy(params.HTTPProxy);
}
delete params.HTTPProxy;
req.addHeader('Content-Type: application/json');
req.addHeader('X-Notifly-Key: ' + token);
var resp = req.post(url, JSON.stringify(params));
if (req.getStatus() < 200 || req.getStatus() >= 300) {
throw 'Notifly: HTTP ' + req.getStatus() + ': ' + resp;
}
return 'OK';

On the Message templates tab add Problem, Problem recovery and Problem update templates — the defaults are enough. Without templates Zabbix will not send anything (No message defined for media type).

The {$ZABBIX.URL} macro is your Zabbix frontend address; define it in Administration → Macros (or drop the url parameter).

  1. Users → user → Media → Add: type Notifly, Send to — the channel token. Different users (or different media of one user) can point to tokens of different channels while sharing one media type.
  2. Alerts → Actions → Trigger actions: add an operation sending via Notifly (plus recovery/update operations if you need them).
Zabbix eventPriority
problem, Disaster10
problem, High8
problem, Average6
problem, Warning5
problem, Information3
problem, Not classifiedthe channel default priority
recovery ({EVENT.VALUE}=0)2
update (ack, comment…)3

The title is {ALERT.SUBJECT}, the text is {ALERT.MESSAGE} as is (plain multi-line text) plus a link to the event. Without message templates the title and text are built from the trigger, host and severity. extras.zabbix holds status (problem/resolved/update), eventId, host, trigger, triggerId, severity, url and the parsed tags.

Parameter names of the official Zabbix webhook templates are understood too: alert_subject, alert_message, event_nseverity, event_value, event_update_status, host_name, trigger_name, zabbix_url — an existing media type can be reused by changing only the URL and the script.

An alert from Alertmanager, Grafana or Zabbix is an ordinary channel message, so the same rules as for POST /message apply to it:

  • the channel owner’s quiet hours suppress escalation to external channels (email, SMS, phone call, messengers, webhooks) when the message priority is below the breakthroughPriority threshold (8 by default). With the mapping above, critical (9) and Zabbix Disaster (10) break through the silence, warning does not;
  • during an active maintenance window covering the channel, messages are created as usual but marked silent, and no escalation is performed for them.
Окно терминала
curl -X POST "https://api.notifly.ru/integrations/alertmanager" \
-H "Authorization: Bearer <channel token>" \
-H "Content-Type: application/json" \
-d '{"version":"4","status":"firing","alerts":[{"status":"firing",
"labels":{"alertname":"TestAlert","severity":"warning","instance":"host-1"},
"annotations":{"summary":"Receiver check"},
"startsAt":"2026-09-27T10:00:00Z"}]}'

The response is {"created": 1, "ids": [...]}. Error codes:

CodeReason
400the body could not be parsed or exceeds the limit; for Alertmanager — no alerts, for Zabbix — no subject, message or trigger
401no token or an unknown token
403a token without write access, or the system channel
429the daily quota is exhausted (the response carries created and ids of those already made) or too many requests
  • Delivery & escalation — forward an unread alert to PagerDuty, Opsgenie, Telegram or a phone call, and acknowledge or close the PagerDuty/Opsgenie incident once the alert is read in Notifly (onRead).
  • Webhook router — arbitrary webhooks and elaborate routing across channels.
  • Extra message fields — client::display, client::notification.