Every LibreNMS integration starts the same way: someone adds an API transport, points it at a webhook, and calls it done before lunch. Two weeks later the remediation platform is the noisiest system in the building, because what is crossing that webhook is not an incident — it is a state change on a single interface, repeated a few hundred times in a row. The integration that actually pays for itself runs in the opposite direction: pulling device role, neighbor topology, and maintenance state out of LibreNMS so the platform can decide whether the alert deserves an action at all.
The API transport is a fan-out device, not an event stream
LibreNMS alerting was designed for humans reading mail. A rule is a SQL predicate over the database, it fires per matching entity, and each matching rule hits each enabled transport once. That means your webhook volume is roughly (rules matched) × (transports) × (entities), and entities are usually ports.
Do the arithmetic on your own estate: 2,000 devices polled every five minutes is 576,000 poll cycles per day. Give each device 48 ports and you are evaluating roughly 96,000 interfaces continuously. At even 1% daily port churn — staff unplugging laptops, spare ports never used, admins shutting down unused access — you produce close to a thousand transition events before a single thing actually breaks. The default port-down rule without an ifAdminStatus guard will happily fire on every unused port in the building.
The fix is not a better filter. It is accepting that the alert body is the least informative artifact LibreNMS produces, and treating it as a trigger to go ask questions rather than as a diagnosis.
LibreNMS already knows the blast radius
Before any action runs, the platform needs three things the alert payload does not carry: what role the device plays, what it is connected to, and whether someone is already working on it. LibreNMS stores all three. The device record exposes purpose, type, and os; LLDP and CDP discovery populate the links resource with neighbor relationships; maintenance state is a flag on the device and its groups.
Three API lookups — device group, link neighbors, maintenance flag — complete in well under a second against a 2,000-device instance and eliminate the majority of bad remediation candidates on their own. A port on a device in a maintenance window is not an incident. A port whose LLDP neighbor is a firewall pair is not an access port no matter what its ifAlias claims.
This is also where ifAlias discipline earns its keep. Teams that enforce a naming convention on descriptions get free intent data; teams that leave them blank are stuck inferring role from link speed and neighbor count, which is guesswork at the distribution layer.
One alert tells you a port changed state; the topology tells you whether anyone noticed. Remediation should key off the second one.
Deduplicate on root cause, not on alert rule
Take a 48-port top-of-rack switch that loses its uplink. LibreNMS reports the uplink port down, then every access port behind it that had an active neighbor, then the devices downstream. A single cable produces one real fault and up to 46 accompanying port alerts. Open a ticket per alert and you have taught your team to ignore the queue.
Correlation has to happen before enrichment, in this order:
- Group incoming events by device inside a 120-second correlation window — long enough to catch the cascade, short enough that unrelated faults do not merge.
- Within a device, identify the parent port: highest
ifSpeed, trunk-configured, admin up, most neighbors. - Walk the links resource to see whether the parent's neighbor is another device already reporting failures.
- Climb until you reach the highest device with a single upstream failure and no upstream fault of its own.
- Emit one incident with the affected endpoints attached as evidence, not as separate alerts.
The output is one incident carrying 46 affected ports instead of 46 incidents carrying nothing. Same data, radically different decision quality.
Four preconditions before anything executes
Auto-remediation on network gear is a trust product, not a speed product. An action should only run when all of the following hold:
- The device is not in a maintenance window, checked against both the device flag and its groups.
- The target port is not a trunk, uplink, or LAG member — inferred from
ifType, speed, and neighbor count. - The action is reversible inside the current change window. Bouncing an access port is reversible; changing a VLAN is a config change with its own approval path.
- The blast radius is bounded and known: one access port affects one endpoint, a distribution trunk affects a floor.
All four preconditions are cheap to evaluate and each one blocks a class of outage that no amount of model confidence will get you forgiven for. Then close the loop: after remediation, write back a 10-minute maintenance window on the device through the API so LibreNMS does not re-alert while the port finishes negotiating.
Instrument the integration like a production service
The integration is now in the decision path, so it gets an SLO. Watch webhook delivery latency, receiver 5xx rates, API token expiry, and — most importantly — poller duration drift. If polling takes longer than the poll interval, data goes stale, and a platform making decisions on stale data is worse than no platform. On a 2,000-device instance the poller should finish in a fraction of its interval; when P95 poll duration crosses 60% of the interval, you are one slow device away from remediating on fiction.
Where this heads: LibreNMS as a control surface
Maintenance write-back is the thin end of it. The next step is treating LibreNMS as a bidirectional control surface — acknowledging alerts with the incident ID, stamping device notes with the action taken, administratively disabling a port after remediation and re-enabling it after verification, and feeding post-remediation state back so the platform learns which alerts actually preceded user impact. In that architecture the alert transport becomes the least-used component of the integration, and the API reads and writes become the product.

