Configure advanced Uptime Kuma monitoring with API integrations and automated alerting

Intermediate 45 min May 09, 2026 678 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Set up Uptime Kuma with advanced API endpoints, custom notification channels, and automated monitoring workflows. Configure health check automation, status page customization, and enterprise alerting rules for production environments.

Prerequisites

  • Running Uptime Kuma instance
  • Admin access to monitoring system
  • Basic understanding of REST APIs
  • Python 3.8 or higher

What this solves

Uptime Kuma's web interface works well for basic monitoring, but production environments need programmatic control, custom integrations, and advanced alerting workflows. This tutorial shows you how to configure Uptime Kuma's API, set up automated monitor management, integrate with external services, and build sophisticated alerting chains that scale with your infrastructure.

Prerequisites

You need a running Uptime Kuma instance with admin access. This tutorial builds on basic monitoring concepts and requires familiarity with REST APIs and webhook integrations. If you need to set up basic monitoring first, check out our Uptime Kuma installation guide.

Step-by-step configuration

Enable API access and authentication

First, enable API access in Uptime Kuma's settings. The API requires authentication tokens for security.

curl -X POST http://localhost:3001/api/login \
  -H "Content-Type: application/json" \
  -d '{"username": "admin", "password": "your_password"}'

Save the returned token. Create a dedicated API user for automation scripts:

curl -X POST http://localhost:3001/api/user \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "username": "api-user",
    "password": "secure_password_123",
    "active": true,
    "role": "user"
  }'

Configure API token management

Generate long-lived API tokens for automation. Store these securely and rotate them regularly.

{
  "api_base_url": "http://localhost:3001/api",
  "auth_token": "your_api_token_here",
  "timeout": 30,
  "retry_attempts": 3,
  "rate_limit": {
    "requests_per_minute": 60,
    "burst_limit": 10
  }
}

Set proper file permissions to protect the API configuration:

sudo chown root:uptime-kuma /etc/uptime-kuma/api-config.json
sudo chmod 640 /etc/uptime-kuma/api-config.json

Create automated monitor management scripts

Build scripts to programmatically create, update, and delete monitors. This enables infrastructure-as-code workflows.

#!/usr/bin/env python3
import requests
import json
import sys
import os
from datetime import datetime

class UptimeKumaAPI:
    def __init__(self, config_file='/etc/uptime-kuma/api-config.json'):
        with open(config_file) as f:
            self.config = json.load(f)
        self.base_url = self.config['api_base_url']
        self.headers = {
            'Authorization': f"Bearer {self.config['auth_token']}",
            'Content-Type': 'application/json'
        }
    
    def create_monitor(self, monitor_config):
        """Create a new monitor with advanced configuration"""
        response = requests.post(
            f"{self.base_url}/monitor",
            headers=self.headers,
            json=monitor_config,
            timeout=self.config['timeout']
        )
        response.raise_for_status()
        return response.json()
    
    def bulk_create_monitors(self, monitors_file):
        """Create multiple monitors from configuration file"""
        with open(monitors_file) as f:
            monitors = json.load(f)
        
        results = []
        for monitor in monitors:
            try:
                result = self.create_monitor(monitor)
                results.append({'status': 'success', 'monitor': result})
                print(f"Created monitor: {monitor.get('name', 'unnamed')}")
            except Exception as e:
                results.append({
                    'status': 'error', 
                    'monitor': monitor.get('name', 'unnamed'),
                    'error': str(e)
                })
                print(f"Failed to create {monitor.get('name')}: {e}")
        
        return results

if __name__ == '__main__':
    if len(sys.argv) != 3:
        print("Usage: uk-monitor-manager.py 

Make the script executable and secure:

sudo chmod 750 /usr/local/bin/uk-monitor-manager.py
sudo chown root:uptime-kuma /usr/local/bin/uk-monitor-manager.py

Set up advanced notification integrations

Configure custom webhook notifications that integrate with your existing alerting infrastructure.

{
  "slack_critical": {
    "type": "slack",
    "webhook_url": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
    "username": "Uptime Kuma",
    "channel": "#alerts-critical",
    "icon_emoji": ":rotating_light:",
    "color": "danger",
    "conditions": {
      "status": ["down"],
      "tags": ["critical", "production"]
    }
  },
  "pagerduty_escalation": {
    "type": "webhook",
    "url": "https://events.pagerduty.com/v2/enqueue",
    "method": "POST",
    "headers": {
      "Content-Type": "application/json",
      "Authorization": "Token token=YOUR_PAGERDUTY_TOKEN"
    },
    "body_template": {
      "routing_key": "YOUR_INTEGRATION_KEY",
      "event_action": "trigger",
      "dedup_key": "uptime-kuma-{monitor_id}",
      "payload": {
        "summary": "Monitor {monitor_name} is {status}",
        "source": "uptime-kuma",
        "severity": "critical",
        "component": "infrastructure",
        "group": "monitoring",
        "custom_details": {
          "monitor_id": "{monitor_id}",
          "monitor_url": "{monitor_url}",
          "response_time": "{response_time}",
          "status_code": "{status_code}",
          "timestamp": "{timestamp}"
        }
      }
    },
    "conditions": {
      "consecutive_failures": 3,
      "tags": ["production"]
    }
  }
}

Create advanced monitor configurations

Define comprehensive monitor templates for different service types with proper health check logic.

[
  {
    "name": "Web Service - Production",
    "type": "http",
    "url": "https://api.example.com/health",
    "method": "GET",
    "interval": 60,
    "timeout": 30,
    "maxretries": 3,
    "headers": {
      "User-Agent": "Uptime-Kuma/1.0",
      "Accept": "application/json"
    },
    "body": "",
    "httpBodyEncoding": "json",
    "expectedStatusCodes": ["200", "201"],
    "keyword": "healthy",
    "invertKeyword": false,
    "ignoreTls": false,
    "tags": ["production", "api", "critical"],
    "notification_ids": [1, 2, 3],
    "advanced_settings": {
      "follow_redirect": true,
      "max_redirects": 5,
      "check_certificate": true,
      "certificate_expiry_warning": 30
    }
  },
  {
    "name": "Database Connection",
    "type": "postgres",
    "hostname": "db.example.com",
    "port": 5432,
    "database": "production",
    "username": "monitor_user",
    "password": "secure_password",
    "interval": 120,
    "timeout": 15,
    "maxretries": 2,
    "query": "SELECT 1 as health_check",
    "tags": ["production", "database", "critical"],
    "notification_ids": [1, 3]
  },
  {
    "name": "TCP Service Check",
    "type": "port",
    "hostname": "service.example.com",
    "port": 22,
    "interval": 300,
    "timeout": 10,
    "maxretries": 3,
    "tags": ["infrastructure", "ssh"],
    "notification_ids": [2]
  }
]

Implement automated health check workflows

Create scripts that automatically adjust monitoring based on service discovery and infrastructure changes.

#!/bin/bash

# Uptime Kuma Auto-Discovery Script
# Automatically creates monitors for discovered services

set -euo pipefail

API_CONFIG="/etc/uptime-kuma/api-config.json"
DISCOVERY_CONFIG="/etc/uptime-kuma/discovery-config.json"
LOG_FILE="/var/log/uptime-kuma/auto-discovery.log"
TEMP_DIR="/tmp/uk-discovery"

# Create required directories
sudo mkdir -p /var/log/uptime-kuma "$TEMP_DIR"

log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | sudo tee -a "$LOG_FILE"
}

discover_docker_services() {
    log_message "Discovering Docker services..."
    
    # Get running containers with health checks
    docker ps --format "table {{.Names}}\t{{.Ports}}\t{{.Status}}" | \
    grep -E "(healthy|Up)" | \
    tail -n +2 | \
    while IFS=$'\t' read -r name ports status; do
        if [[ "$ports" =~ ([0-9]+):([0-9]+) ]]; then
            host_port="${BASH_REMATCH[1]}"
            container_port="${BASH_REMATCH[2]}"
            
            cat > "$TEMP_DIR/docker-${name}.json" << EOF
{
  "name": "Docker - ${name}",
  "type": "http",
  "url": "http://localhost:${host_port}/health",
  "interval": 120,
  "timeout": 15,
  "tags": ["docker", "auto-discovered", "${name}"],
  "auto_managed": true
}
EOF
            log_message "Created monitor config for Docker service: $name"
        fi
    done
}

discover_systemd_services() {
    log_message "Discovering systemd services..."
    
    # Get critical systemd services
    systemctl list-units --type=service --state=active | \
    grep -E "(nginx|apache2|postgresql|mysql|redis|mongodb)" | \
    awk '{print $1}' | \
    while read -r service; do
        service_name=$(echo "$service" | sed 's/\.service$//')
        
        cat > "$TEMP_DIR/systemd-${service_name}.json" << EOF
{
  "name": "SystemD - ${service_name}",
  "type": "http",
  "url": "http://localhost/server-status",
  "interval": 180,
  "timeout": 10,
  "tags": ["systemd", "auto-discovered", "${service_name}"],
  "auto_managed": true
}
EOF
        log_message "Created monitor config for systemd service: $service_name"
    done
}

create_discovered_monitors() {
    log_message "Creating monitors from discovered services..."
    
    # Combine all discovered monitors into a single file
    echo "[" > "$TEMP_DIR/all-monitors.json"
    
    first=true
    for config_file in "$TEMP_DIR"/*.json; do
        if [[ "$config_file" != "$TEMP_DIR/all-monitors.json" ]]; then
            if [[ "$first" == "false" ]]; then
                echo "," >> "$TEMP_DIR/all-monitors.json"
            fi
            cat "$config_file" >> "$TEMP_DIR/all-monitors.json"
            first=false
        fi
    done
    
    echo "]" >> "$TEMP_DIR/all-monitors.json"
    
    # Create monitors using our Python script
    if [[ -s "$TEMP_DIR/all-monitors.json" ]]; then
        /usr/local/bin/uk-monitor-manager.py create-bulk "$TEMP_DIR/all-monitors.json"
        log_message "Completed monitor creation from auto-discovery"
    else
        log_message "No new services discovered"
    fi
}

cleanup() {
    rm -rf "$TEMP_DIR"
}

trap cleanup EXIT

# Main discovery workflow
log_message "Starting auto-discovery process"

discover_docker_services
discover_systemd_services
create_discovered_monitors

log_message "Auto-discovery process completed"

Make the script executable and set up automated execution:

sudo chmod 755 /usr/local/bin/uk-auto-discovery.sh

# Create systemd timer for automated discovery
sudo tee /etc/systemd/system/uk-auto-discovery.timer << 'EOF'
[Unit]
Description=Uptime Kuma Auto-Discovery Timer
Requires=uk-auto-discovery.service

[Timer]
OnCalendar=*:0/15
Persistent=true

[Install]
WantedBy=timers.target
EOF

sudo tee /etc/systemd/system/uk-auto-discovery.service << 'EOF'
[Unit]
Description=Uptime Kuma Auto-Discovery Service
After=network.target uptime-kuma.service

[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/uk-auto-discovery.sh
TimeoutSec=300

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now uk-auto-discovery.timer

Configure status page automation

Set up programmatic status page management with custom styling and maintenance scheduling.

#!/usr/bin/env python3
import requests
import json
import sys
from datetime import datetime, timedelta

class StatusPageManager:
    def __init__(self, config_file='/etc/uptime-kuma/api-config.json'):
        with open(config_file) as f:
            self.config = json.load(f)
        self.base_url = self.config['api_base_url']
        self.headers = {
            'Authorization': f"Bearer {self.config['auth_token']}",
            'Content-Type': 'application/json'
        }
    
    def create_status_page(self, config):
        """Create a public status page with custom configuration"""
        status_page_config = {
            'title': config.get('title', 'Service Status'),
            'description': config.get('description', 'Real-time status of our services'),
            'theme': config.get('theme', 'auto'),
            'published': config.get('published', True),
            'show_tags': config.get('show_tags', True),
            'domainNames': config.get('domains', []),
            'customCSS': config.get('custom_css', ''),
            'footerText': config.get('footer', 'Powered by Uptime Kuma'),
            'showPoweredBy': config.get('show_powered_by', False)
        }
        
        response = requests.post(
            f"{self.base_url}/status-page",
            headers=self.headers,
            json=status_page_config
        )
        response.raise_for_status()
        return response.json()
    
    def schedule_maintenance(self, maintenance_config):
        """Schedule maintenance windows with automatic notifications"""
        maintenance = {
            'title': maintenance_config['title'],
            'description': maintenance_config['description'],
            'strategy': maintenance_config.get('strategy', 'single'),
            'active': True,
            'intervalDay': maintenance_config.get('interval_days', 0),
            'dateTime': maintenance_config['start_time'],
            'dateTimeEnd': maintenance_config['end_time'],
            'monitors': maintenance_config.get('monitor_ids', []),
            'statusPages': maintenance_config.get('status_page_ids', [])
        }
        
        response = requests.post(
            f"{self.base_url}/maintenance",
            headers=self.headers,
            json=maintenance
        )
        response.raise_for_status()
        return response.json()
    
    def update_incident_status(self, incident_data):
        """Update incident information on status pages"""
        incident = {
            'title': incident_data['title'],
            'content': incident_data['description'],
            'style': incident_data.get('style', 'warning'),
            'created_date': datetime.utcnow().isoformat(),
            'last_updated_date': datetime.utcnow().isoformat()
        }
        
        response = requests.post(
            f"{self.base_url}/incident",
            headers=self.headers,
            json=incident
        )
        response.raise_for_status()
        return response.json()

if __name__ == '__main__':
    manager = StatusPageManager()
    
    # Example: Create status page
    if len(sys.argv) > 1 and sys.argv[1] == 'create-page':
        config = {
            'title': 'Example.com Service Status',
            'description': 'Real-time status of example.com services',
            'theme': 'dark',
            'domains': ['status.example.com'],
            'custom_css': '.header { background: #2563eb; }'
        }
        result = manager.create_status_page(config)
        print(f"Created status page: {result['slug']}")
    
    # Example: Schedule maintenance
    elif len(sys.argv) > 1 and sys.argv[1] == 'schedule-maintenance':
        config = {
            'title': 'Database Migration',
            'description': 'Upgrading database servers for improved performance',
            'start_time': (datetime.now() + timedelta(days=1)).isoformat(),
            'end_time': (datetime.now() + timedelta(days=1, hours=2)).isoformat(),
            'monitor_ids': [1, 2, 3]
        }
        result = manager.schedule_maintenance(config)
        print(f"Scheduled maintenance: {result['id']}")

Make the status manager executable:

sudo chmod 755 /usr/local/bin/uk-status-manager.py

Set up advanced alerting rules

Configure complex alerting workflows with escalation chains and conditional logic.

&

Automated install script

Run this to automate the entire setup

不想自己管理这些吗?

我们为依赖稳定运行时间的企业管理基础设施。全托管服务,配备一位熟悉您系统架构的固定联系人。

您将拥有一位了解您整体架构的固定联系人

Rotterdam 04:09 · 一条消息即可联系我们,无需填写工单表单