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:
| Source | Receiver URL | Body format |
|---|---|---|
| Prometheus Alertmanager | POST /integrations/alertmanager | Alertmanager webhook (version 4) |
| Grafana Alerting | POST /integrations/alertmanager | webhook contact point (version 1) |
| Zabbix (“Webhook” media type) | POST /integrations/zabbix | media 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.
Prometheus Alertmanager
Section titled “Prometheus Alertmanager”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>How alerts become messages
Section titled “How alerts become messages”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] HighCPUUsagemessage (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.
Priority from severity
Section titled “Priority from severity”severity label | Priority |
|---|---|
disaster | 10 |
critical, crit, page, emergency, emerg, alert, fatal | 9 |
error, err, high, major | 8 |
warning, warn, average, minor | 6 |
info, information, informational, notice, low | 3 |
none, debug | 1 |
| no label or another value | the channel default priority |
| resolved | 2 |
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.
Grafana Alerting
Section titled “Grafana Alerting”The Grafana webhook contact point sends the same format as Alertmanager — use the same receiver:
- Alerting → Contact points → Add contact point, integration Webhook.
- URL —
https://api.notifly.ru/integrations/alertmanager. - 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.
Zabbix
Section titled “Zabbix”Receiving works through a media type of type Webhook (Zabbix 6.0 and later).
1. Media type
Section titled “1. Media type”Alerts → Media types → Create media type: type Webhook, name
Notifly. Parameters:
| Name | Value |
|---|---|
notifly_url | https://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).
2. User and action
Section titled “2. User and action”- 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. - Alerts → Actions → Trigger actions: add an operation sending via
Notifly(plus recovery/update operations if you need them).
Mapping
Section titled “Mapping”| Zabbix event | Priority |
|---|---|
| problem, Disaster | 10 |
| problem, High | 8 |
| problem, Average | 6 |
| problem, Warning | 5 |
| problem, Information | 3 |
| problem, Not classified | the 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.
Quiet hours and maintenance windows
Section titled “Quiet hours and maintenance windows”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
breakthroughPrioritythreshold (8 by default). With the mapping above,critical(9) and Zabbix Disaster (10) break through the silence,warningdoes not; - during an active maintenance window covering the channel, messages are created as usual but marked silent, and no escalation is performed for them.
Checking
Section titled “Checking”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:
| Code | Reason |
|---|---|
400 | the body could not be parsed or exceeds the limit; for Alertmanager — no alerts, for Zabbix — no subject, message or trigger |
401 | no token or an unknown token |
403 | a token without write access, or the system channel |
429 | the daily quota is exhausted (the response carries created and ids of those already made) or too many requests |
See also
Section titled “See also”- 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.