Static Documentation

Zabbix Integration

Version latest · Updated 2026-09-01
Interactive docs View on GitHub

Zabbix integration#

Zabbix is an incoming alert source.

Endpoint:

POST /api/integrations/zabbix

Authentication uses a route intake token:

Authorization: Bearer ROUTE_TOKEN

Route setup#

Create a route with:

Source: zabbix

Attach at least one notification channel and copy the route intake token into the Zabbix media type or webhook configuration.

Ready-to-copy Zabbix Webhook Media Type#

For Zabbix 6.x/7.x, create Alerts → Media types → Create media type and select Webhook. A custom Webhook media type can call IncidentRelay directly without an external script.

Recommended parameters:

ParameterValue
urlhttps://incidentrelay.example.com/api/integrations/zabbix
token{$INCIDENTRELAY.TOKEN}
event_id{EVENT.ID}
trigger_id{TRIGGER.ID}
event_name{EVENT.NAME}
host{HOST.NAME}
event_severity{EVENT.SEVERITY}
event_status{EVENT.STATUS}
opdata{EVENT.OPDATA}
tags_json{EVENT.TAGSJSON}
team{EVENT.TAGS.oncall_team}
event_link{$ZABBIX.URL}/tr_events.php?triggerid={TRIGGER.ID}&eventid={EVENT.ID}
HTTPProxyoptional proxy URL or an empty value

Define {$INCIDENTRELAY.TOKEN} as a Zabbix secret user macro and {$ZABBIX.URL} as the externally reachable Zabbix frontend URL.

Use this Webhook script:

try {
    var params = JSON.parse(value),
        req = new HttpRequest(),
        payload,
        response,
        status;

    if (params.HTTPProxy) {
        req.setProxy(params.HTTPProxy);
    }

    req.addHeader('Content-Type: application/json');
    req.addHeader('Authorization: Bearer ' + params.token);

    payload = {
        event_id: params.event_id,
        trigger_id: params.trigger_id,
        event_name: params.event_name,
        host: params.host,
        event_severity: params.event_severity,
        event_status: params.event_status,
        opdata: params.opdata,
        tags: params.tags_json,
        team: params.team,
        event_link: params.event_link
    };

    response = req.post(params.url, JSON.stringify(payload));
    status = req.getStatus();

    if (status < 200 || status >= 300) {
        throw 'HTTP ' + status + ': ' + response;
    }

    return response;
} catch (error) {
    Zabbix.log(3, '[ IncidentRelay webhook ] ' + error);
    throw 'IncidentRelay webhook failed: ' + error;
}

Create a Zabbix user/media entry using this media type and add that user or user group to the required trigger action. Configure both Operations and Recovery operations, otherwise a Zabbix recovery will never reach IncidentRelay.

The same media type can be tested from the Zabbix UI before it is attached to production actions.

Service assignment#

After a route matches the incoming alert, IncidentRelay can attach the alert to a service.

There are two ways:

  • Select a default service on the route.
  • Configure service match rules.

Use a default service when all alerts through the route belong to the same system. Use service match rules when one route receives alerts for multiple systems.

Example service match rule:

{
  "labels": {
    "service": "cpu",
    "environment": {
      "op": "regex",
      "value": "^(prod|production)$"
    }
  }
}

Payload example#

{
  "status": "firing",
  "event_id": "123456",
  "trigger_id": "98765",
  "event_name": "High CPU load on host1",
  "host": "host1",
  "event_severity": "High",
  "event_status": "PROBLEM",
  "opdata": "CPU load is above 90%",
  "event_tag": "team: infra, service: cpu",
  "tags": [
    {
      "tag": "team",
      "value": "infra"
    },
    {
      "tag": "service",
      "value": "cpu"
    }
  ],
  "event_link": "https://zabbix.example.com/tr_events.php?triggerid=98765&eventid=123456",
  "team": "infra",
  "labels": {
    "host": "host1",
    "service": "cpu",
    "environment": "prod"
  }
}

Zabbix media type parameters can use macros:

{
  "event_id": "{EVENT.ID}",
  "trigger_id": "{TRIGGER.ID}",
  "event_name": "{EVENT.NAME}",
  "host": "{HOST.NAME}",
  "event_severity": "{EVENT.SEVERITY}",
  "event_status": "{EVENT.STATUS}",
  "opdata": "{EVENT.OPDATA}",
  "event_tag": "{EVENT.TAGS}",
  "tags": "{EVENT.TAGSJSON}",
  "event_link": "{$ZABBIX.URL}/tr_events.php?triggerid={TRIGGER.ID}&eventid={EVENT.ID}",
  "team": "{EVENT.TAGS.oncall_team}"
}

event_link is stored in labels.event_link and is also exposed as alert.event_link in the alert API response. It is used by the alert details modal to open the original Zabbix event.

event_tag is stored in labels.event_tag. When it contains tag-like data such as team: infra, service: cpu, IncidentRelay also extracts individual labels such as team and service.

Required payload content#

A Zabbix payload should contain enough data to identify and describe an alert.

Empty JSON objects should be rejected by validation.

Useful fields:

event_id
trigger_id
event_name
trigger_name
problem_name
title
subject
message
opdata
event_tag
tags
event_link
fingerprint

Normalized fields#

IncidentRelay fieldSource
sourcezabbix
team_slugteam, labels.team, labels.oncall_team, or parsed Zabbix tags
external_idevent_id, eventid, trigger_id, or triggerid
titletitle, subject, event_name, problem_name, trigger_name, labels.alertname, then default title
messagemessage, description, or opdata
severitynormalized from severity, event_severity, trigger_severity, or labels.severity
labelslabels, parsed tags, parsed event_tag, plus helper labels such as host, event_name, trigger_name, zabbix_severity, and event_link
event_linkevent_link, event_url, problem_url, trigger_url, labels.event_link, or built from zabbix_url and event_id
statusstatus or event_status, default firing

Zabbix severity values are normalized for IncidentRelay routing and filtering:

Zabbix severityIncidentRelay severity
Disastercritical
Highcritical
Averagewarning
Warningwarning
Informationinfo
Not classifiedinfo

The original Zabbix severity is kept in labels.zabbix_severity.