tutorial

Monitoring Your Notifiarr Notification Relay with Vigilmon

Add uptime monitoring, health checks, and alerts to your self-hosted Notifiarr instance — covering web server availability, upstream service connectivity (Sonarr/Radarr/Plex), Discord webhooks, and notification queue health.

Monitoring Your Notifiarr Notification Relay with Vigilmon

Notifiarr is the glue layer of a media automation stack: it receives events from Sonarr, Radarr, Plex, Tautulli, and dozens of other tools, then forwards them to Discord, Telegram, and other notification destinations.

When Notifiarr goes down, your entire notification pipeline silently breaks. Downloads complete without alerts, Plex playback events disappear, and health check failures from your *arr stack go unannounced. The frustrating part: everything looks fine until you realize you haven't seen a notification in hours.

This tutorial adds external monitoring to your Notifiarr deployment:

  • Health check endpoint for the Go web server
  • HTTP uptime monitoring with Vigilmon
  • Upstream service connectivity checks (Sonarr, Radarr, Plex)
  • Heartbeat monitoring for scheduled polling and notification queues
  • Slack/Discord alerts and a public status page

Architecture overview

Notifiarr runs as a single Go binary on port 5454 with several outbound dependencies:

| Component | What breaks when it's down | |-----------|---------------------------| | Notifiarr web server (port 5454) | All notification routing, UI | | Sonarr connectivity | TV show download notifications | | Radarr connectivity | Movie download notifications | | Plex connectivity | Playback event notifications | | Discord webhook delivery | All Discord notifications | | Telegram endpoint | All Telegram notifications | | Notification queue | Queued events accumulate and are lost | | Health check polling service | Upstream status checks stop running |


Step 1: Expose a health check endpoint

Notifiarr exposes /api/v1/info which returns server information. Use this as your primary health endpoint, or create a lightweight wrapper with a reverse proxy health check:

Using nginx upstream check:

# /etc/nginx/sites-available/notifiarr
upstream notifiarr {
    server 127.0.0.1:5454;
}

server {
    listen 443 ssl;
    server_name notifiarr.yourdomain.com;

    # Health check endpoint
    location /health {
        proxy_pass http://notifiarr/api/v1/info;
        proxy_connect_timeout 5s;
        proxy_read_timeout 10s;
        proxy_set_header Host $host;

        # Strip auth for monitoring
        proxy_set_header X-API-Key "";
    }

    location / {
        proxy_pass http://notifiarr;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Test it:

curl https://notifiarr.yourdomain.com/health
# {"version":"0.7.x","uptime":"2h45m","started":"..."}

Alternative: lightweight Go health proxy

If you're running Notifiarr without a reverse proxy, add a minimal health check script:

#!/bin/bash
# /usr/local/bin/notifiarr-health
# Run as a systemd service on port 8080

while true; do
  if curl -sf http://localhost:5454/api/v1/info > /dev/null; then
    echo -e "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\nok" | nc -l -p 8080 -q 1
  else
    echo -e "HTTP/1.1 503 Service Unavailable\r\nContent-Type: text/plain\r\n\r\nerror" | nc -l -p 8080 -q 1
  fi
done

For production, use a proper sidecar instead of this script approach.


Step 2: Set up HTTP monitoring in Vigilmon

Point Vigilmon at your health endpoint:

  1. Sign up at vigilmon.online
  2. Click New Monitor → HTTP
  3. Enter https://notifiarr.yourdomain.com/health
  4. Set check interval: 1 minute (paid) or 5 minutes (free)
  5. Add a keyword check for "version" to verify the response body is valid
  6. Save

Vigilmon pings from multiple geographic regions. This catches network failures between your homelab/VPS and the internet — the most common failure mode for self-hosted Notifiarr deployments.


Step 3: Monitor upstream service connectivity

Notifiarr's value depends on its connections to upstream services. Add individual monitors for each:

Sonarr connectivity:

https://sonarr.yourdomain.com/api/v3/system/status?apikey=YOUR_KEY

Radarr connectivity:

https://radarr.yourdomain.com/api/v3/system/status?apikey=YOUR_KEY

Lidarr connectivity:

https://lidarr.yourdomain.com/api/v1/system/status?apikey=YOUR_KEY

Plex connectivity:

http://YOUR_PLEX_IP:32400/identity

In Vigilmon, create an HTTP monitor for each upstream. Set keyword checks:

  • Sonarr/Radarr/Lidarr: keyword "version" in response body
  • Plex: keyword MediaContainer in response body

These monitors tell you when upstream services are down independently of Notifiarr — so when you get a notification gap, you can immediately distinguish "Notifiarr is down" from "Sonarr is down but Notifiarr is fine."


Step 4: Alerts via Slack or Discord

Slack alerts:

In Vigilmon, go to Notifications → New Channel → Slack and paste your Slack incoming webhook URL.

  1. api.slack.com/appsCreate New App → From scratch
  2. Enable Incoming WebhooksAdd New Webhook to Workspace
  3. Select your homelab alerts channel → copy URL

Discord alerts (alternative):

In Vigilmon, go to Notifications → New Channel → Webhook and paste your Discord webhook URL:

  1. Discord server → channel settings → Integrations → Webhooks → New Webhook
  2. Copy the webhook URL
  3. Add a /slack suffix to the URL: https://discord.com/api/webhooks/.../slack

Enable the notification channel on all your monitors. Vigilmon sends alerts when Notifiarr or any upstream goes down, and recovery notifications when service resumes.


Step 5: Heartbeat monitoring for scheduled polling

Notifiarr runs scheduled health checks that poll upstream services and queue notifications. These background tasks can fail silently when the Go runtime is healthy but the task scheduler has stalled.

Using a monitoring cron job:

Create a script that runs alongside Notifiarr and pings a heartbeat URL after verifying the service is processing:

#!/bin/bash
# /usr/local/bin/notifiarr-heartbeat-check
# Run every 5 minutes via cron

VIGILMON_HEARTBEAT_URL="${VIGILMON_HEARTBEAT_URL}"
NOTIFIARR_URL="http://localhost:5454"
NOTIFIARR_API_KEY="${NOTIFIARR_API_KEY}"

# Check if Notifiarr is accepting API calls
response=$(curl -sf \
  -H "X-API-Key: ${NOTIFIARR_API_KEY}" \
  "${NOTIFIARR_URL}/api/v1/trigger/cfsync" \
  -o /dev/null -w "%{http_code}" 2>/dev/null)

if [ "$response" = "200" ] || [ "$response" = "202" ]; then
  # Notifiarr is healthy and processing — ping heartbeat
  curl -sf "${VIGILMON_HEARTBEAT_URL}" > /dev/null
else
  echo "Notifiarr health check failed (HTTP ${response})" >&2
  # No ping — Vigilmon will alert after the window expires
fi

Add to crontab:

*/5 * * * * /usr/local/bin/notifiarr-heartbeat-check

In Vigilmon:

  1. Click New Monitor → Heartbeat
  2. Set expected interval: 10 minutes (2x the cron interval for tolerance)
  3. Copy the ping URL → set as VIGILMON_HEARTBEAT_URL in your environment
  4. Enable Discord/Slack alerts

If Notifiarr's task scheduler stalls (a known issue when upstream services repeatedly fail), the heartbeat misses and you get an alert — without waiting for users to report missing notifications.


Step 6: Monitor Discord webhook delivery

Add a direct monitor for Discord's webhook API to distinguish between "Notifiarr is down" and "Notifiarr is up but Discord is having an incident":

  1. In Vigilmon, click New Monitor → HTTP
  2. Enter https://discord.com/api/v10/gateway
  3. Set check interval: 5 minutes
  4. Add keyword check for "url" in response body
  5. Label it: Discord API Gateway

When Discord has an incident, this monitor goes red and you immediately know Notifiarr's failures are Discord-side, not yours. This prevents unnecessary restarts and config changes during external incidents.


Step 7: API key validation monitoring

Notifiarr uses API keys to authenticate against upstream services. Expired or revoked keys cause silent notification failures. Add a scheduled validation check:

#!/bin/bash
# /usr/local/bin/notifiarr-api-validate
# Run daily via cron

NOTIFIARR_URL="http://localhost:5454"
NOTIFIARR_API_KEY="${NOTIFIARR_API_KEY}"
VIGILMON_HEARTBEAT_APIKEY="${VIGILMON_HEARTBEAT_APIKEY}"

# Validate API key is accepted
status=$(curl -sf \
  -H "X-API-Key: ${NOTIFIARR_API_KEY}" \
  "${NOTIFIARR_URL}/api/v1/user/info" \
  -o /dev/null -w "%{http_code}" 2>/dev/null)

if [ "$status" = "200" ]; then
  curl -sf "${VIGILMON_HEARTBEAT_APIKEY}" > /dev/null
fi
0 9 * * * /usr/local/bin/notifiarr-api-validate

Set the Vigilmon heartbeat window to 25 hours to account for daily execution drift.


Step 8: Status page and badge

Status page:

  1. Go to Status Pages → New Status Page in Vigilmon
  2. Add monitors: Notifiarr web, Sonarr, Radarr, Plex, Discord API, heartbeat checks
  3. Copy the public URL

Keep the status page URL in your homelab wiki or pinned in your Discord server. When notifications stop flowing, checking the status page first saves 15 minutes of log-diving.

README badge:

[![Notifiarr Status](https://vigilmon.online/badge/your-monitor-slug)](https://status.yourdomain.com)

What you've built

| What | How | |------|-----| | Notifiarr web uptime | HTTP monitor on /health or /api/v1/info | | Sonarr/Radarr/Plex checks | Individual HTTP monitors per upstream | | Discord API health | HTTP monitor on Discord gateway endpoint | | Slack/Discord alerts | Vigilmon notification channel | | Scheduler heartbeat | Cron + heartbeat ping every 5 minutes | | API key validation | Daily cron heartbeat check | | Status page | Vigilmon public status page |

Notifiarr routes your notification data. Vigilmon makes sure the router itself stays healthy.


Next steps

  • Add monitors for Readarr, Tautulli, and any other *arr tools in your stack
  • Use Vigilmon response time history to detect when upstream services are slowing down before they fail
  • Set up multi-region monitoring from different continents to catch ISP-level routing issues
  • Add a separate heartbeat for the Telegram notification path if you use it alongside Discord

Get started free at vigilmon.online.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →