Static Documentation

LibreNMS Integration

Version latest · Updated 2026-06-18
Interactive docs View on GitHub

LibreNMS integration#

IncidentRelay can receive LibreNMS alerts through the LibreNMS API Transport and normalize them into regular IncidentRelay incidents.

LibreNMS API Transport should send a JSON payload to:

POST /api/integrations/librenms

The route intake token must belong to an IncidentRelay route with:

source = librenms

Behavior#

IncidentRelay normalizes every LibreNMS transport payload into one alert event:

LibreNMS fieldIncidentRelay field
uid, alert_uid, id, alert_idexternal_id
fingerprintexplicit dedup_key
title, subject, rule, namealert title
message, msg, description, alert_notesalert message
state, statusalert status
severityalert severity
hostname, display, sysNamehostname label
device_iddevice_id label
teamIncidentRelay team slug override
event_link, event_url, alert_url, source_url, device_urlexternal alert link
librenms_url + hostname or device_idgenerated LibreNMS device link

Status mapping#

IncidentRelay treats these LibreNMS states/statuses as resolved:

0, ok, clear, cleared, recover, recovery, recovered, resolve, resolved, closed

Any other state/status is treated as firing.

Examples:

LibreNMS stateIncidentRelay status
1firing
2firing
alertfiring
0resolved
okresolved
recoveredresolved

Severity mapping#

LibreNMS severityIncidentRelay severity
critical, crit, error, err, highcritical
warning, warn, mediumwarning
info, informational, notice, low, ok, clear, normalinfo
unknown non-empty valueoriginal value
empty valueinfo

Deduplication#

IncidentRelay uses the first available value from this list as external_id:

uid, alert_uid, id, alert_id

If fingerprint is provided, it is used as the explicit dedup key.

If there is no explicit fingerprint, IncidentRelay builds a stable dedup key from:

source=librenms
external_id
hostname
rule/name
device_id

For reliable firing/recovery correlation, configure LibreNMS to send the same uid or id for both alert and recovery events.

Create IncidentRelay route#

Create or update an alert route with source librenms.

Example route properties:

{
  "name": "LibreNMS",
  "source": "librenms",
  "team_id": 1,
  "matchers": {},
  "group_by": ["hostname", "rule"],
  "enabled": true
}

Copy the route intake token. It will be used in the LibreNMS API Transport Authorization header.

Configure LibreNMS API Transport#

In LibreNMS, create an Alert Transport with type API.

Recommended settings:

SettingValue
API MethodPOST
API URLhttps://incidentrelay.example.com/api/integrations/librenms
API HeadersAuthorization=Bearer INCIDENTRELAY_ROUTE_TOKEN
API HeadersContent-Type=application/json
API BodyJSON body from the example below

Use a JSON body like this in the LibreNMS API Transport configuration:

{
  "id": "{{ $id }}",
  "uid": "{{ $uid }}",
  "state": "{{ $state }}",
  "severity": "{{ $severity }}",
  "title": "{{ $title }}",
  "message": "{{ $msg }}",
  "hostname": "{{ $hostname }}",
  "display": "{{ $display }}",
  "sysName": "{{ $sysName }}",
  "device_id": "{{ $device_id }}",
  "ip": "{{ $ip }}",
  "os": "{{ $os }}",
  "type": "{{ $type }}",
  "hardware": "{{ $hardware }}",
  "version": "{{ $version }}",
  "location": "{{ $location }}",
  "rule": "{{ $name }}",
  "timestamp": "{{ $timestamp }}",
  "team": "sre",
  "librenms_url": "https://librenms.example.com"
}

team is optional. Use it only when you want the payload to override routing to a specific IncidentRelay team slug.

librenms_url is optional. When it is set, IncidentRelay can generate a LibreNMS device link from librenms_url and hostname or device_id.

Custom labels#

You can attach additional labels with the labels object:

{
  "uid": "{{ $uid }}",
  "state": "{{ $state }}",
  "severity": "{{ $severity }}",
  "title": "{{ $title }}",
  "message": "{{ $msg }}",
  "hostname": "{{ $hostname }}",
  "labels": {
    "environment": "prod",
    "service": "network",
    "source_system": "librenms"
  }
}

IncidentRelay copies labels into the normalized alert labels and also adds normalized LibreNMS labels such as:

hostname
device_id
ip
os
type
hardware
version
location
rule
librenms_id
librenms_uid
librenms_state
librenms_timestamp
librenms_severity
event_link

Example firing payload#

{
  "id": "12345",
  "uid": "lnms-alert-12345",
  "state": "1",
  "severity": "critical",
  "title": "Device down",
  "message": "Device router1 is unreachable",
  "hostname": "router1",
  "device_id": "77",
  "ip": "10.0.0.1",
  "rule": "Device down",
  "timestamp": "2026-06-17 10:00:00",
  "team": "sre",
  "librenms_url": "https://librenms.example.com"
}

Normalized result:

{
  "source": "librenms",
  "team_slug": "sre",
  "external_id": "lnms-alert-12345",
  "title": "Device down",
  "message": "Device router1 is unreachable",
  "severity": "critical",
  "status": "firing",
  "labels": {
    "hostname": "router1",
    "device_id": "77",
    "ip": "10.0.0.1",
    "rule": "Device down",
    "event_link": "https://librenms.example.com/device/device=router1/"
  }
}

Example recovery payload#

Send the same uid or id, but set state to a recovery value:

{
  "id": "12345",
  "uid": "lnms-alert-12345",
  "state": "0",
  "severity": "ok",
  "title": "Device down",
  "message": "Device router1 recovered",
  "hostname": "router1",
  "device_id": "77",
  "rule": "Device down"
}

Normalized status:

{
  "status": "resolved"
}

Test with curl#

curl -X POST "https://incidentrelay.example.com/api/integrations/librenms" \
  -H "Authorization: Bearer INCIDENTRELAY_ROUTE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "12345",
    "uid": "lnms-alert-12345",
    "state": "1",
    "severity": "critical",
    "title": "Device down",
    "message": "Device router1 is unreachable",
    "hostname": "router1",
    "device_id": "77",
    "rule": "Device down",
    "team": "sre",
    "librenms_url": "https://librenms.example.com"
  }'

Expected response is the same shape as other IncidentRelay incoming alert integrations: the request should be accepted and routed through the matching librenms route.

Troubleshooting#

401 unauthorized#

Check that the Authorization header contains the route intake token:

Authorization=Bearer INCIDENTRELAY_ROUTE_TOKEN

Also check that the token belongs to a route with:

source = librenms

400 validation_error#

The payload must contain at least one meaningful identity or content field, for example:

id, uid, alert_id, title, name, rule, message, msg, description, hostname, display, sysName, fingerprint or labels

Recovery creates a new incident instead of resolving the old one#

Make sure firing and recovery payloads use the same stable identity:

uid or id

Do not include changing values such as timestamp in fingerprint.

Send one of these fields:

event_link, event_url, alert_url, source_url, device_url

Or send librenms_url together with hostname or device_id so IncidentRelay can generate a device link.