How to Add a Custom Notification Provider to Uptime Kuma

Extend the NotificationProvider base class in server/notification-providers/, implement the send() method, and register your class in server/notification.js to add custom alerting capabilities to Uptime Kuma.

Uptime Kuma supports extensible alerting through a modular notification provider system. By implementing a small JavaScript class that conforms to the existing provider interface, you can integrate proprietary webhooks, internal APIs, or niche messaging services directly into the monitoring workflow.

Understanding the Notification Architecture

Uptime Kuma’s notification system relies on three core components working in sequence. First, the abstract NotificationProvider class in server/notification-providers/notification-provider.js defines the contract that all providers must follow, including utility methods for HTTP requests and template rendering. Second, concrete implementations such as Webhook or Discord in the same directory extend this base and contain the actual API integration logic. Finally, the Notification class in server/notification.js maintains a static registry (providerList) populated during server initialization; when a monitor triggers an alert, Notification.send() routes the request to the appropriate provider based on the notification.type field stored in the database.

Step-by-Step Implementation Guide

Create the Provider Class

Create a new file in server/notification-providers/ (for example, custom-webhook.js). Your class must extend NotificationProvider, set a unique name property, and implement the async send() method. The send() method receives four arguments: the notification configuration object, the generated message string, optional monitor metadata (monitorJSON), and optional heartbeat data (heartbeatJSON).

// server/notification-providers/custom-webhook.js
const NotificationProvider = require("./notification-provider");
const axios = require("axios");

class CustomWebhook extends NotificationProvider {
    // Unique identifier referenced in the database and UI
    name = "customwebhook";

    async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
        // Use Liquid templating support from the base class
        const text = await this.renderTemplate(
            notification.bodyTemplate ?? "{{msg}}", 
            msg, 
            monitorJSON, 
            heartbeatJSON
        );

        const payload = {
            alert: text,
            monitor: monitorJSON,
            timestamp: heartbeatJSON?.time
        };

        // Automatically respects proxy settings from notification_proxy env var
        const config = this.getAxiosConfigWithProxy({
            headers: { "Content-Type": "application/json" },
            timeout: 10000
        });

        try {
            await axios.post(notification.webhookURL, payload, config);
            return "Sent Successfully.";
        } catch (error) {
            // Leverage base class error handling for consistent logging
            this.throwGeneralAxiosError(error);
        }
    }
}

module.exports = CustomWebhook;

Key implementation details:

  • The name property must be unique across all providers; it maps directly to the type column in the database.
  • renderTemplate() processes Liquid syntax (e.g., {{msg}}, {{monitor.name}}) using the same engine as built-in providers.
  • getAxiosConfigWithProxy() returns an Axios configuration object that automatically incorporates proxy settings from the NOTIFICATION_PROXY environment variable.
  • throwGeneralAxiosError() standardizes error formatting and stack traces for the Uptime Kuma logs.

Register Your Provider in the Notification Registry

Open server/notification.js and locate the init() method (approximately lines 7-33). Import your new class and instantiate it inside the list array. The initialization loop automatically adds your provider to the static providerList object using the name property as the key.

// server/notification.js
const CustomWebhook = require("./notification-providers/custom-webhook");

class Notification {
    static providerList = {};

    static init() {
        const list = [
            // ... existing providers ...
            new CustomWebhook(),
        ];

        for (let item of list) {
            this.providerList[item.name] = item;
        }
    }

    static async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
        const provider = this.providerList[notification.type];
        if (provider) {
            return await provider.send(notification, msg, monitorJSON, heartbeatJSON);
        }
        throw new Error("Unknown notification type");
    }
}

After modifying notification.js, restart the Uptime Kuma server (or restart your Docker container) to execute Notification.init() and load the new provider into memory.

(Optional) Add Frontend UI Support

To surface your provider in the web interface’s “Add Notification” dropdown, create a corresponding Vue component in src/components/notifications/forms/ following the pattern of existing providers like webhook.vue. The frontend stores the selected provider type in the same type field used by the backend registry, ensuring seamless integration without additional API modifications.

Key Methods and Utilities from the Base Class

When extending NotificationProvider, you inherit several utilities that ensure consistency with Uptime Kuma’s networking and templating stack:

  • async renderTemplate(templateString, msg, monitorJSON, heartbeatJSON): Renders Liquid templates with access to monitor and heartbeat variables.
  • getAxiosConfigWithProxy(baseConfig): Merges your Axios configuration with global proxy settings, ensuring compliance with network policies.
  • throwGeneralAxiosError(error): Converts Axios errors into standardized exceptions that the Uptime Kuma logger can parse and display in the dashboard.

Refer to server/notification-providers/notification-provider.js for the full implementation of these helpers, and examine server/notification-providers/webhook.js for a production-ready example of how to structure HTTP requests and handle authentication headers.

Summary

  • Extend NotificationProvider in a new file under server/notification-providers/ and set a unique name property.
  • Implement async send() to handle the actual API call, using base class utilities for templating and proxy support.
  • Register the class in server/notification.js by importing it and adding an instance to the list array inside init().
  • Restart the server to load the provider into the static providerList registry.
  • Optionally extend the frontend by adding a Vue form component if UI visibility is required.

Frequently Asked Questions

What file should I edit to register a new notification provider?

Edit server/notification.js and add your provider class instance to the list array inside the static init() method. This registration step is mandatory; without it, the backend cannot resolve the provider by its type string when dispatching alerts.

Do I need to modify the database schema to add a custom provider?

No. Uptime Kuma stores the provider identifier in the existing type column of the notification table as a plain string. As long as your class sets a unique name property (e.g., name = "myprovider"), the system will recognize and route alerts to your implementation without migrations.

How do I access monitor metadata inside the send() method?

The send() method receives monitorJSON and heartbeatJSON as the third and fourth arguments. These objects contain the monitor’s configuration, current status, latency, and heartbeat timestamp. Use this.renderTemplate() to interpolate these values into your message payload using Liquid syntax like {{monitor.name}} or {{heartbeat.status}}.

Can my custom provider respect the global proxy settings?

Yes. Call this.getAxiosConfigWithProxy() from your send() method and pass the result as the configuration object to your HTTP client (e.g., Axios). This helper automatically checks the NOTIFICATION_PROXY environment variable and applies the appropriate proxy agent to the request, maintaining parity with built-in providers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →