{"docs":[{"publicId":"01KJ7Q9ZT4XRY3HHAY3VMBBFTZ","locale":"en","translationGroup":"dashboard","slug":"en-dashboard","title":"Dashboard","description":"Main dashboard overview cards, system health score, charts, and alert system guide","body":"# Dashboard\n\nThe Dashboard summarizes the real-time status of your entire monitoring infrastructure on a single screen. Your monitors, SSL certificates, active incidents, and AI predictions are all displayed here.\n\n## Alert Panel\n\nThe top of the page shows the current status:\n\n- **If there are issues**: A red alert banner lists items that require attention:\n  - How many monitors are **down**\n  - **SSL certificates** about to expire\n  - Number of **active incidents**\n  - Each alert includes a button linking to the relevant page\n\n- **If everything is fine**: A green banner shows **\"All Systems Operational\"** with the last update time\n\n## Summary Cards\n\nBelow the alert panel, 4 summary cards are displayed:\n\n| Card | Description | Detail |\n|------|-------------|--------|\n| **Total Monitors** | Total number of monitors | Shows how many are down |\n| **Uptime** | Last 24-hour uptime percentage | Excellent / Good / Needs attention rating |\n| **Response Time** | Average response time (ms) | Fast / Normal / Slow rating |\n| **SSL Certificates** | Total SSL certificate count | Expiring ones shown with warning |\n\nClick any card to navigate to the relevant page.\n\n## System Health Score\n\nIn the left panel, a large ring chart shows your system health score from 0-100:\n\n- **95+**: Green — Excellent\n- **80-94**: Yellow — Good\n- **60-79**: Red — Fair\n- **Below 60**: Red — Poor\n\nBelow the ring, 3 mini stat boxes display:\n- Uptime percentage\n- Response time (ms)\n- Incident count\n\n## Monitor Status Summary\n\nThe center panel shows the overall status of your monitors:\n\n- **Up**: Number of running monitors (green badge)\n- **Down**: Number of offline monitors (red, pulsing badge)\n- **Slow**: Monitors with slow response (>2000ms, yellow badge)\n\nIf there are problematic monitors, up to 5 are listed under a **\"Needs Attention\"** heading. When all monitors are healthy, an **\"All Monitors Healthy\"** message is displayed.\n\n## Recent Activities\n\nThe right panel lists the 6 most recent events chronologically:\n\n- Recent incidents (active and resolved)\n- Currently down monitors\n- SSL certificates expiring within 7 days\n\nEach event shows a colored status dot, title, description, and when it occurred. Click an event to go to its detail page.\n\n## Proactive AI Insights\n\nIf you have access to AI-powered monitoring, this panel shows:\n- Monitors in critical condition\n- Monitors with declining performance\n- Detected anomalies\n\nClick **\"View All\"** to go to the AI Insights page.\n\n> This feature is active on paid plans. The free plan shows an **\"Upgrade Plan\"** button.\n\n## Response Time Distribution\n\nA horizontal bar chart showing the response time distribution of your monitors:\n\n| Range | Color |\n|-------|-------|\n| <500ms | Green |\n| 500ms - 1s | Blue |\n| 1s - 2s | Yellow |\n| >2s | Red |\n\nThe number of monitors in each range is shown numerically.\n\n## Most Problematic Monitors\n\nMonitors with high incident counts or uptime below 99% are ranked. For each monitor:\n- Rank number\n- Monitor name\n- Uptime percentage\n- Incident count\n- Status badge\n\n## SSL Certificate Timeline\n\nSSL certificates approaching expiration are sorted by days remaining:\n\n| Days Remaining | Color |\n|---------------|-------|\n| ≤7 days | Red |\n| ≤14 days | Orange |\n| ≤30 days | Yellow |\n| >30 days | Green |\n\nClick **\"Manage SSL\"** to go to the SSL certificates page.\n\n## First-Time Experience (Onboarding)\n\nIf you haven't created any monitors yet, a welcome screen is shown instead of the dashboard:\n\n- **\"Welcome to UptimeWarden!\"** heading\n- 3 feature cards: Real-time Monitoring, SSL Certificate Tracking, Performance Insights\n- **\"Create Your First Monitor\"** button\n- **\"Take a Quick Tour\"** button\n\n## Tips\n\n1. **Check regularly**: The dashboard auto-refreshes every 60 seconds, but you can click the refresh button anytime\n2. **Take alerts seriously**: When the red alert banner appears, take relevant actions quickly\n3. **Track SSL certificates**: Start the renewal process 30 days before expiration\n4. **Use AI insights**: Check proactive alerts to detect issues before they occur","category":"getting-started","tags":["dashboard","overview","monitoring","health-score","ssl"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Main dashboard overview cards, system health score, charts, and alert system guide","icon":"Rocket","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZT23TPSK42PJ652J8R3","locale":"en","translationGroup":"quick-start","slug":"en-quick-start","title":"Quick Start - Your First Monitor in 5 Minutes","description":"Start monitoring your first website with UptimeWarden in 5 minutes","body":"# Quick Start - Your First Monitor in 5 Minutes\n\nWelcome to UptimeWarden! This guide walks you through creating your first monitor and starting to track your website.\n\n## Step 1: Create an Account\n\n1. Go to [UptimeWarden.com](https://uptimewarden.com)\n2. Click the **Get Started Free** button\n3. Enter your email address and password\n4. Verify your account via email\n\n> 💡 **Tip**: You can create up to 10 monitors on the free plan!\n\n## Step 2: Create Your First Monitor\n\nAfter logging in to the Dashboard:\n\n1. Click the **Add Monitor** button\n2. Fill in the following information:\n   - **Name**: A descriptive name for your monitor (e.g., \"Main Website\")\n   - **URL**: The website address you want to monitor\n   - **Check Interval**: How often to check (e.g., 1 minute)\n\n3. Click **Create Monitor**\n\n```\nExample:\nName: Company Website\nURL: https://mycompany.com\nCheck Interval: 1 minute\n```\n\n## Step 3: Configure Notifications\n\nYour monitor is ready! Now let's set up how you'll be notified when something goes wrong:\n\n1. Go to the monitor details page\n2. Click the **Notifications** tab\n3. Choose your preferred notification method:\n   - **Email**: Active by default\n   - **SMS**: Add your phone number\n   - **Webhook**: For custom integrations\n\n## Step 4: Review Initial Data\n\nWithin a few minutes, your monitor will start collecting data:\n\n- **Uptime Percentage**: Your site's availability rate\n- **Response Time**: Your site's average response time\n- **Last 24 Hours**: Detailed performance chart\n\n## Step 5: Create a Status Page (Optional)\n\nCreate a public status page to show your customers your site's status:\n\n1. Click **Status Pages** in the left menu\n2. Click the **New Status Page** button\n3. Give your page a name\n4. Select the monitors to display\n5. Click **Create**\n\nYour status page is ready! Share the link with your customers.\n\n## Next Steps\n\nCongratulations! You've successfully created your first monitor. Here's what else you can do:\n\n- Add [SSL Certificate Monitoring](/docs/en-ssl-monitor)\n- Invite [Team Members](/docs/en-team-management)\n- Set up [API Integration](/docs/en-api-getting-started)\n- Configure [Advanced Monitor Settings](/docs/en-monitor-settings)\n\n## FAQ\n\n**Q: How many monitors can I create?**\nA: 10 on the Free plan, 50 on Starter, 250 on Professional.\n\n**Q: Can I change the check interval later?**\nA: Yes, you can change it anytime from the monitor settings.\n\n**Q: What should I do about false alarms?**\nA: Check the retry logic settings and increase the timeout if needed.\n\n## Need Help?\n\n- 📧 Email: support@uptimewarden.com\n- 💬 Live Chat: Chat icon in the bottom right of the Dashboard\n- 📚 [Full Documentation](/docs)","category":"getting-started","tags":["getting-started","quickstart","first-steps"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Start monitoring your first website with UptimeWarden in 5 minutes","icon":"Rocket","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZT3A48BSZ8CK39MASBH","locale":"en","translationGroup":"basic-concepts","slug":"en-basic-concepts","title":"Basic Concepts - What is a Monitor, Incident, Uptime?","description":"Learn the fundamental concepts in UptimeWarden","body":"# Basic Concepts\n\nBefore you start using UptimeWarden, it's important to understand the fundamental concepts you'll encounter throughout the platform.\n\n## Monitor\n\nA monitor is a monitoring task that periodically checks a website, API endpoint, or service at regular intervals.\n\n### Monitor Properties:\n- **URL/Endpoint**: The address being monitored\n- **Check Interval**: How often it's checked (30 seconds to 24 hours)\n- **Timeout**: Response wait time\n- **Location**: Server locations where checks are performed\n\n### Monitor Types:\n\n#### HTTP/HTTPS Monitor\nThe most common monitor type. Monitors websites and APIs.\n- Status code validation (200, 301, 404, etc.)\n- Keyword validation — checks whether a specific word exists in the page content\n- Response time measurement\n\n#### SSL Certificate Monitor\nMonitors SSL certificate validity and expiration dates.\n- Certificate expiry tracking\n- Certificate chain validation\n- Automatic renewal reminders\n\n#### TCP Port Monitor\nChecks whether specific TCP ports are open.\n- Database servers (3306, 5432, etc.)\n- Mail servers (25, 587, 993, etc.)\n- Custom services\n\n#### UDP Port Monitor\nChecks the availability of UDP-based services.\n- DNS servers\n- Game servers\n- VoIP services\n\n#### Ping (ICMP) Monitor\nMeasures availability and latency by sending ICMP pings to the target server.\n- Simple availability check\n- Network latency measurement\n\n#### WebSocket Monitor\nMonitors WebSocket connections.\n- Connection establishment test\n- Message send/receive validation\n- Real-time service monitoring\n\n#### gRPC Monitor\nMonitors gRPC endpoints.\n- Health check validation\n- Specialized monitoring for gRPC services\n\n#### MCP Monitor\nMonitors Model Context Protocol (MCP) services.\n- Availability checks for AI tool services\n\n## Incident\n\nAn incident is a situation where a monitor fails or doesn't meet expected conditions.\n\n### Incident Lifecycle:\n\n1. **Detection**: Monitor detects a problem\n2. **Verification**: False alarm check via retry logic\n3. **Notification**: Users are alerted\n4. **Resolution**: Problem is fixed\n5. **Closure**: Incident is closed and duration is recorded\n\n### Incident Levels:\n\n- **Down**: Service is completely unreachable\n- **Degraded**: Service is running but slow or partially impaired\n- **Maintenance**: Planned maintenance period\n\n## Uptime\n\nUptime is the percentage of time a service is accessible.\n\n### Uptime Calculation:\n\n```\nUptime % = (Total Time - Downtime) / Total Time × 100\n```\n\n### SLA Levels:\n\n| Uptime % | Annual Downtime | Monthly Downtime | Weekly Downtime |\n|----------|----------------|-----------------|----------------|\n| 99.9%    | 8.77 hours     | 43.83 minutes   | 10.08 minutes  |\n| 99.95%   | 4.38 hours     | 21.92 minutes   | 5.04 minutes   |\n| 99.99%   | 52.60 minutes  | 4.38 minutes    | 1.01 minutes   |\n\n## Response Time\n\nThe time elapsed from sending a request to receiving a response.\n\n### Response Time Metrics:\n\n- **Average**: Mean response time\n- **P95**: Time below which 95% of requests fall\n- **P99**: Time below which 99% of requests fall\n- **Max**: Highest response time recorded\n\n### Ideal Response Times:\n\n- **Excellent**: < 200ms\n- **Good**: 200ms - 1s\n- **Acceptable**: 1s - 3s\n- **Slow**: > 3s\n\n## Status Page\n\nA public web page that shows your customers the status of your services.\n\n### Status Page Components:\n\n- **Current Status**: Real-time status indicator\n- **Incident History**: Past incidents\n- **Uptime Graph**: Availability timeline\n- **Maintenance Schedule**: Planned maintenance\n- **Subscriber System**: Email notifications\n\n## Alert\n\nA notification sent when an incident occurs.\n\n### Alert Channels:\n\n- **Email**: Detailed incident report\n- **SMS**: Urgent notification for critical situations\n- **WhatsApp**: Urgent notification (SMS alternative)\n- **Voice Call**: Phone call for the most critical situations\n- **Push Notification**: Mobile app notifications\n- **Telegram**: Notification via Telegram bot\n- **Slack**: Channel notification via Slack webhook\n- **Microsoft Teams**: Channel notification via Teams webhook\n- **Webhook**: For custom integrations (Discord, PagerDuty, etc. connect via webhook)\n\n### Alert Fatigue Prevention:\n\n- **Escalation Policy**: Tiered notification system\n- **Alert Grouping**: Grouping similar alerts\n- **Quiet Hours**: Silent hours setting\n- **Alert Throttling**: Excessive notification prevention\n\n## Check Location\n\nGeographic locations where monitor checks are performed.\n\n### Why It Matters:\n\n- **Global Accessibility**: Access verification from different regions\n- **Latency Measurement**: Regional performance analysis\n- **CDN Validation**: Content delivery network verification\n- **Redundancy**: Single point of failure prevention\n\n### Available Locations:\n\n- **ae** — Sydney, Australia (Australia East)\n- **brs** — São Paulo, Brazil (Brazil South)\n- **gwc** — Frankfurt, Germany (Germany West Central)\n- **sea** — Singapore (Southeast Asia)\n- **uaen** — Dubai, UAE (UAE North)\n- **wus3** — Phoenix, Arizona, USA (West US 3)\n\n## Maintenance Window\n\nA time period designated for planned maintenance work.\n\n### Maintenance Window Features:\n\n- **Scheduled**: Pre-planned\n- **Recurring**: Repeating (weekly, monthly)\n- **Alert Suppression**: Notification suppression\n- **Status Page Integration**: Automatic announcement\n\n## Retry Logic\n\nRepeating failed checks to prevent false alarms.\n\n### Retry Strategy:\n\n1. First failure: Wait 30 seconds and retry\n2. Second failure: Wait 60 seconds and retry\n3. Third failure: Create incident and send notification\n\n## Summary\n\nUnderstanding these fundamental concepts will help you use UptimeWarden effectively. You'll encounter these terms frequently throughout the platform.\n\n## Next Steps\n\n- [Create Your First Monitor](/docs/en-quick-start)\n- [Explore Monitor Types](/docs/en-other-monitor-types)\n- [Set Up Notifications](/docs/en-notification-channels)","category":"getting-started","tags":["basics","concepts","getting-started"],"order":2,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Learn the fundamental concepts in UptimeWarden","icon":"Rocket","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZT6XWM0TQN3ND5XMZSR","locale":"en","translationGroup":"audit-log","slug":"en-audit-log","title":"Audit Logs","description":"User activity tracking, filtering, and audit log management guide","body":"# Audit Logs\n\nThe Audit Logs page chronologically records all user activities and system changes in your account. It answers the questions: who, when, and what was done.\n\n## Log Information\n\nEach audit record contains the following information:\n\n| Field | Description |\n|-------|-------------|\n| **Action** | Operation type badge (color-coded) |\n| **Severity** | Importance level badge |\n| **Timestamp** | Date and time of the operation |\n| **Description** | Description of the operation |\n| **Table** | Name of the table where the change was made |\n| **Record ID** | ID of the affected record |\n| **IP Address** | IP address of the user who performed the action |\n| **User Agent** | Browser/client information |\n\n## Action Types\n\n| Action | Description | Color |\n|--------|-------------|-------|\n| **Create** | New record creation | Green |\n| **Update** | Existing record update | Blue |\n| **Delete** | Record deletion | Red |\n| **Login** | System login | Purple |\n| **Logout** | System logout | Gray |\n| **Export** | Data export | Yellow |\n| **Permission Change** | Permission modification | Orange |\n| **Settings Change** | Settings modification | Indigo |\n| **Monitor Create** | Monitor creation | Teal |\n| **Monitor Update** | Monitor update | Cyan |\n| **Monitor Delete** | Monitor deletion | Pink |\n\n## Severity Levels\n\n| Level | Description |\n|-------|-------------|\n| **Critical** | Critical operations (deletion, permission changes) |\n| **High** | High importance (security settings) |\n| **Medium** | Medium importance (configuration changes) |\n| **Low** | Low importance (read, login operations) |\n\n## Filtering\n\nYou can filter audit records by multiple criteria:\n\n| Filter | Description |\n|--------|-------------|\n| **Search** | Search in description text |\n| **Action Type** | Filter by action type (e.g., Create, Delete) |\n| **Severity** | Filter by severity level (Low, Medium, High, Critical) |\n| **Start Date** | Start date |\n| **End Date** | End date |\n\nUse the **\"Clear Filters\"** button to clear active filters.\n\n## View Modes\n\nTwo different view modes are available:\n\n### List View (Default)\n\nAudit records are displayed as a flat list, sorted by date. Each record is shown in card format with all details.\n\n### Group by Type View\n\nClick the **\"Group by Type\"** button to group records by action type. Each group is shown as a collapsible section:\n\n- The group header includes the action icon, name, and record count (e.g., `Create (5 records)`)\n- Click a group to expand or collapse its details\n\n## Pagination\n\nWhen there are many records, pagination is automatically enabled:\n- Navigate between pages using **\"Previous\"** and **\"Next\"** buttons\n- Page indicator: `Page 1 / 5`\n- Total record count is displayed (e.g., `128 records found`)\n\n## Tips\n\n1. **Review regularly**: Periodically review Critical-level operations\n2. **Use date ranges**: Use date filters to examine changes in specific periods\n3. **Track deletions**: Delete action records help identify accidentally deleted data\n4. **Monitor login activity**: Detect unauthorized access attempts through Login records\n5. **Use grouped view**: Group by type to see all records of a specific action type","category":"getting-started","tags":["audit","logs","security","activity","tracking"],"order":3,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"User activity tracking, filtering, and audit log management guide","icon":"Rocket","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZT532A9GWQ38BX33TV0","locale":"en","translationGroup":"profile-management","slug":"en-profile-management","title":"Profile and Account Management","description":"User profile editing, password change, and account settings management","body":"# Profile and Account Management\n\nFrom your profile page, you can update your personal information, change your password, and check your subscription status.\n\n## Accessing the Profile Page\n\nClick **My Profile** in the left menu, or access your profile page from the user menu in the top right corner.\n\n## Subscription Status\n\nThe top section of the profile page shows your current subscription plan and usage statistics:\n\n- **Plan name**: Free, Starter, Professional, or Enterprise\n- **Status**: Active, trial period, etc.\n- **Price**: Monthly payment amount\n\n### Usage Statistics\n\nUsage for each resource type is displayed with a progress bar:\n\n| Resource | Display |\n|----------|---------|\n| **Monitors** | Used / Maximum (e.g., 8 / 10) |\n| **Teams** | Used / Maximum |\n| **Agents** | Used / Maximum |\n\nClick the **\"Change Plan\"** button to make plan changes.\n\n## Personal Information\n\nYou can update the following information:\n\n| Field | Description |\n|-------|-------------|\n| **First Name** | Your first name |\n| **Last Name** | Your last name |\n| **Username** | Your system username |\n| **Email** | Your account email address |\n\nAfter making changes, click the **\"Update Profile\"** button.\n\n## Change Password\n\nTo change your password:\n\n1. Enter your current password in the **Current Password** field\n2. Enter your new password in the **New Password** field\n3. Re-enter your new password in the **Confirm Password** field\n4. Click the **\"Change Password\"** button\n\n## Tips\n\n1. **Use a strong password**: Include at least 8 characters with uppercase, lowercase, numbers, and special characters\n2. **Keep your email current**: An up-to-date email address is important for notifications and account recovery\n3. **Track usage limits**: Consider upgrading or purchasing add-ons when approaching your plan limits","category":"getting-started","tags":["profile","account","password","security","settings"],"order":3,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"User profile editing, password change, and account settings management","icon":"Rocket","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2ENYF52FW2909QY7K0TCJ","locale":"en","translationGroup":"quick-start","slug":"quick-start","title":"Quick Start","description":"Sign up, add your first monitor, hook up a notification channel, and watch your first incident, about a minute end-to-end.","body":"# Quick Start\n\nThis guide walks you from a fresh account to a live monitor and your first alert. Total time: about a minute.\n\n## 1. Create your account\n\n1. Visit [uptimewarden.online](https://uptimewarden.online) and click **Sign up**.\n2. Register with email and password, or sign up with **Google** or **GitHub**.\n3. Click the verification link in the email we send you, some surfaces stay restricted until your email is verified.\n\nA new account starts on the **Free** plan. Free plan limits include:\n\n- A small cap on the number of monitors\n- A minimum check interval (the most frequent cadence Free can use)\n- Limited regions to check from\n- Limited notification channels and webhooks\n\nFor the full per-plan matrix, see [Subscription Plans](/docs/subscription-plans).\n\n## 2. Add your first monitor\n\nFrom the left navigation, open **Monitors -> New Monitor**.\n\nUptimeWarden supports 10 monitor types. Start with one of the most common:\n\n- **HTTP / HTTPS**: verifies a web endpoint is alive ([HTTP Monitor](/docs/http-monitor))\n- **Ping**: ICMP echo to a host\n- **DNS**: verifies record values ([DNS Monitor](/docs/dns-monitor))\n- **SSL**: certificate validity and expiry ([SSL Monitor](/docs/ssl-monitor))\n- **Heartbeat**: inverse monitor for cron and ETL jobs ([Heartbeat Monitor](/docs/heartbeat-monitor))\n\nFor a typical HTTP monitor, fill in:\n\n| Field | Example |\n|---|---|\n| Name | `Marketing Site` |\n| URL | `https://example.com` |\n| Method | `GET` (switches to POST automatically when you supply a request body) |\n| Check interval | `1m` (down to your plan's minimum) |\n| Region(s) | Sweden Central by default, add verification regions via Multi-Location Consensus (count depends on your plan) |\n| Expected status | `200-299` or a specific code |\n\nClick **Save**. The monitor enters the schedule, and the first check result appears within seconds.\n\n:::note\nTo run the same check from multiple regions and reduce false alarms from a single network blip, enable [Multi-Location Consensus](/docs/multi-location-consensus). The maximum number of verification regions depends on your plan.\n:::\n\n## 3. Hook up a notification channel\n\nNavigate to **Notifications -> Channels -> Add Channel** and pick one:\n\n- **Email**: default; uses your account email\n- **Slack**: webhook URL or OAuth workspace install\n- **Telegram**: bot token plus chat ID ([Telegram](/docs/telegram))\n- **SMS / WhatsApp / Voice**: global delivery, with full Turkish coverage\n- **Webhook**: POST JSON to your own system ([Webhook Configuration](/docs/webhook-configuration), [Webhook Security](/docs/webhook-security))\n- **Push**: mobile app push ([Push Notifications](/docs/push-notifications))\n\nAfter connecting a channel, open the monitor's detail page, switch to the **Notifications** tab, and pick the alert types you want: down, recovery, SSL warning, high response time, domain expiring. The full list lives in [Notifications](/docs/notifications-overview).\n\n:::tip\nSo that a cascade does not page you once per monitor, [Smart Alert Grouping](/docs/smart-alert-grouping) is on for every plan: the first alert goes out at once and the rest of the burst arrives as one message. On plans where Cascade Suppression is enabled, downstream alerts caused by an upstream root are suppressed automatically.\n:::\n\n## 4. Watch your first incident\n\nWhen a monitor goes down:\n\n1. An **incident** opens automatically.\n2. Your linked notification channels fire.\n3. If you have configured an [Escalation Policy](/docs/escalation-policies), it kicks in.\n4. When the recovery signal arrives, the incident moves to **Resolved** and a recovery notification goes out.\n\nOpen incidents appear on **Dashboard -> Priority Alerts** and on the **Incidents** page. The one-click **Acknowledge** button stops further escalation while you investigate.\n\nIf Cascade Suppression is active, downstream incidents are recorded as **Suppressed (cascade)** with no notification and no escalation. See [Monitor Dependencies](/docs/monitor-dependencies).\n\n## Next steps\n\n- [Basic Concepts](/docs/basic-concepts): monitor, heartbeat, incident, agent terminology\n- [Dashboard](/docs/dashboard): modern dashboard widgets\n- [Health Prediction](/docs/health-prediction-overview): forecasts and recommendations built from your monitor history (Professional and above)\n- [Monitoring as Code](/docs/developers-monitoring-as-code): declarative monitor management from the terminal\n- [Agent Management](/docs/agent-management): monitoring services in private networks","category":"getting-started","tags":["getting-started","onboarding","quickstart","monitor","notifications"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Quick Start. UptimeWarden Docs","metaDescription":"From a fresh account to a live monitor and your first alert. UptimeWarden onboarding step by step.","icon":"Rocket","createdAt":"2026-10-12T22:06:41.615Z","updatedAt":"2026-10-12T22:06:41.615Z","publishedAt":"2026-10-12T22:06:41.615Z"},{"publicId":"01M4S2ENYP253X20BAWY1CPMT7","locale":"en","translationGroup":"basic-concepts","slug":"basic-concepts","title":"Basic Concepts","description":"Core terminology used across UptimeWarden, monitor, heartbeat, incident, agent, status page, multi-location consensus, SLO, team, and role.","body":"# Basic Concepts\n\nUse this page as a reference for the terms you will see across every UptimeWarden screen.\n\n## Monitor\n\nA **monitor** is an automated check that runs on a fixed interval. Each monitor has a target (URL, IP address, host, or port) and a type. UptimeWarden supports 10 monitor types:\n\n| Type | What it checks |\n|---|---|\n| HTTP / HTTPS | A web endpoint responds and returns the expected status code |\n| TCP | A port accepts connections (for example, a database port) |\n| UDP | A connectionless port returns a response |\n| Ping | A host is reachable via ICMP echo |\n| SSL | A certificate is valid and how soon it expires |\n| DNS | A, AAAA, CNAME, MX, NS, and TXT records return the expected values |\n| MCP | Model Context Protocol services are healthy |\n| gRPC | A gRPC service answers correctly on its health endpoint |\n| WebSocket | A WebSocket connection opens successfully |\n| Heartbeat | **Inverse monitor**, your job pings *us*; if late, we alert |\n\nCheck results are retained based on your plan's data retention window.\n\n## Heartbeat\n\nA **heartbeat** monitor flips the polling direction: instead of UptimeWarden polling your endpoint, your background job (cron task, ETL pipeline, serverless function) pings **us** on a schedule.\n\nWhen you create a heartbeat monitor, UptimeWarden gives you a unique URL. Your job sends a request to that URL on every successful run. If the expected ping does not arrive within the configured window, an incident opens. See [Heartbeat Monitor](/docs/heartbeat-monitor).\n\n## Incident\n\nWhen a monitor goes down, an **incident** is opened. Its lifecycle:\n\n1. **Open**, newly created, not yet acknowledged\n2. **Acknowledged**, someone took the page; escalation halts and the acknowledger is recorded\n3. **Investigating** *(optional)*, root-cause work in progress\n4. **Monitoring** *(optional)*, fix applied, watching for recurrence\n5. **Resolved**, the recovery signal arrived or the incident was closed manually\n\nIf multi-location verification is on, you may also see **Pending verification** and **Rejected** states. With Cascade Suppression and a dependency graph defined, downstream incidents are recorded as **Suppressed (cascade)** with no notification and no escalation. See [Incident Lifecycle](/docs/incident-lifecycle).\n\n## Agent\n\nAn **agent** is UptimeWarden's lightweight monitoring app that you run on your own servers. You run it inside your own network to monitor private services such as intranet apps and anything behind a VPN. The agent only opens **outbound HTTPS** to UptimeWarden, no inbound port is required, and it never connects directly to your internal systems. See [Agent Management](/docs/agent-management).\n\n## Status page\n\nA **status page** is the public-facing page you give customers so they can see live service health. Every plan includes at least one. Custom domains (for example, `status.example.com`, on Professional and Enterprise), white-label branding (Enterprise), and an incident timeline are all supported. Email subscriber digests are coming soon. See [Status Page Subscribers](/docs/status-page-subscribers).\n\n## Multi-Location Consensus\n\nA single \"down\" signal from one region can be misleading, a transient routing issue or a single data centre outage might be the cause. **Multi-Location Consensus** runs the same check from two or more regions in parallel and only opens an incident once an **N-of-M agreement** threshold is met.\n\nPlan-level controls:\n\n- **Maximum verification regions**: how many witness regions your monitors can use\n- **Default confirming regions**: the threshold applied when a new monitor is created\n- **Allow consensus override**: whether you can change those numbers yourself\n\nFree and Hobby plans use opinionated defaults with no override. Starter and above let you adjust them. See [Multi-Location Consensus](/docs/multi-location-consensus).\n\n## SLO and Error Budget\n\nA **Service Level Objective** is a target such as \"99.9% uptime per month\". UptimeWarden computes it automatically and shows your remaining **error budget**, the downtime you can still afford before missing the target. The SLO surface is available on Professional and above. See [SLO Error Budgets](/docs/slo-error-budgets).\n\n## Team and Role\n\nA **team** is a group of users under your account. They share monitors, alerts, and settings. Roles:\n\n- **Admin**: full access, including user and team management\n- **Editor**: manage monitors, channels, and status pages\n- **Reader**: read-only access\n\nThe team creator is added as an **Admin**, and account-level billing stays with the account owner. See [Roles & Permissions](/docs/roles-permissions).\n\n## Region\n\nUptimeWarden runs checks from five physical regions:\n\n| Region | Location |\n|---|---|\n| Sydney | Australia |\n| São Paulo | Brazil |\n| Sweden Central | Europe (default, global services run here) |\n| East Asia | Asia |\n| Phoenix | US West |\n\nEach monitor runs from a single home region. Your plan determines how many additional regions can act as verification (witness) regions for [Multi-Location Consensus](/docs/multi-location-consensus). If checks in one region stop running, the nearest live region picks up your monitors automatically, your monitor's home region is not changed.\n\n## Next steps\n\n- [Quick Start](/docs/quick-start): hands-on walkthrough\n- [Dashboard](/docs/dashboard): turning data into a glanceable view\n- [Notifications](/docs/notifications-overview): channels and escalation\n- [Health Prediction](/docs/health-prediction-overview): the AI prediction layer","category":"getting-started","tags":["glossary","concepts","terminology","fundamentals"],"order":20,"parentSlug":null,"published":true,"version":1,"metaTitle":"Basic Concepts. UptimeWarden Docs","metaDescription":"Concise definitions of monitor, heartbeat, incident, agent, status page, SLO error budget, and role concepts in UptimeWarden.","icon":"Rocket","createdAt":"2026-10-12T22:06:41.623Z","updatedAt":"2026-10-12T22:06:41.623Z","publishedAt":"2026-10-12T22:06:41.623Z"},{"publicId":"01M4S2ENYYR0D9R6G1D7BPJ31V","locale":"en","translationGroup":"dashboard","slug":"dashboard","title":"Dashboard","description":"The dashboard's problems-first layout: status bar, needs-attention list, context strip, availability, the This week card, and the SLOs and Insights panel.","body":"# Dashboard\n\nThe dashboard is your live single-page view of the account. After signing in, you land on it directly.\n\n## Layout\n\nThe dashboard is built problems first: it answers whether anything is wrong, then shows what needs a decision, the context around it, and the history. Top to bottom:\n\n1. **Header and controls** — the page title; a time range control (24 h, 7 d, 30 d, 90 d), a group filter when your account has groups, and the **Add Monitor** button. (\"Ask Wardy\" is not dashboard-specific; it lives as a floating button in the bottom-right corner on every page.)\n2. **Status bar** — the account's one-line answer, status chips, and the live freshness indicator\n3. **Needs attention now** — only when something needs a decision\n4. **Context strip** — on call · maintenance · expiring soon\n5. **Availability** — uptime per window and a 90-day downtime strip\n6. **Monitors, worst first** — the monitors in scope\n7. **Reliability** — appears once there is an incident to measure\n8. **This week** and suggested Wardy questions\n9. **SLOs and Insights** — two collapsed rows that open in place\n\nEach section below explains what it shows.\n\n## Status Bar\n\nThe bar at the top of the page is the one-line answer to \"is anything wrong?\":\n\n- **\"All systems operational\"** — nothing is. The subline names the last outage (\"last outage 3 hours ago\") or says there were no outages in the last 90 days.\n- **\"N monitors down\"**, **\"N monitors slow\"**, or **\"N certificates and domains expiring or expired\"** — something is; the subline shows the oldest one and how long it has been running (\"Oldest since 11:42 · 18 min · 1 acknowledged\"). Before any monitor has reported, it says **\"Waiting for the first check\"**.\n\nThe chips — **Down**, **Slow**, **Up**, **Maintenance**, **Paused** — carry the matching counts, and each one opens its list. (Up is always shown; the others appear when their count is above zero.)\n\nThe **\"Live · updated 12 s ago\"** line on the right says how fresh the view is. When no update has arrived for two minutes it turns amber and reads **\"Not live\"**.\n\n## Needs Attention Now\n\nThe list below the status bar collects everything that needs a decision right now; the whole section is hidden when nothing does. Rows are individual situations, not grouped summaries:\n\n- **DOWN** / **SLOW** — a monitor that is down or slow, with how long it has been that way (\"Down 18 min\") and its acknowledgement state. A failure with no incident open yet is listed here too.\n- **SSL** / **DOMAIN** — certificates and domains expiring within 7 days (\"5 days left\", \"Expired\")\n- **EARLY** — early warnings that do not page anyone yet (\"May page\" / \"Does not page\"). When only those remain, the card's heading reads **\"Early warnings\"**.\n\nEvery row carries a duration, an ownership line (not acknowledged yet, or acknowledged by someone), and one action: **Open incident** / **View** for the target, or **Acknowledge** when an open incident is waiting. **All incidents** in the card's header opens the full incident list.\n\n:::tip\nYou can acknowledge an incident right here with **Acknowledge**; acknowledging pauses that incident's escalation. Acknowledging requires editor access to the incident's monitor.\n:::\n\n## Context Strip\n\nThe strip has three blocks, and each opens its page:\n\n- **On call** — who is on call right now; when nobody is, it says so.\n- **Maintenance** — the monitors inside a maintenance window right now; alerts are muted for them. The next scheduled window shows here too.\n- **Expiring soon** — certificates and domains expiring within 30 days. The most urgent ones (7 days or less) appear as their own rows in Needs attention now instead.\n\n## Availability\n\nFour window tiles — **Last 24 h**, **7 days**, **30 days**, **90 days** — show the uptime for each window; a tile reads \"—\" until there is data to average.\n\nBelow them, every one of the last 90 days is a cell: green **No downtime**, yellow **Under 15 min**, red **15 min or more**. Hovering a day shows its downtime minutes. Days before you were watching anything stay grey as **Not monitored** — they count as \"not watched\", not as \"no downtime\".\n\nThe summary under the strip gives the total downtime, how many days had downtime, and the longest outage (with its date and monitor).\n\nUptime values are cut, not rounded: 100 appears only when the value is exactly 100; anything below shows two decimals with trailing zeros dropped (99.97 stays 99.97), so an outage never reads as 100%.\n\n## Monitors, Worst First\n\nThe monitors in scope are ordered worst first — down and slow monitors at the top. Each row shows the monitor's name, a strip of its latest checks, its uptime over the selected range, and its average response time. The ten worst are shown; **\"All N monitors\"** opens the full list.\n\n## Reliability\n\nThis row appears only once there is an incident to measure, and it looks at confirmed outages from the last 30 days:\n\n- **Time to recover** — the median time to recover across outages that ended\n- **Time to acknowledge** — the median time to acknowledge across incidents that were acknowledged\n- **Outages this week** — this week's count and the week before's\n- **Flapping** or **Most affected** — the monitor going down and back up right now when there is one; otherwise the monitor with the most downtime in 30 days\n\nWhen the outage list was cut off, the numbers carry a \"+\" — they are lower bounds, not exact counts.\n\n## This Week\n\nThe **This week** card summarizes the last 7 days in a few lines. The numbers are deterministic and rendered as rule-based lines: up to four of them, and the numbers in each line link to the lists they came from.\n\nWhen your account allows AI (AI processing is on, your plan includes it, and you have allowance left this month), the card adds two to four lines written by a model. Each line links the monitors or incident lists it is about; a line that cites nothing is dropped. **\"Show the numbers\"** reveals the rule-based lines and **\"Hide the numbers\"** hides them again. Text a model did not write is never labelled as AI.\n\nThe card's title is **\"This week\"**, or **\"This week · 30 Sep – 7 Oct\"** when the period is known. Its states:\n\n- **Nothing to say** — no monitors and no incidents, or no lines at all: the card is hidden entirely.\n- **A model is writing** — the card says so (\"Writing a short summary of the week…\") and asks again shortly: every 4 seconds, up to 10 times.\n- **No AI processing consent** — one quiet line says a short written summary of the week is available with AI features on, and offers a **\"Turn on AI features in Profile\"** link (see [Profile Management](/docs/profile-management)).\n- **AI unavailable** — the card shows the rule-based lines only, labelled as rule-based.\n\nThe model's text is kept and reused while the week's facts are the same — it is not rewritten on every page load (at most one attempt per account every 15 minutes). The same card appears in the mobile app.\n\nEvery piece of text the product shows as AI output carries one provenance line, for example **\"Written by AI · cites N sources · sensitive values masked before sending · N AI uses this month\"** with a **\"How we use AI\"** link; it also shows when the text was written (\"updated 4 min ago\"). Sensitive values are masked before sending (see [PII Redaction for AI Prompts](/docs/pii-redaction)). Rule-based text instead says **\"Rule-based · no AI used\"** and is never labelled as AI.\n\nBelow the card sits a row of suggested Wardy questions built from what the page shows; the questions are templates, not model output.\n\n## Smart Alert Grouping banner\n\nWhen Smart Alert Grouping is enabled for your account, an informational banner appears while everything is healthy: *\"Smart alert grouping is on for your account. When several monitors fail within the same minute, the first alert goes out at once; the rest of a burst arrives as one message.\"* The banner offers **Learn more** and **Turn off** links plus a dismiss (×) button. Dismissing it is remembered persistently in your browser, surviving reloads and sessions. See [Smart Alert Grouping](/docs/smart-alert-grouping).\n\n## SLOs and Insights\n\nTwo collapsed rows at the bottom of the page hold the deeper analytics: **SLOs** and **Insights**. Opening one reveals it in place, and your choice is remembered in your browser.\n\n### SLOs *(Professional and above)*\n\nShows the remaining error budget for monitors that have an SLO defined; the row summarizes it (\"3 objectives · all within budget\"). Without a plan that includes SLOs it points at an upgrade; with none defined yet it points at setting a target in a monitor's settings. See [SLO Error Budgets](/docs/slo-error-budgets).\n\n### Proactive Insights *(Health Prediction enabled)*\n\nAI-generated at-risk predictions and recommendations. If your plan does not include Health Prediction, the card shows an upgrade prompt instead. See [Health Prediction Overview](/docs/health-prediction-overview).\n\n### Noisy Monitors\n\nMonitors with at least 10 alerts in the last 7 days. The first five are shown, each with a suggested response-time threshold you can apply in one click. If there are more, **\"+N more noisy monitors\"** opens the rest in place; **\"Show fewer\"** closes them again.\n\n### Outcome Prompt\n\nThe dashboard asks for the outcome of a recent incident. Your answer is used to tune future predictions.\n\n## Next steps\n\n- [Quick Start](/docs/quick-start)\n- [Profile Management](/docs/profile-management)\n- [Monitors](/docs/monitors-overview)\n- [Health Prediction](/docs/health-prediction-overview)","category":"getting-started","tags":["dashboard","ui","widgets","overview"],"order":30,"parentSlug":null,"published":true,"version":1,"metaTitle":"Dashboard. UptimeWarden Docs","metaDescription":"What each dashboard section shows: live status and freshness, what needs attention now, on-call and maintenance context, 90-day availability, the This week summary, and the AI provenance line.","icon":"Rocket","createdAt":"2026-10-12T22:06:41.630Z","updatedAt":"2026-10-12T22:06:41.630Z","publishedAt":"2026-10-12T22:06:41.630Z"},{"publicId":"01M4S2ENZ5YKB629KD94B0Y1GS","locale":"en","translationGroup":"profile-management","slug":"profile-management","title":"Profile Management","description":"Account info, password change, single sign-on linking (Google and GitHub), email update, and account deletion, what the profile page actually offers.","body":"# Profile Management\n\nThe profile page is where you manage your name, email, password, and connected sign-in providers. Open it from the user menu in the top right, or visit **Settings -> Profile**.\n\n## Account info\n\nThe profile page lets you edit the basics:\n\n- **First and last name**: appears in notifications, the audit log, and team invites\n- **Email**: your sign-in address and where notifications are sent (changing it requires reverification, see below)\n- **Avatar**: pulled automatically from Google or GitHub when those providers are linked\n\n## Change password\n\nIn the **Password & Security** section, enter:\n\n1. Your current password\n2. The new password\n3. The new password again to confirm\n\nPassword requirements:\n\n- At least 8 characters\n- At least one lowercase letter\n- At least one uppercase letter\n- At least one digit\n- At least one special character (`!@#$%^&*(),.?\":{}|<>`)\n\nIf the current password is wrong, the change is rejected. A successful change is recorded in the audit log at medium severity.\n\n:::warning\nChanging your password does not currently sign you out of other active sessions automatically. To kick old sessions, sign in again on each device and end stale sessions manually.\n:::\n\n## Multi-factor authentication (MFA)\n\nUptimeWarden does not yet offer first-party MFA / TOTP on the core account. For an extra security layer:\n\n- **Link Google or GitHub sign-in**: your provider's own two-factor authentication then protects the sign-in.\n- **Mobile app biometric lock**: the UptimeWarden mobile app supports a local biometric unlock (Face ID, Touch ID, fingerprint). This is a local convenience layer, not server-side MFA.\n\nTOTP is on the account-security roadmap. This page will be updated when it ships.\n\n## Single sign-on\n\nUptimeWarden supports two single sign-on providers:\n\n- **Google**\n- **GitHub**\n\nLinking a provider lets you sign in without your password; both methods can co-exist on the same account.\n\nA provider is auto-linked to an existing account only if the email address matches, the provider has verified that address, **and** the existing account's own email is already verified. Linking happens automatically the first time you sign in with the provider, there is no separate connect/disconnect control on the profile page today.\n\n## Change email\n\nEdit the email field and save. Validation:\n\n- The new address must be in valid email format.\n- If another account already uses it, the change is rejected.\n- If your account is linked to Google or GitHub, the email change is rejected, that email is managed by your sign-in provider, so update it in the provider's account instead.\n- After a successful change, your email is marked as unverified. No confirmation link is sent automatically; use the **Resend verification** flow to receive a link, since login is blocked until the new address is verified.\n\n## Delete account\n\nAccount deletion is not on the profile page, start it from the **Delete account** action on the **Settings -> Data & Privacy** page. Deletion has a 30-day grace period during which you can cancel before your account and associated data are permanently removed. For data export and the right to be forgotten, see [GDPR Export & Delete](/docs/gdpr-export-delete) and [KVKK Compliance](/docs/kvkk-compliance).\n\n## API tokens\n\nAPI tokens are not on the profile page. Manage them under **Developers -> API Tokens**. For the granular permission list and creation flow, see [API Tokens](/docs/api-tokens).\n\n## Audit log\n\nProfile actions are written to the audit log:\n\n- Password changes are recorded at medium severity.\n- Email and other profile updates are recorded as standard update events on your user record.\n\nFor the full list of recorded actions, see [Audit Log](/docs/audit-log).\n\n## Next steps\n\n- [SSO & OAuth](/docs/sso-oauth): Google & GitHub sign-in\n- [Audit Log](/docs/audit-log): see who did what\n- [Roles & Permissions](/docs/roles-permissions): manage team roles\n- [API Tokens](/docs/api-tokens): programmatic access","category":"getting-started","tags":["profile","account","security","sso","gdpr"],"order":40,"parentSlug":null,"published":true,"version":1,"metaTitle":"Profile Management. UptimeWarden Docs","metaDescription":"Manage your UptimeWarden account, password, single sign-on, email change, and account deletion.","icon":"Rocket","createdAt":"2026-10-12T22:06:41.638Z","updatedAt":"2026-10-12T22:06:41.638Z","publishedAt":"2026-10-12T22:06:41.638Z"},{"publicId":"01M4S2ENZC862JYX5XTBR63W9W","locale":"en","translationGroup":"audit-log","slug":"audit-log","title":"Audit Log","description":"An attributed, time-stamped record of every meaningful action in your account, what gets logged, severity levels, and plan-based access.","body":"# Audit Log\n\nThe audit log is an immutable record of every meaningful action in your account: who did it, when, from which IP address, and the before/after values. It is the foundation for compliance work (KVKK, GDPR, SOC 2 evidence), incident investigation, and insider-threat detection.\n\n## Plan availability\n\n| Plan | Audit Log |\n|---|---|\n| Free | Not available |\n| Hobby | Not available |\n| Starter | Not available |\n| Professional | Available |\n| Enterprise | Available |\n\nOn Free, Hobby, and Starter, the Audit Log page is hidden from your account. For full retention windows and export policies, see [Audit Log Retention](/docs/audit-log-retention).\n\n## Where to find it\n\nOpen **Settings -> Audit Log** from the left navigation. The page lists every recorded action with filters for narrowing your view.\n\nAvailable filters:\n\n- **Action**: a single action, such as a sign-in or monitor creation\n- **Resource type**: monitors, users, teams, notification channels, and similar\n- **Severity**: low, medium, high, or critical\n- **Date range**: start and end date\n- **Search**: free-text search against the description\n- **Pagination**: page number and page size (1 to 100 rows per page)\n\nEach entry shows the action, severity, timestamp, description, the affected resource, the record identifier, the IP address, and the browser the action came from. You can group entries by action type or view them as a flat list.\n\n## What gets recorded\n\nThe audit log captures all meaningful actions across your account.\n\n### Authentication\n\n- Successful sign-in, sign-out, failed sign-in, and blocked sign-in attempts\n- Account lockouts triggered by repeated failed attempts\n- Password resets and password changes\n- Unauthorized access attempts\n\n### Create, update, and delete\n\n- Single and bulk create, update, and delete operations\n- Every update captures both the previous and new values for full visibility\n\n### Monitor lifecycle\n\n- When monitors are created, updated, or deleted\n- When monitors are paused or resumed\n\n### Team and subscription\n\n- Joining, leaving, and inviting team members\n- Role changes and permission grants or revocations\n- Subscription creation, updates, and cancellations\n\n### API and integrations\n\n- Creating, revoking, and regenerating API tokens\n- Creating, updating, deleting, and testing webhooks\n\n### Security and system configuration\n\n- Changes to notification settings and security settings\n- System configuration changes and feature toggles\n- Data export, import, and purge actions\n- Security violations\n\n## Severity levels\n\nEach action is classified automatically:\n\n| Severity | Examples |\n|---|---|\n| Critical | System configuration changes, security setting changes, feature toggles |\n| High | Deletes, bulk deletes, data purges, permission revocations, API token revocations, failed sign-ins, password resets, role changes, permission grants, subscription cancellations |\n| Medium | Updates, bulk updates, password changes, leaving a team, deleting a webhook |\n| Low | Everything else, such as standard sign-ins and creates |\n\nSecurity violations are recorded at high or critical severity depending on the context.\n\nHigh and critical entries are preserved regardless of your plan's retention window. Lower-severity entries follow the retention window of your plan.\n\n## Access and retention\n\nAudit log access varies by plan:\n\n- **Free, Hobby, Starter**: no audit log access\n- **Professional, Enterprise**: view and filter audit entries from the Audit Log page\n\nRetention also varies by plan; high and critical entries are preserved regardless of the retention window. For the full retention table, see [Audit Log Retention](/docs/audit-log-retention).\n\n## FAQ\n\n**Q: An audit log entry was deleted, can I recover it?**\nA: No. Once an entry passes its retention window, it is permanently removed. High and critical severity entries are kept regardless of your plan's standard retention window. If you need longer retention, you can upgrade your plan; retention windows are listed on the [Audit Log Retention](/docs/audit-log-retention) page.\n\n**Q: Can an admin see another user's audit log?**\nA: The audit log is always scoped to the signed-in user. Each person sees their own actions only.\n\n## Next steps\n\n- [Audit Log Retention](/docs/audit-log-retention): per-plan retention and export policy\n- [GDPR Export & Delete](/docs/gdpr-export-delete): managing personal data\n- [Roles & Permissions](/docs/roles-permissions)","category":"getting-started","tags":["audit-log","compliance","security","logging"],"order":50,"parentSlug":null,"published":true,"version":1,"metaTitle":"Audit Log. UptimeWarden Docs","metaDescription":"How to access the UptimeWarden audit log, what's recorded, and which plans expose it.","icon":"Rocket","createdAt":"2026-10-12T22:06:41.645Z","updatedAt":"2026-10-12T22:06:41.645Z","publishedAt":"2026-10-12T22:06:41.645Z"},{"publicId":"01M4S2EP9ENXCQ4N34PGKAA8A3","locale":"en","translationGroup":"feature-flags","slug":"feature-flags","title":"Feature Flags","description":"Two ways UptimeWarden controls feature availability, plan features tied to your subscription, and engineering rollouts for gradual feature releases.","body":"# Feature Flags\n\nUptimeWarden controls feature availability in two distinct ways. They are independent, do not confuse them.\n\n## 1. Plan features\n\nPlan features are the capabilities included with your subscription tier. When you upgrade or downgrade, the set of available features changes accordingly.\n\nExamples of features gated by plan:\n\n- SSL monitoring\n- Security headers analysis\n- Health Prediction\n- Advanced notifications\n- Multi-location consensus\n- Custom domains and white-label branding\n- Incident management\n- Audit log\n- SLO and error budgets\n- Service Map\n- Auto-Fix recommendations\n- \"Ask Wardy\" AI assistant\n- Cascade Suppression\n- AI-drafted post-mortems\n\nEach feature is either **available** or **not available** for your current plan. Pages and surfaces that depend on a feature you do not have show an upgrade prompt instead. For the full per-plan matrix, see [Subscription Plans](/docs/subscription-plans).\n\nWhen in doubt, the answer is \"not available\", if your plan does not explicitly include a feature, you do not have access.\n\n## 2. Engineering rollouts\n\nEngineering rollouts are how the UptimeWarden team gradually releases new functionality without redeploying the product. A flag can:\n\n- Be **off globally** while the team is still testing\n- Be **enabled for a small percentage** of accounts to gather feedback\n- Be **opened up to everyone** once it is stable\n- Be **opted into individually** by users when there is a self-service toggle on the page\n\nMost engineering rollouts are invisible to you, the feature simply appears once it has been turned on for your account. A handful are exposed as user-controllable toggles inside settings; in those cases, you can switch the feature on or off for yourself at any time.\n\n> Engineering rollouts only control whether *you can see* a feature. They do not bypass your plan. A feature gated by both your plan and an engineering rollout requires both to be in your favour.\n\n### Lifecycle of a typical rollout\n\n1. **Hidden**, the feature exists in code but is off everywhere.\n2. **Beta**, opened up to a small group of early-adopter accounts.\n3. **Gradual rollout**, the percentage of enabled accounts ramps up over days or weeks.\n4. **General availability**, the feature is on by default for everyone, and the rollout flag is removed in a later release.\n\n### Audit trail\n\nWhen an admin turns a flag on or off globally, the change is recorded in the [Audit Log](/docs/audit-log), so you can see who made the change and when. Adjusting a flag's rollout percentage or setting a per-account override takes effect the same way but is not currently written to the Audit Log.\n\n## FAQ\n\n**Q: A feature was working yesterday and is gone today, what happened?**\nA: Either an engineering rollout was rolled back (rare, usually for stability reasons) or your plan changed. Check the Audit Log for the relevant change.\n\n**Q: Can I opt out of a feature I do not want?**\nA: For features exposed as user-controllable toggles, yes, open Settings and switch them off. For most other features, opt-out is not exposed; contact support if it is causing a problem.\n\n**Q: Does turning a feature off affect the API?**\nA: When a feature is unavailable, the corresponding API endpoints reject requests with a permission error. The exact behaviour depends on the endpoint.\n\n**Q: An admin just changed something. When does it take effect?**\nA: Almost immediately. Requests that were already in flight finish with the previous value; the next request you make picks up the new one.\n\n## Related topics\n\n- [Subscription Plans](/docs/subscription-plans): what is included on each plan\n- [Audit Log](/docs/audit-log): see every flag change\n- [Smart Alert Grouping](/docs/smart-alert-grouping): currently the most user-visible toggle","category":"getting-started","tags":["feature-flags","rollout","beta","plans"],"order":50,"parentSlug":null,"published":true,"version":1,"metaTitle":"Feature Flags. UptimeWarden Documentation","metaDescription":"How UptimeWarden's two feature controls work, plan-based feature access and gradual engineering rollouts.","icon":"Rocket","createdAt":"2026-10-12T22:06:41.966Z","updatedAt":"2026-10-12T22:06:41.966Z","publishedAt":"2026-10-12T22:06:41.966Z"},{"publicId":"01KJ7Q9ZT7VG24VWA2C6YPV4J8","locale":"en","translationGroup":"http-monitor","slug":"en-http-monitor","title":"HTTP/HTTPS Monitor Guide","description":"HTTP/HTTPS monitor setup and configuration for websites and APIs","body":"# HTTP/HTTPS Monitor Guide\n\nHTTP/HTTPS monitors are used to track the availability and performance of your websites and API endpoints. This is the most common monitor type in UptimeWarden.\n\n## Creating a Monitor\n\n### Basic Settings\n\n1. Click the **Add Monitor** button from the Dashboard\n2. Select **HTTP(S)** as the monitor type\n3. Fill in the required fields:\n\n```\nName: Your Site Name\nURL: https://example.com\nCheck Interval: 1 minute\nTimeout: 30 seconds\n```\n\n### Advanced Settings\n\n#### Request Method\nYou can use different HTTP methods besides the default GET:\n- **GET**: Read data (default)\n- **POST**: Send data\n- **PUT**: Update data\n- **DELETE**: Delete data\n- **HEAD**: Headers only\n- **PATCH**: Partial update\n\n#### Custom Headers\nAdd custom headers for APIs:\n\n```json\n{\n  \"Authorization\": \"Bearer YOUR_API_TOKEN\",\n  \"Content-Type\": \"application/json\",\n  \"X-Custom-Header\": \"value\"\n}\n```\n\n#### Request Body\nAdd a request body for POST, PUT, PATCH methods:\n\n```json\n{\n  \"test\": true,\n  \"monitor\": \"uptimewarden\"\n}\n```\n\n## Response Validation\n\n### Status Code Check\nDefine which HTTP status codes are considered \"successful\":\n- **2xx**: Standard successful responses (200, 201, 204)\n- **3xx**: Redirections (301, 302, 304)\n- **Custom**: Expect a specific code (e.g., 200, 201)\n\n### Content Validation\n\n#### Keyword Monitoring\nWords or phrases that should be present in the response:\n- **Contains**: \"Welcome\"\n- **Not Contains**: \"Error\"\n- **Regex**: `/user-\\d+/`\n\n#### JSON Response Validation\nValidate API responses using JSONPath:\n\n```javascript\n// Response example:\n{\n  \"status\": \"active\",\n  \"users\": [\n    { \"id\": 1, \"name\": \"Alice\" },\n    { \"id\": 2, \"name\": \"Bob\" }\n  ]\n}\n\n// JSONPath examples:\n$.status == \"active\"           // status field must be \"active\"\n$.users.length > 0             // At least 1 user required\n$.users[0].name == \"Alice\"     // First user must be Alice\n```\n\n## Authentication\n\n### Basic Authentication\n```\nUsername: admin\nPassword: secretpassword\n```\n\n### Bearer Token\n```\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...\n```\n\n### API Key\n```\nX-API-Key: your-api-key-here\n```\n\n### OAuth 2.0\nConfigure the token endpoint and credentials for OAuth 2.0.\n\n## Performance Monitoring\n\n### Response Time Thresholds\nSet response time thresholds:\n\n| Level | Threshold | Action |\n|-------|-----------|--------|\n| Normal | < 1s | Green indicator |\n| Warning | 1-3s | Yellow indicator, optional notification |\n| Critical | > 3s | Red indicator, create incident |\n\n### Performance Metrics\nTracked metrics:\n- **DNS Lookup Time**: DNS resolution duration\n- **Connection Time**: Connection establishment time\n- **TLS Handshake**: SSL/TLS handshake time\n- **Time to First Byte (TTFB)**: Time until first byte received\n- **Download Time**: Content download duration\n- **Total Response Time**: Overall response time\n\n## Multi-Location Monitoring\n\nTest global accessibility by running checks from different locations:\n\n### Location Selection\n- **All Locations**: Maximum coverage\n- **Specific Regions**: Close to your target audience\n- **Single Location**: Minimum cost\n\n## SSL Certificate Monitoring\n\nHTTPS monitors automatically check SSL certificates:\n\n- **Certificate Validity**: Is it valid and trusted?\n- **Expiry Tracking**: Warning at 30, 14, 7 days before expiry\n- **Certificate Chain**: Is the entire chain correct?\n- **Domain Match**: Does the certificate match the domain?\n\n## Retry Logic and False Positive Prevention\n\n### Default Retry Strategy\n1. First failure: Wait 30 seconds\n2. Second attempt fails: Wait 60 seconds\n3. Third attempt fails: Create incident\n\n### Customization\n```\nRetry Count: 3\nRetry Interval: 30s\nRetry Multiplier: 2x (30s, 60s, 120s)\n```\n\n## Best Practices\n\n### 1. Correct Timeout Value\n- Fast APIs: 5-10 seconds\n- Normal websites: 30 seconds\n- Heavy operations: 60+ seconds\n\n### 2. Check Interval Optimization\n- Critical services: 30 seconds - 1 minute\n- Normal services: 5 minutes\n- Low priority: 10-30 minutes\n\n### 3. Alert Fatigue Prevention\n- Use retry logic\n- Define maintenance windows\n- Enable alert grouping\n\n### 4. Content Validation\n- Status code alone is not enough\n- Validate critical content with keywords\n- Use JSON schema validation for APIs\n\n## Troubleshooting\n\n### False Positive Alarms\n**Problem**: Site is up but I'm getting down alerts.\n\n**Solution**:\n- Increase timeout duration\n- Increase retry count\n- Check from different locations\n\n### Slow Response Times\n**Problem**: Site opens but is very slow.\n\n**Checklist**:\n1. Are you using a CDN?\n2. Are database queries optimized?\n3. Are there large images/files?\n4. Is caching enabled?\n\n### SSL Certificate Warnings\n**Problem**: SSL certificate is valid but I'm getting warnings.\n\n**Possible Causes**:\n- Missing intermediate certificates\n- SNI support issue\n- Wildcard certificate misconfiguration","category":"monitors","tags":["monitor","http","https","api"],"order":1,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"HTTP/HTTPS monitor setup and configuration for websites and APIs","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZSDX5MSFKKQY28HXKE5","locale":"en","translationGroup":"monitors-overview","slug":"en-monitors","title":"Creating and Managing Monitors","description":"Monitor types, creation process, configuration options, and best practices in UptimeWarden","body":"# Creating and Managing Monitors\n\nUptimeWarden allows you to monitor various service types. This guide covers the monitor creation process and common configuration options.\n\n## Supported Monitor Types\n\n| Type | Use Case |\n| --- | --------- |\n| **HTTP/HTTPS** | Website and REST API monitoring |\n| **SSL Certificate** | SSL certificate validity monitoring |\n| **TCP** | Port and TCP service monitoring |\n| **UDP** | UDP service monitoring (DNS, SNMP, etc.) |\n| **WebSocket** | WebSocket connection monitoring |\n| **gRPC** | gRPC API monitoring |\n| **Ping (ICMP)** | Server availability check |\n| **MCP** | AI model service monitoring |\n\n> See the **Monitor Types** documentation for detailed information on each type.\n\n## Creating a Monitor\n\nClick the **\"Add Monitor\"** button to create a new monitor. The form guides you step by step.\n\n### Basic Information\n\n| Field | Required | Description |\n| ----- | -------- | ----------- |\n| **Monitor Name** | Yes | Descriptive name (e.g., \"Main Page\", \"API Health Check\") |\n| **Target** | Yes | URL, IP address, or hostname |\n| **Check Interval** | Yes | 30 seconds, 1 minute, 2 minutes, 3 minutes, 5 minutes, 10 minutes, 30 minutes, 1 hour |\n| **Timeout** | Yes | Request wait time (5-120 seconds) |\n\n### Optional Information\n\n- **Description**: Detailed description of the monitor\n- **Tags**: Tags for categorization\n- **Group**: Grouping related monitors\n- **Retry Count**: Retry on failure (0-5)\n- **Check Location**: Region or custom agent selection\n\n## HTTP/HTTPS Configuration\n\nAdditional options for HTTP monitors are configured in the **Basic** tab on the monitor detail page:\n\n### HTTP Method\n\nChoose from GET, POST, HEAD, PUT, DELETE, OPTIONS.\n\n### HTTP Options (Advanced)\n\nThe **\"HTTP Options\"** collapsible section contains:\n\n#### Content Validation\n\nResponse content validation methods:\n\n| Method | Description |\n| ------ | ----------- |\n| **Text Match** | Checks if specified text exists in the response |\n| **Regex** | Regular expression response matching |\n| **JSON** | Checks specific fields in JSON structure |\n| **XML** | Checks specific elements in XML responses |\n\n#### Custom Headers\n\nAdd custom HTTP headers:\n\n```text\nAuthorization: Bearer your-token\nX-API-Key: your-api-key\nCustom-Header: custom-value\n```\n\n#### Authentication\n\n- **Basic Auth**: Username and password\n- **Bearer Token**: Token-based authentication\n\n#### Request Body\n\nWhen HTTP method is **POST**, **PUT**, or **PATCH**, the request body field appears. Body can be sent in JSON, XML, or plain text format. Useful for monitoring API endpoints.\n\n### Alert Settings\n\n| Setting | Description |\n| ------- | ----------- |\n| **Expected Status Codes** | HTTP codes considered successful (e.g., 200, 201, 204) |\n| **Response Time Threshold** | Time above this triggers an alert (ms) |\n| **SSL Expiry Days** | Days before SSL expiry to alert |\n| **Follow Redirects** | Follow HTTP redirects (on/off) |\n\n## Notification Settings\n\nConfigure notification channels and alert types separately for each monitor:\n\n| Channel | Description |\n| ------- | ----------- |\n| **Email** | Email notification |\n| **SMS** | SMS notification via phone number |\n| **WhatsApp** | Notification via WhatsApp |\n| **Voice** | Notification via voice call |\n| **Push** | Mobile/web push notification |\n| **Webhook** | Custom webhook integrations |\n\nChoose which alert types to receive notifications for per channel (down, recovery, SSL warning, etc.).\n\n> See the **Notification Channels** documentation for detailed notification settings.\n\n## Advanced Settings\n\nFrom the **Advanced** tab on the monitor detail page:\n\n- **SSL Monitoring**: Certificate status and expiry tracking (on/off)\n- **Domain Monitoring**: Domain expiry tracking via WHOIS + threshold day setting\n- **Security Analysis**: Security header analysis (on/off)\n- **Check Location**: Region or custom agent selection\n\n## Retry Logic\n\nAutomatic retry on failed checks:\n\n- **Retry Count**: Configurable 0-5\n- Each retry runs with the same parameters as the original check\n- If all retries fail, an incident is created\n\n## Monitor Limits\n\nMonitor limits vary by subscription plan. Track your current usage from the **Subscription** page.\n\n## Best Practices\n\n### Naming\n\n```\nGood: \"API - User Service Health\"\nGood: \"Website - Homepage (Production)\"\nBad: \"test\", \"monitor1\"\n```\n\n### Grouping\n\nOrganize related monitors under meaningful groups:\n\n- **Frontend**: Website, CDN, Static assets\n- **Backend**: APIs, Databases, Services\n- **Infrastructure**: Servers, Load balancers\n\n### Check Intervals\n\n| Environment | Recommended Interval |\n| ----------- | -------------------- |\n| **Critical Production** | 30 seconds - 1 minute |\n| **Standard Production** | 1-5 minutes |\n| **Development/Staging** | 5-15 minutes |\n\n### Troubleshooting\n\n| Error | Possible Solution |\n| ----- | ----------------- |\n| **Certificate verify failed** | Check SSL monitoring settings |\n| **Request timeout** | Increase timeout or check network |\n| **DNS resolution failed** | Check hostname accuracy and DNS settings |\n| **401 Unauthorized** | Check API key, token, or credentials |\n\n## Related Documentation\n\n- **Monitor Detail Page**: KPIs, charts, and event history\n- **Monitor Settings**: All configuration option details\n- **Monitor Types**: TCP, UDP, WebSocket, gRPC, Ping, MCP details\n- **HTTP Monitor**: HTTP/HTTPS monitor details\n- **SSL Monitor**: SSL certificate monitoring\n- **Regional Monitoring**: Monitoring from different locations\n- **Monitor Groups**: Grouping and organization","category":"monitors","tags":["monitors","creation","configuration","setup"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Monitor types, creation process, configuration options, and best practices in UptimeWarden","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTADXM6MGB47WW845AZ","locale":"en","translationGroup":"monitor-detail","slug":"en-monitor-detail","title":"Monitor Detail Page","description":"Monitor detail page KPIs, charts, event history, and settings guide","body":"# Monitor Detail Page\n\nClicking a monitor opens the detail page, which presents all performance data, event history, and settings for that monitor on a single screen.\n\n## Header Section\n\nThe top of the page shows basic information about the monitor:\n\n- **Monitor name**\n- **URL** (clickable external link)\n- **Monitor type badge** (HTTP, HTTPS, TCP, etc.)\n- **Region badge** (if assigned — region name and globe icon)\n- **Agent badge** (if a custom agent is assigned)\n- **Time range selector** (top right — changes the period of displayed data)\n\n## KPI Bar\n\n5-column main metrics panel:\n\n| Metric | Description |\n|--------|-------------|\n| **Current Status** | Real-time status: UP (green), DOWN (red), or SSL_WARNING (orange) |\n| **Uptime** | Uptime percentage for the selected period |\n| **Avg Response** | Average response time (ms) |\n| **Latest Check** | Response time of the last check (ms) |\n| **SSL Days Left** | Days until SSL certificate expires (or N/A) |\n\nBelow the KPI bar, the last check time, SSL expiry date, and domain expiry date (if active) are shown.\n\n## Domain WHOIS Information\n\nIf domain monitoring is active, a separate card is displayed:\n\n- **Domain**: Monitored domain name\n- **Registrar**: Domain registration company\n- **Expires**: Expiry date and remaining days (color-coded)\n- **Last WHOIS Check**: Last check time\n- **Name Servers**: First 4 DNS servers\n- **Domain Status**: Domain status badges\n\n## Analytics Section\n\n### Summary Cards (5 Cards)\n\n| Card | Description |\n|------|-------------|\n| **Uptime** | Uptime percentage + total check count. Color: green (≥99.9%), yellow (≥95%), red (<95%) |\n| **SLA Status** | 99.9% SLA target compliance (✓ met / ✗ below) |\n| **Avg Response** | Average response time (ms) |\n| **Incidents** | Total incident count + active ones |\n| **MTTR** | Mean time to resolution (minutes) |\n\n### Uptime Trend Chart\n\nShows the uptime trend as an area chart:\n- **Hourly / Daily** toggle buttons\n- X-axis: Date/time\n- Y-axis: Uptime percentage\n- Tooltip with detailed values (3 decimal places)\n\n### Response Time Chart\n\n3-line chart:\n- **Average** (blue, solid line): Average response time\n- **Max** (red, dashed line): Maximum response time\n- **Min** (green, dashed line): Minimum response time\n- **Hourly / Daily** toggle buttons\n\n### Incident Resolution Trend\n\nArea chart showing the average resolution time (minutes) of resolved incidents. Days with downtime incidents are highlighted in the background.\n\n## Recent Events\n\n5 events per page. For each event:\n\n- **Status icon**: Green (online), red (offline), orange (SSL warning)\n- **Status text**: Service Online / Service Offline / SSL Certificate Warning\n- **Date and time**\n- **Error message** (if any, red text)\n- **Response time** (ms)\n- **HTTP status code** (e.g., HTTP 200)\n\nNavigate previous/next events with pagination buttons.\n\n## Recent Incidents\n\nA separate panel lists the last 5 incidents:\n\n- **Event type**: Service Down, SSL Warning, etc.\n- **Date and time**\n- **Status badge**: Resolved (green) or active (red)\n\nClick an incident to go to its detail page.\n\n## Monitor Settings\n\nThe bottom section has a 5-tab settings panel:\n\n### Basic\n\n- Monitor name, URL, check interval, timeout, retry count\n- HTTP method and description\n- HTTP Options (collapsible): Content validation, custom headers, authentication, and request body (for POST/PUT/PATCH)\n\n### Alerts\n\n- Expected HTTP status codes\n- Response time threshold (ms)\n- SSL expiry warning days\n- Follow redirects option\n\n### Notifications\n\nSeparate configuration for each notification channel:\n\n| Channel | Settings |\n|---------|----------|\n| **Email** | Enable/disable + alert types + email addresses |\n| **SMS** | Enable/disable + alert types + phone numbers |\n| **WhatsApp** | Enable/disable + alert types + WhatsApp numbers |\n| **Voice** | Enable/disable + alert types + phone numbers |\n| **Push** | Enable/disable + alert types |\n| **Webhook** | Enable/disable + alert types + webhook selection |\n\n### Organization\n\n- Monitor groups (add/remove)\n- Tags (add/remove)\n\n### Advanced\n\n- SSL monitoring enable/disable\n- Domain monitoring enable/disable + expiry threshold days\n- Security analysis enable/disable\n- Check location selector (region or agent)\n\n> When you make changes, a **\"Save Changes\"** button appears. Click to save.\n\n## Tips\n\n1. **Change the time range**: Use the top-right selector to compare performance across different periods\n2. **Track SLA compliance**: The SLA Status card shows how close you are to your target uptime\n3. **Monitor MTTR**: A low MTTR means your team responds quickly\n4. **Review event history**: Examine past events to identify recurring failure patterns\n5. **Enable domain monitoring**: Track domain expiry with WHOIS information","category":"monitors","tags":["monitor","detail","analytics","uptime","response-time","events"],"order":2,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"Monitor detail page KPIs, charts, event history, and settings guide","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZT9JRR255CHZQS7D8ZK","locale":"en","translationGroup":"monitor-settings","slug":"en-monitor-settings","title":"Monitor Settings and Configuration","description":"Monitor check interval, timeout, retry, custom headers, and advanced configuration options","body":"# Monitor Settings and Configuration\n\nDetailed configuration options are available for each monitor. This guide covers all settings and what they do.\n\n## Basic Settings\n\n### Check Interval\n\nDetermines how frequently your monitor is checked.\n\n| Interval | Use Case |\n|----------|----------|\n| **30 seconds** | Critical production services |\n| **1 minute** | High priority services |\n| **3 minutes** | Standard services |\n| **5 minutes** | General purpose monitoring |\n| **10 minutes** | Low priority services |\n| **30 minutes** | Services where periodic checks suffice |\n\n> **Tip**: Shorter intervals provide faster notifications but consume your plan's check quota more quickly.\n\n### Timeout\n\nMaximum wait time for a check. If exceeded, the check is considered failed.\n\n- **Default**: 30 seconds\n- **Recommended**: 2-3x your service's normal response time\n- **Minimum**: 5 seconds\n- **Maximum**: 120 seconds\n\n### Retry\n\nWhen a check fails, automatic retries can reduce false positive risk.\n\n- **Retry count**: 0-5\n- **Retry interval**: Wait time between retries\n\n**Example**: 3 retries × 10 second interval = Outage notification delayed by up to 30 seconds, but no false alarms from transient issues.\n\n## HTTP/HTTPS Settings\n\n### Expected Status Code\n\nDefine which HTTP status codes are considered \"successful\":\n\n- **200-299**: Standard successful responses (default)\n- **301, 302**: Accept redirections\n- **Custom**: Expect a specific code (e.g., 401 — auth endpoint testing)\n\n### HTTP Method\n\n| Method | Use |\n|--------|-----|\n| **GET** | Web pages and API endpoints (default) |\n| **POST** | Form or API submission testing |\n| **HEAD** | Header-only check, lighter |\n| **PUT** | API update endpoint testing |\n\n### Custom Headers\n\nAdd custom HTTP headers to requests:\n\n```\nAuthorization: Bearer <token>\nContent-Type: application/json\nX-Custom-Header: value\n```\n\n**Common use cases**:\n- API authentication tokens\n- Custom cache control headers\n- Host header (testing with a different hostname)\n\n### Authentication\n\n- **Basic Auth**: Username and password\n- **Bearer Token**: JWT or API token\n- **Custom Header**: Custom authentication header\n\n## Content Matching\n\n### Content Validation\n\nValidate response content using different methods:\n\n- **Text Match**: Check if specified text exists in the response (case sensitivity configurable)\n- **Regex**: Validate response with regular expressions\n- **JSON**: Validate JSON response structure\n- **XML**: Validate XML response structure\n\n**Example uses**:\n- `\"Welcome\"` (Text Match) — Verify page loaded correctly\n- `\"version\":\\s*\"2\\.\\d+\"` (Regex) — Check API version\n\n### Response Time Threshold\n\nMark response times exceeding a threshold as a warning:\n\n- **Warning threshold**: Triggers warning state when exceeded (e.g., 2000ms)\n- **Critical threshold**: Marks as outage when exceeded (e.g., 5000ms)\n\n## SSL Certificate Check\n\nAutomatic SSL checking for HTTP/HTTPS monitors:\n\n- **SSL validation**: Check certificate validity\n- **Expiry warning**: Alert X days before expiry (default: 30 days)\n- **Ignore SSL**: For test environments with self-signed certificates\n\n## Notification Settings\n\nSet independent notification preferences for each monitor:\n\n### Notification Channels\n\nChoose which channels to use per monitor:\n- Email\n- SMS\n- WhatsApp\n- Webhook\n- Push notification\n\n### Notification Types\n\n| Type | Description |\n|------|-------------|\n| **Down** | When the service goes down |\n| **Recovery** | When the service comes back up |\n| **SSL Expiry** | When SSL certificate is about to expire |\n| **Performance** | When response time threshold is exceeded |\n\n### Recipients\n\nDefine different recipient groups per monitor:\n- Email addresses\n- Phone numbers (SMS/WhatsApp/Voice call)\n\n## Grouping\n\nOrganize your monitors into groups:\n\n1. Go to the **Groups** menu\n2. Create a new group (e.g., \"Production Services\")\n3. Add monitors to the group\n\nGroups provide visual organization on the dashboard and status pages.\n\n## Advanced Settings\n\n### Follow Redirects\n\nDetermine whether HTTP redirections (301/302) are automatically followed. Enabled by default.\n\n## Tips\n\n1. **Separate production and test monitors**: Use different check intervals and notification settings\n2. **Use retries**: Define at least 1 retry to reduce false alarms\n3. **Add content matching**: Check response content, not just status code\n4. **Set sensible timeouts**: Too low = false alarms, too high = late notifications\n5. **Keep SSL checking active**: Learn about certificate expiry in advance","category":"monitors","tags":["monitor","settings","configuration","interval","timeout","headers"],"order":2,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"Monitor check interval, timeout, retry, custom headers, and advanced configuration options","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTB38WF0X8AH7BXXW6M","locale":"en","translationGroup":"regional-monitoring","slug":"en-regional-monitoring","title":"Regional Monitoring","description":"Running monitors from different geographic regions, region selection, and multi-region monitoring guide","body":"# Regional Monitoring\n\nUptimeWarden allows you to run your monitors from different geographic regions. This enables you to track the performance and accessibility of your services worldwide.\n\n## Why is Regional Monitoring Important?\n\n- **Real user experience**: Measure actual performance by testing from your users' regions\n- **Detect regional outages**: Instantly notice CDN or DNS issues in specific regions\n- **Response time comparison**: Compare response times from different regions\n- **Geographic redundancy check**: Verify that your failover mechanisms work correctly\n\n## Available Regions\n\nUptimeWarden enables monitoring from various geographic regions. To see available regions, open the **Check Location** selector when creating or editing a monitor.\n\nEach region includes:\n- **Region name**: Full geographic location (e.g., \"Germany West Central\")\n- **Status**: Active/Inactive\n- **Default**: The region automatically assigned\n\n## Region Selection\n\n### When Creating a Monitor\n\n1. Enter connection details in the new monitor form\n2. In the **\"Check Location\"** field, select a region:\n   - **Auto**: Default region is automatically assigned (used on free plans)\n   - **Region list**: Select your desired region\n   - **Private Agent**: Select an agent on your own infrastructure\n\n### Changing on an Existing Monitor\n\n1. Go to the monitor detail page\n2. Switch to the **Settings** tab\n3. Select a new region in the **Check Location** field\n4. Click **Save**\n\n## Private Agents\n\nIn addition to cloud regions, you can monitor from within your own network:\n\n### What is an Agent?\n\nA private agent is lightweight software installed on your own server or network. This agent connects to UptimeWarden and allows you to monitor services on your internal network.\n\n### Agent Use Cases\n\n- **Internal services**: Monitor internal APIs not accessible from outside\n- **Behind VPN**: Test services protected by VPN\n- **Private network**: Monitor services within a corporate network\n- **Local performance**: Measure response time from a specific data center\n\n### Agent Setup\n\n1. Go to the **Agents** menu\n2. Click the **\"Create Agent\"** button\n3. Enter agent details (name, location)\n4. Follow the setup instructions:\n\n```bash\n# Docker setup\ndocker run -d \\\n  --name uptimewarden-agent \\\n  -e AGENT_TOKEN=<your-token> \\\n  -e SERVER_URL=<server-url> \\\n  uptimewarden/agent:latest\n```\n\n5. Once the agent connects, it will appear in the **Private Agents** list when creating a monitor\n\n## Plan Restrictions\n\n| Feature | Free Plan | Starter | Professional | Enterprise |\n|---------|-----------|---------|-------------|------------|\n| Default region | ✅ | ✅ | ✅ | ✅ |\n| Region selection | ❌ | ✅ | ✅ | ✅ |\n| Private agents | ❌ | Limited | ✅ | ✅ |\n\n> **Note**: On the free plan, monitors are automatically assigned to the default region. Region selection is available on Starter and above plans.\n\n## Region Information in Monitor List\n\nIn your monitor list, you can see which region each monitor runs from. Region information appears as a small badge next to the monitor name:\n\n- 🌐 **Germany West Central** — Cloud region\n- 🖥️ **My Agent** — Private agent\n\n## Best Practices\n\n1. **Choose the region closest to your users**: Prefer the region where your main user base is located\n2. **Test from different regions**: Monitor the same service from multiple regions for comprehensive coverage\n3. **Adjust response time thresholds by region**: Define higher response time thresholds for distant regions\n4. **Keep agents updated**: Regularly update your private agents\n5. **Be careful with region changes**: Response times may vary when changing regions — this is normal","category":"monitors","tags":["regional","monitoring","location","multi-region","latency"],"order":3,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"Running monitors from different geographic regions, region selection, and multi-region monitoring guide","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTCP29WK6ZT8PKZT4F1","locale":"en","translationGroup":"ssl-monitor","slug":"en-ssl-monitor","title":"SSL Certificate Monitoring","description":"SSL certificate monitoring setup, expiry alerts, and security assessment","body":"# SSL Certificate Monitoring\n\nAn expired SSL certificate blocks secure access to your website and causes trust loss among your users. With UptimeWarden, you can proactively monitor your certificates and be notified before they expire.\n\n## What is SSL Monitoring?\n\nSSL certificate monitoring regularly checks your website's HTTPS certificate and tracks:\n\n- **Validity period**: When the certificate will expire\n- **Certificate chain**: Correctness of intermediate certificates\n- **Security assessment**: Security level of your SSL configuration\n- **Protocol support**: TLS version compatibility\n\n## Creating an SSL Monitor\n\n### Automatic SSL Check (Within HTTP Monitor)\n\nEvery HTTP/HTTPS monitor you create automatically enables SSL checking. No additional setup is needed.\n\nYou can customize SSL checking from monitor settings:\n- **Expiry warning days**: Default 30 days (configurable between 1-90 days)\n- **Skip SSL validation**: Allow self-signed certificates for test environments\n\n### Dedicated SSL Monitor\n\nTo monitor only the SSL certificate:\n\n1. Go to the **Monitors** menu\n2. Click the **\"Add Monitor\"** button\n3. Select **\"SSL Certificate\"** as the monitor type\n4. Enter the domain name (e.g., `example.com`)\n5. Set alert thresholds\n6. Save\n\n## Alert Thresholds\n\nSet how many days before certificate expiry you want to be alerted:\n\n| Threshold | Default | Description |\n|-----------|---------|-------------|\n| **Warning** | 30 days | First alert — plan your renewal |\n| **Critical** | 7 days | Urgent — certificate must be renewed immediately |\n| **Urgent** | 1 day | Certificate expires tomorrow |\n\n## SSL Certificate Information\n\nUptimeWarden tracks your SSL certificate details:\n\n- **Issuer**: The certificate authority\n- **Validity dates**: Start and end dates\n- **Days remaining**: How many days until expiry\n- **Domain match**: Whether the certificate belongs to the correct domain\n\n## Security Header Analysis\n\nIn addition to SSL monitoring, when security analysis is enabled for a monitor, HTTP security headers are also checked:\n\n- **Content-Security-Policy**: XSS protection\n- **X-Frame-Options**: Clickjacking protection\n- **X-Content-Type-Options**: MIME sniffing protection\n- **Referrer-Policy**: Referrer information leak protection\n- **Permissions-Policy**: Browser feature access control\n\nSee the **Security Headers** page for details.\n\n## Notifications\n\nYou'll receive notifications in the following SSL-related situations:\n\n1. **Expiry approaching**: Based on your configured thresholds\n2. **Certificate changed**: When the certificate changes unexpectedly\n3. **SSL error**: Invalid certificate, broken chain, or protocol issue\n4. **Renewal successful**: When the certificate is successfully renewed (recovery notification)\n\n## Listing SSL Certificates\n\nFrom the **SSL & Security** menu, you can view all monitored certificates on a single screen:\n\n- Domain name\n- Certificate issuer\n- Expiry date\n- Days remaining\n- Last check time\n\n## Best Practices\n\n1. **Get notified 30 days in advance**: Leave enough time for the renewal process\n2. **Notify multiple people**: Share SSL renewal responsibility\n3. **Monitor wildcard certificates too**: Don't forget `*.example.com` certificates\n4. **Check subdomains**: Monitor subdomains like api, cdn, mail alongside the main domain\n5. **Use auto-renewal**: Prefer automatic renewal services like Let's Encrypt, but keep monitoring active","category":"monitors","tags":["ssl","certificate","security","https","tls","expiry"],"order":4,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"SSL certificate monitoring setup, expiry alerts, and security assessment","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTD88HG7DC3YPVK54EM","locale":"en","translationGroup":"groups","slug":"en-groups","title":"Monitor Groups","description":"Organize your monitors into logical groups and monitor group-level status","body":"# Monitor Groups\n\nMonitor groups allow you to organize your monitored services into logical categories. Groups make it easy to manage large numbers of monitors and see their collective status at a glance.\n\n## What is a Group?\n\nA group is a logical unit where monitors serving a common purpose come together. For example:\n\n- **Production Services**: All live web and API services\n- **Payment System**: All endpoints related to payment infrastructure\n- **Customer Portal**: All applications used by customers\n\nEach monitor can belong to multiple groups.\n\n## Creating a Group\n\nGroups are automatically created when a group name is assigned to a monitor. There is no separate \"create group\" step.\n\n### Assigning a Group to a Monitor\n\n1. Open the edit modal for an existing monitor\n2. Type a group name in the **Group** field\n3. Select from existing groups or enter a new name to create a new group\n4. Press Enter\n5. Save\n\nA monitor can be added to multiple groups.\n\n## Group List\n\nView all your groups from the **Groups** menu. Each group card shows:\n\n- **Group name** and status icon\n- **Monitor count**: How many monitors are in the group\n- **Uptime percentage**: Average uptime of monitors in the group\n- **Average response time**: Average response time of monitors in the group\n- **Status distribution**: How many are up, down, and warning\n- **Tags**: Tags collected from monitors in the group\n- **Favorite**: Group can be favorited with the heart icon\n\n## Filtering and Sorting\n\nFilter the group list with various criteria:\n\n| Filter | Options |\n|--------|---------|\n| **Search** | Search by group name |\n| **Time range** | Period for statistics calculation |\n| **Status** | Healthy / Warning / Critical |\n| **Tag** | Groups with a specific tag |\n| **Favorites** | All / Favorites only / Non-favorites |\n| **Sort** | Name / Uptime / Monitor count / Favorites |\n\n## Group Detail\n\nClicking a group opens the detail panel showing:\n\n- Total monitor count, online and offline distribution\n- All tags in the group\n- Monitor list: each monitor's status, response time, last check time, and check interval\n\n## Use Cases\n\n### Service-Based Grouping\n```\nPayment System → payment-api, payment-gateway, payment-webhook\nEmail Service → smtp-server, email-api, email-templates\n```\n\n### Environment-Based Grouping\n```\nProduction → prod-api, prod-web, prod-db\nStaging → staging-api, staging-web\n```\n\n### Team-Based Grouping\n```\nBackend Team → api-server, graphql, worker-service\nFrontend Team → web-app, cdn, static-assets\n```\n\n## Tips\n\n1. **Use meaningful names**: The group's contents should be clear from the name\n2. **Use multiple groups**: A monitor can belong to multiple groups — use this flexibility\n3. **Use favorites**: Add frequently viewed groups to favorites\n4. **Combine with status pages**: Use your group structure as a reference when organizing monitors on status pages","category":"monitors","tags":["groups","organization","monitoring","dashboard"],"order":5,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"Organize your monitors into logical groups and monitor group-level status","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTE2Z6XSZHFYFTSFW7A","locale":"en","translationGroup":"other-monitor-types","slug":"en-other-monitor-types","title":"Monitor Types (TCP, UDP, WebSocket, gRPC, Ping, MCP)","description":"Setup and use cases for non-HTTP monitor types","body":"# Monitor Types\n\nUptimeWarden supports many protocols beyond HTTP/HTTPS. This guide covers each monitor type and its use cases.\n\n## TCP Monitor\n\nTCP monitors establish a TCP connection to the specified host and port to check service availability.\n\n**Use cases:**\n- Database servers (PostgreSQL: 5432, MySQL: 3306, Redis: 6379)\n- Mail servers (SMTP: 25/587, IMAP: 993)\n- Custom application ports\n\n**Setup:**\n1. Select **TCP** as the monitor type\n2. **Host**: Target server address (e.g., `db.example.com`)\n3. **Port**: Port number to check (e.g., `5432`)\n4. Set check interval and timeout\n\n## UDP Monitor\n\nUDP monitors send a UDP packet to the specified host and port and check for a response.\n\n**Use cases:**\n- DNS servers (53)\n- VoIP services\n- Game servers\n- SNMP services\n\n**Setup:**\n1. Select **UDP** as the monitor type\n2. **Host**: Target server address\n3. **Port**: UDP port number\n\n> **Note**: Since UDP is a connectionless protocol, it's recommended to use retries to ensure the service is actually down when no response is received.\n\n## WebSocket Monitor\n\nWebSocket monitors establish a WS or WSS (secure) connection to check if the bidirectional communication channel is working.\n\n**Use cases:**\n- Real-time chat applications\n- Live data streaming services\n- IoT gateways\n- WebSocket-based APIs\n\n**Setup:**\n1. Select **WebSocket** as the monitor type\n2. **URL**: WebSocket address (e.g., `wss://api.example.com/ws`)\n3. Configure timeout and retry settings\n\n## gRPC Monitor\n\ngRPC monitors check the health check endpoint of a gRPC service.\n\n**Use cases:**\n- Microservice architecture services\n- gRPC-based APIs\n- Inter-service communication checks\n\n**Setup:**\n1. Select **gRPC** as the monitor type\n2. **Host**: gRPC server address (e.g., `grpc.example.com`)\n3. **Port**: gRPC port number (typically 50051)\n\n## Ping (ICMP) Monitor\n\nPing monitors send ICMP echo requests to check whether a server is reachable at the network level.\n\n**Use cases:**\n- Server availability check\n- Network connectivity test\n- Infrastructure monitoring\n- VPN connection check\n\n**Setup:**\n1. Select **Ping** as the monitor type\n2. **Host**: Target IP address or hostname (e.g., `192.168.1.1` or `server.example.com`)\n\n> **Note**: Ping monitors use ICMP. Some servers and firewalls may block ICMP packets. In this case, TCP monitors can be used as an alternative.\n\n## MCP Monitor\n\nMCP (Model Context Protocol) monitors are a specialized check type for AI model services.\n\n**Use cases:**\n- AI/ML model serving endpoints\n- LLM API gateways\n- Model Context Protocol compatible services\n\n**Setup:**\n1. Select **MCP** as the monitor type\n2. **URL**: MCP endpoint address\n\n## Which Type Should I Choose?\n\n| Scenario | Recommended Type |\n|----------|-----------------|\n| Website or REST API | **HTTP/HTTPS** |\n| Database access | **TCP** |\n| DNS server | **UDP** |\n| Real-time application | **WebSocket** |\n| Microservice | **gRPC** |\n| Server availability | **Ping** |\n| AI model service | **MCP** |\n| SSL certificate monitoring | **SSL Certificate** |\n\n## Common Settings\n\nCommon settings for all monitor types:\n- **Check interval**: How often to check\n- **Timeout**: Maximum wait time\n- **Retry**: Number of retries\n- **Notification channels**: Which channels to send alerts through\n- **Tags**: Tags for organization\n- **Region/Agent**: Which location to check from\n\nSee the **Monitor Settings** documentation for detailed settings.","category":"monitors","tags":["tcp","udp","websocket","grpc","ping","mcp","monitor-types"],"order":6,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"Setup and use cases for non-HTTP monitor types","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTFQ8D6AH0M2E4BYK0R","locale":"en","translationGroup":"agent-management","slug":"en-agent-management","title":"Private Agent Management","description":"Private agent setup, security token management, and deployment methods guide","body":"# Private Agent Management\n\nA Private Agent runs on your own infrastructure to monitor internal network services (behind VPN, intranet, localhost). Agents establish secure connections to the UptimeWarden server and report check results.\n\n## Agents Page\n\nWhen you go to the **Agents** menu, 4 summary cards appear at the top:\n\n| Card | Description |\n|------|-------------|\n| **Total Agents** | Total registered agent count |\n| **Online Now** | Currently online agent count |\n| **Active Tokens** | Active security token count |\n| **Assigned Monitors** | Monitors assigned to agents |\n\nThe page has 4 tabs: **Agents**, **Security Tokens**, **Download**, and **Setup Guide**.\n\n## Creating an Agent\n\n1. Click the **\"Create Agent\"** button on the **Agents** tab\n2. Fill in the fields:\n\n| Field | Required | Description |\n|-------|----------|-------------|\n| **Agent Name** | Yes | Descriptive name for the agent |\n| **Description** | No | Description about the agent |\n| **Location** | No | Physical location (e.g., `US-East`, `EU-West`, `On-Premise`) |\n\n3. After creation, a setup token is automatically generated\n\n## Agent Details\n\nEach agent card shows:\n\n- **Status**: Online, Offline, or Unknown (color-coded badge)\n- **Location**: Physical location\n- **Version**: Agent software version\n- **Last Seen**: Last connection time\n- **Hostname**: Server name\n- **Platform**: OS and architecture (e.g., `linux/x86_64`)\n- **CPU**: Core count and usage (e.g., `4 cores (15.2%)`)\n- **Memory**: Used / Total memory (e.g., `512 MB / 2.0 GB (25.6%)`)\n- **Uptime**: Agent running time\n\n## Security Tokens\n\nManage tokens used for agent connections in the **Security Tokens** tab.\n\n### Creating a Token\n\n1. Click the **\"Create Token\"** button\n2. Enter a token name (required)\n3. Add a description (optional)\n4. Token is automatically generated\n\n### Token List\n\nInformation shown for each token:\n\n| Field | Description |\n|-------|-------------|\n| **Name** | Token name |\n| **Token** | Masked token value (show/hide with eye icon) |\n| **Status** | Active (green) or Inactive (red) |\n| **Last Used** | Last usage time |\n| **Created** | Creation time |\n\nUse the copy button to copy the token value. Click the trash icon to delete a token (confirmation required).\n\n## Deployment Methods\n\nMultiple ways to deploy the agent from the **Download** tab:\n\n### Binary Download\n\nSupported platforms:\n- Linux x64 / ARM64\n- Windows x64\n- macOS x64 / ARM64\n\n### Docker\n\nQuick start with **Docker Run** command:\n\nEnvironment variables:\n- `SERVER_URL` — UptimeWarden server address\n- `AGENT_TOKEN` — Security token\n- `AGENT_NAME` — Agent name\n- `AGENT_LOCATION` — Location info\n- `MAX_WORKERS` — Concurrent check count\n\n**Docker Compose** file is also available for download.\n\n### Kubernetes\n\nTwo methods available:\n- **kubectl** deployment YAML application\n- **Helm Chart** installation\n\nKubernetes manifests include: Deployment, Service, Secret, ServiceAccount, ClusterRole, and ClusterRoleBinding.\n\n## Setup Guide\n\nDetailed setup information in the **Setup Guide** tab:\n\n### Network Requirements\n\n- Outbound HTTPS (port 443)\n- Outbound WebSocket (port 443, WSS)\n- DNS resolution\n- Access to monitor targets\n- No inbound connections required (firewall-friendly)\n\n### System Requirements\n\n| Level | CPU | RAM | Disk |\n|-------|-----|-----|------|\n| **Minimum** | 1 core | 512 MB | 100 MB |\n| **Recommended** | 2+ cores | 1 GB | 1 GB |\n| **High Load** | 4+ cores | 2+ GB | 5+ GB |\n\n### Quick Start\n\n1. **Create a Token**: Create a new token from the Security Tokens tab\n2. **Download and Deploy**: Download binary or use Docker/K8s\n3. **Assign Monitors**: Select your agent in monitor settings\n\n## Deleting an Agent\n\nUse the **\"Delete Agent\"** button on the agent card to permanently delete an agent. This action:\n- Deletes the agent record\n- Stops monitoring operations\n- Removes historical data\n\n## Tips\n\n1. **Rotate tokens regularly**: Renew tokens periodically for security\n2. **Use separate tokens per environment**: Create different tokens for production and staging\n3. **Distribute geographically**: Place agents in different locations for global monitoring\n4. **Monitor resource usage**: Check CPU and memory metrics on the agent card\n5. **Use multiple agents**: Run multiple agents in the same region for redundancy","category":"monitors","tags":["agent","private-agent","deployment","security-token","on-premise"],"order":8,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"Private agent setup, security token management, and deployment methods guide","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTG94F8D8JRS0SNDASC","locale":"en","translationGroup":"service-map","slug":"en-service-map","title":"Service Map","description":"Service dependency map, automatic discovery, and cascade failure analysis guide","body":"# Service Map\n\nThe Service Map visualizes the dependency relationships between services in your infrastructure as an interactive graph. Connections between services are automatically detected, and cascade failure analyses are performed.\n\n## Overview\n\nThe service map page consists of these components:\n- **Interactive graph**: Drag-and-drop, zoom-in/out supported dependency graph\n- **Summary panel**: Total service, connection, and status statistics\n- **Filters**: Environment and service type filtering\n- **Cascade failure alerts**: Chain impact analysis\n\n## Nodes\n\nEach node represents a monitor/service and displays:\n\n- **Service name**\n- **Health status** (color-coded icon):\n  - 🔴 **Critical**: Critical condition\n  - 🟠 **Degrading**: Performance declining\n  - 🔵 **Stable**: Stable\n  - 🟢 **Improving**: Improving trend\n- **Uptime percentage** (e.g., `99.50%`)\n- **Response time** (e.g., `245ms`)\n- **Environment badge**: Production, Staging, Development, Testing\n- **Service type badge**: API, Web, Database, Cache, Queue, Gateway, Auth, CDN, Service\n- **Primary Service badge** (yellow): Critical services that are potential sources of cascade failures\n\n## Edges\n\nEdges show dependencies between services. Color and style vary by detection method:\n\n| Style | Color | Description |\n|-------|-------|-------------|\n| Solid line | Red | Timing-based detection |\n| Solid line | Blue | URL-based detection |\n| Dashed line | Purple | Manual correlation |\n| Solid line | Gray | Other/unknown |\n\nBidirectional dependencies show arrows at both ends of the edge.\n\n## Dependency Detection Methods\n\n### Automatic Detection\n\nUptimeWarden automatically detects dependencies between services using multiple methods:\n\n- **URL pattern analysis**: Domain and subdomain matching\n- **Naming conventions**: References in service names\n- **Timing analysis**: Correlations in event times\n\n### AI Discovery\n\nClick the **\"AI Discovery\"** button to launch AI-powered topology analysis. This reveals deeper dependency relationships. An animation is shown on the button during analysis.\n\n### Manual Connection\n\n1. Click the **\"Add Manual Link\"** button at the top\n2. Click **2 service nodes** in sequence (selection counter shown: `1/2 selected`)\n3. Confirm in the dialog and optionally add a note\n4. The connection appears as a purple dashed line\n\nDelete a connection by clicking the edge and confirming.\n\n### Re-analyze\n\nClick the **\"Re-analyze\"** button to rerun correlation analysis on the last 7 days of data.\n\n## Summary Statistics\n\n7-column summary panel at the top:\n\n| Metric | Description |\n|--------|-------------|\n| **Total Services** | Total service count |\n| **Correlations** | Number of detected dependency groups |\n| **Primary** | Number of primary/critical services |\n| **Critical** | Services in critical condition (red) |\n| **Degrading** | Services with declining performance (orange) |\n| **Stable** | Stable services (blue) |\n| **Improving** | Improving services (green) |\n\n## Cascade Failure Alert\n\nWhen a chain failure is detected, a red alert card appears at the top of the page showing:\n- **Primary service**: The main service causing the failure\n- **Affected services**: Other services affected in the chain\n\n## Filtering\n\n| Filter | Options |\n|--------|---------|\n| **Environment** | All, Production, Staging, Development, Testing |\n| **Service Type** | All, API, Web, Database, Cache, Queue, Gateway, Auth, CDN, Service |\n\nA **\"Clear Filters\"** button appears when filters are active.\n\n## Layout Controls\n\nChange the graph layout:\n- **Vertical (TB)**: Top-to-bottom layout\n- **Horizontal (LR)**: Left-to-right layout\n\nThe legend in the top right explains health status colors and special markers.\n\n## Graph Interaction\n\n- **Drag**: Reposition nodes\n- **Zoom**: 0.1x - 4x range\n- **Pan**: Scroll the graph\n- **Fit to View**: Fit entire graph to screen\n- **MiniMap**: Quick navigation via the small map in the bottom left\n\n## Tips\n\n1. **Track primary services**: Yellow-badged services may be the source of failure propagation\n2. **Use AI Discovery**: Run AI analysis to discover overlooked dependencies\n3. **Add manual connections**: Manually define known dependencies not detected automatically\n4. **Take cascade failure alerts seriously**: When the red alert card appears, prioritize the primary service\n5. **Use environment filters**: Focus by viewing your production services separately","category":"monitors","tags":["service-map","topology","dependencies","correlation","ai-discovery"],"order":9,"parentSlug":"monitors","published":true,"version":1,"metaTitle":null,"metaDescription":"Service dependency map, automatic discovery, and cascade failure analysis guide","icon":"Monitor","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2ENZKWRWC14C6PE9EFJ5E","locale":"en","translationGroup":"http-monitor","slug":"http-monitor","title":"HTTP Monitor","description":"Monitor websites and APIs with status code, content, and response time checks.","body":"# HTTP Monitor\n\nThe HTTP monitor is the most common monitor type. It sends a periodic HTTP request to a URL and verifies the status code, the response content (optional), and the total response time. It is the default choice for websites, REST APIs, GraphQL endpoints, and health-check routes.\n\n## When to use\n\n- **Public website**: Is `https://example.com` up and returning 200?\n- **REST API**: Does `/api/v1/health` return `{\"status\":\"ok\"}`?\n- **Third-party integration**: Is your webhook proxy correctly forwarding upstream requests?\n- **Login page**: Returns 200 and still contains \"Sign in\"?\n- **CDN edge**: Are your edge nodes serving the cached content you expect?\n\n## Supported request methods\n\n| Method | When it is used |\n|---|---|\n| `GET` | Default, used whenever the request body is empty |\n| `POST` | Used automatically as soon as you fill in a request body |\n\nEvery check sends a `User-Agent: UptimeWarden/1.0.0` header. Any extra headers you need are added through the headers table on the form.\n\n## Creating a monitor\n\n1. **Monitors → New Monitor** → Type: `Website & API` (HTTP)\n2. Core fields:\n\n   - **Name**: e.g. `Production API - Health`\n   - **URL**: `https://api.example.com/health`\n   - **Check Interval**: The fastest interval depends on your plan; see the [pricing page](https://uptimewarden.online/pricing) for current values\n   - **Timeout**: maximum time to wait for a response (default 30s, min 5s, max 300s)\n\n3. **Expected status code(s)**: comma-separated list, e.g. `200,201,204`. Defaults to `200`.\n\n4. **Custom headers** (optional): API keys, user agent, accepted MIME type, etc.\n   ```\n   Authorization: Bearer eyJhbGc...\n   X-API-Version: 2024-01\n   Accept: application/json\n   ```\n\n5. **Request body** (optional): when filled in, the request is automatically sent as POST. JSON, form-data, or plain text are all supported.\n\n6. **Save**.\n\n## Status code validation\n\nAny response that matches your expected list is **up**. Anything outside the list (`500`, `503`, `404`, network errors, timeouts) is **down**.\n\nCommon patterns:\n- API health: `200`\n- Public site that may redirect: `200,301,302`\n- Login form: `200,302` (200 for the rendered page, 302 after a successful submit)\n- HEAD or CDN cache validators: `200,304`\n\n## Content validation\n\nStatus codes are not always enough, a server can return 200 along with an HTML error page. UptimeWarden supports four ways to validate the response body:\n\n| Type | Use case | Example |\n|---|---|---|\n| Text | Substring or exact match | `\"status\":\"ok\"` |\n| Regex | Regex pattern match | `^(OK\\|HEALTHY)$` |\n| JSON | Expected JSON content | `{\"status\":\"ok\"}` |\n| XML | Expected XML content | `<status>ok</status>` |\n\nA case-sensitivity toggle controls the behaviour for text and regex.\n\n**Example. JSON API health check**:\n```http\nGET /api/health → 200\n{\"status\": \"ok\", \"version\": \"1.4.2\"}\n```\nWith JSON content validation expecting `\"ok\"`, a `{\"status\":\"degraded\"}` response drops to `down`.\n\n## Authentication\n\n### Custom header (recommended)\nThe custom header table is how you attach authentication headers to the monitored request. Headers you define here are sent on every check, for example `Authorization: Bearer <token>` (JWTs or API keys), `X-API-Key`, or signed headers.\n\n### Basic Auth / Bearer Token fields\nThe Basic Auth (username/password) and Bearer Token fields on the form store credentials encrypted at rest, but they are not currently applied as an `Authorization` header on the monitored request. To check an endpoint behind authentication, enter the credential as an `Authorization` header in the custom header table above.\n\n## Redirect handling\n\nUptimeWarden follows redirects automatically, up to a maximum of 10 hops. The status code of the final destination is compared against your expected list. If you want to assert on a redirect itself (e.g. a 301/302), add that code to your expected status list.\n\n## SSL verification\n\nFor HTTPS URLs, certificates are validated strictly by default (invalid, expired, or self-signed certs cause a down state). Lab environments can turn `Verify SSL` off, but never disable it in production.\n\n> **Note**: Use a dedicated SSL Monitor for **expiry** tracking, the HTTP monitor only confirms the certificate is valid right now, not how many days remain.\n\n## Response time threshold\n\nThe `Response Time Threshold` (ms) gives you a third state:\n- Response at or under the threshold → up\n- Response above the threshold → recorded as a slow check (`high_response`)\n- Timeout → down\n\nA high response time alert fires only after N slow checks in a row, where N is\nthe same number of consecutive checks that confirms a recovery (default 3). A\nsingle slow spike stays in your results and charts but does not notify anyone.\nIf the slowness goes on, the alert goes out on the Nth slow check, at most N−1\ncheck intervals after the first one, and the incident starts at the first slow\ncheck.\n\nThis surfaces creeping latency before it becomes an outage.\n\n## Creating a monitor via API\n\n```bash\ncurl -X POST https://app.uptimewarden.online/api/v1/monitors \\\n  -H \"Authorization: Bearer $UW_API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"Production API\",\n    \"url\": \"https://api.example.com/health\",\n    \"type\": \"http\",\n    \"interval\": 60,\n    \"timeout\": 30\n  }'\n```\n\nThe response is `201 Created` and includes the new monitor's ID. The `v1` create endpoint reads only the `name`, `url`, `type`, `interval`, and `timeout` fields (`name`, `url`, `type` are required); expected status codes default to `200`. You can edit the expected codes and other details afterward from the dashboard.\n\n## Plan limits and interval\n\nThe shortest check interval you can pick depends on your plan, and the form locks faster intervals behind an \"upgrade\" prompt. See the [pricing page](https://uptimewarden.online/pricing) for current plan limits; your account's exact values render live on the dashboard's **Billing → Plan details** page.\n\n## FAQ\n\n**Q: My page returns 200 but says \"Database error\" in the body, the monitor still shows up.**\nA: Add a content validation rule that checks \"Database error\" is absent (regex `^(?!.*Database error).*`), or assert that your healthy banner is present.\n\n**Q: I want to monitor an endpoint behind a login.**\nA: Add the credential as an `Authorization` header in the custom header table (it is sent on every check). UptimeWarden sends a single request, for multi-step flows, a Heartbeat monitor combined with an external script is cleaner.\n\n**Q: I do not want my POST checks to write a row in my database every minute.**\nA: Use a dry-run or `?ping` mode in your API, or hit an idempotent endpoint. Health endpoints should always be free of side effects.\n\n## Related topics\n\n- [SSL Monitor](/docs/ssl-monitor): certificate expiry tracking\n- [Monitor Settings](/docs/monitor-settings): every form field explained\n- [Multi-Location Consensus](/docs/multi-location-consensus)\n- [Notification Channels](/docs/notification-channels)","category":"monitors","tags":["http","api","monitoring","rest"],"order":10,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"HTTP Monitor. UptimeWarden Documentation","metaDescription":"Track HTTP services with GET or POST checks, expected status codes, content assertions, basic or bearer authentication, and response time thresholds.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.652Z","updatedAt":"2026-10-12T22:06:41.652Z","publishedAt":"2026-10-12T22:06:41.652Z"},{"publicId":"01M4S2ENWTHTBREHKSAFHA1RJG","locale":"en","translationGroup":"monitors-overview","slug":"creating-and-managing","title":"Creating and Managing Monitors","description":"Create your first monitor in two minutes; everything you'll touch most often, pause, edit, delete, bulk actions.","body":"# Creating and Managing Monitors\n\nA monitor is the unit of work in UptimeWarden. You point it at a target, a URL, a host and port, a domain, and it checks on a schedule. This page walks through creating, editing, pausing, and deleting monitors. For type-specific detail (HTTP, SSL, DNS, gRPC, and the rest), follow the dedicated pages.\n\n## Creating your first monitor\n\nFrom the dashboard pick **Monitors → New Monitor**:\n\n1. **Choose a type.** HTTP for a website or REST API; Ping for raw ICMP reachability; SSL for certificate health; the [Monitors overview](/docs/monitors-overview) lists every type with a one-line description of what it's for.\n2. **Fill in the target.** A URL, a host plus port, or a domain, depending on type. The form validates as you type.\n3. **Pick a check interval.** How often the check runs. Faster intervals catch outages sooner but consume more of your monitor allowance; the form locks intervals faster than your plan allows behind an upgrade prompt.\n4. **Pick a region** (or accept the default). Choosing a region is available on Professional (up to 5 regions) and Enterprise (all regions); on other plans the monitor runs from the default region. On Starter and above you can also pick verification regions for [multi-location consensus](/docs/multi-location-consensus).\n5. **Pick notification channels and alarm types.** Which channels (email, SMS, WhatsApp, voice, push, webhook, Slack, Telegram) get which alarm types (`down`, `recovery`, `ssl`, `high_response`, etc.).\n6. **Save.**\n\nThe first check usually completes within a few seconds and the result lands on the monitor's detail page.\n\n:::tip Tag liberally\nAdd tags like `env:prod`, `team:platform`, `customer:acme`. Tags drive dashboard filters, status-page selection, and API token scoping. They cost nothing and pay back the moment your list grows.\n:::\n\n## The monitor detail page\n\nOpen any monitor and you'll see:\n\n- **Status header**: current state (`up`, `down`, `recovery`, or `unknown`), last check time, latest response time\n- **Uptime chart**: rolling uptime percentage over 24h / 7d / 30d\n- **Response-time chart**: latency over the same windows\n- **Recent checks**: a scrollable list of the last N results with timing and any error text\n- **Incidents**: every incident this monitor has triggered, with duration and notification trail\n- **Settings**: the same form you saw at creation, editable in place\n\nFor the full reference see [Monitor Detail](/docs/monitor-detail).\n\n## Editing a monitor\n\nOpen the monitor → **Settings** → change what you need → **Save**. UptimeWarden picks up the change on the next cycle (under a minute), so you don't need to wait around for old behaviour to expire.\n\nA few changes are worth flagging:\n\n- **Changing the URL or host** is treated as the same monitor: historical data continues against the new target. If that's not what you want, create a new monitor instead.\n- **Changing the region** keeps historical data; the breakdown panel labels old checks against their original region.\n- **Changing the interval** takes effect immediately; the next check follows the new schedule.\n- **Disabling all alarm types** silences notifications but the monitor still records data. Useful for \"I want the chart but not the page.\"\n\n## Pausing and resuming\n\nPausing a monitor stops checks immediately, no data is recorded, no incidents fire. Resume restarts checks on the next check cycle.\n\nPause is the right tool for:\n\n- Planned maintenance you don't want polluting uptime\n- A monitor someone configured wrong and you're not ready to delete\n- Decommissioning a service while you keep the monitor for reference\n\nIf you find yourself pausing the same monitor on a recurring schedule, consider a [Maintenance Window](/docs/maintenance-windows), it suppresses notifications without zeroing out check data.\n\n## Deleting a monitor\n\nDelete is permanent, the monitor and its history go away. Your plan's monitor count drops by one. There is no undo, so we ask you to type the monitor's name to confirm.\n\nIf you might want the data later, **pause** instead. Paused monitors still count toward your plan limit, your monitor count only drops when you delete. (On Enterprise the limit is unlimited, so it doesn't matter there.)\n\n## Bulk operations\n\nWhen you select multiple rows on the Monitors page, a sticky toolbar appears with:\n\n- **Pause / Resume**: flip a whole batch at once\n- **Add tag**: same tag on the whole selection\n- **Set group**: assign to a [monitor group](/docs/groups)\n- **Assign escalation policy**: wire to a tiered on-call rotation\n- **Delete**: bulk delete (with a confirmation phrase)\n\nEvery bulk action lands in the audit log so you have a record of what changed.\n\n## Search and filtering\n\nThe Monitors page header has a search box and filter dropdowns:\n\n- **Search** matches name, URL/host, and tags simultaneously\n- **Status** filter narrows to `up` / `down` / `recovery` / `paused`\n- **Type** filter shows only HTTP, only SSL, etc.\n- **Group** filter scopes to one group's monitors\n- **Tag** filter scopes to monitors carrying that tag\n\nThe URL updates as you filter, so a complex filtered view is shareable as a link.\n\n## Sharing monitors with a team\n\nBy default, a monitor is private to the user who created it. To share access, add the monitor's owner team to the monitor (or create the monitor under a team in the first place). Team members inherit the team's role: readers see the data, editors can change settings, admins can delete.\n\nFor role detail see [Roles & Permissions](/docs/roles-permissions).\n\n## Plan limits\n\n| Plan | Monitor limit | Minimum interval |\n|---|---|---|\n| Free | 20 | 3 minutes |\n| Hobby | 35 | 2 minutes |\n| Starter | 50 | 2 minutes |\n| Professional | 100 | 1 minute |\n| Enterprise | Unlimited | 30 seconds |\n\nReaching your monitor limit blocks new monitor creation until you delete one or upgrade your plan. There's no overage billing.\n\n## FAQ\n\n**Q: How long does it take for a new monitor to start checking?**\nA: A few seconds. The first result usually appears before you've finished moving to the detail page.\n\n**Q: Can I copy an existing monitor?**\nA: Yes, click the **Clone Monitor** button on the monitor's row in the Monitors list. The new monitor inherits every setting except the name (which gets a `(Copy)` suffix). Tweak what's different and save.\n\n**Q: What happens to a monitor's data when I delete it?**\nA: The monitor row, its check results, and its incidents are removed. If you want the data preserved, pause the monitor instead.\n\n**Q: Can I import or export monitors?**\nA: Yes. See [Monitoring as Code](/docs/developers-monitoring-as-code) for a TypeScript/CLI workflow and the [Terraform Provider](/docs/developers-terraform-provider) for HCL.\n\n## Related topics\n\n- [Monitors overview](/docs/monitors-overview): the full type catalogue\n- [Monitor Detail](/docs/monitor-detail)\n- [Monitor Groups](/docs/groups)\n- [Monitoring as Code](/docs/developers-monitoring-as-code)","category":"monitors","tags":["monitors","getting-started","basics"],"order":15,"parentSlug":null,"published":true,"version":1,"metaTitle":"Creating and Managing Monitors. UptimeWarden Documentation","metaDescription":"Walk through creating a monitor, editing it later, pausing and resuming, and the bulk actions that make managing dozens of monitors painless.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.563Z","updatedAt":"2026-10-12T22:06:41.563Z","publishedAt":"2026-10-12T22:06:41.563Z"},{"publicId":"01M4S2EP0KRBXVE5P2ZKQABAMR","locale":"en","translationGroup":"ssl-monitor","slug":"ssl-monitor","title":"SSL Monitor","description":"Continuously track SSL/TLS certificates: expiry, chain integrity, hostname match, and certificate authority trust.","body":"# SSL Monitor\n\nThe SSL monitor periodically downloads a hostname's TLS certificate and runs several layers of validation: expiry date, certificate chain, hostname match, and trust against the public certificate authority store. Missed renewals turn into \"this site is not secure\" warnings, lost revenue and lost trust in equal measure. SSL monitors warn you weeks in advance.\n\n## What gets checked\n\nOn every successful TLS handshake, UptimeWarden validates:\n\n| Check | Description |\n|---|---|\n| **Expiry** | The certificate's expiry date and the number of days remaining |\n| **Hostname match** | The certificate's common name or subject alternative names cover the queried hostname (wildcards cover one level) |\n| **Chain validity** | The full certificate chain is verified against the public trust store |\n| **CA trust** | The chain is anchored in a trusted root certificate authority |\n| **Identity details** | Issuer, subject, serial number, and SHA-256 fingerprint are extracted for the monitor detail page |\n\nThe handshake requires modern TLS, so very old servers stuck on legacy versions cannot be monitored, and you would not want them to be.\n\n> **Scope**: The SSL monitor focuses on **certificate validity, expiry, hostname match, and chain integrity**. It does not run weak-cipher detection or revocation checks. Use it for the renewal-window guarantees that matter most in production.\n\n## When to use\n\n- Public SaaS app, `app.example.com`\n- Customer-facing API, `api.example.com`\n- Marketing site, `example.com` and `www.example.com`\n- Status page, `status.example.com`\n- Wildcard or multi-SAN certificates: one SSL monitor does not cover every subdomain it includes; **add one monitor per hostname**.\n\n## Creating a monitor\n\n1. **Monitors → New Monitor** → Type: `SSL Certificate`\n2. Fields:\n\n   - **Name**: e.g. `app.example.com - Cert`\n   - **Domain URL**: `https://app.example.com` (port defaults to 443)\n   - **Check Interval**: 6 hours or daily is plenty: certificates do not change every minute\n\n3. **Expiry alert thresholds**: choose which thresholds should fire.\n\n   ```\n   30 days   - proactive renewal reminder (default on)\n   15 days   - last chance (default on)\n   7 days    - critical (default on)\n   1 day     - page on-call (default on)\n   ```\n\n4. **Save**.\n\n## How expiry alerts work\n\nAfter every successful SSL check, the certificate's expiry date is stored. UptimeWarden scans the configured thresholds and emits **one** alert per threshold crossing, never re-fires the same threshold. Two additional advisory thresholds are built in:\n\n- 30 days or fewer remaining → SSL warning\n- 7 days or fewer remaining → SSL warning (critical message)\n- Already expired → down\n- Hostname mismatch or untrusted CA → SSL warning\n\nExample timeline (cert expires 2026-05-30):\n\n- 2026-04-30: 30-day alert → email and Slack\n- 2026-05-15: 15-day alert → email and SMS\n- 2026-05-23: 7-day alert → email and voice\n- 2026-05-29: 1-day alert → all channels and on-call escalation\n\n## The certificates page: \"Do I need to act?\"\n\nThe SSL certificates page answers \"Do I need to act?\" first. One status line at the top says how many certificates expire within 30 days (the within-7 count is broken out) and how many have already expired. Directly below it, the **Needs attention** list brings forward the expired and soon-to-expire certificates, soonest first, and gives each one a plain answer: **Yes.**, **Not urgent, but check.** or **No.** — \"No.\" means there is nothing to do yet (an auto-renewing certificate such as a Let's Encrypt one may simply not be late), and the other answers say the next step in the same row. Certificates that expire later than 30 days are not in that list at all; the full table (\"All certificates, soonest first\") comes after it.\n\n- An expired certificate reads as \"Expired\" everywhere.\n- A certificate whose check never returned a result is marked \"Not checked yet\" (its days column shows \"—\") and is not shown as a problem; it sits at the end of the full table. Expired and never-checked are never mixed.\n- Every row names the monitor group(s) the certificate belongs to (the Group column), so you can see which part of your sites a certificate covers. You can filter by group, and certificates in no group are found under \"No group\".\n\n## Certificate chain and CA validity\n\nBrowsers walk the chain, if an intermediate certificate is missing or out of order, Chrome may work while mobile Safari, Java clients, and other strict clients fail. UptimeWarden extracts the full chain and verifies it against the public trust store; failure marks the certificate as untrusted on the monitor detail page.\n\n```\nServer → Intermediate CA → Root CA (trust store)\n```\n\n**Common failure**: a certificate is renewed but the web server still serves the old intermediate, breaking mobile clients. The SSL monitor catches this.\n\n## Hostname mismatch\n\nUptimeWarden walks the common name and subject alternative names list. Wildcards cover one level only:\n\n- `*.example.com` → `api.example.com`: matches\n- `*.example.com` → `v2.api.example.com`: does not match (two levels)\n\nA common name of just `example.com` does not cover `www.example.com`.\n\n## Transient errors and retry\n\nConnection resets, refused connections, I/O timeouts, broken pipes, and handshake failures are treated as transient and retried with exponential backoff (2s, 4s, 8s). The retry count is configurable on the form (default 2). When the failure is a certificate problem, UptimeWarden falls back to a non-verifying handshake just long enough to capture the certificate details and reports an SSL warning so you do not lose the \"why isn't it trusted\" diagnostics.\n\n## Self-signed and internal CAs\n\nFor certificates issued by an internal authority, turn `Verify SSL` off. Chain and expiry are still validated, but the public trust store check is skipped. This is useful for internal mTLS endpoints.\n\n## Creating an SSL monitor via API\n\n```bash\ncurl -X POST https://app.uptimewarden.online/api/v1/monitors \\\n  -H \"Authorization: Bearer $UW_API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"app.example.com SSL\",\n    \"url\": \"https://app.example.com\",\n    \"type\": \"ssl\",\n    \"interval\": 21600,\n    \"sslAlerts\": {\n      \"thirtyDays\": true,\n      \"fifteenDays\": true,\n      \"sevenDays\": true,\n      \"oneDay\": true\n    }\n  }'\n```\n\n## Notification mapping\n\nSSL monitors expose dedicated alert types:\n\n| Alert | Trigger |\n|---|---|\n| SSL | 30 / 15 / 7 / 1-day threshold crossed |\n| SSL recovery | Certificate renewed, new expiry beyond 30 days |\n| Down | TLS handshake failed or certificate expired |\n| Recovery | Handshake succeeds again |\n\nEach alert type can be routed to a different channel, send SSL alerts to email and down alerts to SMS plus voice.\n\n## Plan availability\n\nSSL monitors are available across plans, but the **number of SSL monitors and how often they run** varies by plan. The form shows the limits relevant to your subscription.\n\n## FAQ\n\n**Q: My HTTP monitor already does HTTPS, why a separate SSL monitor?**\nA: The HTTP monitor checks \"is the certificate valid right now?\" The SSL monitor watches days remaining and fires a renewal-window alarm.\n\n**Q: I have a wildcard certificate, one monitor per subdomain?**\nA: Recommended. Wildcards cover one level only, and different load balancers may serve stale certificates even after one renews.\n\n**Q: Let's Encrypt auto-renews every 90 days. Do I still need this?**\nA: Yes. When renewal automation fails (and one day it will), the 30-day alert wakes you up 60 days before browsers do.\n\n## Related topics\n\n- [HTTP Monitor](/docs/http-monitor)\n- [Notification Channels](/docs/notification-channels)\n- [Monitor Settings](/docs/monitor-settings)\n- [Monitor Groups](/docs/groups)\n- [Monitor Detail](/docs/monitor-detail)","category":"monitors","tags":["ssl","tls","certificate","security"],"order":20,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"SSL Monitor. UptimeWarden Documentation","metaDescription":"30/15/7/1-day SSL expiry alerts plus chain, hostname, and CA-trust checks before browsers flag your site.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.683Z","updatedAt":"2026-10-12T22:06:41.683Z","publishedAt":"2026-10-12T22:06:41.683Z"},{"publicId":"b0155a7587a14f0bbb0486c889","locale":"en","translationGroup":"multi-location-consensus","slug":"en-multi-location-consensus","title":"Multi-Location Consensus","description":"Require several regions to agree before an incident opens — and dramatically cut false alarms caused by one region's hiccup.","body":"# Multi-Location Consensus\n\nYou get the page: \"site is down.\" You open your browser — it loads fine. No customers complain. Then you realize: one region's monitor caught a brief network hiccup, and the whole alert came from there.\n\nMulti-location consensus fixes this: **require several regions to agree that a service is down before opening an incident**. 2 of 2, 2 of 3, 3 of 5 — you pick the threshold.\n\n## Why it matters\n\nA brief routing glitch on one ISP. A stale DNS cache on a single monitor host. A CPU spike on the pod running the check. Each of these produces **locally misleading signals**. Single-region systems turn them into incidents. The result: 3-AM false alarms, team burnout, and — worst — alert fatigue that blunts response to real outages.\n\nConsensus records these signals but doesn't escalate them. Only when **2+ regions agree at the same time** does an alarm fire.\n\n## UptimeWarden's challenger positioning\n\nMost competitors gate multi-region verification behind their paid tiers. UptimeWarden doesn't:\n\n| Plan | Verification regions (total) | Default consensus | User-configurable? |\n|---|---|---|---|\n| **Free** | 2 | **2/2 — always** | No (false-alarm protection is mandatory even on Free) |\n| **Hobby** | 3 | **2/3** | No (still locked) |\n| **Starter** | 3 | 2/3 | **Yes** (1/3 → 3/3) |\n| **Professional** | 5 | 3/5 | Yes (1/5 → 5/5) |\n| **Business** | 6 | 3/6 | Yes |\n| **Enterprise** | 6 | 3/6 | Yes |\n\n> Free users get 2/2 consensus by default. That's the spine of our \"free plan, still trustworthy\" philosophy.\n\n## How consensus works\n\n```mermaid\nsequenceDiagram\n    participant P as Primary region<br/>(e.g. gwc)\n    participant W1 as Witness 1<br/>(e.g. sea)\n    participant W2 as Witness 2<br/>(e.g. brs)\n    participant O as Orchestrator\n\n    Note over P: Check ran → FAIL\n    P->>O: Please verify this fail\n    O->>W1: Independently check the same URL\n    O->>W2: You check too\n    W1-->>O: FAIL\n    W2-->>O: OK\n\n    Note over O: 2 of 3 FAIL<br/>Threshold is 2/3<br/>(compute pass/fail)\n\n    alt Threshold met\n        O->>O: Open incident\n    else Threshold not met\n        O->>O: Record as flap<br/>(no alarm)\n    end\n```\n\n**Step by step:**\n\n1. The **primary check** fails (the monitor's home region says \"down\").\n2. The orchestrator asks the **witness regions** to independently verify.\n3. Witnesses check separately — they don't see each other; each reports back to the central aggregator.\n4. How many of `primary + witnesses` said FAIL? If it meets the threshold → incident opens. If not → recorded as a \"flap,\" no alarm.\n\n## Choosing verification regions\n\nOn the monitor detail page, in the **Multi-Location Consensus** card:\n\n1. **Primary region**: Where the main check runs (usually close to your customers).\n2. **Verification regions**: Up to your plan's limit, used as \"witnesses.\" The system suggests **geographic diversity** — 1 EU + 1 Americas + 1 Asia over three EU regions.\n3. **Minimum confirming regions**: How many must agree for an alarm. Default is usually `(total / 2) + 1` — a majority.\n\n## When to tune the threshold\n\n**Lower makes sense for:**\n- Critical prod services (2/5 instead of default 3/5 — faster alarms, accept slight risk)\n- Financial systems (one witness's failure should be enough to investigate)\n\n**Higher makes sense for:**\n- Test / staging environments (5/5 — only page if every region sees the failure)\n- Monitors with flapping history (bump from 3 to 4)\n\n## Impact on SLA\n\nConsensus doesn't directly change uptime %% — each region still records its own check result. It does reduce the number of incidents opened, which improves **mean time between incidents** and keeps post-mortems focused on real failures.\n\nThe dashboard surfaces \"flap\" events separately — no alarm fired, but a region saw anomaly. Over time this data reveals which regions' networks are most stable.\n\n## Plan upgrade / downgrade behavior\n\n- **Upgrade (Starter → Pro)**: The system **does not** automatically change your monitors' consensus settings. Your new plan allows more regions, but existing configurations stay exactly as they were — we don't silently shift alarm timing on your monitors.\n- **Downgrade (Pro → Starter)**: Settings above the new plan's limit are silently clamped (`min_confirming_regions` drops to the new cap, excess `verification_regions` are trimmed). The change is logged.\n\n## Real-world scenarios\n\n**Scenario A — Single-region false alarm**:\n- Primary (gwc) `fail`, witnesses (sea, brs) `ok`\n- 1 of 3 fails → threshold 2/3 → **no alarm**, flap recorded\n- Team slept through the night, saw the flap report in the morning\n\n**Scenario B — Real outage**:\n- Primary (gwc) `fail`, witnesses (sea, brs) `fail`\n- 3 of 3 fail → **alarm**, incident opened\n- On-call Burak acked in 2 minutes\n\n**Scenario C — Geographically partial outage**:\n- Primary (wus3) `fail`, one witness (sea) `fail`, other (ae) `ok`\n- 2 of 3 fail → threshold 2/3 → **alarm**, but \"Middle East still reachable\" logged\n- Post-mortem used this detail to scope the DDoS's geographic reach\n\n## FAQ\n\n**Q: Do witness regions cost extra?**\nA: No — as long as you stay within your plan's region count, no extra charge. Multiple regions checking the same URL counts as one check.\n\n**Q: What if the primary fails and witnesses are unreachable?**\nA: The primary's fail alone doesn't automatically mean alarm. The system waits 2–3 seconds for witness replies; if they don't respond (e.g., pod issue), we fall back to the primary's verdict — **but** this condition is metric-logged, and a sustained pattern means your infrastructure is struggling.\n\n**Q: Does a heavy check type (e.g. browser-based) respect consensus?**\nA: Yes, all check types honour consensus. For expensive checks (Lighthouse, AI-based), keeping witness count at 2 is a sensible cost trade-off.\n\n## Related topics\n\n- [Regional Monitoring](/docs/en-regional-monitoring)\n- [Other Monitor Types](/docs/en-other-monitor-types)\n- [Incident Management](/docs/en-incidents-overview)","category":"monitors","tags":["consensus","regions","false-alarms","quality"],"order":25,"parentSlug":"monitors","published":true,"version":2,"metaTitle":"Multi-Location Consensus — UptimeWarden Documentation","metaDescription":"Don't get paged at 3 AM because one region's DNS cache went stale.","icon":"Monitor","createdAt":"2026-04-19T00:06:52.889Z","updatedAt":"2026-04-19T00:16:16.629Z","publishedAt":"2026-04-19T00:06:52.889Z"},{"publicId":"01M4S2EP2FP9H5JA5FX3Y0FP31","locale":"en","translationGroup":"multi-location-consensus","slug":"multi-location-consensus","title":"Multi-Location Consensus","description":"When a check fails, other regions repeat it. Most alerts are confirmed from at least two regions; an alert that cannot be confirmed is still sent, labelled unverified.","body":"# Multi-Location Consensus\n\nYou get the page: \"site is down.\" You open your browser, it loads fine. No customer complains. Then you realize: one region's check caught a brief network hiccup, and the whole alert came from there.\n\nMulti-location consensus reduces this: **when a check fails, other regions repeat it before the alert goes out**, and the alert says what they found. On Starter and above you choose how many regions must agree: 2 of 3, 3 of 5, and so on.\n\n## Why it matters\n\nA brief routing glitch on one ISP. A stale DNS cache on a single observation point. A CPU spike on the host running that check. Each of these produces **locally misleading signals**. A second opinion from other regions helps tell a service failure from a problem near one monitoring location.\n\nIt is not a promise of zero false alarms, and it never trades a real outage for silence: when the other regions cannot settle the question, the alert goes out anyway.\n\n## Three outcomes\n\n| Outcome | When | What happens |\n|---|---|---|\n| **Confirmed** | Enough regions saw the site down (the threshold counts the first region too). | The alert goes out and says so, for example \"Confirmed from 3 of 5 regions\". |\n| **Unverified** | The other regions could not settle it: they split, did not answer in time, could not tell, or no other region was available. | The alert still goes out, labelled unverified, on the first region's evidence. |\n| **Rejected** | Most regions reached the site, so the failure is most likely near the first region. | No alert. The incident is recorded as a false positive. If the first region still sees the failure five minutes later, it is verified again. |\n\n## Plans\n\n| Plan | Regions that check | Default threshold | Can you change it? |\n|---|---|---|---|\n| **Free** | 2 | 2 of 2 | No |\n| **Hobby** | 3 | 2 of 3 | No |\n| **Starter** | 3 | 2 of 3 | **Yes** (1 to 3) |\n| **Professional** | 5 | 3 of 5 | Yes (1 to 5) |\n| **Enterprise** | 6 | 3 of 6 | Yes (1 to 6) |\n\n:::note Free's two regions\nWith two regions, a failure can be confirmed but never rejected. If the second region reaches the site, that is a one-to-one split, and the alert is still sent, labelled unverified. From Hobby up, at least three regions check, so a failure most regions do not see can be held.\n:::\n\n## How consensus works\n\n```mermaid\nsequenceDiagram\n    participant P as Primary region\n    participant W1 as Witness 1\n    participant W2 as Witness 2\n    participant O as UptimeWarden\n\n    Note over P: Check ran → FAIL\n    P->>O: Please verify this result\n    O->>W1: Check the same target\n    O->>W2: Check the same target\n    W1-->>O: FAIL\n    W2-->>O: OK\n\n    Note over O: 2 of 3 regions saw it down<br/>threshold 2 of 3 met\n\n    alt Enough regions saw it down\n        O->>O: Alert, confirmed\n    else Most regions reached the site\n        O->>O: No alert, rejected<br/>(verified again in 5 min if still failing)\n    else Split or no answer\n        O->>O: Alert, unverified\n    end\n```\n\n**Step by step:**\n\n1. The **primary check** fails: the monitor's home region reports \"down\".\n2. UptimeWarden asks the **witness regions** to repeat the same check independently. A witness tries as many times as the primary did and looks up the address fresh instead of reusing a cached DNS answer.\n3. Witnesses report back without seeing each other's results.\n4. If enough regions saw the site down, the alert goes out **confirmed**. If most regions reached the site, it is **rejected**. Anything else, including no answer within about 10 seconds, goes out **unverified**.\n\n## Choosing verification regions\n\nThe monitor detail page shows a **Consensus** card; the incident detail page shows a live verification panel while the vote is in flight. On Free and Hobby the card is read-only (\"Upgrade to customize\"); Starter and above unlock a +/− stepper bounded by your plan's maximum.\n\n1. **Primary region**: where the schedule runs, you choose this in the \"Check location\" picker (or let it auto-pick the closest healthy region). The primary's own DOWN observation always counts as one vote.\n2. **Verification regions**: the additional regions used as witnesses. You do not pick these individually. UptimeWarden selects them automatically (deterministically, up to your plan's maximum).\n3. **Minimum confirming regions**: the only consensus value you set directly. The \"Alert confirmation\" stepper controls how many regions, primary plus witnesses, must observe DOWN for an alert to count as confirmed.\n\n## When to tune the threshold\n\nThe threshold decides when an alert counts as **confirmed**. It does not decide whether an alert is sent: a failure is held back only when most regions reach the site, whatever the threshold.\n\n**Lowering makes sense for:**\n- Critical production services where you want the confirmed label from fewer regions (2 of 5 instead of the default 3 of 5).\n- Setting it to 1 turns verification off for that monitor: every failure alerts at once, without asking other regions.\n\n**Raising makes sense for:**\n- Services where you only want to call an outage confirmed when nearly every region sees it (for example 5 of 5). Failures that fewer regions see still alert, labelled unverified.\n\n## Effect on SLA accounting\n\nConsensus does not directly change the uptime percentage, every region still records its own check result. What changes is the number of incidents that page you: rejected failures are recorded as false positives instead.\n\nThe monitor's verification panel lists every verification with its outcome (confirmed, unverified or rejected), so a held alert stays visible. Over time this shows which regions disagree most often for your services.\n\n## Upgrade and downgrade behavior\n\n- **Upgrade (Starter → Professional)**: existing monitors keep their consensus settings as they are. The new plan unlocks more regions, but UptimeWarden does not silently relax alarm thresholds during an upgrade, fewer-than-expected incidents after an upgrade are much harder to debug than an unchanged setup.\n- **Downgrade (Professional → Starter)**: monitors above the new plan's limit are aligned automatically. The minimum confirming region count drops to the new ceiling and the verification region list is trimmed. The change is recorded in the audit log.\n\n## Real-world scenarios\n\n**Scenario A. A problem near one region (Hobby, 2 of 3)**\n- Primary `fail`, both witnesses `ok`\n- Most regions reached the site → **rejected**, no alert\n- The first region still fails five minutes later, so the failure is verified again; the witnesses reach the site again and it stays rejected\n\n**Scenario B. Real outage**\n- Primary `fail`, both witnesses `fail`\n- 3 of 3 saw it down → **alert, confirmed**\n- The on-call engineer acknowledged in 2 minutes\n\n**Scenario C. Partial outage**\n- Primary `fail`, one witness `fail`, the other witness `ok`\n- 2 of 3 saw it down, threshold 2 of 3 met → **alert, confirmed**\n- The verification panel shows which region could still reach the site, which helped scope the outage in the postmortem\n\n**Scenario D. A split on Free (2 of 2)**\n- Primary `fail`, the witness `ok`\n- One to one: neither confirmed nor rejected → **alert, unverified**\n- The alert says it could not be confirmed from a second region, so the on-call engineer checks the site before escalating\n\n## FAQ\n\n**Q: Do witness regions cost extra?**\nA: No. As long as you stay within your plan's region count, there is no extra charge. Checking the same target from several regions counts as a single check on your bill.\n\n**Q: What if the primary fails and the witnesses don't answer?**\nA: Witnesses have about 10 seconds. If the question is not settled by then, the alert goes out **unverified**, on the primary's evidence, so a real outage isn't masked by a verification delay. Frequent unverified alerts are a sign that something on the verification path is unhealthy and worth investigating.\n\n**Q: Which monitor types are re-checked from other regions?**\nA: Every type that runs from our regions: HTTP, TCP, UDP, ping, SSL, gRPC, WebSocket, MCP and DNS. Heartbeat monitors (your job pings us) and monitors that run on your own agent are not re-checked from other regions.\n\n## Related topics\n\n- [Regional Monitoring](/docs/regional-monitoring)\n- [Other Monitor Types](/docs/other-monitor-types)\n- [Incidents Overview](/docs/incidents-overview)","category":"monitors","tags":["consensus","regions","false-alarms","quality"],"order":25,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Multi-Location Consensus. UptimeWarden Documentation","metaDescription":"How other regions re-check a failure, what confirmed, unverified and rejected mean, and what each plan uses.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.744Z","updatedAt":"2026-10-12T22:06:41.744Z","publishedAt":"2026-10-12T22:06:41.744Z"},{"publicId":"01M4S2EP1ZT9ARGS0MCFC2KZMY","locale":"en","translationGroup":"dns-monitor","slug":"dns-monitor","title":"DNS Monitor","description":"Continuously verify that your domain's A, AAAA, CNAME, MX, NS, and TXT records return the answers you expect.","body":"# DNS Monitor\n\nA DNS monitor periodically queries your domain's DNS servers and verifies the returned records match what you expect. DNS records quietly changing, whether from a misconfigured provider, a stale migration, or a compromised registrar, typically goes unnoticed. DNS monitors close that gap.\n\n## When to use\n\n- **Migration validation**: You moved to a new server; make sure the A record actually points to the new IP.\n- **MX record integrity**: Your email provider accidentally flips an MX record and customer mail starts bouncing. A DNS monitor catches it in minutes.\n- **CDN failover detection**: Your CNAME points to a CDN's load balancer: a mistake in the CDN console can break itself without any server-side signal.\n- **GeoDNS**: If you serve different IPs to different regions, a separate DNS monitor per region (with resolver override) verifies each response path.\n\n## Supported record types\n\n| Type | What it returns | Example expected answer |\n|---|---|---|\n| `A` | IPv4 address | `93.184.216.34` |\n| `AAAA` | IPv6 address | `2606:2800:220:1:248:1893:25c8:1946` |\n| `CNAME` | Canonical name | `example.cloudfront.net` |\n| `MX` | Mail exchanger (priority + host) | `10 mail.example.com` |\n| `NS` | Nameserver | `ns1.dnsprovider.com` |\n| `TXT` | Free text (SPF, DKIM, domain verification) | `v=spf1 include:_spf.google.com ~all` |\n\n## Creating the monitor\n\n1. Go to **Monitors → New Monitor**.\n2. Choose **DNS** as the type.\n3. Fill in:\n\n   - **Name**: e.g. `api.example.com A record`\n   - **Hostname**: Domain to query (`api.example.com`)\n   - **Record Type**: One of the types above\n   - **Expected Answers**: Comma-separated values you expect. Order doesn't matter, the monitor checks each value is present in the returned set.\n   - **Resolver (optional)**: Public DNS server IP (e.g. `8.8.8.8`) to query. Leave blank to use the system default resolver.\n\n4. Set a **Check Interval**. The shortest interval you can pick depends on your plan (see the [pricing page](https://uptimewarden.online/pricing) for current values). DNS propagation can take hours, so 5-15 minutes is usually plenty.\n5. **Save**.\n\n## How expected-answer matching works\n\nThe monitor gets the full answer list from the DNS server and checks that **every value you specified** is present in that list.\n\n**Example 1. Multiple A records**:\n```\nHostname: api.example.com\nExpected: 10.0.0.1, 10.0.0.2\n```\nIf DNS returns `10.0.0.1, 10.0.0.2, 10.0.0.3` → **pass** (both expected values present).\nIf DNS returns `10.0.0.1` → **fail** (`10.0.0.2` missing).\n\n**Example 2. TXT / SPF**:\n```\nHostname: example.com\nRecord Type: TXT\nExpected: v=spf1 include:_spf.google.com ~all\n```\nIf the TXT list doesn't include this exact line, the monitor goes down.\n\n## Resolver override + abuse protection\n\nWhen you specify a custom resolver IP, UptimeWarden runs it through a **safety filter** before querying, allowing only public, internet-facing DNS servers:\n\n- Private ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) are blocked\n- Loopback (`127.0.0.0/8`, `::1`) blocked\n- Link-local and CGNAT (`169.254.0.0/16`, `100.64.0.0/10`) blocked\n- Cloud metadata addresses (`168.63.129.16`) blocked\n\nPublic resolvers (8.8.8.8, 1.1.1.1, 9.9.9.9) work fine; internal resolvers behind your firewall are refused. This prevents the monitor from being abused to probe your private network.\n\n## Regional DNS monitoring\n\nFor GeoDNS setups (same hostname, different answer per region), create one DNS monitor per region:\n\n- Paris users resolve → monitor running in Paris region\n- New York users resolve → monitor running in NYC region\n\nBoth query the same hostname but from different physical locations, surfacing cases like \"DNS correct for EU, wrong IP for US.\"\n\n## SLA and notifications\n\nDNS monitors use the same notification pipeline as other monitors:\n\n- **Down**: Expected answer not in the returned set, or the DNS query timed out\n- **Recovery**: Expected answer returned again\n\nIf multi-location consensus is enabled, DNS monitors honour it too, a single resolver-cache hiccup in one region won't trigger a false alarm.\n\n## FAQ\n\n**Q: Won't an HTTP monitor cover this indirectly?**\nA: An HTTP monitor checks connectivity to whatever IP resolves; it tests DNS correctness *indirectly*. If your server is up but DNS points somewhere wrong, the HTTP monitor may still succeed (if the wrong IP also happens to answer on port 443). A DNS monitor queries the resolver directly, it catches routing drift even when the host still responds.\n\n**Q: My TTL is 1 hour. Does the shortest check interval my plan allows make sense?**\nA: It does, you catch drift faster than TTL implies. But most DNS providers don't need sub-minute resolution; 5 minutes hits a practical sweet spot.\n\n**Q: One region's resolver might be wrong while others are correct. Now what?**\nA: Turn on multi-location consensus. Requiring 2 of 3 regions to agree before alarming means a single stale resolver cache won't page you at 3 AM.\n\n## Related topics\n\n- [Multi-Location Consensus](/docs/multi-location-consensus): preventing false alarms\n- [Regional Monitoring](/docs/regional-monitoring): picking regions\n- [Notification Channels](/docs/notification-channels): where DNS alerts go","category":"monitors","tags":["dns","monitoring","records"],"order":30,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"DNS Monitor. UptimeWarden Documentation","metaDescription":"Verify that your DNS records return the expected values on every check.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.728Z","updatedAt":"2026-10-12T22:06:41.728Z","publishedAt":"2026-10-12T22:06:41.728Z"},{"publicId":"5442e15307a4444b911d170fa3","locale":"en","translationGroup":"dns-monitor","slug":"en-dns-monitor","title":"DNS Monitor","description":"Continuously verify that your domain's A, AAAA, CNAME, MX, NS, and TXT records return the answers you expect.","body":"# DNS Monitor\n\nA DNS monitor periodically queries your domain's DNS servers and verifies the returned records match what you expect. DNS records quietly changing — whether from a misconfigured provider, a stale migration, or a compromised registrar — typically goes unnoticed. DNS monitors close that gap.\n\n## When to use\n\n- **Migration validation**: You moved to a new server; make sure the A record actually points to the new IP.\n- **MX record integrity**: Your email provider accidentally flips an MX record and customer mail starts bouncing. A DNS monitor catches it in minutes.\n- **CDN failover detection**: Your CNAME points to a CDN's load balancer — a mistake in the CDN console can break itself without any server-side signal.\n- **GeoDNS**: If you serve different IPs to different regions, a separate DNS monitor per region (with resolver override) verifies each response path.\n\n## Supported record types\n\n| Type | What it returns | Example expected answer |\n|---|---|---|\n| `A` | IPv4 address | `93.184.216.34` |\n| `AAAA` | IPv6 address | `2606:2800:220:1:248:1893:25c8:1946` |\n| `CNAME` | Canonical name | `example.cloudfront.net` |\n| `MX` | Mail exchanger (priority + host) | `10 mail.example.com` |\n| `NS` | Nameserver | `ns1.dnsprovider.com` |\n| `TXT` | Free text (SPF, DKIM, domain verification) | `v=spf1 include:_spf.google.com ~all` |\n\n## Creating the monitor\n\n1. Go to **Monitors → New Monitor**.\n2. Choose **DNS** as the type.\n3. Fill in:\n\n   - **Name**: e.g. `api.example.com A record`\n   - **Hostname**: Domain to query (`api.example.com`)\n   - **Record Type**: One of the types above\n   - **Expected Answers**: Comma-separated values you expect. Order doesn't matter — the monitor checks each value is present in the returned set.\n   - **Resolver (optional)**: Public DNS server IP (e.g. `8.8.8.8`) to query. Leave blank to use the system default resolver.\n\n4. Set a **Check Interval** (minimum 1 minute). DNS propagation can take hours, so 5–15 minutes is usually plenty.\n5. **Save**.\n\n## How expected-answer matching works\n\nThe monitor gets the full answer list from the DNS server and checks that **every value you specified** is present in that list.\n\n**Example 1 — Multiple A records**:\n```\nHostname: api.example.com\nExpected: 10.0.0.1, 10.0.0.2\n```\nIf DNS returns `10.0.0.1, 10.0.0.2, 10.0.0.3` → **pass** (both expected values present).\nIf DNS returns `10.0.0.1` → **fail** (`10.0.0.2` missing).\n\n**Example 2 — TXT / SPF**:\n```\nHostname: example.com\nRecord Type: TXT\nExpected: v=spf1 include:_spf.google.com ~all\n```\nIf the TXT list doesn't include this exact line, the monitor goes down.\n\n## Resolver override + SSRF protection\n\nWhen you specify a custom resolver IP, UptimeWarden runs it through an **SSRF filter** before querying:\n\n- Private ranges (`10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16`) are blocked\n- Loopback (`127.0.0.0/8`, `::1`) blocked\n- Link-local and CGNAT (`169.254.0.0/16`, `100.64.0.0/10`) blocked\n- Azure IMDS (`168.63.129.16`) blocked\n\nPublic resolvers (8.8.8.8, 1.1.1.1, 9.9.9.9) work fine; internal resolvers behind your firewall are refused. This prevents agents from being abused to probe your private network.\n\n## Regional DNS monitoring\n\nFor GeoDNS setups (same hostname, different answer per region), create one DNS monitor per region:\n\n- Paris users resolve → monitor running in Paris region\n- New York users resolve → monitor running in NYC region\n\nBoth query the same hostname but from different physical locations, surfacing cases like \"DNS correct for EU, wrong IP for US.\"\n\n## SLA and notifications\n\nDNS monitors use the same notification pipeline as other monitors:\n\n- **Down**: Expected answer not in the returned set, or the DNS query timed out\n- **Recovery**: Expected answer returned again\n\nIf multi-location consensus is enabled, DNS monitors honour it too — a single resolver-cache hiccup in one region won't trigger a false alarm.\n\n## FAQ\n\n**Q: Won't an HTTP monitor cover this indirectly?**\nA: An HTTP monitor checks connectivity to whatever IP resolves; it tests DNS correctness *indirectly*. If your server is up but DNS points somewhere wrong, the HTTP monitor may still succeed (if the wrong IP also happens to answer on port 443). A DNS monitor queries the resolver directly — it catches routing drift even when the host still responds.\n\n**Q: My TTL is 1 hour. Does a 1-minute check interval make sense?**\nA: It does — you catch drift faster than TTL implies. But most DNS providers don't need sub-minute resolution; 5 minutes hits a practical sweet spot.\n\n**Q: One region's resolver might be wrong while others are correct. Now what?**\nA: Turn on multi-location consensus. Requiring 2 of 3 regions to agree before alarming means a single stale resolver cache won't page you at 3 AM.\n\n## Related topics\n\n- [Multi-Location Consensus](/docs/en-multi-location-consensus) — preventing false alarms\n- [Regional Monitoring](/docs/en-regional-monitoring) — picking regions\n- [Notification Channels](/docs/en-notification-channels) — where DNS alerts go","category":"monitors","tags":["dns","monitoring","records"],"order":30,"parentSlug":"monitors","published":true,"version":2,"metaTitle":"DNS Monitor — UptimeWarden Documentation","metaDescription":"Verify that your DNS records return the expected values on every check.","icon":"Monitor","createdAt":"2026-04-19T00:06:52.889Z","updatedAt":"2026-04-19T00:16:16.629Z","publishedAt":"2026-04-19T00:06:52.889Z"},{"publicId":"01M4S2EP03ZPG6VC2QQDY2QQ4N","locale":"en","translationGroup":"monitor-detail","slug":"monitor-detail","title":"Monitor Detail Page","description":"KPIs, response time chart, incident history, escalation policy, and recent checks for a single monitor, all on one screen.","body":"# Monitor Detail Page\n\nThe monitor detail page is a **report card** for a single monitor. Click any monitor in the sidebar to open it. The top has a KPI bar, the middle a tab navigation with content cards, and the bottom hosts incident history and recent checks. To edit the monitor, use the **Settings** tab in the tab bar.\n\n## Top KPI bar\n\nThe top KPI bar shows **5 metrics**:\n\n| Metric | Meaning |\n|---|---|\n| **Current Status** | Latest check result, `UP`, `DOWN`, or `UNKNOWN` |\n| **Uptime** | Percentage of successful checks in the selected period |\n| **Avg Response** | Mean response time across successful checks (ms). *For heartbeat monitors this cell shows **Last Ping** instead.* |\n| **Latest Check** | Most recent response time (ms). *For heartbeats it shows **Interval** in minutes.* |\n| **SSL Days Left** | Days remaining on the certificate. *This cell only renders for certificate-bearing monitor types (HTTP, SSL, WebSocket, gRPC); for ping / TCP / UDP / DNS / heartbeat monitors the KPI bar collapses to 4 columns.* |\n\nUptime and response time are displayed with **one decimal** of precision (`100.0` → `100`, `99.7` → `99.7`).\n\n> **Back behaviour:** the **Back** button at the top returns you to **the view you came from**, e.g. a group-filtered monitors list (filters live in the URL, so they're restored), rather than always resetting to the dashboard. Opening the page from a direct link falls back to the dashboard.\n\nBelow the KPI bar, a thin info bar shows the last-checked time and, where applicable, SSL and domain expiry dates.\n\n> **Team-shared badge:** when the monitor was shared with you via a team, a **\"Team shared · read only / can edit\"** badge appears next to the title. Its tooltip states an important rule: plan-gated panels (AI insights, SSL analysis, SLO…) follow the **owner's subscription**, not yours. If a feature that works on your own monitors looks locked here, that's why.\n\n## Tab navigation\n\nBelow the KPI bar there are 4 tabs:\n\n- **Overview**: KPI summary (status, uptime, response time, SSL), response-time chart, a domain-registration strip when available, and the SLO / Incidents / MTTR cards\n- **Events & Incidents**: incidents opened on this monitor and the status-change timeline\n- **Context**: service context (environment / team / service / tier) and tags, dependencies, a mini service map, the detected stack, type-specific configuration cards (consensus / heartbeat ping / DNS), and the escalation-policy details\n- **Settings**: only visible for users with edit permission (shortcut to the form)\n\n> **Context-carrying outbound links:** the **\"Related\" strip** directly under the tab bar is visible on every tab and carries the monitor context to the target page (via the `?monitor=` parameter): **Security headers** narrows the analysis list to this monitor, **SSL health** opens this monitor's certificate detail directly on the SSL page, **Service map** focuses the map on this monitor, and **Maintenance** goes to maintenance windows. A visible chip on the target page clears the filter with one click.\n\n## Escalation policy chip\n\nWhen a monitor has an escalation policy assigned, a separate card on the **Context** tab shows **\"Escalation policy: {name}\"** with a \"Change\" link beside it that routes to the monitor edit form. If the policy ID does not match an existing policy, the card is not shown.\n\n## Heartbeat-specific KPIs\n\nFor heartbeat monitors, the KPI bar swaps two cells automatically:\n\n- **Avg Response** is replaced by **Last Ping** (HH:MM)\n- **Latest Check** is replaced by **Interval** (in minutes)\n\nThis keeps the telemetry contextually correct, heartbeat monitors have no average latency, only ping time.\n\n## Response time chart\n\nOn the Overview tab, the line chart plots response times across the selected period. Down checks are highlighted, and maintenance windows (if any) are shaded.\n\n## Incident list\n\nThe Events & Incidents tab lists every incident opened on this monitor, newest first. Each row shows the alarm type, the start time, and a status badge. (Mean time to repair, MTTR, is summarized separately as an aggregate metric on the Overview tab.) Clicking an incident opens its detail page where root-cause notes, the affected monitors (for grouped alerts), and the updates timeline live.\n\n## Alert Consensus card\n\nThe **Context** tab includes an **Alert Consensus** card that shows the monitor's primary region, verification regions, and the minimum number of regions that must agree before opening an incident (displayed as an `N / total` threshold badge). This card only appears for monitors configured with two or more distinct regions; single-region monitors do not show it.\n\n## Heartbeat ping card\n\nFor heartbeat monitors, this card on the **Context** tab shows the ping URL, the configured interval and grace (e.g. `every 300s · grace 60s`), and when the last ping was received. Copy the URL into a cron job or CI script, ready-made curl, cron, and Docker recipes are included, and the ping endpoint is rate-limited to 60 pings/minute per token.\n\n## DNS configuration card\n\nFor DNS monitors, this card on the **Context** tab shows the query name, record type, and expected answers.\n\n## Editing the monitor\n\nTo change a monitor's configuration, open the **Settings** tab (visible to users with edit permission). It opens the monitor form, where you can update the URL, interval, thresholds, notification preferences, and more.\n\nPause, resume, and delete are performed from the monitors list rather than this page; those actions are recorded in the audit log.\n\n## Domain WHOIS card\n\nWhen domain monitoring is on, WHOIS data appears as a single-line strip on the Overview tab: domain · registrar · expiry. The strip only renders after the WHOIS lookup resolves. The days-remaining figure turns red below 30 days and amber below 90.\n\n## Related monitors\n\nThe Overview tab lists the monitors linked to this one, on every plan, each with the reasons: outages that started together (\"Went down together 8 times in 30 days\"), the same server address, the same registered domain or CDN, and the links and dependencies you added. When two monitors keep going down together and no dependency is recorded between them, the card asks \"Mark as a dependency?\" and lets you pick the direction, keep them as related without a dependency, or mark them as not related. Nothing is recorded until you choose. The full picture is on the [Service Map](/docs/service-map).\n\n## Related topics\n\n- [Monitor Settings](/docs/monitor-settings)\n- [Regional Monitoring](/docs/regional-monitoring)\n- [Incident Analytics](/docs/incident-analytics)\n- [Multi-Location Consensus](/docs/multi-location-consensus)\n- [Maintenance Windows](/docs/maintenance-windows)\n- [Postmortem Workflow](/docs/postmortem-workflow)","category":"monitors","tags":["monitor","detail","kpi","dashboard"],"order":30,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Monitor Detail. UptimeWarden Documentation","metaDescription":"Monitor detail page: KPI bar, Overview / Events & Incidents / Context / Settings tabs, and escalation policy card.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.668Z","updatedAt":"2026-10-12T22:06:41.668Z","publishedAt":"2026-10-12T22:06:41.668Z"},{"publicId":"dae0fb0848d64a05a6e2b7bb3e","locale":"en","translationGroup":"heartbeat-monitor","slug":"en-heartbeat-monitor","title":"Heartbeat Monitor","description":"Monitor cron jobs, background workers, and scheduled tasks by having them ping UptimeWarden instead of the other way around.","body":"# Heartbeat Monitor\n\nA heartbeat monitor inverts the usual direction: UptimeWarden doesn't reach out to your service, **your service reaches out to UptimeWarden**. Cron jobs, periodic workers, and backup scripts send a small \"I'm alive\" ping after each successful run. If the ping doesn't arrive in time, UptimeWarden alarms.\n\nClassic monitors \"push\" (UptimeWarden pings the target); heartbeat monitors \"pull\" (target pings UptimeWarden). Perfect for systems behind firewalls, in isolated networks, or on periodic schedules that a pull-based check can't observe.\n\n## When to use\n\n- **Nightly backup**: A cron at 02:00 runs `pg_dump`. You want to know if it didn't run, but you don't want to expose the backup server to the internet.\n- **Weekly reports**: A Jenkins job generates a Monday-morning report at 09:00. If Monday's late, you want to hear about it.\n- **Queue workers**: A worker pings every 5 minutes; if it stops, you alert 10 minutes later.\n- **Air-gapped systems**: Isolated servers with outbound HTTPS only — heartbeats fit; inbound HTTP checks don't.\n\n## Creating a monitor\n\n1. **Monitors → New Monitor** → Type: `Heartbeat`\n2. Settings:\n\n   - **Name**: e.g. `Nightly Backup — Postgres`\n   - **Interval (seconds)**: Expected ping cadence (e.g. 86400 = 24 hours for a daily backup)\n   - **Grace period (seconds)**: Lateness tolerance (e.g. 600 = 10 min). Monitor goes down if no ping arrives within `interval + grace`.\n\n3. **Save** — UptimeWarden gives you a unique ping URL:\n\n```\nhttps://app.uptimewarden.online/api/heartbeat/<token>/ping\n```\n\n4. Append this URL to your cron script.\n\n## Sending pings\n\n### curl (most common)\n```bash\n# crontab line\n0 2 * * * /usr/local/bin/backup.sh && curl -fsS https://app.uptimewarden.online/api/heartbeat/TOKEN/ping\n```\n\nThe `&&` ensures the ping fires only if the backup exits successfully. If the backup fails, no ping goes out — and the monitor alarms when the grace period expires.\n\n### Python\n```python\nimport requests\nrequests.post(\"https://app.uptimewarden.online/api/heartbeat/TOKEN/ping\", timeout=5)\n```\n\n### Node.js\n```js\nawait fetch(\"https://app.uptimewarden.online/api/heartbeat/TOKEN/ping\", { method: \"POST\" });\n```\n\n### Bash wrapper (start + end)\nFor long-running jobs, ping at start and end:\n\n```bash\n#!/bin/bash\nHB_URL=\"https://app.uptimewarden.online/api/heartbeat/TOKEN/ping\"\n\n# notify start\ncurl -fsS \"$HB_URL?event=start\" >/dev/null 2>&1\n\n# the real work\n./run-backup.sh\nEXIT=$?\n\n# success or fail ping\nif [ $EXIT -eq 0 ]; then\n  curl -fsS \"$HB_URL\" >/dev/null 2>&1\nelse\n  curl -fsS \"$HB_URL?event=fail\" >/dev/null 2>&1\nfi\nexit $EXIT\n```\n\n## How to pick a grace period\n\n| Scenario | Interval | Grace |\n|---|---|---|\n| Nightly backup (02:00) | 86400 (24h) | 3600 (1h) — backups can drift an hour |\n| Worker every 5 min | 300 | 120 (2 min) — fast alarm |\n| Weekly report | 604800 (7d) | 86400 (1d) — Monday can slip |\n| Per-minute health ping | 60 | 30 |\n\nRule of thumb: **grace = interval × 20–50%**. Too small and network latency produces false alarms; too large and you hear about real problems slowly.\n\n## Rate limiting\n\nThe heartbeat endpoint is rate-limited to **60 requests per minute per token**. Normal cron usage stays well below this — but a misconfigured worker pinging every second gets 429'd so you don't DoS yourself.\n\n## What happens when you pause the monitor?\n\nPause → the system stops expecting pings → no alarms.\n\nWhen you unpause, the last-ping timestamp is refreshed; the grace period starts counting from that moment. Pings received during the paused window aren't \"saved\" — they're just not alarmed against.\n\n## Security\n\n- **Unguessable token**: 26-char ULID, closed to brute-force.\n- **HTTPS enforced**: HTTP pings are rejected (MITM protection).\n- **Log-only storage**: We don't record the ping body — just the timestamp. Secrets accidentally leaked into the URL don't land in our logs.\n- **Token rotation**: If your token leaks, rotate it from the monitor detail page; the old URL becomes invalid immediately.\n\n## Compared to HTTP monitor\n\n| Scenario | HTTP Monitor | Heartbeat Monitor |\n|---|---|---|\n| Is a website / API up? | ✅ | ❌ |\n| Did the cron job finish? | ❌ | ✅ |\n| Is the background worker alive? | ❌ | ✅ |\n| System behind a firewall | ❌ | ✅ |\n| Periodic report generated? | ❌ | ✅ |\n\n## FAQ\n\n**Q: My script occasionally runs late and I get false alarms.**\nA: Increase the grace period. Alternatively, move the ping to the start of the script (\"started\") — but that doesn't prove \"finished successfully.\"\n\n**Q: Can I use HTTP Basic Auth on the endpoint?**\nA: The heartbeat endpoint is anonymous — the token *is* the auth. No extra layer is needed, and secrets in cron are a pain to manage anyway.\n\n**Q: GET or POST?**\nA: Both accepted. POST is semantically correct (there's a side effect — it resets the timer) but practically equivalent.\n\n## Related topics\n\n- [Other Monitor Types](/docs/en-other-monitor-types)\n- [Notification Channels](/docs/en-notification-channels)\n- [On-Call & Escalation](/docs/en-escalation-policies) — route heartbeat alarms to an on-call rotation","category":"monitors","tags":["heartbeat","cron","background-jobs","push"],"order":31,"parentSlug":"monitors","published":true,"version":2,"metaTitle":"Heartbeat Monitor — UptimeWarden Documentation","metaDescription":"Detect silently-failing cron jobs — your job pings UptimeWarden on success, UptimeWarden alerts when the ping stops.","icon":"Monitor","createdAt":"2026-04-19T00:06:52.889Z","updatedAt":"2026-04-19T00:16:16.629Z","publishedAt":"2026-04-19T00:06:52.889Z"},{"publicId":"01M4S2EP27J8WG3SKCPGDSKJQR","locale":"en","translationGroup":"heartbeat-monitor","slug":"heartbeat-monitor","title":"Heartbeat Monitor","description":"Monitor cron jobs, background workers, and scheduled tasks by having them ping UptimeWarden instead of the other way around.","body":"# Heartbeat Monitor\n\nA heartbeat monitor inverts the usual direction: UptimeWarden does not reach out to your service, **your service reaches out to UptimeWarden**. Cron jobs, periodic workers, and backup scripts send a small \"I'm alive\" ping after each successful run. If the ping does not arrive in time, UptimeWarden alarms.\n\nClassic monitors push their checks (UptimeWarden contacts the target); heartbeat monitors pull (the target contacts UptimeWarden). They are perfect for systems behind firewalls, in isolated networks, or on periodic schedules that an outbound check cannot observe.\n\n## How the flow works\n\nThe heartbeat loop ties three actors together: your cron, the UptimeWarden ping endpoint, and a grace timer. When a ping does not arrive, the timer expires and an incident opens.\n\n```mermaid\nsequenceDiagram\n    autonumber\n    participant Cron as Cron / Worker\n    participant API as UptimeWarden Ping API\n    participant Timer as Grace Timer\n    participant Alert as Alert Pipeline\n\n    Cron->>API: POST /heartbeat/<token>/ping\n    API-->>Timer: reset(now + interval + grace)\n    Note over Timer: waits for the next ping\n    Cron-->>API: (ping skipped, script failed)\n    Timer->>Alert: timer expired → incident \"down\"\n    Alert-->>Cron: email / SMS / on-call rotation\n```\n\n## When to use\n\n- **Nightly backup**: A cron at 02:00 runs `pg_dump`. You want to know if it did not run, but you do not want to expose the backup server to the internet.\n- **Weekly reports**: A scheduled job generates a Monday-morning report at 09:00. If Monday is late, you want to hear about it.\n- **Queue workers**: A worker pings every 5 minutes; if it stops, you alert 10 minutes later.\n- **Air-gapped systems**: Isolated servers with outbound HTTPS only: heartbeats fit; inbound checks do not.\n\n## Creating a monitor\n\n1. **Monitors → New Monitor** → Type: `Heartbeat`\n2. Settings:\n\n   - **Name**: e.g. `Nightly Backup - Postgres`\n   - **Interval (seconds)**: Expected ping cadence (e.g. 86400 = 24 hours for a daily backup)\n   - **Grace period (seconds)**: Lateness tolerance (e.g. 600 = 10 minutes). The monitor goes down if no ping arrives within `interval + grace`.\n\n3. **Save**. UptimeWarden gives you a unique ping URL. **The create confirmation screen shows the URL and a ready-to-paste curl command**, copy it right away. If you lose it, you can view it again on the monitor detail page (Configure tab).\n\n```\nhttps://app.uptimewarden.online/api/heartbeat/<token>/ping\n```\n\n4. Append this URL to your cron script.\n\n## Sending pings\n\n### curl (most common)\n```bash\n# crontab line\n0 2 * * * /usr/local/bin/backup.sh && curl -fsS https://app.uptimewarden.online/api/heartbeat/TOKEN/ping\n```\n\nThe `&&` ensures the ping fires only if the backup exits successfully. If the backup fails, no ping goes out, and the monitor alarms when the grace period expires.\n\n### Python\n```python\nimport requests\nrequests.post(\"https://app.uptimewarden.online/api/heartbeat/TOKEN/ping\", timeout=5)\n```\n\n### Node.js\n```js\nawait fetch(\"https://app.uptimewarden.online/api/heartbeat/TOKEN/ping\", { method: \"POST\" });\n```\n\n### Bash wrapper (ping on success only)\nFor long-running jobs, wrap the work and ping **only when it finishes successfully**. The endpoint ignores any query string (such as `?event=...`), every request with a matching token resets the timer. There is therefore no \"failure\" ping: *not* pinging on failure is what triggers the alarm.\n\n```bash\n#!/bin/bash\nHB_URL=\"https://app.uptimewarden.online/api/heartbeat/TOKEN/ping\"\n\n# the real work\n./run-backup.sh\nEXIT=$?\n\n# ping only on success; skip the ping on failure → alarm when grace expires\nif [ $EXIT -eq 0 ]; then\n  curl -fsS \"$HB_URL\" >/dev/null 2>&1\nfi\nexit $EXIT\n```\n\nA successful ping returns `204 No Content`.\n\n## How to pick a grace period\n\n| Scenario | Interval | Grace |\n|---|---|---|\n| Nightly backup (02:00) | 86400 (24h) | 3600 (1h), backups can drift an hour |\n| Worker every 5 min | 300 | 120 (2 min), fast alarm |\n| Weekly report | 604800 (7d) | 86400 (1d). Monday can slip |\n| Per-minute health ping | 60 | 30 |\n\nRule of thumb: **grace = interval × 20-50%**. Too small and network latency produces false alarms; too large and you hear about real problems slowly.\n\n## Rate limiting\n\nThe heartbeat endpoint accepts up to **60 requests per minute per token**. Normal cron usage stays well below this, but a misconfigured worker pinging every second is rate-limited so it does not flood your account.\n\n## What happens when you pause the monitor?\n\nPause → the system stops expecting pings → no alarms.\n\nWhen you unpause, the last-ping timestamp is refreshed; the grace period starts counting from that moment. Pings received during the paused window are not \"saved\", they are just not alarmed against.\n\n## Security\n\n- **Unguessable token**: A long random token, closed to brute-force. Any unknown or malformed token returns the same `404`, which never reveals whether a token exists.\n- **HTTPS end-to-end**: HSTS is enforced platform-wide, so browsers and clients upgrade the connection to HTTPS. Always send the ping over `https://`.\n- **Timestamp-only storage**: We do not record the ping body: just the timestamp. Secrets accidentally leaked into the URL do not land in our logs.\n\n## Compared to HTTP monitor\n\n| Scenario | HTTP Monitor | Heartbeat Monitor |\n|---|---|---|\n| Is a website / API up? | Yes | No |\n| Did the cron job finish? | No | Yes |\n| Is the background worker alive? | No | Yes |\n| System behind a firewall | No | Yes |\n| Periodic report generated? | No | Yes |\n\n## FAQ\n\n**Q: My script occasionally runs late and I get false alarms.**\nA: Increase the grace period. Alternatively, move the ping to the start of the script (\"started\"), but that does not prove \"finished successfully.\"\n\n**Q: Can I use HTTP Basic Auth on the endpoint?**\nA: The heartbeat endpoint is anonymous, the token *is* the authentication. No extra layer is needed, and secrets in cron are a pain to manage anyway.\n\n**Q: GET or POST?**\nA: Both are accepted. POST is semantically correct (there is a side effect, it resets the timer) but practically equivalent.\n\n## Related topics\n\n- [Other Monitor Types](/docs/other-monitor-types)\n- [Notification Channels](/docs/notification-channels)\n- [On-Call & Escalation](/docs/escalation-policies): route heartbeat alarms to an on-call rotation","category":"monitors","tags":["heartbeat","cron","background-jobs","push"],"order":31,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Heartbeat Monitor. UptimeWarden Documentation","metaDescription":"Detect silently-failing cron jobs, your job pings UptimeWarden on success and UptimeWarden alerts when the ping stops.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.735Z","updatedAt":"2026-10-12T22:06:41.735Z","publishedAt":"2026-10-12T22:06:41.735Z"},{"publicId":"01M4S2ENZV1V9QW2RWQ1WNFQSN","locale":"en","translationGroup":"monitor-settings","slug":"monitor-settings","title":"Monitor Settings","description":"Reference for every field on the monitor form. Essentials (type / target / interval / name) and Advanced (channels / region / consensus / maintenance / escalation / tags / visibility).","body":"# Monitor Settings\n\nThe monitor form lets you configure everything about a single monitor in one place. The form is split into **two sections**:\n\n- **Essentials**: type, connection (URL / host / port), interval, name\n- **Advanced settings**: notification channels, region, consensus, maintenance windows, escalation policy, tags, and public visibility\n\nMost fields are optional, for most monitors, type + URL + interval is all you need. The rest are advanced features hidden under the Advanced section.\n\n## Essentials\n\n### Type\n\nThe top of the form renders 10 monitor types as cards; the selection drives the connection input below.\n\n| Type | Connection input |\n|---|---|\n| Website & API | URL (`https://...`) |\n| SSL Certificate | Domain URL |\n| Port & Service (TCP) | Hostname + port |\n| UDP Service | Hostname + port |\n| Server Ping | Hostname / IP |\n| WebSocket | URL (`ws://` / `wss://`) |\n| gRPC Service | Hostname + port |\n| AI Model Protocol (MCP) | URL |\n| DNS Resolution | Query name + record type |\n| Cron & Background Jobs | Token + interval |\n\n### Name\n\nDisplay name. The sidebar, dashboard, incident emails, and status page all use it. If you leave it blank, the form derives a name from the connection.\n\n**Good**: `prod-api - health endpoint`\n**Bad**: `monitor 14`\n\n### Connection\n\nVaries by type:\n\n- **URL** field for HTTP, SSL, MCP, and WebSocket\n- **Hostname + port** for TCP, UDP, and gRPC\n- **Hostname / IP** for Ping\n- **Query name + record type + optional resolver + expected answers** for DNS\n- **Heartbeat interval + grace** for Heartbeat (the token is generated on save)\n\n### Check Interval\n\nSeconds between checks. The per-plan minimum depends on your plan, and the form locks faster intervals behind an \"upgrade\" prompt. See the [pricing page](https://uptimewarden.online/pricing) for current plan limits.\n\n### Timeout\n\nMaximum wait for a response, in seconds. Past this, the check is `down`. Default 30s (min 5, max 300).\n\n### Retry count\n\nExtra attempts before declaring down. Filters transient network noise. Default 2.\n\n## Advanced. Region & Agent\n\n### Region\n\nWhich UptimeWarden region checks this monitor. Available regions cover Sydney, São Paulo, Sweden Central, East Asia, and Phoenix. Empty = global pool.\n\n> Pick the region closest to your customers, that's the latency they actually experience.\n\n### Custom Agent\n\nIf you run an agent in your own infrastructure, you can bind this monitor to it. This is the only way to reach private-network endpoints. See [Agent Management](/docs/agent-management).\n\n### Verification regions and minimum agreement\n\n**Multi-location consensus** controls how many regions must see a failure for the alert to count as confirmed. A failure that most regions can reach is held; anything else is still sent, labelled unverified. The minimum number of agreeing regions defaults to 2 (range 1-6); the upper bound is set by your plan's verification region limit.\n\nSee [Multi-Location Consensus](/docs/multi-location-consensus).\n\n## Advanced. Notification settings\n\n### Email / SMS / WhatsApp / Voice / Push / Webhook\n\nEach channel has a **toggle plus recipient list**. The recipient input appears only when the channel is on.\n\n```\nemailAddresses:    ops@example.com, oncall@example.com\nphoneNumbers:      +15551234567\nwhatsappNumbers:   +15557654321\nvoiceNumbers:      +15550001122\n```\n\nPush notifications use the user's enrolled devices automatically, there is no separate list.\n\n### Webhook configurations\n\nWebhooks are **not inline URLs**, they reference reusable configurations you create separately. The webhook channel selector lists existing configurations and supports multi-select. Slack, Microsoft Teams, Discord, custom URL, each is a configuration you tag onto monitors.\n\n### Notifications matrix (channel × alert)\n\nEach channel can be configured per alert type:\n\n| Channel | down | recovery | ssl | ssl_recovery | high_response | high_response_recovery | domain_expiring | domain_expiring_recovery |\n|---|---|---|---|---|---|---|---|---|\n| Email | On | On | On | On | On | On | On | On |\n| SMS | On | Off | Off | Off | Off | Off | Off | Off |\n| Slack (webhook) | On | On | On | On | On | On | Off | Off |\n\n(Illustrative. Defaults: email all on, every other channel all off.) See [Notification Channels](/docs/notification-channels).\n\n### Escalation Policy\n\nFor tiered alerting, choose an escalation policy. With no policy assigned, the channel/alert matrix above runs. With a policy, escalation moves between tiers based on acknowledgement timeouts.\n\nSee [Escalation Policies](/docs/escalation-policies).\n\n## Advanced. HTTP-specific fields\n\n- **Method / Headers / Body**: the request flips to POST automatically when a body is set (see [HTTP Monitor](/docs/http-monitor))\n- **Expected status codes**: comma-separated list (default `200`)\n- **Content validation**: text, regex, JSON, or XML, with a case-sensitivity toggle\n- **Basic auth / Bearer token**: credential fields are stored and hidden from shared / read-only responses\n- **Response time threshold** (ms): fires a high response time alert when exceeded on N checks in a row (default 3, the same N that confirms a recovery)\n- **Verify SSL / Follow Redirects**: both should stay on for production\n- **SSL Alerts**: 30-day, 15-day, 7-day, and 1-day toggles\n- **Domain Monitoring**: domain registration expiry tracking (on every plan; the number of domains you can track depends on the plan)\n\n## Maintenance windows\n\nPlanned maintenance, down checks during a window **do not open incidents** and the time is excluded from uptime calculations. Each window can last at most 4 hours, and a monitor can have up to 20 windows.\n\n### Recurring (editable on the form)\n\n```\ntype: \"recurring\"\nday: \"monday\"\nstart: \"02:00\"\nend: \"04:00\"\ntimezone: \"America/Los_Angeles\"\n```\n\n### One-time (read-only chip)\n\nOne-time windows render as read-only chips on the form. Creation happens via API or the mobile app; the form keeps them when you save, but you cannot add them through the UI today.\n\n```\ntype: \"once\"\nstart: \"2026-05-15T12:00:00Z\"\nend: \"2026-05-15T14:00:00Z\"\n```\n\nSee [Maintenance Windows](/docs/maintenance-windows).\n\n## Tags and public visibility\n\n### Tags\n\nFree-form labels, `prod`, `customer-facing`, `payments`, `eu-only`. Used to filter the monitor list, scope status pages, and scope API tokens.\n\n### Public visibility\n\nAttach the monitor to a status page; up/down state shows publicly under a friendly label (\"Payments API\"); the real URL and internal name stay hidden.\n\n## Monitoring as Code\n\nMonitors created via CLI or Terraform carry a source field (`manual`, `cli`, `terraform`, or `api`) and an optional external ID for drift detection. Monitors created in the UI start with `manual`.\n\nSee [Monitoring as Code](/docs/developers-monitoring-as-code).\n\n## FAQ\n\n**Q: To check the same monitor from multiple regions, do I need one monitor per region?**\nA: No, verification regions let one monitor be checked from many regions.\n\n**Q: Do new settings apply retroactively to past incidents?**\nA: No, they only affect checks from the moment you save.\n\n**Q: Are secrets in custom headers safe?**\nA: Header values are stored and hidden from shared / read-only monitor responses. For the strongest safety we still recommend using short-lived or narrowly-scoped tokens.\n\n## Related topics\n\n- [HTTP Monitor](/docs/http-monitor) · [SSL Monitor](/docs/ssl-monitor)\n- [Regional Monitoring](/docs/regional-monitoring)\n- [Multi-Location Consensus](/docs/multi-location-consensus)\n- [Notification Channels](/docs/notification-channels)\n- [Escalation Policies](/docs/escalation-policies)\n- [Maintenance Windows](/docs/maintenance-windows)\n- [Monitor Detail](/docs/monitor-detail)","category":"monitors","tags":["monitor","settings","configuration","form"],"order":40,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Monitor Settings. UptimeWarden Documentation","metaDescription":"Every field on the monitor create / edit form explained: type, interval, region, consensus, escalation, maintenance windows, tags, and public visibility.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.660Z","updatedAt":"2026-10-12T22:06:41.660Z","publishedAt":"2026-10-12T22:06:41.660Z"},{"publicId":"01M4S2EPAYB6EJR73SBK00X76F","locale":"en","translationGroup":"slo-error-budgets","slug":"slo-error-budgets","title":"SLOs and Error Budgets","description":"Set an availability target, spend an error budget, and page only on burn rates that actually matter. Google SRE-style multi-window alerting, built into every monitor.","body":"# SLOs and Error Budgets\n\nYou set a target: \"this service is up 99.9% of the time.\" That target carries a budget, over a 30-day window, you're allowed **43 minutes and 12 seconds of downtime**. Everything above that is outage; everything below is breathing room to ship changes.\n\nThe useful question isn't \"did a check fail?\" It's \"at the current rate, will we blow the budget?\" UptimeWarden's SLO engine answers that, and only pages when the answer is \"yes, and fast.\"\n\n## What you get\n\n- **Availability SLO** per monitor: any number you like: 99, 99.5, 99.9, 99.95, 99.99.\n- **Latency SLO (optional)**: \"% of checks under N ms.\" Catches degradation that uptime alone hides.\n- **Error-budget snapshot**: a live \"budget remaining %\" gauge, refreshed every minute.\n- **Multi-window burn-rate alerts**: Google SRE's pattern: only page when both a short window and a long window confirm the budget is burning faster than allowed.\n- **Flapping suppression**: if the monitor is bouncing up and down, burn-rate alerts pause until it stabilises.\n\nSLO tracking is off by default. You enable it per monitor.\n\n## Enabling SLO tracking\n\n1. Open the monitor → **Settings** → **SLO Configuration** panel.\n2. Toggle **Enable SLO tracking**.\n3. Fill in:\n   - **Target**: e.g. `99.9` (availability percentage)\n   - **Window**: 7, 14, 30, or 90 days\n   - **Latency target (optional)**: P99 threshold in ms: leave empty to skip\n   - **Flapping threshold**: how many state changes in a 30-minute window before the monitor is treated as flapping (default 5)\n4. Save. UptimeWarden picks it up within a minute and starts publishing budget snapshots.\n\n## Reading the budget gauge\n\nOnce a few checks have run the panel shows:\n\n| Field | Meaning |\n|---|---|\n| **Availability %** | Successful checks divided by total checks in the window. Three decimals (e.g. `99.950`). |\n| **Budget total** | Allowed downtime minutes for the window: `window_minutes × (1 - target/100)`. |\n| **Budget consumed** | Downtime minutes already used. |\n| **Budget remaining %** | `100` = full, `0` = exhausted. The donut gauge is green above 50%, amber 20-50%, red under 20%. |\n| **Current burn rate** | `consumed / nominal`. `1.0` means you're burning exactly at budget; `5.0` means you'll exhaust it 5× faster than planned. |\n| **Excluded minutes** | Maintenance-window time inside the SLO window, left out of the SLO (see below). `0` when the monitor had no window in the period. |\n\n**Worked example**. 30-day window, target 99.9%:\n\n```\nAllowed downtime  = 30 × 24 × 60 × (1 - 0.999) = 43.2 minutes\nAfter 7 days      = 20 minutes consumed\nBudget remaining  = (43.2 - 20) / 43.2 = 53.7%\nBurn rate         = 20 / 43.2 = 0.463  → below nominal, you're fine\n```\n\nIf that same 20 minutes had burned in the first 24 hours, the burn rate would be 13.9× and you'd already have both alerts firing.\n\n## Maintenance windows are left out\n\nPlanned maintenance does not spend the error budget. For a monitor with [maintenance windows](/docs/maintenance-windows):\n\n- **Checks inside a window are not counted**, neither as successes nor as failures. Availability is measured over the remaining checks.\n- **Excluded minutes** is the maintenance time inside the SLO window. Overlapping windows are merged first, so no minute is counted twice.\n- **The budget is sized on the time that is left**: `(window_minutes - excluded_minutes) × (1 - target/100)`. Budget consumed is measured on the same base.\n- **Burn-rate alerts** leave the same checks out, so a planned outage does not page on burn rate either.\n\n**Worked example**. 30-day window, target 99.9%, a weekly 3-hour window (12 hours of maintenance in the period):\n\n```\nMeasured time     = 43,200 - 720 = 42,480 minutes\nAllowed downtime  = 42,480 × (1 - 0.999) = 42.48 minutes\n```\n\nThe rule uses the windows configured **when the snapshot is computed**, not a history of past windows. Editing a recurring window changes the exclusion for the whole rolling window. Closing a one-off window early deletes it, so its minutes stop being excluded and any failures during it count against the budget again. Deleting a window can only make the SLO stricter, never kinder.\n\nThe SLO is the only place maintenance is excluded. Dashboard uptime, the public status page uptime and the uptime report still count every check, so they can show lower availability than the SLO for the same monitor.\n\n## Multi-window burn-rate alerts\n\nA single burn-rate threshold is noisy: a 5-minute blip with a 20× burn rate is usually recoverable, not an outage. The Google SRE answer, and what UptimeWarden ships, is two windows that must both be burning.\n\n| Severity | Short window | Long window | Threshold | Why |\n|---|---|---|---|---|\n| **Fast (critical)** | 5 min | 1 hour | 14.4× | Severe event right now, page immediately |\n| **Slow (warning)** | 6 hours | 3 days | 1× | Slower burn that will still exhaust the budget |\n\nA `fast` alert fires when the **5-minute window is 14.4×+** over nominal **and** the **1-hour window confirms** (≥ 1×). This catches acute outages without firing on brief single-window spikes.\n\nA `slow` alert fires when the **6-hour window is at or above nominal** and the **3-day window confirms**. This catches slow-motion degradation, the \"death by a thousand cuts\" pattern where every individual check looks fine but the monthly budget is quietly draining.\n\nBoth alerts have a **1-hour cooldown per monitor per severity**, you won't get re-paged for the same burn event.\n\nThese are the windows and thresholds recommended by the Google SRE Workbook, implemented as-shipped.\n\n## Flapping suppression\n\nIf a monitor changes state more than the **flapping threshold** times in 30 minutes, UptimeWarden flags it as flapping and **suppresses burn-rate incident creation** until it settles. Budget snapshots still update, so you can see the burn in the UI, but you won't be woken up for a monitor that's already drawing attention to itself.\n\n**The default threshold scales with your check interval.** A raw count of state\nchanges is not comparable across monitors: a 10-second monitor runs 180 checks in\na 30-minute window, a 5-minute monitor runs 6. A flat \"5\" would mean 2.8% of\nchecks for the first (ordinary jitter) and 83% for the second (it would have to\nfail on nearly every check before we noticed).\n\nSo when you leave the threshold at its default, UptimeWarden derives it from the\ninterval at a constant rate, roughly 8% of the checks in the window, with a\nfloor of 3 and a ceiling of 20:\n\n| Check interval | Checks per 30 min | Default threshold |\n|---|---|---|\n| 10 seconds | 180 | 15 |\n| 30 seconds | 60 | 5 |\n| 1 minute | 30 | 3 |\n| 5 minutes | 6 | 3 (floor) |\n\n**If you set the threshold yourself, that number is used exactly as you typed\nit**, we never adapt a value a human chose. Setting it to `0` turns flapping\ndetection off for that monitor and it stays off.\n\nTune per monitor in the SLO panel.\n\n## Seeing that a monitor is being suppressed\n\nSuppression used to be invisible: alerts simply stopped. There was no way to\ntell a genuinely quiet monitor from one that had gone quiet *because* it was\nflapping.\n\nA suppressed monitor now reports it on the monitor API and in the dashboard:\n\n```json\n{\n  \"name\": \"checkout-api\",\n  \"isFlapping\": true,\n  \"flappingReason\": \"Repeated TLS handshake failures - consistent with a certificate rotation on the origin\"\n}\n```\n\n- **`isFlapping`**, `true` while UptimeWarden is holding back incidents for this\n  monitor. It clears on its own once the monitor settles; there is nothing to\n  reset.\n- **`flappingReason`**, a short explanation of *why*, generated from the\n  distinct failure messages the oscillation produced. Available on\n  **Professional** and **Enterprise** plans; it does not use your AI credits.\n\n`flappingReason` is often absent, and that is normal. If the monitor produced no\nerror text, the plan does not include AI explanations, or there is simply\nnothing useful to say, you still get `isFlapping`, the\nfact that alerts are paused, which is the actionable part. We would rather return\nnothing than a confident-sounding guess.\n\nThe dashboard's reliability panel prefers real suppression state over an\nincident count, because suppression is precisely what stops incidents being\ncreated, the monitors that flap hardest produce the fewest incidents.\n\n## Wiring alert policies\n\nSLO burn-rate events use the standard UptimeWarden notification pipeline. You don't need a special channel.\n\n1. **Assign a notification policy** to the monitor, the same escalation policy / on-call rotation you use for regular incidents.\n2. The burn-rate alert is emitted with a `severity` of either `critical` (fast) or `warning` (slow). Your escalation policy tiers can branch on severity: e.g. `critical` goes to phone + SMS, `warning` goes to Slack only.\n3. Maintenance windows suppress regular incident notifications, and checks inside them are left out of the budget and of the burn-rate windows (see [Maintenance windows are left out](#maintenance-windows-are-left-out)).\n\nSee also [Escalation Policies](/docs/escalation-policies) for the full on-call wiring and [Maintenance Windows](/docs/maintenance-windows) for suppression rules.\n\n## Choosing a target\n\nThe cheap trap is picking 99.99% (four nines) because it sounds impressive. Don't.\n\n| Target | Monthly budget | Typical fit |\n|---|---|---|\n| **99%** | 7h 12m | Internal tools, side projects, generous margin, cheap to run |\n| **99.5%** | 3h 36m | Early-stage product, nights-off on-call |\n| **99.9%** | 43m | Standard web services with a real on-call rotation |\n| **99.95%** | 21m | B2B SaaS with uptime clauses |\n| **99.99%** | 4m 19s | Payment infrastructure, real-time APIs, you'll need redundancy at every layer |\n\nA target that's too tight means every routine deploy eats budget and the burn-rate alerts scream constantly. A target that's too loose and you're not actually protecting users. Pick the one that matches the promise you've already made to your customers.\n\n## Plan availability\n\nSLO tracking is part of **Professional and Enterprise** plans. Free, Hobby, and Starter ship with the SLO surface (configuration panel, dashboard widget, compliance badge) hidden. If you negotiate a custom plan, your administrator can enable it per monitor. Upgrading from Starter to Professional flips it on and any SLO targets you already configured are honoured immediately, no reconfiguration needed.\n\n## FAQ\n\n**Does latency SLO replace availability SLO?**\nNo. They're independent. A monitor can have both, either, or neither. They are computed and stored separately.\n\n**How often are snapshots updated?**\nEvery minute. SLO-enabled monitors are processed in batch on a 1-minute cycle. Dashboard reads are served from the cached snapshot, never recalculated on the fly.\n\n**What counts as \"downtime\" for budget math?**\nEvery `down` check outside a maintenance window. Slow responses and certificate warnings are not downtime. Checks inside a maintenance window are left out entirely.\n\n**Can I export burn events?**\nThere is no separate \"burn events\" export today. When a burn-rate threshold trips, the alert is delivered through the standard notification stack and the resulting incident lands in your incident history. For historical burn-rate trending you can hit `GET /api/monitors/:id/slo/budget/history?days=N` for the per-minute snapshots.\n\n**What happens if the SLO engine is unavailable?**\nBurn-rate evaluation pauses and resumes automatically when service returns, no events are lost because the raw check data is the source of truth, not the snapshots.\n\n## Further reading\n\n- Google SRE Workbook: [Alerting on SLOs](https://sre.google/workbook/alerting-on-slos/), the canonical source for multi-window burn-rate thinking\n- [Maintenance Windows](/docs/maintenance-windows): how to set the windows the SLO leaves out\n- [Escalation Policies](/docs/escalation-policies): wiring burn-rate severity into on-call tiers","category":"monitors","tags":["slo","error-budget","burn-rate","sre","alerting"],"order":40,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"SLOs and Error Budgets. UptimeWarden Documentation","metaDescription":"Alert on error-budget burn rate, not every failed check. Multi-window burn-rate windows, thresholds, and how to wire alert policies.","icon":"Monitor","createdAt":"2026-10-12T22:06:42.014Z","updatedAt":"2026-10-12T22:06:42.014Z","publishedAt":"2026-10-12T22:06:42.014Z"},{"publicId":"01M4S2EP0TRXKK3YRZZ7FMNVBB","locale":"en","translationGroup":"groups","slug":"groups","title":"Monitor Groups","description":"Organise monitors into folders, run bulk actions, and view group-level uptime rollups on the Groups page.","body":"# Monitor Groups\n\nOnce you have a hundred monitors, the list turns into spaghetti. Groups split your monitors into logical folders, `Production`, `Staging`, `Customer-A`, `Payments`, `Internal Tools`, and keep the list manageable.\n\nGroups are **per-user**: each group lives under a single user and the name has to be unique within that user. A monitor can belong to more than one group, so groups can also act tag-like.\n\n## Where groups appear\n\n- **Monitors page**: the bulk-action toolbar exposes a \"Set group\" action.\n- **Groups page** (`/groups`), the list of groups with uptime rollups and a favourite toggle. Starred (favourite) groups sort to the top here.\n- **Group scope filter**: the group you pick on the dashboard carries into the Monitors list and the Incidents list. The selection lives in the URL (`?group=`), so a filtered view is shareable and bookmarkable; your last selection is also remembered and kept as you move between these pages. The filter renders as a visible chip and clears with one click.\n\nEach group stores a name, an optional description, and a colour.\n\n## Moving a monitor into a group\n\nTwo ways today:\n\n**Bulk action (Monitors page)**\n\n1. Tick one or more row checkboxes.\n2. From the sticky toolbar, pick **Set group**.\n3. Choose an existing group → confirm.\n\nThe selected monitors are **moved** into the chosen group, bulk \"Set group\" replaces any existing group memberships with the single group you pick. To keep a monitor in multiple groups, use the monitor form's `Group` field instead.\n\n**Monitor form**\nWhen you create or edit a monitor, the `Group` field offers the same assignment.\n\n> **Note:** a monitor can effectively sit in more than one group; the UI shows this as a \"Groups: a, b\" tooltip. The many-to-many shape is intentional, so groups can also act tag-like.\n\n## Bulk operations\n\nWhen you select rows on the Monitors page, the sticky toolbar exposes:\n\n| Action | What it does |\n|---|---|\n| **Pause** / **Resume** | Bulk-pause or resume the selection |\n| **Add tag** | Attach a tag to every selected monitor |\n| **Set group** | Assign the selection into a group |\n| **Assign escalation policy** | Wire the selection to a tiered escalation policy |\n| **Delete** | Delete the selection (requires a confirmation phrase) |\n\nEvery bulk action lands in the audit log and reports per-row success/failure via toast.\n\n> Things that **aren't** in this list (despite appearing in some other products): bulk \"Run check now,\" bulk CSV export, bulk-edit interval/region. Not in the current build.\n\n## Favourite groups\n\nStar a group on the Groups page to **favourite** it. Favourite groups sort to the top of the Groups page, so the areas you watch most stay within reach.\n\n## Listing groups and group monitors\n\nThe Groups page shows every group you have access to with its uptime rollup. Clicking a group opens its monitors with a per-monitor uptime summary; a time-range selector (e.g. 24h / 7d / 30d, plus shorter and longer windows) controls the rollup.\n\n## List appearance\n\nThe Monitors list shows each monitor's groups as a small badge; hovering on a multi-group monitor reveals a \"Groups: Production, Payments\" tooltip. There is no folder tree in the sidebar, the Groups page is the primary navigation surface.\n\n## Relationship with public status pages\n\nMonitor groups and status pages are separate features. A status page does **not** bind to a monitor group: you add monitors to a status page one at a time, and a monitor's group membership has no effect on whether it appears there. (A status page does have its own free-text \"group\" label for arranging monitors visually, but that label is unrelated to monitor groups.) So adding a monitor to a group later will **not** automatically publish it on any status page. Still, be deliberate about which monitors you expose, don't publish sensitive internal monitors on a public status page.\n\nFor details see [Creating a Status Page](/docs/creating-status-page).\n\n## Limits and plan differences\n\n- Groups are available on every plan, including Free.\n- There's no per-group monitor cap; the **total monitor count** is bounded by your plan's overall monitor limit.\n- The same user cannot create two groups with the same name.\n\n## Best practices\n\n- **By domain**: `Marketing`, `Auth`, `Payments`, `Search`, service boundaries.\n- **By customer** (B2B SaaS): one group per tenant. Postmortems instantly answer \"who was affected?\"\n- **By severity tier**: `Critical` / `Important` / `Best-effort`, bind escalation policies per tier.\n- **Don't over-group**: 7-15 groups is a comfortable range.\n\n## FAQ\n\n**Q: Can a monitor live in two groups?**\nA: Yes, but not via the bulk \"Set group\" action, that one **replaces** all existing group memberships with the single group you pick (it's effectively a single-click \"move\"). To put a monitor in multiple groups, use the monitor form's `Group` field, which is a multi-select.\n\n**Q: What happens to monitors when a group is deleted?**\nA: The group's assignments are removed; the monitors themselves are untouched and fall into \"Ungrouped.\" There's no combined \"delete group + monitors\" flow, delete monitors via a separate bulk action if that's what you want.\n\n**Q: Can I assign a group to a team?**\nA: Today's model is per-user; groups aren't directly bound to a team. For shared access see [Team Management](/docs/team-management) and [Roles & Permissions](/docs/roles-permissions).\n\n**Q: Drag-and-drop reordering or nested groups?**\nA: Not today, groups are a flat list, sorted by name, uptime, monitor count, or favourite.\n\n## Related topics\n\n- [Monitor Settings](/docs/monitor-settings): tags for multi-categorisation\n- [Monitor Detail](/docs/monitor-detail)\n- [Creating a Status Page](/docs/creating-status-page): adding monitors to a public status page\n- [Team Management](/docs/team-management): for shared access","category":"monitors","tags":["groups","organization","batch","folders"],"order":50,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Monitor Groups. UptimeWarden Documentation","metaDescription":"Folder your monitors by domain, team, or service. Bulk-pause, tag, and move them. Favourite groups for at-a-glance uptime rollups.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.690Z","updatedAt":"2026-10-12T22:06:41.690Z","publishedAt":"2026-10-12T22:06:41.690Z"},{"publicId":"01M4S2EPAN5PSCAQQ667BPCR1A","locale":"en","translationGroup":"websocket-monitor","slug":"websocket-monitor","title":"WebSocket Monitor","description":"Verify that a WebSocket endpoint completes the handshake and stays connected long enough to write a control ping, catch TLS, upgrade, and proxy failures before your users do.","body":"# WebSocket Monitor\n\nChat rooms, live dashboards, trading feeds, collaborative editors, all of them sit on WebSockets. Unlike HTTP, the connection is not torn down after one round-trip; it stays open for minutes or hours. When it fails, it fails silently, the browser's connection drops and reconnect loops spin up. Users only notice when the UI stops updating.\n\nA WebSocket monitor opens a real WebSocket connection on a schedule, writes a control ping after the handshake, and closes the socket. If the handshake fails, the TLS certificate is invalid, the server refuses the upgrade, or the socket dies before the ping write completes, the monitor fires immediately, minutes before anyone would have noticed in the UI. (We do not wait for a pong.)\n\n## When to use\n\n- **Chat or presence services**: Slack-like products, gaming lobbies, multi-user editors.\n- **Live dashboards**: trading platforms, admin consoles streaming metrics.\n- **IoT backends**: devices that maintain a long-lived connection for command-and-control.\n- **Supplement to HTTP monitoring**: your REST API may be fine while the WebSocket upgrade path (`/socket.io`, `/ws`, load-balancer-specific) is broken.\n\n## How the check runs\n\nEach check does four things in order:\n\n1. **Dial**, open a TCP/TLS socket to the host.\n2. **Handshake**, perform the HTTP Upgrade request (`Upgrade: websocket`). The server must respond with HTTP 101.\n3. **Ping write**, write a WebSocket control frame (opcode 0x9, payload `ping`). If the write returns without error the monitor is up, we do not wait for a pong.\n4. **Close**, the connection is closed.\n\nAny failure in steps 1-3 marks the monitor **down** with a specific error message (for example `WebSocket connection failed: x509: certificate has expired`).\n\n## Creating the monitor\n\n1. **Monitors → New Monitor**.\n2. Choose **WebSocket** as the type.\n3. Fill in:\n\n   - **Name**: e.g. `Chat realtime channel`\n   - **URL**: One of:\n     - `ws://host:port/path`, plaintext\n     - `wss://host:port/path`. TLS\n     - `http://...` / `https://...`, auto-converted to `ws://` / `wss://` before dialing\n   - **Check Interval**: the minimum depends on your plan. Realtime services typically use 1 minute.\n   - **Timeout**: default 10 s; raise it if your handshake is slow behind a proxy.\n\n4. **Advanced → Allow self-signed certificates**: leave off unless you are monitoring a staging host with a self-signed cert.\n5. **Save**.\n\n## Reaching internal endpoints\n\nBy default UptimeWarden only dials public hosts. For intra-cluster WebSocket services, run a custom agent inside the cluster, private network access is enabled per-agent.\n\n## What \"up\" actually tests\n\nThe standard WebSocket monitor tests **connectivity and the handshake**, not application semantics. If the server accepts the upgrade but your chat logic is broken, this monitor still reports **up**.\n\nFor deeper validation, combine:\n\n- A WebSocket monitor (catches handshake / TLS / network issues)\n- An HTTP monitor against a `GET /health` style endpoint (catches application-level failures)\n\nThe two together cover both the transport and the application layer.\n\n## Common failure modes\n\n| Error message | Likely cause |\n|---|---|\n| `WebSocket connection failed: dial tcp ... connection refused` | Service down or not listening on that port. |\n| `... websocket: bad handshake` | The server returned a non-101 response. Usually a load balancer that drops the Upgrade header. |\n| `... x509: certificate has expired or is not yet valid` | The `wss://` certificate rotation went wrong. |\n| `WebSocket ping failed: ...` | The handshake succeeded but the server closed the socket before the ping write completed. Often a proxy idle timeout that is too aggressive for the WebSocket lifetime. |\n\n## SLA and notifications\n\nWebSocket monitors use the same notification pipeline as every other type:\n\n- **Down**: any of the four check steps fails.\n- **Recovery**: the next check completes all four steps.\n- **Multi-location consensus**: honoured: a single hiccupping region will not open an incident.\n- **SLO tracking**: supported: configure availability or latency SLOs exactly as you would for HTTP.\n\n## FAQ\n\n**Q: Can I send a custom message instead of a ping frame?**\nA: Not in the current release. The check writes a single WebSocket control ping; the server is not required to reply with a pong, but if the socket dies during the ping write the monitor goes down.\n\n**Q: Will this catch my Socket.IO server?**\nA: Yes. UptimeWarden now auto-detects framework hubs. A Socket.IO endpoint (`/socket.io`) is probed with the HTTP polling handshake first; if healthy the monitor is up even though it rejects a raw WebSocket upgrade. You can also add an HTTP monitor on `/socket.io/?EIO=4&transport=polling` as a fallback.\n\n**Q: I have a SignalR or SockJS hub, are those supported?**\nA: Yes. SignalR hubs are probed via the `/negotiate` HTTP handshake, SockJS via `/info`. These frameworks reject a raw WebSocket upgrade but are healthy; UptimeWarden recognizes this and reports them correctly as up. Just add the hub's root URL (e.g. `wss://api.example.com/chathub`) as the monitor, no extra configuration needed.\n\n**Q: My GraphQL/STOMP/MQTT WebSocket server says \"unexpected response\"?**\nA: Those protocols require a **subprotocol** (`Sec-WebSocket-Protocol`). UptimeWarden auto-detects from the URL shape (graphql path → `graphql-transport-ws`, mqtt host/`:9001` → `mqtt`, stomp host → `stomp`). If it's still rejected, set the subprotocol explicitly in the monitor settings.\n\n**Q: What if the endpoint is actually SSE (Server-Sent Events)?**\nA: That's HTTP, not WebSocket, it returns `text/event-stream`. UptimeWarden detects this and suggests switching the monitor type to HTTP; SSE endpoints should be monitored with an HTTP monitor.\n\n**Q: Self-signed cert in staging, real cert in production, one monitor for both?**\nA: Create two monitors. Keeping \"allow self-signed\" off for production protects you against a real certificate expiry; turning it on for staging prevents noise.\n\n## Related topics\n\n- [Multi-Location Consensus](/docs/multi-location-consensus): reduce false alarms\n- [SLOs & Error Budgets](/docs/slo-error-budgets): alert on burn rate, not every failure\n- [gRPC Monitor](/docs/grpc-monitor): for service-to-service RPC health","category":"monitors","tags":["websocket","realtime","monitoring","ws","wss"],"order":50,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"WebSocket Monitor. UptimeWarden Documentation","metaDescription":"Monitor WebSocket endpoints by completing the handshake and sending a control ping on every check.","icon":"Monitor","createdAt":"2026-10-12T22:06:42.006Z","updatedAt":"2026-10-12T22:06:42.006Z","publishedAt":"2026-10-12T22:06:42.006Z"},{"publicId":"01M4S2EPA4X3MBHGFTNM53Y387","locale":"en","translationGroup":"grpc-monitor","slug":"grpc-monitor","title":"gRPC Monitor","description":"Monitor gRPC services through the standard gRPC Health Checking Protocol, catch service-to-service failures with the same rigor as external HTTP checks.","body":"# gRPC Monitor\n\nMany microservices talk to each other over gRPC. A plain uptime check can't tell whether a gRPC service is healthy; the service reports that itself (`SERVING` or `NOT_SERVING`) through the standard health RPC. A gRPC monitor calls the same `grpc.health.v1.Health/Check` RPC that platform readiness probes use.\n\n## When to use\n\n- **Internal APIs**: payment, authentication, or inventory services that other services call over gRPC.\n- **Mobile and web gateways**: apps often reach a gRPC-Web gateway in front of the core services.\n- **ML serving**: TensorFlow Serving, Triton, and most inference servers expose gRPC health.\n- **Health for partners**: when a customer integrates over gRPC and needs an external uptime number.\n\n## How the check runs\n\nThe monitor implements the [gRPC Health Checking Protocol v1](https://grpc.io/docs/guides/health-checking/):\n\n1. **Dial**, open a gRPC connection to `host:port`.\n2. **Call**, invoke `grpc.health.v1.Health/Check` with an empty service name.\n3. **Evaluate**, expect `SERVING`. Anything else (`NOT_SERVING`, `UNKNOWN`, `SERVICE_UNKNOWN`) marks the monitor **down**.\n4. **Close**, close the connection.\n\nThe check does not require you to ship your `.proto` files, the health-check proto is standard across every gRPC implementation.\n\n## Creating the monitor\n\n1. **Monitors → New Monitor**.\n2. Choose **gRPC** as the type.\n3. Fill in:\n\n   - **Name**: e.g. `PaymentService health`\n   - **URL**: One of:\n     - `host:port`, plaintext\n     - `grpc://host:port`, plaintext, explicit scheme\n     - `grpcs://host:port`. TLS\n   - **Timeout**: default 10 s.\n   - **Check Interval**: plan-dependent minimum (see the [pricing page](https://uptimewarden.online/pricing) for current values).\n\n4. **Save**.\n\n## TLS vs plaintext\n\n| URL prefix | Connection type | Typical use |\n|---|---|---|\n| `grpcs://payment.example.com:443` | TLS (public trust store) | Internet-facing services behind a load balancer with a real certificate. |\n| `grpc://payment.example.internal:9000` | Plaintext | Service mesh interior (Linkerd, Istio, Consul). The check must run from inside the mesh, plaintext over the public internet is never safe. |\n| `payment.example.com:443` (no scheme) | Plaintext | Legacy shorthand, equivalent to `grpc://`. Prefer the explicit scheme. |\n\n## Reaching internal services\n\nBy default UptimeWarden only dials public targets. To monitor cluster-internal gRPC endpoints, run a custom agent inside your environment; private network access can be enabled per-agent.\n\n## What \"SERVING\" actually means\n\nYour service decides what `SERVING` requires. The default most frameworks ship:\n\n- **Go**: return `SERVING` as soon as the gRPC server is up.\n- **Java**: same, via `HealthStatusManager`.\n- **Node.js**: same, via the built-in health service.\n\nThis is a **liveness** check, not a deep health check. If you need to verify database connectivity or queue health, register named health services inside your server. The standard UptimeWarden check sends an empty service name, which corresponds to overall server health.\n\n## Common failure modes\n\n| Error message | Likely cause |\n|---|---|\n| `gRPC connection failed: ...` | No service listening, wrong port, or TLS mismatch (plaintext client vs TLS server). |\n| `gRPC health check failed: ... code = Unimplemented` | The server does not implement the standard health proto. Add `HealthStatusManager` (Java), `health.NewServer()` (Go), or the equivalent. |\n| `gRPC service status: NOT_SERVING` | The service implemented the proto and is deliberately reporting unhealthy. Check your readiness logic. |\n| `... certificate signed by unknown authority` | The `grpcs://` target uses a certificate the public trust store does not recognise. Use `grpc://` from an in-mesh agent. |\n\n## SLA and notifications\n\n- **Down**: dial error, call error, or `NOT_SERVING`.\n- **Recovery**: a subsequent check returns `SERVING`.\n- **Multi-location consensus**: supported: useful in multi-region service meshes.\n- **SLO tracking**: supported: pair a gRPC monitor with an availability SLO for each service.\n\n## FAQ\n\n**Q: Can I monitor a specific gRPC service (e.g. `payment.orders`) instead of the whole server?**\nA: The standard check sends an empty service name for overall server health. Workaround: expose the sub-service as its own gRPC server and monitor it separately.\n\n**Q: My service uses gRPC-Web behind a proxy. Should I use gRPC or HTTP monitoring?**\nA: Both have their place. The gRPC monitor catches upstream service failures; an HTTP monitor against the gRPC-Web endpoint catches proxy or CORS issues. Run them in parallel.\n\n**Q: The check says \"Unimplemented\", my server has a health endpoint, what's wrong?**\nA: The server implements *some* health service, but not `grpc.health.v1.Health`. Many teams write custom ones, switch to the standard proto (`grpc/health/v1/health.proto`); it is five lines.\n\n## Related topics\n\n- [WebSocket Monitor](/docs/websocket-monitor): for long-lived streaming endpoints\n- [Multi-Location Consensus](/docs/multi-location-consensus): cross-region verification\n- [Escalation Policies](/docs/escalation-policies): on-call routing for critical services","category":"monitors","tags":["grpc","rpc","monitoring","microservices","health-check"],"order":55,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"gRPC Monitor. UptimeWarden Documentation","metaDescription":"Use the standard gRPC Health Checking Protocol to monitor internal and external gRPC services.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.988Z","updatedAt":"2026-10-12T22:06:41.988Z","publishedAt":"2026-10-12T22:06:41.988Z"},{"publicId":"01M4S2EPABTVH1AYM15KCXDZ87","locale":"en","translationGroup":"mcp-monitor","slug":"mcp-monitor","title":"MCP Monitor","description":"Monitor Model Context Protocol servers that expose tools to AI agents, catch authentication failures, stream disconnects, and protocol drift before your agents do.","body":"# MCP Monitor\n\nMCP (Model Context Protocol) servers expose **tools, resources, and prompts** to AI agents. AI assistants, custom agents, and most newer agent frameworks reach out to MCP servers to extend what they can do: file system access, database queries, internal API calls.\n\nWhen an MCP server goes down, AI agents do not fail loudly, they silently lose a capability. A monitoring pipeline that only counts HTTP response codes will not see the problem. The MCP monitor probes the actual protocol: it sends a `tools/list` request and verifies that the server responds with a tool catalog.\n\n## When to use\n\n- **Self-hosted MCP servers**: internal tool catalogs running on your own infrastructure.\n- **Vendor MCP endpoints**: when you depend on a third-party MCP (DeepWiki, GitHub, Linear) for agent workflows.\n- **Gateway or proxy health**: agents reach MCP through a gateway and the gateway is the weak link.\n- **Regression catch**: a post-deploy check that your MCP server still exposes the expected surface.\n\n## Supported transports\n\nThe MCP specification lists three transports. UptimeWarden supports the two that are reachable over the network:\n\n| Transport | URL pattern | Behaviour |\n|---|---|---|\n| **HTTP (Streamable HTTP or JSON response)** | `https://server.example.com/mcp` | Default. The monitor sends a `tools/list` request; the server responds with JSON **or** an event-stream response. |\n| **Server-Sent Events** | `https://server.example.com/sse` or URL contains `event-stream` | The monitor connects and reads the first event-stream frame. The server must emit `data:` or `event:` lines. |\n| **STDIO** | `./server.py`, `./server.js` | **Not supported**. STDIO requires a local process and is not reachable remotely. The monitor returns a clear \"STDIO not supported\" error. |\n\nTransport selection is automatic: the monitor inspects the URL for `/sse` or `event-stream` and falls back to HTTP if neither is present.\n\n## How the check runs\n\nFor HTTP servers:\n\n1. Send a `tools/list` request to the URL.\n2. Include the MCP-required headers, including a unique session header per check.\n3. Expect HTTP 2xx.\n4. If the server returned an event-stream instead of JSON, read the first 1 KB; pass if it contains `data:` or `event:`.\n5. Otherwise parse the JSON. The `result` field must exist. JSON-RPC error responses generally count as down, except session errors (`Session not found` or `Mcp-Session-Id header is required`), which count as up because they prove the server is responsive.\n\nFor SSE servers, the monitor opens the stream and waits for the first data frame.\n\n## Creating the monitor\n\n1. **Monitors → New Monitor**.\n2. Choose **MCP** as the type.\n3. Fill in:\n\n   - **Name**: e.g. `GitHub MCP server`\n   - **URL**: The MCP server endpoint (`https://...`). SSE-based servers typically end in `/sse`; HTTP Streamable servers typically end in `/mcp`.\n   - **Timeout**: default 10 s. Raise to 30 s for cold-start heavy servers.\n   - **Check Interval**: the minimum depends on your plan; see the [pricing page](https://uptimewarden.online/pricing) for current values.\n\n4. **Save**.\n\n## Reaching internal endpoints\n\nBy default UptimeWarden only contacts public MCP endpoints. For private or internal MCP servers, run a custom agent inside your environment; private network access is enabled per-agent.\n\n## What \"up\" actually tests\n\nThe standard check verifies that the **server accepts the protocol handshake and returns a tool catalog**. It does not:\n\n- List every individual tool.\n- Try to invoke a tool.\n- Validate authentication beyond \"the request was not rejected.\"\n\nIf your MCP server uses per-tool authorisation and one tool is broken, this monitor still reports up. For deeper validation, run the failing-tool call from a synthetic test (outside the scope of MCP monitor).\n\n## Authenticated endpoints\n\nMany public MCP servers require a bearer token (for example an API key or session token). The MCP monitor does not inject custom Authorization headers today, it only sends the MCP-required session header. Options:\n\n- **Public-readable endpoints**: DeepWiki-style servers without authentication, work out of the box.\n- **Token-protected endpoints**: expose an unauthenticated `/health` or `/mcp/ping` variant and point the monitor there.\n- **Gateway-protected endpoints**: many teams front their MCP with an authentication gateway. Monitor the gateway with an HTTP monitor and the MCP itself from an internal agent where authentication is injected at the network layer.\n\n## Common failure modes\n\n| Error | Likely cause |\n|---|---|\n| `STDIO-based MCP endpoints are not supported in remote mode` | The URL points to a filesystem path. STDIO MCPs cannot be monitored remotely. |\n| `MCP HTTP request failed: connection refused` | The server is not running or the port is wrong. |\n| `HTTP 401` / `HTTP 403` | The server requires authentication on `tools/list`. See \"Authenticated endpoints\". |\n| `HTTP 400: Bad Request` | The server does not speak the MCP Streamable HTTP subset. Try appending `/sse` to switch transports. |\n| Stream opens but no data | The server is up but not emitting events correctly. Check server logs. |\n\n## SLA and notifications\n\n- **Down**: any of the steps fails.\n- **Recovery**: a subsequent check completes.\n- **Multi-location consensus**: supported.\n- **SLO tracking**: supported.\n\n## FAQ\n\n**Q: Does this call an individual tool?**\nA: No, it only calls `tools/list` (a protocol-level health check). Invoking a real tool could have side effects (sending email, charging a card), so the check stays passive.\n\n**Q: My MCP server is behind Cloudflare Access. What do I do?**\nA: Cloudflare Access rejects requests that do not carry service-token headers. Either whitelist UptimeWarden's outbound IPs in your Access policy, or expose an internal `/health` endpoint that bypasses Access.\n\n**Q: The check says `up`, but my agent still errors when calling a tool.**\nA: The MCP monitor does not guarantee per-tool health. Use it as a **protocol-level** indicator and layer a synthetic test on top for tool-level validation.\n\n## Related topics\n\n- [WebSocket Monitor](/docs/websocket-monitor): for long-lived streaming protocols\n- [HTTP Monitor](/docs/http-monitor): for token-authenticated REST endpoints\n- [Health Prediction](/docs/health-prediction-overview): predicting issues before they page you","category":"monitors","tags":["mcp","ai","agents","tools","json-rpc"],"order":60,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"MCP Monitor. UptimeWarden Documentation","metaDescription":"Check Model Context Protocol servers by calling tools/list over HTTP or SSE on every check.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.995Z","updatedAt":"2026-10-12T22:06:41.995Z","publishedAt":"2026-10-12T22:06:41.995Z"},{"publicId":"01M4S2EP113NGKJ6Q7H08699QK","locale":"en","translationGroup":"other-monitor-types","slug":"other-monitor-types","title":"Other Monitor Types","description":"Overview of TCP, UDP, Ping, MCP, gRPC, WebSocket, DNS, and Heartbeat monitors, which to pick for which scenario.","body":"# Other Monitor Types\n\nUptimeWarden supports **8 monitor types** beyond HTTP and SSL. This page is a fast overview, each type has its own dedicated doc. Use the **decision matrix** below to pick the right type quickly.\n\n## Type list\n\n| Type | Target | Typical use | Detail |\n|---|---|---|---|\n| TCP | Hostname + port | Database, message queue, custom protocol port | Below |\n| UDP | Hostname + port | DNS server, syslog, custom UDP daemon | Below |\n| Ping | Hostname / IP | Network reachability, gateway | Below |\n| DNS | Hostname + record type | DNS record verification | [DNS Monitor](/docs/dns-monitor) |\n| Heartbeat | Token | Cron job, background worker | [Heartbeat Monitor](/docs/heartbeat-monitor) |\n| MCP | URL | Model Context Protocol server | [MCP Monitor](/docs/mcp-monitor) |\n| gRPC | Hostname + port | gRPC services | [gRPC Monitor](/docs/grpc-monitor) |\n| WebSocket | `wss://` URL | WebSocket connection lifecycle | [WebSocket Monitor](/docs/websocket-monitor) |\n\n## TCP Monitor\n\nTCP checks \"is this port open and does the handshake complete?\", the layer beneath HTTP.\n\n**When to use**:\n\n- Postgres / MySQL / MongoDB / Redis port reachable?\n- Message broker port accessible?\n- Custom binary protocol (game server, IoT, MQTT) up?\n\n**How it works**: Three-way handshake (SYN → SYN-ACK → ACK). Failed handshake or timeout = down. No data is sent, just connect.\n\n```\nhostname: db.internal.example.com\nport: 5432\ntimeout: 5s\n```\n\n**Limitation**: Cannot validate content, the port may be open but the wrong service running. For that, use a custom HTTP endpoint or a gRPC monitor.\n\n## UDP Monitor\n\nUDP is connectionless, so \"is it open?\" does not have a clean answer. UptimeWarden sends a **probe packet** and waits for a response (or an ICMP \"port unreachable\").\n\n**When to use**:\n\n- DNS server (53): but the DNS monitor is better for that\n- Syslog (514)\n- Custom UDP daemon (game servers, VoIP signalling)\n- VPN gateway (IPSec 500/4500, WireGuard 51820)\n\n**Limitation**: UDP firewall behaviour is murky, some firewalls silently drop packets. An application-layer monitor (DNS, gRPC) is usually more reliable.\n\n## Ping Monitor (ICMP)\n\nClassic network ping. Confirms a hostname is reachable on the network through ICMP echo request → echo reply.\n\n**When to use**:\n\n- Is an internal gateway, router, or firewall up?\n- Network connectivity health\n- Reachability sanity check (a **lower bound** for uptime: ping working means HTTP *might* work; HTTP working does not guarantee ping)\n\n**Note**: Some servers block ICMP but allow HTTP, ping down, service up. Do not use ping alone for SLA; pair it with HTTP or TCP. The reachability check keeps working even when ICMP is blocked: if ICMP gets no reply, it automatically confirms reachability over common ports (80, 443, 53, 22) instead.\n\n## DNS Monitor\n\nVerifies your DNS records resolve to the IPs or hostnames you expect. A, AAAA, CNAME, MX, NS, TXT.\n\nFull doc: [DNS Monitor](/docs/dns-monitor).\n\n## Heartbeat Monitor\n\nA push-style monitor, instead of UptimeWarden reaching out to your service, your service pings UptimeWarden. Designed for cron jobs, background workers, and backup scripts.\n\nFull doc: [Heartbeat Monitor](/docs/heartbeat-monitor).\n\n## MCP Monitor\n\nTracks Model Context Protocol servers, the endpoints your AI agents connect to.\n\nFull doc: [MCP Monitor](/docs/mcp-monitor).\n\n## gRPC Monitor\n\nPerforms the standard gRPC health check over HTTP/2.\n\nFull doc: [gRPC Monitor](/docs/grpc-monitor).\n\n## WebSocket Monitor\n\nCan a WebSocket connect? Does the handshake succeed and the control ping write complete? Suitable for realtime apps.\n\nFull doc: [WebSocket Monitor](/docs/websocket-monitor).\n\n## Decision matrix: which type to pick\n\n| Scenario | First choice | Backup |\n|---|---|---|\n| Public website, REST API | HTTP | - |\n| TLS certificate expiry | SSL | - |\n| Database port reachable | TCP | - |\n| Postgres login + query works | HTTP (via proxy) | TCP |\n| DNS record correct | DNS | - |\n| Cron job ran | Heartbeat | - |\n| WebSocket pub/sub | WebSocket | HTTP (handshake) |\n| gRPC microservice | gRPC | TCP (port-only fallback) |\n| Internal load balancer or gateway up | Ping | TCP |\n| AI MCP server | MCP | HTTP |\n| GeoDNS regional answers | DNS (per region) | - |\n| Background worker alive | Heartbeat | - |\n\n## Combining multiple types\n\nMost critical services deserve 2-3 monitors:\n\n**Web app**:\n\n- HTTP → `https://app.example.com/health` (200 + content validation)\n- SSL → certificate expiry\n- Ping → optional network reachability\n\n**Database service**:\n\n- TCP → `db.internal:5432` (port open)\n- HTTP → `https://db-proxy.internal/health` (real query)\n\n**Realtime API**:\n\n- WebSocket → `wss://realtime.example.com`\n- HTTP → REST fallback endpoint\n- SSL → wss certificate\n\n## Plan availability\n\nAll ten monitor types (HTTP, SSL, TCP, UDP, WebSocket, MCP, gRPC, DNS, Heartbeat, and Ping) are available on every plan, including Free. What varies by plan is check frequency (interval) and the number of concurrent monitors. See [Monitor Settings](/docs/monitor-settings).\n\n## Related topics\n\n- [HTTP Monitor](/docs/http-monitor) · [SSL Monitor](/docs/ssl-monitor)\n- [DNS Monitor](/docs/dns-monitor) · [Heartbeat Monitor](/docs/heartbeat-monitor)\n- [gRPC Monitor](/docs/grpc-monitor) · [WebSocket Monitor](/docs/websocket-monitor) · [MCP Monitor](/docs/mcp-monitor)\n- [Agent Management](/docs/agent-management)","category":"monitors","tags":["tcp","udp","ping","grpc","websocket","mcp"],"order":60,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Other Monitor Types. UptimeWarden Documentation","metaDescription":"Quick guide to the monitor types beyond HTTP and SSL: TCP, UDP, Ping, MCP, gRPC, WebSocket, DNS, Heartbeat, and when to use each.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.698Z","updatedAt":"2026-10-12T22:06:41.698Z","publishedAt":"2026-10-12T22:06:41.698Z"},{"publicId":"01M4S2EP0B80YFZKTHEN56VA22","locale":"en","translationGroup":"regional-monitoring","slug":"regional-monitoring","title":"Regional Monitoring","description":"Run your monitors from one or more of UptimeWarden's five worldwide locations; consensus voting and automatic failover reduce false alarms.","body":"# Regional Monitoring\n\nUptimeWarden runs your monitors from five locations spread across the world, not from a single point. That gives you both a true picture of **what your customers actually experience** and resistance to single-region network blips that would otherwise wake you up at 3 AM.\n\n## Available regions\n\n| Region | Location |\n|---|---|\n| Australia | Sydney |\n| Brazil | São Paulo |\n| Europe | Sweden Central |\n| Asia | East Asia |\n| US West | Phoenix |\n\nEach region is sized to absorb traffic spikes and scales automatically. Every region only checks the monitors assigned to it.\n\n## How to pick a region\n\nOn Professional and Enterprise, the **Region** dropdown on the monitor form chooses the home region. Three strategies cover most cases:\n\n### 1. Match your customers\nPick the region nearest to where your traffic comes from. EU-heavy SaaS → Sweden Central. Asia → East Asia or Sydney. Americas → Phoenix or São Paulo.\n\n### 2. Match your data centre\nChoose the UptimeWarden region closest to where your service is hosted. That removes extra network hops from your response-time numbers.\n\n### 3. Multi-region (consensus)\nHave several regions check at the same time. Best for global services. Detail below.\n\n## Multi-location consensus\n\nTo keep a short internet blip in one region from paging you, UptimeWarden uses **consensus voting**. When the monitor's region sees a failure, other regions repeat the check. The alert is **confirmed** when **K of N** regions see the target down, **held** when most regions can reach it, and otherwise sent **unverified**.\n\nCommon patterns:\n\n| Pattern | Meaning |\n|---|---|\n| `2/2` | Two regions; both must see the failure to confirm it |\n| `2/3` | Three regions; at least two must see the failure to confirm it |\n| `3/5` | Five regions; at least three must see the failure to confirm it |\n\n> **Practical note:** 3/5 suits production SaaS: a failure that only one region sees is held, while an outage most regions see is confirmed.\n\nFull detail: [Multi-Location Consensus](/docs/multi-location-consensus).\n\n## Plan availability\n\nRegion selection on the monitor form is available on **Professional** (your monitors across up to 5 regions) and **Enterprise** (all regions); on Free, Hobby and Starter, monitors run from the default region. This is a separate limit from verification regions. The number of regions a monitor can vote across also varies by plan:\n\n| Plan | Max verification regions | Default consensus | Customisable |\n|---|---|---|---|\n| Free | 2 | 2/2 | No |\n| Hobby | 3 | 2/3 | No |\n| Starter | 3 | 2/3 | Yes |\n| Professional | 5 | 3/5 | Yes |\n| Enterprise | 6 | 3/6 | Yes |\n\nOn Free, the second region can confirm an alert but cannot hold one back: if it reaches the site, the alert is still sent, labelled unverified. From Hobby up, a failure most regions do not see is held and checked again five minutes later.\n\n## Verification regions\n\nWhen you use multi-region, you have a **primary region** (where the schedule runs) and **verification regions** (the witnesses). The form looks like:\n\n```\nRegion (primary):       Sweden Central\nVerification regions:   East Asia, Phoenix\nMin confirming regions: 2  (2/3 - any two must agree)\n```\n\nIn this setup:\n\n- Sweden Central alone says down → no incident\n- Sweden Central + East Asia say down → incident\n- Sweden Central + Phoenix say down → incident\n- Only East Asia says down → no incident (Sweden Central is still up)\n\n## Automatic regional failover\n\nIf an entire region goes offline, the **nearest live region** automatically picks up its monitors. No reconfiguration on your side, no change to the monitor's home region, when the original region comes back, control snaps back to it.\n\nProximity follows a fixed priority list (nearest first):\n\n- Sydney → East Asia → Sweden Central → Phoenix → São Paulo\n- São Paulo → Phoenix → Sweden Central → East Asia → Sydney\n- Sweden Central → East Asia → Phoenix → São Paulo → Sydney\n- East Asia → Sydney → Sweden Central → Phoenix → São Paulo\n- Phoenix → São Paulo → East Asia → Sydney → Sweden Central\n\n## One incident, one notification\n\nMonitor scheduling is **per region**, but a few coordination tasks (incident creation, notification dispatch, data retention) run from a single region. That's why a single outage produces a single email, not one per region that observed it.\n\n## Private agents and regions\n\nA private agent acts as its own location, what matters is where the agent runs, not which UptimeWarden region observes it. Private agents are the only way to monitor private-network endpoints. See [Agent Management](/docs/agent-management).\n\n## Assigning regions\n\nRegion, verification regions, and the confirming-region threshold are configured on the **monitor form** in the dashboard. When you reference a region in configuration or support requests, use its slug rather than its display name:\n\n| Region | Slug |\n|---|---|\n| Sweden Central | `gwc` (default) |\n| East Asia | `sea` |\n| Phoenix, US | `wus3` |\n| Sydney, Australia | `ae` |\n| São Paulo, Brazil | `brs` |\n\n> **API note:** The public REST API (`/api/v1`) does not yet expose region assignment. The create endpoint (`POST /api/v1/monitors`) accepts `name`, `url`, `type`, `interval`, and `timeout` only, and there is no update endpoint for monitors. Set region and verification regions from the monitor form for now.\n\n## FAQ\n\n**Q: How do I know which region is closest to my service?**\nA: Pick the UptimeWarden region nearest your cloud region (a European cloud region → Sweden Central, Sydney → Sydney, an East or Southeast Asian one → East Asia). When in doubt, run a 2-3 region test for a day and compare response times.\n\n**Q: If I change a monitor's region, what happens to historical data?**\nA: Past checks keep their old region label; new checks come from the new one. The detail page shows the breakdown cleanly.\n\n**Q: If my region goes down, do my monitors stop running?**\nA: Failover is automatic, the nearest live region picks up the load and hands it back when the home region recovers. The monitor's configured region never changes.\n\n## Related topics\n\n- [Multi-Location Consensus](/docs/multi-location-consensus)\n- [Agent Management](/docs/agent-management)\n- [Monitor Settings](/docs/monitor-settings)","category":"monitors","tags":["regions","multi-region","geography","consensus"],"order":70,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Regional Monitoring. UptimeWarden Documentation","metaDescription":"Five worldwide monitoring locations, per-monitor region assignment, consensus voting, and automatic failover when a region goes silent.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.675Z","updatedAt":"2026-10-12T22:06:41.675Z","publishedAt":"2026-10-12T22:06:41.675Z"},{"publicId":"01M4S2EP188X3RHQ111RGK1FVQ","locale":"en","translationGroup":"agent-management","slug":"agent-management","title":"Agent Management","description":"Run a private monitoring agent inside your own network to watch internal APIs, databases, and air-gapped systems. The agents page keeps the monitors nothing is checking in view.","body":"# Agent Management\n\nUptimeWarden's cloud locations cover everything reachable from the public internet. For everything else, internal APIs, databases behind a VPN, factory floor controllers, air-gapped systems, you run a **private monitoring agent inside your own network**.\n\nThe agent is a small, single-binary program that runs the same checks our cloud locations do, then reports the results back to UptimeWarden over a standard outbound HTTPS connection. No inbound ports, no firewall holes, only port 443 outbound.\n\n## What a private agent is for\n\n- **Internal-network monitoring**: reach private endpoints without exposing them publicly.\n- **On-premises systems**: corporate data centres, factory networks, hospital LANs.\n- **Lowest-latency measurement**: an agent sitting next to the target gives you the closest possible read on what your users actually experience.\n- **Custom locations**: when our cloud locations don't include the geography you care about, the agent fills the gap.\n\n## What an agent can monitor\n\nA private agent runs the check types UptimeWarden actively reaches out to test: HTTP/HTTPS, TCP, UDP, SSL, WebSocket, gRPC, MCP, and Ping. DNS and Heartbeat monitors are the exceptions. DNS-record checks run server-side from our cloud, and Heartbeat is an inbound signal from your job to us, so no agent is involved in either.\n\n## Plan availability\n\nPrivate agents are available on **every plan, including Free**. What changes per plan is how many agents you can run: Free 1, Hobby and Starter 3, Professional 10, Enterprise unlimited. Need more on your tier? Agent add-on packs are available on Professional and above.\n\n## Installing an agent\n\nEach agent is identified by a unique connection token. The dashboard walks you through it:\n\n1. Open **Add agent** on the **Agents** page and give it a recognisable name, something like `paris-edge-01` or `factory-floor-vpn`.\n2. Click **Create agent**. The token is issued at that moment and shown **once**; copy it into your password manager or secret store immediately. If you lose it, you can issue a new one from the agent's menu.\n3. Choose where the agent runs (Docker, Linux binary or Kubernetes/Helm). The dashboard generates the exact command for that platform, pre-filled with your token.\n4. Run the command on the host. When the agent sends its first heartbeat, the screen shows the connection and the time of that first heartbeat.\n5. Once connected, the last step offers a monitor that runs from the new agent.\n\nIf you need help running the agent in a more locked-down environment, contact our support team, we'll walk through the deployment with you.\n\n## Connecting an agent to a monitor\n\nOnce the agent registers, it shows up as **online** on the **Agents** page. When you create or edit a monitor, pick that agent from the **Custom Agent** dropdown. From that moment on, only the chosen agent runs that monitor, our cloud locations stop checking it.\n\n```\nRegion:        - (the agent overrides the region)\nCustom Agent:  paris-edge-01\n```\n\nThe install flow ends here: once the agent is connected, an **Add a monitor that runs from …** button appears and opens the new-monitor form with that agent chosen.\n\nResults from an agent follow the same slow-response rule as the rest of the product: the alert opens only after N slow checks in a row (N defaults to 3, the same number that confirms a recovery). A single slow check never alerts.\n\n## Watching agent health\n\nThe **Agents** page puts what is **not** being checked first. The status line at the top summarises offline and never-connected agents and the monitors nothing is checking; **View the N monitors** lists those monitors one by one. The table then shows every agent together with the monitors running from it and the ones not being checked:\n\n| Column | What it tells you |\n|---|---|\n| Agent | The label you gave the agent |\n| Status | `Online` while a heartbeat has arrived in the last 2 minutes; `Offline since 12:31 (1 h 49 min)` after that; `Never connected` for an agent whose binary has not registered yet |\n| Host · OS/arch | The machine the agent runs on, and its operating system and architecture |\n| Version | The agent build it's running; `—` for a never-connected agent |\n| Last seen | When the agent last reported in; `—` for a never-connected agent |\n| Monitors | The monitors running from this agent; when the agent is not online, the active monitors it is not checking are counted here too |\n\nAn agent that has never connected has no version and no last-seen time. The table shows those fields as `—`, never a made-up value, and never labels the agent offline with a time: its status reads `Never connected`. `Online` means a heartbeat arrived within the last two minutes; a stored status from earlier does not keep an agent online.\n\nIf an agent goes `offline`, the monitors bound to it pause, no checks, no incidents, until the agent reconnects. The page marks those monitors as not being checked, so it's obvious the silence is the agent, not your service. Checks resume the moment it comes back.\n\n## Rotating a token\n\nIf a token leaks or you have a periodic rotation policy:\n\n1. Open **Agents → [agent] → Rotate token**.\n2. A new token is generated, and the old one stays valid for a **24-hour grace period** so rotation is zero-downtime.\n3. Update the agent with the new token, the install instructions screen has the exact command.\n\nDuring the 24-hour grace window the agent keeps working on the old token, giving you time to roll out the new one; after that the old token expires automatically. Because the old token remains usable for up to 24 hours, rotation alone does not instantly cut off a leaked token, if you need to kill a compromised token immediately, contact our support team.\n\n## Private-network safety\n\nAn agent has whatever network reach the host you put it on has, that's the point, but it deserves care:\n\n- Run agents in a **dedicated network segment** with the smallest possible egress.\n- Grant access only to the endpoints you intend to monitor.\n- DNS resolver overrides are protected automatically: private IP ranges and cloud metadata endpoints are blocked even if you point a check at them.\n- Forward agent logs to your central log system for auditing.\n\n## Cloud location vs private agent, when to use which\n\n| Scenario | Cloud location | Private agent |\n|---|---|---|\n| Public website | yes | - |\n| Public REST API | yes | - |\n| Database in a private network | no | yes |\n| Internal cluster service | no | yes |\n| Customer-perceived latency | yes | yes |\n| Air-gapped factory equipment | no | yes |\n| CDN edge node | yes (nearest location) | yes (ideal) |\n\n## FAQ\n\n**Q: How many monitors can one agent handle?**\nA: A single agent comfortably handles dozens of monitors at typical intervals. If you need more capacity, install additional agents, each gets its own token, and split your monitors across them.\n\n**Q: What happens if the agent goes down?**\nA: The monitors bound to it stop checking until the agent reconnects. The dashboard marks it `offline` after about 2 minutes of silence so it's clear the agent itself is the issue. Checks resume the moment it comes back online.\n\n**Q: Can two agents check the same monitor in parallel?**\nA: A monitor is bound to one agent at a time. For redundancy, run two agents and split the monitor pool between them.\n\n## Related topics\n\n- [Regional Monitoring](/docs/regional-monitoring)\n- [Monitor Settings](/docs/monitor-settings)\n- [Other Monitor Types](/docs/other-monitor-types)","category":"monitors","tags":["agent","private-network","internal-monitoring"],"order":80,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Agent Management. UptimeWarden Documentation","metaDescription":"Install a private monitoring agent inside your network to monitor internal endpoints. Token-based registration, status tracking, and the list of monitors nothing is checking.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.705Z","updatedAt":"2026-10-12T22:06:41.705Z","publishedAt":"2026-10-12T22:06:41.705Z"},{"publicId":"01M4S2EP1GZNXZKZ2WR0FGACZN","locale":"en","translationGroup":"service-map","slug":"service-map","title":"Service Map","description":"A live dependency graph of your monitors, root cause tracing, blast radius visualisation, and cascade alert suppression.","body":"# Service Map\n\nService Map shows your monitors as a dependency graph instead of a flat list. You define dependencies between services (database → API → frontend → CDN), and when a node goes down, the graph highlights everything downstream of it.\n\n## What it gives you\n\n- **Root cause analysis**: When the frontend is down, is the problem the frontend itself, the API it depends on, or the database underneath the API?\n- **Blast radius**: If \"Postgres is down\" is the real cause, which 12 services break? Which customers feel it?\n- **Cascade alert suppression**: When a database is down, suppress 12 redundant downstream alerts and send one root alert.\n- **Onboarding**: Show a new engineer the system \"map\" in 5 minutes.\n\n## Plan availability\n\nService Map is available on **Starter and above** (Starter, Professional, Enterprise). Free and Hobby accounts see an upgrade prompt instead of the graph.\n\n## How services are linked\n\nEvery link on the map comes from evidence, and says which. Click a link to see its reasons:\n\n| Reason | What it means |\n|---|---|\n| Went down together | The two monitors' outages started within one check interval of each other at least 3 times in the last 30 days, and at least 10 times as often as chance would give. The link shows the counts (\"Went down together 12 times in 30 days\"). |\n| Same IP | Both monitors reached the same server address. Two sites behind the same CDN edge address are not linked by it: a CDN address is shared by many unrelated sites. |\n| Same registered domain | Both are under the same registered domain, read with the Public Suffix List: `api.example.com.tr` and `www.example.com.tr` are related, two different companies under `.com.tr` are not. |\n| Same CDN | Both are served through the same CDN. Shown next to other evidence, never a link on its own. |\n| Your link / Your dependency | A link you drew or a dependency you declared. |\n\nA shared server or domain links monitors in groups of up to 10. When 30 of your monitors share one domain, the fact is true for every pair and says nothing about any one of them, so it is only shown next to a link that other evidence made. Names are never used to link monitors, and no AI model decides a link.\n\nLinks are found every night, and on demand with **Discover dependencies**, which shows a spinner until the pass finishes (up to ~45 seconds).\n\n### Confirming, rejecting and adding links\n\nA found link is **suggested** (dashed) until you look at it. Click it, then:\n\n- **Confirm link** keeps it, even when its evidence later fades.\n- **Not related** removes it, and it is never suggested again.\n- **Mark as a dependency** records which of the two depends on the other.\n\nWhen discovery misses something, add it yourself: click **Add manual link**, pick two services on the canvas, and confirm. You can add an optional note. Deleted links stay deleted, they are not re-created by later discovery.\n\nEvery monitor's page also lists its **Related monitors** with the same reasons, on every plan. When two monitors keep going down together and no dependency is recorded between them, it asks whether one depends on the other.\n\n## Visualisation\n\nThe Service Map page draws monitors as an interactive graph:\n\nEach node is colored by its **health trend** (the node border, with the matching trend icon):\n\n- **Red border**: critical\n- **Orange border**: degrading\n- **Blue border**: stable\n- **Green border**: improving\n- **Grey border**: unknown / no trend yet\n- **Gold border and \"Upstream\"**: other services are recorded as depending on it\n- **Dashed edge**: a suggested link you have not confirmed yet\n- **Arrow**: a dependency, pointing from the service that depends to the one it depends on\n- **Edge label**: the strongest reason (Down together ×12, Same IP, Same domain, Your link, Dependency)\n\nEach node card shows that monitor's uptime % and average response time inline. Use the **Environment** and **Service Type** filters to narrow the canvas to a cluster of services.\n\n## Blast radius\n\nEach node shows the state of its latest check, so when a service fails you can follow its links to the monitors that depend on it and see which of them are failing too. Conceptually, a Postgres outage propagates like this:\n\n```\nPostgres (DOWN) ─────┬─> Auth API ─────> Frontend ──> CDN\n                     ├─> Reports API ──> Dashboard\n                     ├─> Webhooks Worker\n                     └─> Search Service\n```\n\nThat tells you \"who's affected?\" at a glance, so customer comms can paint the right services red on the status page.\n\n## Cascade alert suppression\n\nWith a service map in place, the incident pipeline can suppress downstream noise:\n\n- **Postgres down** → root incident opens with normal severity routing\n- **Auth API down** (depends on Postgres) → recorded as suppressed under the parent incident, no notification fired\n- **Frontend down** (depends on Auth) → same, suppressed under the same root\n\nOnly the **root incident** pages a human. When Postgres recovers, downstream incidents auto-resolve.\n\n> **Important, two switches must both be on.** Cascade suppression has a global switch that your administrator turns on, plus a per-plan opt-in. Both are off by default. Turn the global switch on first, then enable it on the plans where you want it.\n\n## Discovery details\n\nDiscovery reads three things we already collect: when each monitor's outages started, which address, CDN and certificate each HTTP check landed on, and each monitor's URL. It does not ingest distributed traces from your code, and it never adds a dependency by itself: a dependency, and so cascade suppression, only follows your choice.\n\n## FAQ\n\n**Q: I have 200 monitors, drawing a service map by hand is impossible.**\nA: Start with the critical 20-30 (databases, gateways, key APIs). 80% of the value, 20% of the effort. Add the rest incrementally.\n\n**Q: What if I label a dependency wrong?**\nA: With cascade suppression on, a downstream alert gets silenced, quietly. For the first few weeks, keep suppression **off** and use the map only for visualisation.\n\n**Q: Service Map vs Incident Analytics, what's the difference?**\nA: Service Map is real-time topology, \"what's the state right now?\" Incident Analytics is a time-series report. MTTR, frequency. Different questions.\n\n## Related topics\n\n- [Monitor Detail](/docs/monitor-detail)\n- [Incident Analytics](/docs/incident-analytics)\n- [Multi-Location Consensus](/docs/multi-location-consensus)","category":"monitors","tags":["service-map","dependencies","topology","root-cause"],"order":90,"parentSlug":"monitors","published":true,"version":1,"metaTitle":"Service Map. UptimeWarden Documentation","metaDescription":"See dependencies between your monitors. When something breaks upstream, see which downstream services are affected.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.713Z","updatedAt":"2026-10-12T22:06:41.713Z","publishedAt":"2026-10-12T22:06:41.713Z"},{"publicId":"01M4S2EP1QHYW87H5MCR53KE92","locale":"en","translationGroup":"incident-analytics","slug":"incident-analytics","title":"Incident Analytics","description":"See incidents in your account over time, broken down by alarm type and by the noisiest monitors.","body":"# Incident Analytics\n\nThe Incident Analytics page answers \"how many incidents in the last X days, how long did they take, and which monitors made the most noise?\" It is available on every plan, including Free.\n\n## Plan availability\n\nReporting is on for every plan, including Free. On a custom plan where reporting has been switched off, the page shows an upgrade prompt that links to the billing page instead.\n\n## Top bar, filters\n\nThe top-right of the page exposes two dropdowns and two buttons:\n\n| Control | Values |\n|---|---|\n| **Time range** | `Last 24 Hours`, `Last 7 Days`, `Last 30 Days`, `Last 90 Days` |\n| **Group by** | `Hour`, `Day`, bucket size for the time-series chart |\n| **Refresh** | Refetch with the current filters |\n| **Export** | Download the top-affected-monitors list as CSV |\n\n> Custom date ranges, weekly/monthly grouping, and group/tag filters are **not** available today, only the four ranges and two bucket sizes above.\n\n## Summary cards\n\nFour cards render at the top:\n\n| Card | What it shows |\n|---|---|\n| **Total Incidents** | Total incidents opened in the selected window |\n| **Avg Resolution Time** | Average time from when an incident opens to when it's resolved, in minutes |\n| **Active Incidents** | Currently open incidents (the card is clickable → filtered Incidents list) |\n| **Resolved** | Resolved incident count for the window (the card is clickable → Incidents list filtered to `status=resolved`) |\n\n`Avg Resolution Time` is the page's MTTR equivalent.\n\n## Time series. Incidents Over Time by Type\n\nA single full-width line chart. The X axis is bucketed by hour or day depending on **Group by**; Y is incident count. The chart overlays multiple series:\n\n- **Total**: dashed grey reference line\n- **Down**: solid red (most critical)\n- **Timeout**: solid amber\n- **SSL**: solid purple\n- **Other**: solid grey\n\nFor each bucket the page shows down, timeout, SSL, and other counts plus the total. A severity pie (`critical / warning / info`) and a day-of-week × hour-of-day heatmap are **not** shown today.\n\n## Resolution metrics and type distribution\n\nBelow the line chart there are two additional panels:\n\n- **Resolution Metrics**, `Resolution Rate` (resolved / total, as a percentage), `Active Incidents`, and an `MTTR Performance` rating (`Excellent` ≤ 30 min, `Good` ≤ 60 min, otherwise `Needs Improvement`).\n- **Incident Type Distribution**: a count and percentage breakdown for each alarm type. Each row is clickable: it opens the Incidents list filtered to that type (via the `?type=` parameter).\n\n## Top affected monitors\n\nA simple table:\n\n| Column | Content |\n|---|---|\n| Monitor name | Monitor name (plain text, not a link) |\n| Incident count | Incidents opened in the window |\n\nSorted descending by incident count. The toolbar **Export** button downloads this list as CSV:\n\n```csv\nMonitor Name,Incident Count\npayments-api,8\nauth-service,5\ncdn-edge-eu,4\n```\n\nCSV export covers **only this list**, there are no per-panel CSV or PDF buttons elsewhere on the page today.\n\n## Access scope\n\nEvery signed-in user sees only the incidents from monitors they have access to (monitors they own plus monitors shared via team membership).\n\n## FAQ\n\n**Q: Are MTTA (acknowledge time), MTBF, or P95 metrics shown?**\nA: MTTA, MTBF, and P95 are not shown today. The page surfaces the total count, average resolution time, resolved count, a Resolution Rate, and an MTTR Performance rating. If you need more, you can export the raw incident data and feed it into your own BI tool.\n\n**Q: I don't see a heatmap, severity pie, or group/tag filter, is it hidden?**\nA: They aren't part of the current page. We document only what's actually live; we'd rather not promise a UI that hasn't shipped.\n\n**Q: Can I email a PDF report on a schedule?**\nA: Not today. The only download is the \"Top affected monitors\" CSV.\n\n**Q: Which time ranges are supported?**\nA: 24 hours, 7 days, 30 days, and 90 days. Custom date ranges and weekly/monthly buckets aren't supported.\n\n**Q: How long is the data retained?**\nA: Incident records follow your plan's retention policy. See [Subscription Plans](/docs/subscription-plans) for plan-level retention.\n\n## Related topics\n\n- [Incident Lifecycle](/docs/incident-lifecycle): how an incident is opened, acknowledged, resolved\n- [Postmortem Workflow](/docs/postmortem-workflow): post-incident analysis\n- [SLOs and Error Budgets](/docs/slo-error-budgets): windowed health view\n- [Monitor Detail](/docs/monitor-detail): a single monitor's incident history","category":"monitors","tags":["analytics","mttr","reporting","incidents"],"order":100,"parentSlug":"incidents","published":true,"version":1,"metaTitle":"Incident Analytics. UptimeWarden Documentation","metaDescription":"Total incidents, average resolution time, breakdown by alarm type, and the top affected monitors. Professional and above.","icon":"Monitor","createdAt":"2026-10-12T22:06:41.720Z","updatedAt":"2026-10-12T22:06:41.720Z","publishedAt":"2026-10-12T22:06:41.720Z"},{"publicId":"01KJ7Q9ZTH54DAVXCBSR7Z1H2V","locale":"en","translationGroup":"notification-channels","slug":"en-notification-channels","title":"Notification Channels and Integrations","description":"Guide to configuring and managing UptimeWarden notification channels","body":"# Notification Channels\n\nUptimeWarden offers a variety of notification channels to alert you instantly when an issue occurs with your services. Each channel has its own advantages and use cases.\n\n## First-Class Notification Channels\n\n| Channel | Description | Settings Page |\n|---------|-------------|---------------|\n| **Email** | Detailed email notifications | Settings → Email |\n| **SMS** | Text messages via Twilio | Settings → SMS |\n| **WhatsApp** | WhatsApp messages via Twilio | Settings → WhatsApp |\n| **Voice (Call)** | Automated voice calls via Twilio | Settings → Voice / On-Call |\n| **Push** | Mobile and web push notifications | Settings → Push Notifications |\n| **Telegram** | Messages via Telegram bot | Settings → Telegram |\n| **Webhook** | Notifications to custom HTTP endpoints | Settings → Webhooks |\n| **Slack** | Slack workspace integration | Integrations → Slack |\n| **Microsoft Teams** | Teams webhook integration | Integrations → Teams |\n\n### Services Connected via Webhook\n\nThe following services are supported as **webhook providers** rather than direct integrations. You can connect them by selecting the provider type when creating a webhook:\n\n- **Discord** — Notifications via Discord webhook URL\n- **PagerDuty** — Create PagerDuty incidents\n- **OpsGenie** — Create OpsGenie alerts\n- **Generic** — Any HTTP endpoint\n\n## Email Notifications\n\nEmail is the default notification method, active for all users by default.\n\n### Email Content\n\nEach email notification includes:\n- Monitor name and status\n- Timestamp\n- Error message (if any)\n- Response time\n- Direct link to monitor dashboard\n\n### Setting Up Email for a Monitor\n\n1. Go to monitor settings\n2. Enable the **Email** channel in the notifications section\n3. Enter recipient email addresses\n4. Select which alert types to receive notifications for\n\n> SMTP configuration is done from the **Settings → Email** page.\n\n## SMS Notifications\n\nAn instantly reachable notification method for critical situations. Uses **Twilio** infrastructure.\n\n### SMS Setup\n\n1. Go to **Settings → SMS** and enter your Twilio credentials\n2. Configure Twilio Account SID, Auth Token, and phone number\n3. Save\n\n### Setting Up SMS for a Monitor\n\n1. Go to monitor settings\n2. Enable the **SMS** channel in the notifications section\n3. Enter recipient phone numbers (including country code, e.g., `+15551234567`)\n4. Select alert types\n\n> SMS credits are limited based on your plan. You can purchase additional credits via **Add-ons**.\n\n## WhatsApp Notifications\n\nReceive rich media notifications via WhatsApp. Uses **Twilio** infrastructure.\n\n### WhatsApp Setup\n\n1. Go to **Settings → WhatsApp** and enter your Twilio WhatsApp credentials\n2. Configure your Twilio WhatsApp number\n3. Save\n\n### Setting Up WhatsApp for a Monitor\n\n1. Go to monitor settings\n2. Enable the **WhatsApp** channel in the notifications section\n3. Enter recipient phone numbers\n4. Select alert types\n\n> WhatsApp credits are limited based on your plan. You can purchase additional credits via **Add-ons**.\n\n## Voice Calls (Voice / On-Call)\n\nAutomatically call your team members via voice during critical outages. Uses **Twilio** infrastructure.\n\n**Features:**\n- Text-to-speech (TTS) message delivery\n- DTMF keypress acknowledgment\n- Multi-level escalation policy\n- Test call capability\n\n> For detailed information, see the **On-Call Settings** documentation.\n\n## Push Notifications\n\nSends instant notifications to mobile apps and web browsers.\n\n- iOS, Android, and Web support\n- Device management (Settings → Push Notifications)\n- Customizable message templates\n\n> For detailed information, see the **Push Notifications** and **Push Templates** documentation.\n\n## Telegram\n\nSends notifications via Telegram bot.\n\n- Create a bot with @BotFather\n- Message format options (Markdown, HTML, MarkdownV2)\n- Test notification sending\n- Custom message templates\n\n> For detailed setup, see the **Telegram Settings** documentation.\n\n## Webhook Integrations\n\nSend notifications to external systems via custom HTTP webhooks.\n\n**Supported providers:** Slack, Discord, Telegram, Microsoft Teams, PagerDuty, OpsGenie, Generic\n\n**Features:**\n- 4-step configuration wizard\n- Authentication support (Bearer Token, Basic Auth, Custom Headers)\n- Targeting by alert type and monitor type\n- Quiet hours\n\n> For detailed setup, see the **Webhook Configuration** documentation.\n\n## Slack and Microsoft Teams Integrations\n\nSend notifications directly to your team communication tools.\n\n**Slack:** Setup with Bot Token and Channel ID. One-time configuration applied to all monitors.\n\n**Microsoft Teams:** Setup with Incoming Webhook URL. Adaptive Card template support.\n\n> For detailed setup, see the **Integrations** documentation.\n\n## Per-Monitor Notification Settings\n\nConfigure notifications per channel from the **Notifications** tab on each monitor's detail page:\n\n1. **Enable/disable** a channel (toggle switch)\n2. Select which **alert types** to receive notifications for\n3. Enter **recipient information**:\n   - Email: Email addresses\n   - SMS / WhatsApp / Voice: Phone numbers\n   - Webhook: Webhook selection\n   - Push: Automatic (sent to registered devices)\n\n## Notification Priorities\n\nYou can differentiate channels by alert type:\n\n| Situation | Recommended Channels |\n|-----------|---------------------|\n| **Critical outage** | SMS + Voice + Email + Slack |\n| **Performance warning** | Email + Slack |\n| **SSL warning** | Email |\n| **Recovery** | Email |\n\n## Best Practices\n\n1. **Use multiple channels**: Don't rely on a single channel — add backup channels\n2. **Enable SMS/Voice for critical monitors**: Email can be delayed; SMS arrives instantly\n3. **Send test notifications**: Test after each channel configuration\n4. **Create a dedicated channel**: Use a separate channel like #alerts in Slack/Teams\n5. **Narrow alert types**: Select only relevant alert types for each channel\n\n## Troubleshooting\n\n**Email not arriving:**\n- Check spam/junk folder\n- Verify email address\n- Add `noreply@` to your whitelist\n\n**SMS not arriving:**\n- Is the number format correct? (Include country code: `+1...`)\n- Is your SMS credit balance sufficient?\n- Are Twilio settings configured correctly?\n\n**Webhook failing:**\n- Is the URL publicly accessible?\n- Does the endpoint return a `2xx` status code?\n- Is the timeout sufficient?\n\n## Related Documentation\n\n- **Webhook Configuration**: Webhook wizard and provider details\n- **Push Notifications**: Device management and platform support\n- **Push Templates**: Notification message customization\n- **Telegram Settings**: Bot setup and templates\n- **On-Call Settings**: Voice calls and escalation policy\n- **Integrations**: Slack and Teams setup","category":"notifications","tags":["notifications","email","sms","whatsapp","voice","webhook","slack","teams","push","telegram"],"order":1,"parentSlug":"notifications","published":true,"version":1,"metaTitle":null,"metaDescription":"Guide to configuring and managing UptimeWarden notification channels","icon":"Bell","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZSM4E757JHNTNRMT6PN","locale":"en","translationGroup":"notifications-overview","slug":"en-notifications","title":"Notification Channels and Configuration","description":"UptimeWarden notification channels, alert types, and configuration guide","body":"# Notification Channels and Configuration\n\nUptimeWarden offers multi-channel notification support to deliver outage and performance issues to you in a timely manner. This guide summarizes all notification channels and configuration processes.\n\n## Supported Notification Channels\n\n| Channel | Description | Settings Page |\n|---------|-------------|---------------|\n| **Email** | Basic email notifications | Settings → Email |\n| **SMS** | SMS notification via Twilio | Settings → SMS |\n| **WhatsApp** | WhatsApp notification via Twilio | Settings → WhatsApp |\n| **Voice** | Twilio voice call notification | Settings → Voice / On-Call |\n| **Push** | Mobile and web push notifications | Settings → Push Notifications |\n| **Telegram** | Notification via Telegram bot | Settings → Telegram |\n| **Webhook** | Custom HTTP webhook integrations | Settings → Webhooks |\n| **Slack** | Slack workspace integration | Integrations → Slack |\n| **Microsoft Teams** | Teams webhook integration | Integrations → Teams |\n\n## Alert Types\n\n| Type | Description |\n|------|-------------|\n| **Monitor Down** | When a service becomes unreachable |\n| **Recovery** | When a service becomes reachable again |\n| **SSL Warning** | When an SSL certificate is about to expire |\n| **High Response Time** | When response time exceeds the threshold |\n| **High Response Recovery** | When response time returns to normal |\n\n## Per-Monitor Notification Settings\n\nConfigure per channel from the **Notifications** tab on each monitor's detail page:\n\n1. **Enable/disable** a channel (toggle switch)\n2. Select which **alert types** to receive notifications for\n3. Enter **recipient information**:\n   - Email: Email addresses\n   - SMS / WhatsApp / Voice: Phone numbers\n   - Webhook: Webhook selection\n   - Push: Automatic (sent to registered devices)\n\n## Email Notifications\n\nEmail is active by default for all users.\n\n**Email content:**\n- Monitor name and status\n- Timestamp\n- Error message (if any)\n- Response time\n- Direct link to monitor dashboard\n\n> Detailed SMTP configuration is done from the **Settings → Email** page.\n\n## SMS and WhatsApp Notifications\n\nPowered by Twilio infrastructure. Twilio account credentials must be configured by the system administrator.\n\n**SMS features:**\n- Short message format notification\n- Daily limit (plan-based)\n- Summary information due to character limits\n\n**WhatsApp features:**\n- Rich media support\n- Delivery status tracking\n- Template message format\n\n## Voice Calls (Voice / On-Call)\n\nVoice call notifications via Twilio. Ideal for critical situations.\n\n- Text-to-speech (TTS) message delivery\n- DTMF acknowledgment (confirm by keypress)\n- Multi-level escalation policy\n\n> For detailed information, see the **On-Call Settings** documentation.\n\n## Push Notifications\n\nSends instant notifications to mobile apps and web browsers.\n\n- iOS, Android, and Web support\n- Device management (Settings → Push Notifications)\n- Customizable message templates\n\n> For detailed information, see the **Push Notifications** and **Push Templates** documentation.\n\n## Telegram\n\nSends notifications via Telegram bot.\n\n- Create a bot with @BotFather\n- Message format options (Markdown, HTML, MarkdownV2)\n- Test notification sending\n- Custom message templates\n\n> For detailed setup, see the **Telegram Settings** documentation.\n\n## Webhook Integrations\n\nSend notifications to external systems via custom HTTP webhooks.\n\n- 7 built-in providers (Slack, Discord, Telegram, Teams, PagerDuty, OpsGenie, Generic)\n- 4-step configuration wizard\n- Authentication support (Basic Auth, Bearer Token, API Key, Custom Header)\n- Targeting by alert type and monitor type\n- Quiet hours\n\n> For detailed setup, see the **Webhook Configuration** documentation.\n\n## Integrations (Slack and Teams)\n\nSend notifications directly to team communication tools.\n\n**Slack:**\n- Setup with Bot Token and Channel ID\n- One-time configuration applied to all monitors\n\n**Microsoft Teams:**\n- Setup with Incoming Webhook URL\n- Adaptive Card template support\n\n> For detailed setup, see the **Integrations** documentation.\n\n## Notification Priorities\n\nYou can differentiate channels by alert type:\n\n| Situation | Recommended Channels |\n|-----------|---------------------|\n| **Critical outage** | SMS + Voice + Email + Slack |\n| **Performance warning** | Email + Slack |\n| **SSL warning** | Email |\n| **Recovery** | Email |\n\n## Tips\n\n1. **Use multiple channels**: Don't rely on a single channel — add backup channels\n2. **Enable SMS/Voice for critical monitors**: Email can be delayed; SMS arrives instantly\n3. **Send test notifications**: Test after each channel configuration\n4. **Create a dedicated channel**: Use a separate channel like #alerts in Slack/Teams\n5. **Narrow alert types**: Select only relevant alert types for each channel\n\n## Related Documentation\n\n- **Webhook Configuration**: Webhook wizard and provider details\n- **Push Notifications**: Device management and platform support\n- **Push Templates**: Notification message customization\n- **Telegram Settings**: Bot setup and templates\n- **On-Call Settings**: Voice calls and escalation policy\n- **Integrations**: Slack and Teams setup","category":"notifications","tags":["notifications","alerts","email","slack","sms","webhook","teams","whatsapp"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"UptimeWarden notification channels, alert types, and configuration guide","icon":"Bell","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTJ8MC6R3GX5Z2RWBGQ","locale":"en","translationGroup":"on-call","slug":"en-on-call","title":"Voice Call and On-Call Settings","description":"Voice call notification configuration, Twilio integration, and escalation policy settings","body":"# Voice Call and On-Call Settings\n\nUptimeWarden can automatically make voice calls to your team members during critical outages. This feature provides an effective notification channel during nighttime hours or emergencies when email and SMS might be missed.\n\n## What is Voice Call Notification?\n\nVoice call notification is a notification channel that automatically calls designated phone numbers when a monitor goes down, delivering outage information verbally.\n\n**Advantages:**\n- Guarantees waking up during nighttime hours\n- No risk of missing like SMS or email\n- DTMF keypress acknowledgment mechanism (verify the recipient received the message)\n- Escalation with multi-level calling\n\n## Twilio Integration\n\nThe voice call feature uses **Twilio** infrastructure. A Twilio account is required to get started.\n\n### Twilio Settings\n\n1. Go to the **Settings → On-Call Settings** page\n2. Enter your Twilio credentials in the **Settings** tab:\n\n| Field | Description |\n|-------|-------------|\n| **Account SID** | Twilio account identifier |\n| **Auth Token** | Twilio authentication token |\n| **Phone Number** | Twilio phone number for outgoing calls (e.g., +1234567890) |\n\n3. Click **\"Save\"**\n\n### Voice Settings (TTS)\n\nYou can customize the text-to-speech settings used in voice calls:\n\n- **Voice**: Alice (default), Man, or Woman\n- **Language**: Language code (e.g., en-US, tr-TR)\n- **Speed**: Speech rate (0.8 - 1.2)\n\n## Escalation Policy\n\nThe escalation policy determines the order and recipients of voice calls.\n\n### Escalation Steps\n\nCreate a tiered calling plan in the **Escalation Policy** tab:\n\n| Step | Setting | Description |\n|------|---------|-------------|\n| **Level 1** | Phone numbers | People to call first |\n| **Level 2** | Phone numbers | People to call if Level 1 doesn't respond |\n| **Level 3** | Phone numbers | Backup contacts |\n\nFor each level:\n- **Phone numbers**: Numbers to call\n- **Call strategy**: Sequential or parallel\n- **Wait time**: Wait before moving to the next level\n- **Retry delay**: Wait before calling the same number again\n\n### DTMF Acknowledgment\n\nWhen a called person answers, they can be asked to press a key to confirm they received the message. This ensures:\n- A real person answered, not voicemail\n- If not acknowledged, the system moves to the next level\n\n## Voice Message Templates\n\nEdit the message templates spoken during voice calls from the **Templates** tab.\n\nAvailable variables in templates:\n- `{monitor_name}` — Name of the monitor that went down\n- `{incident_time}` — Incident start time\n- `{status}` — Monitor status\n\n**Example template:**\n> \"Attention! {monitor_name} service has been down since {incident_time}. Please check the status. Press 1 if you received this message.\"\n\n## Test Call\n\nTest your settings from the **Test** tab:\n\n1. Enter the phone number to test\n2. Click the **\"Make Test Call\"** button\n3. Your phone will ring and play a sample outage message\n\n## Using Voice Calls with Monitors\n\nTo add voice call notifications to monitors:\n\n1. Go to monitor settings\n2. Enable the **Voice** channel in the notifications section\n3. Add phone numbers to call\n4. Select which events should trigger calls (down, recovery, etc.)\n\n## Best Practices\n\n1. **Use only for critical outages**: Don't make voice calls for every alert — reserve for serious outages only\n2. **Define multiple levels**: Have a backup plan if the first person doesn't respond\n3. **Keep DTMF acknowledgment enabled**: Ensure you reach a real person, not voicemail\n4. **Make test calls**: Always test after setup\n5. **Monitor your Twilio balance**: Insufficient balance will prevent calls","category":"notifications","tags":["on-call","voice","call","twilio","escalation","alert"],"order":2,"parentSlug":"notifications","published":true,"version":1,"metaTitle":null,"metaDescription":"Voice call notification configuration, Twilio integration, and escalation policy settings","icon":"Bell","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTKJ8MB8604S921XVQG","locale":"en","translationGroup":"webhook-configuration","slug":"en-webhook-configuration","title":"Webhook Configuration","description":"Webhook notification channel setup, provider integrations, and custom webhook configuration guide","body":"# Webhook Configuration\n\nWebhooks are notification channels that automatically send HTTP requests to a specified URL when an event occurs on your monitors. You can integrate with Slack, Discord, Microsoft Teams, and your custom systems.\n\n## Supported Providers\n\n| Provider | Description |\n|----------|-------------|\n| **Slack** | Send notifications to a Slack channel |\n| **Discord** | Send notifications to a Discord channel |\n| **Telegram** | Send messages via Telegram bot |\n| **Microsoft Teams** | Send notifications to a Teams channel |\n| **PagerDuty** | Create PagerDuty incidents |\n| **OpsGenie** | Create OpsGenie alerts |\n| **Generic** | Send to any HTTP endpoint |\n\n## Creating a Webhook\n\nGo to the **Settings → Webhooks** page and click the **\"New Webhook\"** button. A 4-step wizard will guide you.\n\n### Step 1: Basic Information\n\n| Field | Description |\n|-------|-------------|\n| **Name** | Descriptive name for the webhook (e.g., \"Slack - DevOps Channel\") |\n| **Webhook Type** | Provider selection (Slack, Discord, Generic, etc.) |\n| **URL** | Target webhook URL |\n| **HTTP Method** | GET, POST, PUT, PATCH, or DELETE |\n| **Message Format** | JSON, Markdown, HTML, or Plain Text |\n| **Timeout** | Maximum wait time (1-300 seconds, default: 30) |\n\nWhen you select a provider, an example format is shown in the URL field. Use the **\"URL Test\"** button to verify the URL is accessible.\n\n### Step 2: Authentication\n\nIf your webhook endpoint requires authentication:\n\n- **None**: No authentication\n- **Bearer Token**: Send token in Authorization header\n- **Basic Auth**: Username and password\n- **Custom Headers**: Add custom headers\n\n### Step 3: Targeting\n\nSelect which events should trigger the webhook:\n\n**Alert Types:**\n- Monitor Down (outage)\n- Monitor Recovery\n- SSL Certificate (certificate warning)\n- High Response Time\n- Response Time Recovery\n\n**Monitor Types:**\nSelect which monitor types to trigger for: HTTP/HTTPS, TCP, UDP, SSL, WebSocket, MCP, gRPC\n\n**Quiet Hours:**\nYou can prevent the webhook from triggering during specific hours:\n- Quiet hours start and end time\n- Timezone selection\n\n### Step 4: Summary\n\nReview all settings and click the **\"Save\"** button.\n\n## Testing a Webhook\n\nClick the **\"Test\"** button on the webhook card to test it. A test notification is sent to the specified URL and the result is shown as success/failure.\n\n## Webhook Status\n\nEach webhook card displays:\n- **Active/Inactive** status (toggleable)\n- **Success rate**: Percentage of recent notifications that succeeded\n- **Last error**: Last error message, if any\n\n## Provider Setup Guides\n\n### Slack\n\n1. Create an **Incoming Webhook** in your Slack workspace:\n   - Add the \"Incoming Webhooks\" app from the Slack API page\n   - Select the target channel\n   - Copy the Webhook URL\n2. Select **Slack** as the webhook type in UptimeWarden\n3. Paste the copied URL\n\n### Discord\n\n1. Go to the target channel settings in your Discord server\n2. Create a new webhook via **Integrations → Webhooks → New Webhook**\n3. Copy the Webhook URL\n4. Select **Discord** as the webhook type in UptimeWarden\n5. Paste the URL\n\n### Microsoft Teams\n\n1. Add **Connectors → Incoming Webhook** in a Teams channel\n2. Give the webhook a name and icon\n3. Copy the generated URL\n4. Select **Teams** as the webhook type in UptimeWarden\n5. Paste the URL\n\n### Generic (Custom Endpoint)\n\nTo send notifications to your own API endpoint:\n1. Select **Generic** as the webhook type\n2. Enter your endpoint URL\n3. Configure the required authentication settings\n4. Select JSON as the message format\n\n## Message Templates\n\nYou can define custom message templates for each webhook. Click the **\"Templates\"** button on the webhook card to open the template management panel.\n\n## Tips\n\n1. **Choose the correct provider type**: Optimized payload format is used for each provider\n2. **Test it**: Always send a test notification after creating a webhook\n3. **Adjust the timeout**: Increase the timeout for slow endpoints\n4. **Use quiet hours**: Prevent unnecessary notifications during scheduled maintenance\n5. **Monitor success rate**: Low success rate may indicate connection or authentication issues","category":"notifications","tags":["webhook","integration","notification","slack","discord","teams","pagerduty"],"order":3,"parentSlug":"notifications","published":true,"version":1,"metaTitle":null,"metaDescription":"Webhook notification channel setup, provider integrations, and custom webhook configuration guide","icon":"Bell","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTKAKE5QWQ1XJARPQCM","locale":"en","translationGroup":"push-notifications","slug":"en-push-notifications","title":"Push Notifications","description":"Guide to enabling mobile and web push notifications, device management, and testing","body":"# Push Notifications\n\nPush notifications deliver outage alerts directly to your phone or browser instantly. Get notified immediately without relying on email or SMS.\n\n## How Push Notifications Work\n\n1. Download the mobile app or allow notifications in your web browser\n2. Your device is automatically registered with UptimeWarden\n3. You receive push notifications when an event occurs on your monitors\n\n## Supported Platforms\n\n| Platform | Setup |\n|----------|-------|\n| **iOS** | Download the UptimeWarden app from the App Store |\n| **Android** | Download the UptimeWarden app from Google Play |\n| **Web** | Grant browser notification permission |\n\n## Device Management\n\nView your registered devices on the **Settings → Push Notifications** page.\n\n### Device List\n\nFor each registered device:\n- **Platform**: iOS, Android, or Web (shown with icon)\n- **Device name**: Device model or browser information\n- **App version**: Installed app version\n- **Status**: Active (used in the last 30 days) or Inactive\n- **Last activity**: When the last notification was received\n- **Registration date**: When the device was registered\n\n### Device Actions\n\n- **Test**: Send a test notification to the selected device\n- **Delete**: Remove the device from the list (confirmation required)\n\nDevices inactive for more than 30 days are automatically marked as inactive.\n\n## Push Notifications for Monitors\n\nTo enable push notifications on a per-monitor basis:\n\n1. Go to monitor settings\n2. Enable the **Push** channel in the notifications section\n3. Select which events to receive notifications for (down, recovery, etc.)\n4. Save\n\n## Tips\n\n1. **Keep the app updated**: The latest version provides the best notification experience\n2. **Check notification permissions**: Make sure UptimeWarden notifications are enabled in your phone settings\n3. **Send a test**: Verify it works by sending a test notification after setup\n4. **Clean up unused devices**: Remove devices you no longer use from the list","category":"notifications","tags":["push","notification","mobile","browser","fcm"],"order":4,"parentSlug":"notifications","published":true,"version":1,"metaTitle":null,"metaDescription":"Guide to enabling mobile and web push notifications, device management, and testing","icon":"Bell","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTMA95Z1E79ADJ65X5Y","locale":"en","translationGroup":"integrations","slug":"en-integrations","title":"Integrations (Slack and Microsoft Teams)","description":"Slack and Microsoft Teams integration setup and configuration guide","body":"# Integrations (Slack and Microsoft Teams)\n\nUptimeWarden provides direct integration with Slack and Microsoft Teams. These integrations automatically deliver outage notifications to your team communication tools.\n\n## Slack Integration\n\n### Setup\n\n1. Go to the **Integrations** menu\n2. Select the **Slack** tab\n3. Enter the following information:\n\n| Field | Description |\n|-------|-------------|\n| **Bot Token** | Slack Bot User OAuth Token (starts with xoxb-) |\n| **Channel ID** | Channel ID where notifications will be sent |\n\n4. Check the **\"Enable Slack notifications\"** checkbox\n5. Test the connection with the **\"Test Connection\"** button\n6. Save with **\"Save Configuration\"**\n\n### Getting a Slack Bot Token\n\n1. Go to [api.slack.com/apps](https://api.slack.com/apps)\n2. Create a new app with **\"Create New App\"**\n3. Go to the **OAuth & Permissions** section\n4. Add the following permissions under Bot Token Scopes:\n   - `chat:write` — Send messages\n   - `chat:write.public` — Write to public channels\n5. Install to your workspace with **\"Install to Workspace\"**\n6. Copy the Bot User OAuth Token\n\n### Finding the Channel ID\n\n1. Go to the target channel in Slack\n2. Click the channel name → Channel details\n3. Find the **Channel ID** at the bottom (e.g., `C1234567890`)\n\n## Microsoft Teams Integration\n\n### Basic Setup\n\n1. Go to the **Integrations** menu\n2. Select the **Microsoft Teams** tab\n3. In the **Basic Settings** sub-tab:\n\n| Field | Description |\n|-------|-------------|\n| **Webhook URL** | Teams Incoming Webhook URL |\n\n4. Check the **\"Enable Teams notifications\"** checkbox\n5. Save with **\"Save Configuration\"**\n\n### Getting a Teams Webhook URL\n\n1. Go to the target channel's settings in Microsoft Teams\n2. Add **Connectors** → **Incoming Webhook**\n3. Assign a name and icon to the webhook\n4. Click **\"Create\"**\n5. Copy the generated URL\n\n### Adaptive Card Templates\n\nIn the **Adaptive Cards** sub-tab, you can customize the appearance of Teams notifications:\n\n- Create custom adaptive card templates\n- Edit and delete templates\n- Define different templates for each notification type (down, recovery, etc.)\n\nAdaptive Cards allow you to add rich visual elements (buttons, colors, cards) to your Teams messages.\n\n## Integration vs Webhook Difference\n\n| | Integration | Webhook |\n|---|---|---|\n| **Setup** | One-time configuration | Each webhook created separately |\n| **Scope** | All monitors | Selected monitor types/alert types |\n| **Customization** | Adaptive Card support (Teams) | Template and message format |\n| **When to use** | Entire team monitoring from one channel | Targeted notifications for specific monitors |\n\nBoth methods can be used. Prefer integrations for general notifications and webhooks for targeted notifications.\n\n## Tips\n\n1. **Create a dedicated channel**: Direct notifications to a dedicated channel like #monitoring or #alerts, not general channels\n2. **Test first**: Test the connection before saving\n3. **Check bot permissions**: The Slack bot must have write access to the target channel\n4. **Protect the Teams URL**: Don't share the webhook URL publicly","category":"notifications","tags":["integrations","slack","teams","microsoft","notification"],"order":5,"parentSlug":"notifications","published":true,"version":1,"metaTitle":null,"metaDescription":"Slack and Microsoft Teams integration setup and configuration guide","icon":"Bell","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTN9X1JT8N27K6A80A2","locale":"en","translationGroup":"telegram","slug":"en-telegram","title":"Telegram Notification Settings","description":"Telegram bot setup, message templates, and test notification guide","body":"# Telegram Notification Settings\n\nWith Telegram integration, you can receive outage notifications directly in your Telegram chat or group. All you need is to create a Telegram bot.\n\n## Telegram Settings Page\n\nThe **Settings → Telegram** page consists of 3 tabs: **Settings**, **Templates**, and **Test**.\n\n## Setup (Settings Tab)\n\n### Step 1: Create a Telegram Bot\n\n1. Start a chat with **@BotFather** on Telegram\n2. Send the `/newbot` command and follow the instructions\n3. Copy your bot token\n4. Start a chat with your created bot (send `/start`)\n5. To find your Chat ID, start a chat with **@userinfobot**\n\n### Step 2: Configure Settings\n\n| Field | Description |\n|-------|-------------|\n| **Bot Token** | Token from @BotFather (e.g., `1234567890:ABCdefGHIjklMNOpqrsTUVwxyz`) |\n| **Message Format** | Message format: Markdown (recommended), HTML, or MarkdownV2 |\n\nThe Bot Token field is a password type; the value is displayed hidden.\n\nSave the configuration with the **\"Save Settings\"** button.\n\n## Test Notification (Test Tab)\n\nYou can send a test notification to verify your setup:\n\n1. Enter your Telegram **Chat ID** (numeric value, e.g., `123456789`)\n2. Click the **\"Send Test Notification\"** button\n3. Verify the test message arrived in Telegram\n\n> **Note**: You must have started a chat with your bot before sending tests (send `/start`). You can find your Chat ID with `@userinfobot`.\n\nIf you have previously saved Chat IDs, they appear in a list and can be quickly selected with the **\"Use\"** button.\n\n## Message Templates (Templates Tab)\n\nYou can customize the content of Telegram notifications.\n\n### Creating Templates\n\n1. Click the **\"New Template\"** button\n2. Enter the message content in the template editor\n3. Save\n\n### Template List\n\nInformation shown for each template:\n- Template name\n- **System** badge (if system template)\n- **Default** badge (if default template)\n- Template type and format information\n- Edit and delete buttons\n\n### Message Format Options\n\n| Format | Description |\n|--------|-------------|\n| **Markdown** | Standard Markdown format (recommended) |\n| **HTML** | Formatting with HTML tags |\n| **MarkdownV2** | Telegram's advanced Markdown format |\n\n## Finding Your Chat ID\n\n### Personal Chat ID\n\n1. Start a chat with **@userinfobot** on Telegram\n2. Send `/start`\n3. The bot will tell you your Chat ID\n\n### Group Chat ID\n\n1. Add the bot to the group\n2. Send a message in the group\n3. Open this URL in your browser: `https://api.telegram.org/bot<TOKEN>/getUpdates`\n4. Use the `chat.id` value from the response (group IDs start with `-`)\n\n## Tips\n\n1. **Add the bot to a group**: For team monitoring, add the bot to a group and use the group Chat ID\n2. **Prefer Markdown format**: The most widely supported and readable format\n3. **Send tests**: Send a test notification after each configuration change\n4. **Multiple chats**: You can use different Telegram groups for different monitors","category":"notifications","tags":["telegram","bot","notification","messaging"],"order":6,"parentSlug":"notifications","published":true,"version":1,"metaTitle":null,"metaDescription":"Telegram bot setup, message templates, and test notification guide","icon":"Bell","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTN3854W0TW3H9TXJ89","locale":"en","translationGroup":"push-templates","slug":"en-push-templates","title":"Push Notification Templates","description":"Guide to customizing push notification messages, template variables, and management","body":"# Push Notification Templates\n\nPush notification templates let you customize the content of mobile and web push notifications. You can define separate messages for each alert type.\n\n## Accessing the Template Page\n\nAccess the template management page from **Settings → Push Templates**.\n\n## Template Types\n\nYou can define templates for 5 different alert types:\n\n| Type | Description |\n|------|-------------|\n| 🔴 **Downtime Alert** | Service outage notification |\n| ✅ **Recovery Alert** | Service restored notification |\n| 🔒 **SSL Warning** | SSL certificate warning |\n| ⚠️ **High Response Time** | High response time warning |\n| ⚡ **Response Recovered** | Response time back to normal |\n\n## Creating a Template\n\n1. Click the **\"New Template\"** button\n2. Select a **template type** (one of 5 types)\n3. Enter the notification text in the **message content** field\n4. Save with **\"Save Template\"**\n\n### Message Editor\n\n- Enter your notification message in the text field\n- Use the **\"Load Default\"** button to revert to the default template\n- Recommended character limit: **178 characters** (mobile notifications have limited display space)\n\n## Available Variables\n\nUse dynamic variables with curly braces `{}` in templates. These variables are replaced with actual values when the notification is sent:\n\n| Variable | Description |\n|----------|-------------|\n| `{monitor_id}` | Monitor ID |\n| `{monitor_name}` | Monitor name |\n| `{monitor_url}` | Monitor URL |\n| `{monitor_type}` | Monitor type |\n| `{timestamp}` | Event time |\n| `{iso_timestamp}` | ISO format timestamp |\n| `{incident_type}` | Incident type |\n| `{incident_message}` | Incident description |\n| `{status}` | Status information |\n| `{response_time}` | Response time (ms) |\n| `{status_code}` | HTTP status code |\n| `{ssl_expiry}` | SSL expiration date |\n| `{ssl_expiry_days}` | Days until SSL expiration |\n| `{threshold}` | Threshold value |\n| `{downtime_duration}` | Downtime duration |\n| `{recovery_details}` | Recovery details |\n\n## Default Templates\n\nPre-built default templates are available for each type:\n\n- **Downtime**: `{monitor_name} is currently down. Error: {incident_message}`\n- **Recovery**: `{monitor_name} is back online. Response time: {response_time}ms`\n- **SSL**: `SSL certificate for {monitor_name} expires in {ssl_expiry_days} days`\n- **High Response**: `{monitor_name} is responding slowly ({response_time}ms > {threshold}ms)`\n- **Response Recovered**: `{monitor_name} response time is back to normal ({response_time}ms)`\n\n## Template Management\n\n### Template List\n\nExisting templates are displayed in a list. For each template:\n- Alert type icon and label\n- Message content preview\n- Edit (pencil icon) and delete (trash can) buttons\n\n### Editing Templates\n\nClick the edit button to update an existing template. Template type and message content can be modified.\n\n### Deleting Templates\n\nClick the delete button to remove a template. Confirmation is required before deletion.\n\n## Tips\n\n1. **Keep it short and concise**: Mobile notifications display limited space — 178 characters recommended\n2. **Include the monitor name**: Use the `{monitor_name}` variable to identify the affected service\n3. **Put critical information first**: Write the status information at the beginning of the message\n4. **Test it**: Send test notifications from the Push Notifications page after saving a template\n5. **Separate templates for each type**: Write customized messages for different alert types","category":"notifications","tags":["push","templates","notification","customization","fcm"],"order":7,"parentSlug":"notifications","published":true,"version":1,"metaTitle":null,"metaDescription":"Guide to customizing push notification messages, template variables, and management","icon":"Bell","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"6ad642ea8151460e978fb570ab","locale":"en","translationGroup":"escalation-policies","slug":"en-escalation-policies","title":"Escalation Policies (On-Call)","description":"Build a PagerDuty-style on-call ladder — if the first person doesn't respond, the next one gets paged automatically.","body":"# Escalation Policies (On-Call)\n\nPayment API crashes at 3 AM. An email alert fires to a team alias. Three engineers are in it — two are asleep, one's on vacation. The fourth, who could actually fix it, isn't in the list because she joined last month. Nobody responds for 40 minutes.\n\nEscalation policies solve this: first, try this week's on-call Ayşe (phone + push + email). If she doesn't respond, **wait 5 minutes** and page Burak. If still nothing, **wait 10 more minutes** and page the team lead Ebru. The moment anyone clicks the email's \"Acknowledge\" button, the ladder stops climbing.\n\n## Feature summary\n\n| | |\n|---|---|\n| **On-call rotation** | Weekly — one person per day |\n| **Escalation tier count** | 1–N (typically 3–5) |\n| **Tier target types** | Direct user / rotation schedule |\n| **Channels (per-tier selectable)** | email, sms, whatsapp, voice, push (FCM), slack, telegram |\n| **Acknowledgement** | One-click email link OR dashboard \"Acknowledge\" button |\n| **Auto-resolution** | Monitor recovery completes the ladder automatically |\n\n## Scenario: step by step\n\nThe team attached the \"API Critical\" escalation policy to the Payment API monitor. The policy has 3 tiers:\n\n1. **Tier 1**: Page the \"Weeknights\" rotation. Wait 5 minutes.\n2. **Tier 2**: Page team lead Ebru. Wait 10 minutes.\n3. **Tier 3**: Page CTO Fatih. Done.\n\n### Happy-path ack\n\n| Time | Event |\n|---|---|\n| 03:12:00 | Monitor fails. Incident opens, ack token minted. |\n| 03:12:15 | 15-second runner tick → Tier 1 fires: Tuesday's on-call **Burak** gets email + SMS + push. |\n| 03:15:40 | Burak wakes up, clicks \"Acknowledge\" in the email. Incident is acked. |\n| 03:15:45 | Next runner tick sees `acknowledged_at != NULL` and skips the row. **Tier 2 never fires.** Ebru and Fatih are not disturbed. |\n| 03:18:00 | Burak fixes the issue. Monitor recovers. Escalation state is completed. |\n\n### No-ack scenario\n\n| Time | Event |\n|---|---|\n| 03:12:15 | Tier 1 fires (Burak). |\n| 03:17:15 | 5 minutes elapsed, still unacked → Tier 2 fires (Ebru). |\n| 03:27:15 | 10 minutes elapsed → Tier 3 fires (Fatih). |\n| 03:27:15 | Policy exhausted. Runner marks state completed. |\n\n### Nobody on-call on Tuesday\n\n| Time | Event |\n|---|---|\n| 03:12:15 | Runner looks up Tuesday's on-call → empty → Tier 1 **skipped**. `escalation_tiers_skipped_total{reason=\"no_on_call\"}` increments. State advances anyway. |\n| 03:17:15 | Tier 2 fires (Ebru). |\n\nSchedule gaps never stall the ladder — the next tier fires normally.\n\n## Defining an on-call rotation\n\n**Settings → On-call Rotations**:\n\n1. **New Schedule** → name it (e.g. `Weeknights`).\n2. **Timezone** — day-of-week boundaries are computed in this zone.\n3. Assign a user to each day:\n   - Monday: Ayşe\n   - Tuesday: Burak\n   - Wednesday: Cem\n   - Thursday: Ayşe\n   - Friday: Deniz\n   - Sat/Sun: (empty — no weekend work)\n\nEmpty days mean \"no one on-call that day.\" The ladder records a **tier skip** and advances.\n\n## Defining an escalation policy\n\n**Settings → Escalation Policies → New Policy**:\n\n1. **Name**: `API Critical`, `Low-Priority Warnings`, etc.\n2. **Tiers** (ordered):\n   - **Tier 0**: Target type (`user` or `schedule`) + target + wait_minutes (how long before the next tier) + channels (which channels to page through).\n   - **Tier 1**: ...\n   - **Tier N**: The final tier's wait_minutes is ignored (nothing after it).\n\n**Channel-selection tips:**\n\n- First tier: `email + push + sms` — fastest-attention trio.\n- Second tier: above + `voice` (the phone rings; they might be asleep).\n- Last tier: whatever works — CTO probably reads email too, but voice is typical.\n\n## Attaching to a monitor\n\nOn the monitor form, pick an **Escalation Policy** from the dropdown. Leave it empty and the monitor uses the legacy per-channel notification path — no escalation at all.\n\n**Important**: When you attach a policy, the monitor's legacy channel pipeline is **fully bypassed** (otherwise the same person would be double-paged). The policy becomes the sole dispatch authority.\n\n## How acknowledgement works\n\nTwo paths:\n\n**1. Anonymous one-click (email link)**\n\nThe email's **Acknowledge incident** button links to `https://app.uptimewarden.online/api/incidents/ack/<token>`. The token IS the authentication — no login required. 32-byte unguessable token, rate-limited to 30 req/min per IP.\n\nDesigned so the 3-AM engineer reading email on their phone can ack in one tap — no login friction.\n\n**2. Dashboard \"Acknowledge\" button**\n\nA logged-in user opens the incident detail page and clicks the button. This records `acknowledged_by = user.id` (anonymous path leaves it NULL). Use this path if you want audit trails of who acknowledged what.\n\n## Supported channels\n\nEach tier can pick from these channels:\n\n| Channel | Where recipient comes from | If missing |\n|---|---|---|\n| `email` | `users.email` | Tier skips channel + records metric |\n| `sms` | `users.phone` | Skip + metric |\n| `whatsapp` | `users.phone` | Skip + metric |\n| `voice` | `users.phone` | Skip + metric |\n| `push` | User's active `device_tokens` | Skip + metric |\n| `slack` | User's own `slack_settings` row | Skip + metric |\n| `telegram` | User's own `telegram_settings` row | Skip + metric |\n\n**Critical**: For Slack/Telegram, **each** on-call user needs their own settings row. If only the team lead has `slack_settings` configured, the other on-call users won't receive Slack notifications — reported as a profile-hygiene metric.\n\n## Metrics\n\nThree Prometheus counters:\n\n- `escalation_tiers_fired_total{tier, target_type, result}` — tier dispatches (result: dispatched / error / no_router)\n- `escalation_tiers_skipped_total{tier, reason}` — whole tier skipped (e.g., schedule empty: `reason=\"no_on_call\"`)\n- `escalation_channel_skipped_total{channel, reason}` — fired tier but one channel skipped (e.g., `reason=\"no_phone\"`)\n\n**Dashboard intent**: high `tiers_skipped` means policy misconfiguration; high `channel_skipped` means user profile hygiene problems.\n\n## FAQ\n\n**Q: Can I page multiple people in parallel from a single tier?**\nA: There's no in-tier parallel fan-out today — each tier has one target (user or schedule). For \"wake up two people together,\" put both in consecutive tiers with `wait_minutes: 0`.\n\n**Q: Does recovery stop the ladder?**\nA: Yes. Monitor recovery → the incident subscriber calls `ResolveForIncident` → state completed. The next tick skips the row. Same for an already-acked incident.\n\n**Q: Does the ack token expire?**\nA: No — it's valid until the incident closes. An already-acked incident's token, clicked again accidentally at night, is a no-op (already-acked response).\n\n**Q: I edited the policy — does it affect a live incident?**\nA: No. `incident_escalations.policy_id` is a snapshot. We don't mutate page sequence mid-ring. Edits apply to the next incident.\n\n**Q: What happens to the monitor when I ack?**\nA: Ack only stops the ladder. The monitor is still down. The incident stays open until recovery — but the pager stops ringing.\n\n## Known limits\n\n- Day-of-week granularity — no intra-day handoffs (\"Ayşe 9-5, Burak 5-9\") today\n- One policy per monitor — no alert-type-based routing (different policy for down vs. SSL)\n- Teams/webhook channels aren't available in escalation (the recipient is a URL, not a user)\n\n## Related topics\n\n- [On-Call Rotations](/docs/en-on-call) — rotation management details\n- [Notification Channels](/docs/en-notification-channels) — per-channel configuration\n- [Incident Management](/docs/en-incidents-overview)","category":"notifications","tags":["on-call","escalation","pagerduty","rotation"],"order":10,"parentSlug":"notifications","published":true,"version":2,"metaTitle":"Escalation Policies — UptimeWarden Documentation","metaDescription":"The payment API goes down at 3 AM. If the primary doesn't wake up, the backup is paged in 5 minutes.","icon":"Bell","createdAt":"2026-04-19T00:06:52.889Z","updatedAt":"2026-04-19T00:16:16.629Z","publishedAt":"2026-04-19T00:06:52.889Z"},{"publicId":"01M4S2EP4Q15F8H40WAXDE4E38","locale":"en","translationGroup":"escalation-policies","slug":"escalation-policies","title":"Escalation Policies (On-Call)","description":"Build a PagerDuty-style on-call ladder, if the first person doesn't respond, the next one gets paged automatically.","body":"# Escalation Policies (On-Call)\n\nThe Payment API crashes at 3 AM. An email alert fires to a team alias. Three engineers are on it, two are asleep, one's on vacation. The fourth, who could actually fix it, isn't on the list because she joined last month. Nobody responds for 40 minutes.\n\nEscalation policies solve this. First, try this week's on-call Ayşe (phone, push, and email). If she doesn't respond, wait five minutes and page Burak. If still nothing, wait ten more minutes and page the team lead Ebru. The moment anyone clicks the email's **Acknowledge** button, the ladder stops climbing.\n\n> **Plan:** On-call escalation (rotations and policies) is managed from the **Settings → Notifications → On-Call** tab; the editors open on **Hobby and up**. Users on the Free plan see an upgrade prompt instead of the editors.\n\n## Escalation ladder, visual flow\n\n```mermaid\nflowchart TD\n    Incident([Incident open])\n    L1[Tier 1: Primary on-call<br/>email + push + voice]\n    Wait1{Acknowledged<br/>within 5 min?}\n    L2[Tier 2: Backup on-call<br/>email + sms + voice]\n    Wait2{Acknowledged<br/>within 10 min?}\n    L3[Tier 3: Team lead<br/>all channels]\n    Resolved([Acknowledged, ladder stops])\n\n    Incident --> L1 --> Wait1\n    Wait1 -- Yes --> Resolved\n    Wait1 -- No --> L2 --> Wait2\n    Wait2 -- Yes --> Resolved\n    Wait2 -- No --> L3 --> Resolved\n```\n\nEach tier can target a different channel set. A single acknowledgement stops every tier, any tier that hasn't fired yet is never paged.\n\n## Feature summary\n\n| | |\n|---|---|\n| On-call rotation | Weekly, one person per day |\n| Escalation tier count | 1 to N (typically 3 to 5) |\n| Tier target types | User (direct user) or schedule (rotation), team and webhook targets are on the roadmap |\n| Channels (per-tier selectable) | email, SMS, WhatsApp, voice, push, Slack, Telegram |\n| Acknowledgement | One-click email link or dashboard \"Acknowledge\" button |\n| Auto-resolution | Monitor recovery completes the ladder automatically |\n\n## Scenario: step by step\n\nThe team attached the \"API Critical\" escalation policy to the Payment API monitor. The policy has three tiers:\n\n1. **Tier 1**, page the \"Weeknights\" rotation. Wait 5 minutes.\n2. **Tier 2**, page team lead Ebru. Wait 10 minutes.\n3. **Tier 3**, page CTO Fatih. Done.\n\n### Happy-path acknowledgement\n\n| Time | Event |\n|---|---|\n| 03:12:00 | Monitor fails. Incident opens, ack token minted. |\n| 03:12:15 | Tier 1 fires: Tuesday's on-call **Burak** gets email, SMS, and push. |\n| 03:15:40 | Burak wakes up and clicks **Acknowledge** in the email. The incident is acknowledged. |\n| 03:15:45 | The ladder sees the ack and skips ahead. **Tier 2 never fires.** Ebru and Fatih are not disturbed. |\n| 03:18:00 | Burak fixes the issue. Monitor recovers. Escalation completes. |\n\n### No-ack scenario\n\n| Time | Event |\n|---|---|\n| 03:12:15 | Tier 1 fires (Burak). |\n| 03:17:15 | Five minutes elapsed, still unacknowledged → Tier 2 fires (Ebru). |\n| 03:27:15 | Ten more minutes elapsed → Tier 3 fires (Fatih). |\n| 03:27:15 | Policy exhausted. Escalation marked as completed. |\n\n### Nobody on-call on Tuesday\n\n| Time | Event |\n|---|---|\n| 03:12:15 | Tuesday's on-call slot is empty → Tier 1 is skipped, the skip is recorded, and the ladder advances anyway. |\n| 03:17:15 | Tier 2 fires (Ebru). |\n\nSchedule gaps never stall the ladder, the next tier fires normally.\n\n## Defining an on-call rotation\n\nOpen **Settings → Notifications → On-Call**:\n\n1. **New Schedule** → name it (for example, `Weeknights`).\n2. **Timezone**, day-of-week boundaries are computed in this zone.\n3. Assign a user to each day:\n   - Monday: Ayşe\n   - Tuesday: Burak\n   - Wednesday: Cem\n   - Thursday: Ayşe\n   - Friday: Deniz\n   - Sat/Sun: empty (no weekend work)\n\nEmpty days mean no one is on-call that day. The ladder records a tier skip and advances.\n\n## Defining an escalation policy\n\nOpen **Settings → Notifications → On-Call → Escalation Policies → New Policy**:\n\n1. **Name**, `API Critical`, `Low-Priority Warnings`, and so on.\n2. **Tiers** (ordered):\n   - **Tier 0**: target type (user or schedule), target, wait time before the next tier, and the channels to page through.\n   - **Tier 1**: and so on.\n   - **Tier N**: the final tier's wait time is ignored.\n\n:::note Who can you escalate to?\nYou don't type a number or a name, you **select a registered user**. Selectable people are:\n\n- **yourself**, or\n- **active members of any team you belong to**.\n\nSo to escalate to someone, first invite them via **Team → Team Members**; once they're active on your team, you pick them from the **dropdown** in the policy/rotation editor. You never enter a phone number or email here, each person configures their own contact channels in their notification settings; the policy only decides **who** gets paged, and which channel (push/SMS/voice) is used comes from that person's own settings.\n\nA tier target can also be a **schedule** (an on-call rotation), in that case, whoever is on call that day is paged.\n:::\n\n:::warning What if the target person has no channel set up?\nEscalation tries to deliver the tier's **selected channels** to the target, but a channel only goes out **if that person configured it in their own settings**. For example, if a tier selects \"SMS + voice call\" but the target person has no phone number on file:\n\n- That channel is **silently skipped** (logged as \"no recipients configured for channel\"); the other channels still go out.\n- No mobile app → **push** doesn't go; no number → **SMS/voice** don't go.\n- Don't assume everyone has every channel: make sure **at least one channel in a tier is actually configured for the target**, or that tier times out reaching nobody and moves to the next tier.\n\nThat's why the first tier should always include **email**: every registered user has an email; phone/push are optional. Only put voice/SMS on upper tiers for people you know have a number saved.\n:::\n\n**Channel-selection tips:**\n\n- First tier: email + push + SMS: the fastest-attention trio.\n- Second tier: above + voice (the phone rings; they might be asleep).\n- Last tier: whatever works: the CTO probably reads email too, but voice is typical.\n\n## Attaching to a monitor\n\nOn the monitor form, pick an **Escalation Policy** from the dropdown. Leave it empty and the monitor uses the default per-channel notification path, no escalation at all.\n\n:::warning Default channels are bypassed\nWhen you attach a policy, the monitor's default channel pipeline is fully bypassed (otherwise the same person would be double-paged). The policy becomes the sole dispatch authority.\n:::\n\n## How acknowledgement works\n\nThere are two paths:\n\n**1. Anonymous one-click (email link)**\n\nThe email's **Acknowledge incident** button links to a unique acknowledgement URL. The token in the URL is the authentication, no login required. Tokens are unguessable and rate-limited per IP.\n\nThis is designed so the engineer reading email on their phone at 3 AM can acknowledge with one tap, no login friction.\n\n**2. Dashboard \"Acknowledge\" button**\n\nA logged-in user opens the incident detail page and clicks the button. This records who acknowledged, which the anonymous path leaves blank. Use this path if you want an audit trail of who acknowledged what.\n\n## Supported channels\n\nEach tier can pick from these channels:\n\n| Channel | Where the recipient comes from | If missing |\n|---|---|---|\n| email | The user's email address | Tier skips the channel and records a metric |\n| SMS | The user's phone number | Skip + metric |\n| WhatsApp | The user's phone number | Skip + metric |\n| voice | The user's phone number | Skip + metric |\n| push | The user's active mobile devices | Skip + metric |\n| Slack | The user's Slack connection | Skip + metric |\n| Telegram | The user's Telegram connection | Skip + metric |\n\n**Important:** for Slack and Telegram, each on-call user needs their own connection. If only the team lead has Slack configured, the other on-call users won't receive Slack notifications, and we surface this as a profile-hygiene metric.\n\n## Metrics\n\nThree counters are exposed for monitoring escalation behavior (operations/monitoring side, there is no in-app escalation dashboard):\n\n- **Tier dispatches**: by tier, target type, and result (dispatched, error, no channel found).\n- **Tier skips**: by tier and reason (for example, schedule empty).\n- **Channel skips**: by channel and reason (for example, no phone number on file).\n\n**Interpretation:** a high tier-skip rate means policy misconfiguration. A high channel-skip rate means user profile hygiene problems.\n\n## FAQ\n\n**Q: Can I page multiple people in parallel from a single tier?**\nA: Not today. Each tier has one target (user or schedule). For \"wake up two people together,\" put both in consecutive tiers with a zero-minute wait.\n\n**Q: Does recovery stop the ladder?**\nA: Yes. Monitor recovery resolves the escalation, the next check sees it, and the ladder stops. The same is true for an already-acknowledged incident.\n\n**Q: Does the ack token expire?**\nA: No, it's valid until the incident closes. An already-acked incident's token, clicked again accidentally at night, is a no-op.\n\n**Q: I edited the policy, does it affect a live incident?**\nA: Yes. The policy is not frozen when the incident opens, the escalation reads the tier definitions (order, wait time, target, and channels) live from the policy on every check. Only the escalation's current state (which tier it's on, the next page time) is created when the incident opens. So edits to tiers that haven't fired yet will change a live, in-progress escalation too.\n\n**Q: What happens to the monitor when I acknowledge?**\nA: Acknowledgement only stops the ladder. The monitor is still down. The incident stays open until recovery, but the pager stops ringing.\n\n## Known limits\n\n- Day-of-week granularity: no intra-day handoffs (\"Ayşe 9-5, Burak 5-9\") today.\n- One policy per monitor: no alert-type-based routing (different policy for down vs SSL).\n- Teams and webhook channels aren't available in escalation (the recipient is a URL, not a user).\n\n## Related topics\n\n- [On-Call Rotations](/docs/on-call): rotation management details\n- [Notification Channels](/docs/notification-channels): per-channel configuration\n- [Incident Management](/docs/incidents-overview)","category":"notifications","tags":["on-call","escalation","pagerduty","rotation"],"order":10,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Escalation Policies. UptimeWarden Documentation","metaDescription":"The payment API goes down at 3 AM. If the primary doesn't wake up, the backup is paged in five minutes.","icon":"Bell","createdAt":"2026-10-12T22:06:41.816Z","updatedAt":"2026-10-12T22:06:41.816Z","publishedAt":"2026-10-12T22:06:41.816Z"},{"publicId":"01M4S2EP31AS26HTBF3MKRCA8E","locale":"en","translationGroup":"notification-channels","slug":"notification-channels","title":"Notification Channels","description":"Pick the right channel mix for each monitor, email for routine, voice for 3-AM emergencies, push for the alerts you don't want to miss.","body":"# Notification Channels\n\nUptimeWarden ships nine first-party channels. Every monitor can pick any subset, and each channel can be wired to specific alert types, down, recovery, SSL expiry, slow response, and more. This page is the one-stop reference: what's available, where to configure it, and what plan you need.\n\n## Channel matrix\n\n| Channel | Cost class | Plan availability | Recipient source |\n|---|---|---|---|\n| Email | free | Free, Hobby, Starter, Professional, Enterprise | Monitor email recipients |\n| Push | free | Free, Hobby, Starter, Professional, Enterprise | Your registered mobile devices |\n| Webhook | free | Free, Hobby, Starter, Professional, Enterprise | Your saved webhook endpoints |\n| Slack | free | Free, Hobby, Starter, Professional, Enterprise | Your connected Slack account |\n| Telegram | free | Free, Hobby, Starter, Professional, Enterprise | Your connected Telegram bot |\n| Microsoft Teams | free | Free, Hobby, Starter, Professional, Enterprise | Your connected Teams account |\n| SMS | metered | Hobby+ (monthly quota) | Monitor phone recipients |\n| WhatsApp | metered | Hobby+ (monthly quota) | Monitor WhatsApp recipients |\n| Voice call | metered | Hobby+ (monthly quota) | Monitor voice recipients |\n\nSMS, WhatsApp, and voice calls draw from monthly quotas that your whole account shares, one unit for each phone number reached; see [Phone alerts: calls, texts and limits](#phone-alerts-calls-texts-and-limits) below. The free-tier channels, email, push, and webhooks, each have a per-plan monthly quota too (for example, on Free that's 250 email, 100 push, and 1,000 webhook sends per month); only Enterprise lifts these caps entirely. Slack, Telegram and Microsoft Teams are sent as webhooks, so every message counts against the webhook quota. See [Notifications](/docs/notifications-overview) for every plan's quotas.\n\n## Where to configure\n\nOpen **Settings → Notifications → Channels** to see every channel with a connected/disconnected indicator. Click a row to open its detail page:\n\n- **Email**, **SMS**, **WhatsApp**, **Voice**: UptimeWarden handles the underlying delivery infrastructure. You only pick which monitors use these channels and supply recipients.\n- **Slack**, **Teams**, **Telegram**: added as a **Webhook** (**Settings → Notifications → Webhooks**); each user connects their own account. If an on-call user hasn't connected their Slack or Telegram, escalation tiers will skip them.\n- **Webhook**: define webhook endpoints (URL, authentication, signing secret) per user. See [Webhook Configuration](/docs/webhook-configuration).\n- **Push**: devices register automatically when you sign in to the mobile app or grant browser permission. Web push is on the roadmap.\n\n## Per-monitor wiring\n\nOn the monitor edit form, the **Notifications** section shows a grid:\n\n```\n              | down | recovery | ssl | high_response |\n--------------|------|----------|-----|---------------|\nemail         |  on  |    on    |  on |      off      |\nsms           |  on  |    off   |  off|      off      |\npush          |  on  |    on    |  on |      on       |\n```\n\nEach cell is independent. Wake people up via SMS only when something is down, but keep recovery emails flowing so the inbox tells the full story.\n\n## Quiet hours\n\nEach channel supports a quiet-hours window. During the window:\n\n- `down` and critical SSL expiry alerts always fire, emergencies don't snooze.\n- Everything else (recovery, slow response, info-level) is buffered until the window closes.\n\nConfigure quiet hours per channel, not per monitor. This is a \"don't ping me from 11 PM to 7 AM\" personal preference, not a monitor-level setting.\n\n## Recipients\n\nFor SMS, WhatsApp, and voice calls, recipients live on the monitor as comma-separated lists:\n\n- Email recipients: `oncall@team.com,backup@team.com`\n- Phone numbers: `+905551234567,+905559876543`\n- WhatsApp numbers: same format as phone numbers\n- Voice numbers: same format\n\nYour plan limits how many of these phone numbers one alert reaches; see the next section.\n\nFor Slack, Teams, Telegram, and push, the recipient is the user themselves. UptimeWarden looks up your connected account by monitor owner, or by the on-call user when escalation is active. Each user must configure their own connection.\n\n## Phone alerts: calls, texts and limits\n\nSMS, WhatsApp and voice calls each have a monthly quota. The quota belongs to your account as a whole, not to a single monitor, and your plan sets its size (see [Notifications](/docs/notifications-overview)).\n\n### How units are counted\n\nOne unit is one phone number actually reached:\n\n- **SMS and WhatsApp**: a message counts when it is sent successfully.\n- **Voice**: a call counts only when it is answered. A call that goes to voicemail counts too, because it connects.\n- Unanswered, busy, failed or canceled calls use nothing.\n\nFor example, an alert that texts three numbers uses three SMS units. An alert that calls three numbers in order, where the first number does not answer and the second person answers and presses 1, uses one voice unit.\n\n### How voice calls are placed\n\nEach monitor has a call mode:\n\n- **Call in order (on-call style)**: the default. The monitor's voice numbers are called one at a time, in the order they are listed. When a call ends without anyone pressing 1, the next number is called. Calling stops as soon as someone presses 1.\n- **Call everyone at once**: all numbers ring together.\n\nPressing 1 during a call acknowledges the incident, which also stops any escalation for it.\n\n### Numbers per alert\n\nYour plan sets how many phone numbers one alert reaches. The limit applies to SMS, WhatsApp and voice alike.\n\n| Plan | Phone numbers per alert |\n|---|---|\n| Free | 3 |\n| Hobby | 3 |\n| Starter | 5 |\n| Professional | 10 |\n| Enterprise | Unlimited |\n\nIf a monitor lists more numbers than your plan allows, the first numbers in the list, up to the limit, are used. Put the numbers that matter most first.\n\n## Discord, OpsGenie, PagerDuty?\n\nThese have no dedicated settings page. Use the **webhook** channel with the appropriate format; these sends also count against your webhook quota:\n\n- **Discord**: point a webhook at your Discord channel's incoming webhook URL. Discord accepts a JSON `content` field directly.\n- **OpsGenie**: webhook to `https://api.opsgenie.com/v2/alerts` with your API key in the headers.\n- **PagerDuty**: webhook to `https://events.pagerduty.com/v2/enqueue` with the Events API v2 payload shape.\n\nFor PagerDuty-style paging, [escalation policies](/docs/escalation-policies) usually solve the same problem natively without leaving UptimeWarden.\n\n## Related topics\n\n- [Webhook Configuration](/docs/webhook-configuration): outbound webhook setup\n- [Telegram](/docs/telegram): per-user bot setup\n- [Push Notifications](/docs/push-notifications): mobile push\n- [Escalation Policies](/docs/escalation-policies): on-call ladder using these channels\n- [Smart Alert Grouping](/docs/smart-alert-grouping): reduce noise on shared channels","category":"notifications","tags":["channels","email","sms","slack","webhook","push"],"order":10,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Notification Channels. UptimeWarden Documentation","metaDescription":"Configure email, SMS, WhatsApp, voice, push, Slack, Teams, Telegram, and webhook channels per monitor with quiet hours and per-alert-type routing.","icon":"Bell","createdAt":"2026-10-12T22:06:41.762Z","updatedAt":"2026-10-12T22:06:41.762Z","publishedAt":"2026-10-12T22:06:41.762Z"},{"publicId":"01M4S2ENX3GH441N2PQZWKVPJ1","locale":"en","translationGroup":"notifications-overview","slug":"notifications-overview","title":"Notifications","description":"Nine notification channels (email, SMS, WhatsApp, voice, Telegram, Slack, Teams, webhook, push) with smart alert grouping, on-call escalation, and quiet hours.","body":"# Notifications\n\nMonitoring is only useful if the right person hears about a problem on the right channel. UptimeWarden has nine channels, alert grouping, on-call rotations, and quiet hours.\n\n## The nine channels\n\n| Channel | What it does | Plan |\n|---|---|---|\n| Email | To your account address or custom recipients | Free+ |\n| Push | Mobile app push for iOS and Android | Free+ |\n| Webhook | Custom JSON POST, signed for verification | Free+ |\n| SMS | Global SMS including Turkish numbers | Hobby+ (quota-based) |\n| WhatsApp | WhatsApp messages with Turkish templates | Hobby+ (quota-based) |\n| Voice | Auto-dial with a recorded message (TR + global) | Hobby+ (quota-based) |\n| Slack | Bot token or incoming webhook URL | Free+ |\n| Microsoft Teams | Incoming webhook URL | Free+ |\n| Telegram | Bot DM or group chat | Free+ |\n\nSlack, Microsoft Teams and Telegram are delivered as webhooks. Discord is not a separate channel; you add it as a webhook config type. No plan turns these four off; every send counts against your plan's monthly webhook quota.\n\nChannels are managed at **Settings → Notifications → Channels**. Each channel is mapped to alert types, for every monitor, you decide which alert type (down, recovery, SSL warning, slow response, domain expiring) goes to which channel.\n\n## Smart Alert Grouping\n\nWhen one service goes down, five related monitors usually go down with it. Classic monitoring sends five separate notifications, five SMS messages at 3 AM. Smart Alert Grouping, on every plan, keeps the first and bundles the rest:\n\n- **The first alert goes out at once**, exactly as it would without grouping.\n- **The rest of the burst**: alerts of the same kind (outage, recovery, certificate, slow response) that would reach the same recipients on the same channels within 60 seconds arrive together as one message when the window ends, saying what the monitors have in common.\n\nResult: two SMS instead of five, and voice calls only once.\n\nSee [Smart Alert Grouping](/docs/smart-alert-grouping).\n\n## On-Call Escalation\n\nIf the first paged person doesn't respond, the escalation policy moves to the next tier:\n\n```\nT+0   → On-call A (SMS + Push)\nT+10m → On-call A (Voice call)\nT+15m → On-call B (SMS + Push)\nT+30m → Engineering manager (SMS)\n```\n\nTiers, channels, and timings are all configurable. A single click on **Acknowledge** halts the escalation. Pressing 1 during an alert voice call acknowledges the incident too. See [Escalation Policies](/docs/escalation-policies).\n\n:::warning\nOnly put real humans in your rotation. Bot channels (a Slack channel webhook, for example) can't acknowledge, and the policy will escalate forever.\n:::\n\n## Quiet Hours\n\nFor when you really don't want to be paged at 3 AM:\n\n- Per-user (each team member sets their own).\n- Per-recipient (for example, silence one phone number while another stays on).\n\nConfigure quiet hours under each channel's **Quiet Hours** tab.\n\n## Webhook security\n\nWebhooks include an HMAC-SHA256 signature; the receiver must verify it before processing the payload. See [Webhook Security](/docs/webhook-security).\n\n## When a high response time alert opens\n\nA high response time alert does not open on the first slow check. It needs N\nslow checks in a row, the same N that confirms a recovery (default 3). A single\nslow spike is recorded and still shows in your charts, but nobody is notified.\nDown alerts do not wait for this: an outage in the middle of a slow run is\nreported as usual.\n\nOpening and closing a high response time incident take the same evidence: N\nslow checks to open, N normal checks to close. The incident starts at the first\nslow check of the run.\n\n## When \"recovered\" is sent\n\nA recovery notification is not sent on the first good check. Both incident types\nrequire the problem to have actually stopped:\n\n| Incident | Recovery requires |\n|---|---|\n| **Down** | N consecutive successful checks (default 3) |\n| **High response time** | N consecutive responses back at or below the threshold (same N) |\n\nThe response-time rule used to look only at the check that triggered it, a\nsingle sample. A monitor oscillating around its threshold (say 480 ms and 520 ms\nagainst a 500 ms limit) therefore opened and closed an incident on every check,\nand sent you a \"recovered\" message each time. Both alarm types now demand the\nsame sustained recovery before telling you the problem is over.\n\nIf the threshold cannot be read for any reason, the incident stays open rather\nthan being closed on an assumption.\n\n## Retry behaviour\n\nIf a notification can't be delivered on the first try, UptimeWarden retries:\n\n1. After 5 seconds.\n2. After 30 seconds.\n3. After 5 minutes.\n\nIf all three retries fail, the notification is marked as undeliverable. Per-channel success rates and the 24-hour failed-delivery count are shown on the **Notification Health** dashboard.\n\n## Notification usage and plan limits\n\nEach plan has a monthly notification quota per channel:\n\n| Plan | Email | Push | Webhook | SMS | WhatsApp | Voice |\n|---|---|---|---|---|---|---|\n| Free | 250 | 100 | 1,000 | 0 | 0 | 0 |\n| Hobby | 500 | 250 | 2,500 | 25 | 50 | 10 |\n| Starter | 1,000 | 500 | 4,000 | 100 | 100 | 25 |\n| Professional | 2,000 | 2,000 | 10,000 | 300 | 500 | 100 |\n| Enterprise | unlimited | unlimited | unlimited | unlimited | unlimited | unlimited |\n\nFor SMS, WhatsApp and voice, each quota is shared by the whole account and one unit is one phone number reached: a message counts when it is sent successfully, and a call counts only when it is answered (a call that goes to voicemail counts too). Unanswered, busy, failed or canceled calls use nothing. Your plan also limits how many phone numbers one alert reaches: Free 3, Hobby 3, Starter 5, Professional 10, Enterprise unlimited. See [Notification Channels](/docs/notification-channels) for call modes and details.\n\nThe webhook column also covers Slack, Microsoft Teams, Telegram and Discord sends. The number of webhook configs you can create depends on the plan too: Free 3, Hobby 6, Starter 10, Professional 25, Enterprise unlimited.\n\nWhen a quota is used up, sends on that channel are skipped and the attempt is recorded. The account owner gets one email per quota per billing period.\n\n> SMS, WhatsApp, and voice add-on packs stack on top of these quotas, see [Subscription Plans](/docs/subscription-plans).\n\nRemaining quota is shown under **Subscription → Usage**. See [Subscription Plans](/docs/subscriptions-overview).\n\n## Next steps\n\n- [Smart Alert Grouping](/docs/smart-alert-grouping)\n- [Escalation Policies](/docs/escalation-policies)\n- [Webhook Security](/docs/webhook-security)\n- [Incidents](/docs/incidents-overview)","category":"notifications","tags":["notifications","channels","escalation","on-call","alert-grouping"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Notifications. UptimeWarden Docs","metaDescription":"UptimeWarden notification channels, smart alert grouping, on-call escalation, and quiet hours configuration.","icon":"Bell","createdAt":"2026-10-12T22:06:41.572Z","updatedAt":"2026-10-12T22:06:41.572Z","publishedAt":"2026-10-12T22:06:41.572Z"},{"publicId":"a1b74888763f449c8e7ec42d77","locale":"en","translationGroup":"webhook-security","slug":"en-webhook-security","title":"Webhook Security (HMAC V2)","description":"Verify that webhook payloads actually came from UptimeWarden using signed requests.","body":"# Webhook Security (HMAC V2)\n\nYour webhook endpoint sits on a public URL. Anyone who learns the URL can POST to it — including attackers with spoofed payloads that trigger false alerts, or worse, fake \"everything is fine\" messages that mask a real outage.\n\nHMAC V2 signing solves this: every payload arrives with a cryptographic signature that can't be forged without the shared secret. Your endpoint verifies the signature → authentic requests pass, forgeries are rejected.\n\n## Why V2?\n\nUptimeWarden previously supported V1 signing (body-only HMAC). V2 adds **replay-attack protection**: the signature now covers a timestamp. This matches the pattern used by Stripe, GitHub, and Slack.\n\nWith V1, an attacker who captured one signed payload could replay it 3 days later. V2 rejects payloads whose timestamp is more than 5 minutes old — replays fail verification.\n\n## Webhook settings\n\nIn the webhook config wizard, under **Authentication → Request Signing**:\n\n1. **Secret Key**: A 32+ character random string. The \"Generate\" button creates one — or paste your own.\n2. **Signing version**: V2 (default, recommended).\n3. **Save**.\n\nUptimeWarden adds these headers to every POST:\n\n```text\nX-Webhook-Timestamp: 1713360123\nX-Webhook-Signature-V2: sha256=abcdef1234...\nX-Webhook-Signature: abcdef1234...          (legacy V1 — body-only, kept for back-compat)\n```\n\n`X-Webhook-Timestamp` is the Unix timestamp in seconds (as a string). `X-Webhook-Signature-V2` is always prefixed with `sha256=` followed by the HMAC-SHA256 hex digest.\n\n## Verifying the signature\n\nThe signature is computed as:\n\n```text\nsigned_payload = \"<timestamp>.<request_body>\"\nsignature      = HMAC-SHA256(secret, signed_payload)\n```\n\nAt your endpoint:\n\n1. Read `X-Webhook-Timestamp`.\n2. Read `X-Webhook-Signature-V2`; strip the leading `sha256=` prefix.\n3. Build the signed string: `${timestamp}.${rawBody}`.\n4. Compute HMAC-SHA256 with your secret (hex output).\n5. Compare with constant-time comparison — mismatch → 401.\n6. Reject if the timestamp is more than 5 minutes old. The sender signs with the current timestamp, so **replay protection is enforced at the receiver**.\n\n### Node.js (Express)\n\n```js\nimport crypto from 'node:crypto';\n\napp.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {\n  const sigHeader = req.header('X-Webhook-Signature-V2');\n  const ts        = req.header('X-Webhook-Timestamp');\n  const raw       = req.body.toString();\n\n  if (!sigHeader || !ts) return res.status(401).send('missing sig');\n\n  // 5-minute replay protection — enforced at the receiver\n  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) {\n    return res.status(401).send('timestamp too old');\n  }\n\n  // \"sha256=<hex>\" → <hex>\n  if (!sigHeader.startsWith('sha256=')) {\n    return res.status(401).send('invalid signature format');\n  }\n  const provided = sigHeader.slice('sha256='.length);\n\n  const expected = crypto\n    .createHmac('sha256', process.env.WEBHOOK_SECRET)\n    .update(`${ts}.${raw}`)\n    .digest('hex');\n\n  if (provided.length !== expected.length) {\n    return res.status(401).send('invalid signature');\n  }\n  const ok = crypto.timingSafeEqual(\n    Buffer.from(provided, 'utf8'),\n    Buffer.from(expected, 'utf8'),\n  );\n\n  if (!ok) return res.status(401).send('invalid signature');\n\n  // verified — handle\n  const payload = JSON.parse(raw);\n  handleAlert(payload);\n  res.sendStatus(200);\n});\n```\n\n**Critical detail**: use `express.raw()`, not `express.json()`. The JSON parser normalizes whitespace, which breaks signature computation. You need the raw bytes intact.\n\n### Python (Flask)\n\n```python\nimport hmac, hashlib, time, os\nfrom flask import request, abort\n\nSECRET = os.environ['WEBHOOK_SECRET'].encode()\n\n@app.post('/webhook')\ndef webhook():\n    sig_header = request.headers.get('X-Webhook-Signature-V2', '')\n    ts_header  = request.headers.get('X-Webhook-Timestamp', '')\n\n    if not sig_header or not ts_header:\n        abort(401, 'missing sig')\n\n    # replay protection\n    if abs(time.time() - int(ts_header)) > 300:\n        abort(401, 'timestamp too old')\n\n    # \"sha256=<hex>\" → <hex>\n    if not sig_header.startswith('sha256='):\n        abort(401, 'invalid signature format')\n    provided = sig_header[len('sha256='):]\n\n    raw = request.get_data()\n    expected = hmac.new(\n        SECRET,\n        f'{ts_header}.{raw.decode()}'.encode(),\n        hashlib.sha256,\n    ).hexdigest()\n\n    if not hmac.compare_digest(provided, expected):\n        abort(401, 'invalid signature')\n\n    # verified\n    payload = request.get_json()\n    handle_alert(payload)\n    return '', 200\n```\n\n### Go\n\n```go\nfunc verifyWebhook(r *http.Request, secret []byte) ([]byte, error) {\n    sigHeader := r.Header.Get(\"X-Webhook-Signature-V2\")\n    ts        := r.Header.Get(\"X-Webhook-Timestamp\")\n    if sigHeader == \"\" || ts == \"\" {\n        return nil, errors.New(\"missing signature\")\n    }\n\n    // replay protection\n    tsInt, err := strconv.ParseInt(ts, 10, 64)\n    if err != nil || math.Abs(float64(time.Now().Unix()-tsInt)) > 300 {\n        return nil, errors.New(\"timestamp too old\")\n    }\n\n    // \"sha256=<hex>\" → <hex>\n    if !strings.HasPrefix(sigHeader, \"sha256=\") {\n        return nil, errors.New(\"invalid signature format\")\n    }\n    provided := strings.TrimPrefix(sigHeader, \"sha256=\")\n\n    raw, _ := io.ReadAll(r.Body)\n    mac := hmac.New(sha256.New, secret)\n    mac.Write([]byte(ts + \".\" + string(raw)))\n    expected := hex.EncodeToString(mac.Sum(nil))\n\n    if !hmac.Equal([]byte(provided), []byte(expected)) {\n        return nil, errors.New(\"invalid signature\")\n    }\n    return raw, nil\n}\n```\n\n## Common pitfalls\n\n- **JSON re-parse**: Parsing the body, re-serializing with `JSON.stringify()`, and then hashing breaks the signature — whitespace and key order change. **Always hash the raw body.**\n- **Timing attacks**: Don't compare signatures with `==`. Use constant-time comparison (`crypto.timingSafeEqual`, `hmac.compare_digest`). A timing-sensitive comparison lets an attacker learn the signature byte-by-byte by measuring response time.\n- **Clock skew**: If your server's clock drifts (e.g., 10 min fast), every request gets \"timestamp too old.\" Keep NTP sync active.\n- **Secrets in logs**: Don't let `WEBHOOK_SECRET` leak into production logs. Use environment variables; don't commit to source control.\n- **Reverse proxy modifying body**: Some nginx/ALB configurations compress or rewrite bodies. Use a proxy that preserves raw bytes, or verify the signature in the innermost layer.\n\n## Secret rotation\n\nIf your secret leaks:\n\n1. Generate a new secret in the webhook config.\n2. Your endpoint should **verify against both the old and new secret** (deploy this update before rotating).\n3. Wait for the old secret to be fully removed from UptimeWarden.\n4. Switch the endpoint to verify only against the new secret.\n\nThis pattern delivers zero-downtime secret rotation.\n\n## Monitoring\n\nWebhook dispatch metrics via Prometheus:\n\n- `webhook_dispatch_total{result}` — success / 4xx / 5xx / network\n- `webhook_retry_total` — retry attempts (3 tries after failure, exponential backoff)\n- `webhook_ssrf_blocked_total{reason}` — webhook URLs rejected by SSRF policy\n\nIf your endpoint returns 4xx (signature failures typically 401), you'll see it in your logs — that's the signal your verification is working.\n\n## FAQ\n\n**Q: Is V1 still supported?**\nA: Yes, for backwards compatibility. Use V2 for new integrations — V1 is in feature-freeze and will eventually be removed.\n\n**Q: Where should I store the secret instead of hardcoding?**\nA: Environment variable (`process.env.WEBHOOK_SECRET`). If you use a secrets manager (Vault, AWS Secrets Manager, Kubernetes Secret), put it there. Never commit to source control.\n\n**Q: How do I test my verification locally with curl?**\nA: Use the dashboard's \"Test webhook\" button — it signs the request the same way production does, so your endpoint's verification path runs identically. For ad-hoc testing with Postman/curl, you'd need to compute the signature manually with your secret.\n\n## Related topics\n\n- [Webhook Configuration](/docs/en-webhook-configuration)\n- [Notification Channels](/docs/en-notification-channels)\n- [API Getting Started](/docs/en-api-getting-started)","category":"notifications","tags":["webhook","security","hmac","signing"],"order":15,"parentSlug":"notifications","published":true,"version":2,"metaTitle":"Webhook Security — UptimeWarden Documentation","metaDescription":"Protect your webhook endpoint from spoofed requests with HMAC-SHA256 signing.","icon":"Bell","createdAt":"2026-04-19T00:06:52.889Z","updatedAt":"2026-04-19T00:16:16.629Z","publishedAt":"2026-04-19T00:06:52.889Z"},{"publicId":"01M4S2EP50REB2G7D82SG1YG5S","locale":"en","translationGroup":"webhook-security","slug":"webhook-security","title":"Webhook Security (HMAC V2)","description":"Verify that webhook payloads actually came from UptimeWarden using signed requests.","body":"# Webhook Security (HMAC V2)\n\nYour webhook endpoint sits on a public URL. Anyone who learns the URL can POST to it, including attackers with spoofed payloads that trigger false alerts, or worse, fake \"everything is fine\" messages that mask a real outage.\n\nHMAC V2 signing solves this: every payload arrives with a cryptographic signature that cannot be forged without the shared secret. Your endpoint verifies the signature, authentic requests pass, forgeries are rejected.\n\n## Why V2?\n\nUptimeWarden previously supported V1 signing (body-only HMAC). V2 adds **replay-attack protection**: the signature now covers a timestamp as well as the body. This follows an industry-standard pattern.\n\nWith V1, an attacker who captured one signed payload could replay it three days later. V2 rejects payloads whose timestamp is more than five minutes old, replays fail verification.\n\nWhen a secret is configured, the legacy V1 header (`X-Webhook-Signature`) keeps being sent on every request alongside the V2 headers, for backwards compatibility. Prefer V2 for verification in new integrations; keep V1 only as a fallback for receivers that can't do timestamp verification.\n\n## Webhook settings\n\nIn the webhook configuration wizard's **Authentication** step, under **Request Signing (optional)**:\n\n1. **Signing Secret**, paste a 32+ character random string that you generate yourself. (There is no auto-generate button; you supply the value.)\n2. **Save**.\n\nLeave the secret empty and signing is off; enter a secret and signing turns on automatically. There is no separate \"signing version\" choice, when a secret is configured, every request carries both the legacy (V1) and the V2 headers together.\n\n:::tip Treat the secret like a password\nThe secret is shown in full only on the create or rotate screen. Store it in your secret manager (Vault, AWS Secrets Manager, Doppler), never commit it to git. To rotate, generate a new secret and update both UptimeWarden and your endpoint at the same time.\n:::\n\nUptimeWarden adds these headers to every POST:\n\n```text\nX-Webhook-Timestamp: 1713360123\nX-Webhook-Signature-V2: sha256=abcdef1234...\nX-Webhook-Signature: abcdef1234...          (legacy V1 - body-only, kept for back-compat)\n```\n\n`X-Webhook-Timestamp` is the Unix timestamp in seconds (as a string). `X-Webhook-Signature-V2` is always prefixed with `sha256=` followed by the HMAC-SHA256 hex digest.\n\n## Verifying the signature\n\nThe signature is computed as:\n\n```text\nsigned_payload = \"<timestamp>.<request_body>\"\nsignature      = HMAC-SHA256(secret, signed_payload)\n```\n\nAt your endpoint:\n\n1. Read `X-Webhook-Timestamp`.\n2. Read `X-Webhook-Signature-V2` and strip the leading `sha256=` prefix.\n3. Build the signed string: `${timestamp}.${rawBody}`.\n4. Compute HMAC-SHA256 with your secret (hex output).\n5. Compare with constant-time comparison, mismatch means 401.\n6. Reject if the timestamp is more than five minutes old. The sender signs with the current timestamp, so **replay protection is enforced on the receiver side**.\n\n### Node.js (Express)\n\n```js\nimport crypto from 'node:crypto';\n\napp.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {\n  const sigHeader = req.header('X-Webhook-Signature-V2');\n  const ts        = req.header('X-Webhook-Timestamp');\n  const raw       = req.body.toString();\n\n  if (!sigHeader || !ts) return res.status(401).send('missing sig');\n\n  // 5-minute replay protection - enforced on the receiver\n  if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) {\n    return res.status(401).send('timestamp too old');\n  }\n\n  // \"sha256=<hex>\" → <hex>\n  if (!sigHeader.startsWith('sha256=')) {\n    return res.status(401).send('invalid signature format');\n  }\n  const provided = sigHeader.slice('sha256='.length);\n\n  const expected = crypto\n    .createHmac('sha256', process.env.WEBHOOK_SECRET)\n    .update(`${ts}.${raw}`)\n    .digest('hex');\n\n  if (provided.length !== expected.length) {\n    return res.status(401).send('invalid signature');\n  }\n  const ok = crypto.timingSafeEqual(\n    Buffer.from(provided, 'utf8'),\n    Buffer.from(expected, 'utf8'),\n  );\n\n  if (!ok) return res.status(401).send('invalid signature');\n\n  // verified - handle\n  const payload = JSON.parse(raw);\n  handleAlert(payload);\n  res.sendStatus(200);\n});\n```\n\n**Critical detail**: use `express.raw()`, not `express.json()`. The JSON parser normalizes whitespace, which breaks signature computation. You need the raw bytes intact.\n\n### Python (Flask)\n\n```python\nimport hmac, hashlib, time, os\nfrom flask import request, abort\n\nSECRET = os.environ['WEBHOOK_SECRET'].encode()\n\n@app.post('/webhook')\ndef webhook():\n    sig_header = request.headers.get('X-Webhook-Signature-V2', '')\n    ts_header  = request.headers.get('X-Webhook-Timestamp', '')\n\n    if not sig_header or not ts_header:\n        abort(401, 'missing sig')\n\n    # replay protection\n    if abs(time.time() - int(ts_header)) > 300:\n        abort(401, 'timestamp too old')\n\n    # \"sha256=<hex>\" → <hex>\n    if not sig_header.startswith('sha256='):\n        abort(401, 'invalid signature format')\n    provided = sig_header[len('sha256='):]\n\n    raw = request.get_data()\n    expected = hmac.new(\n        SECRET,\n        f'{ts_header}.{raw.decode()}'.encode(),\n        hashlib.sha256,\n    ).hexdigest()\n\n    if not hmac.compare_digest(provided, expected):\n        abort(401, 'invalid signature')\n\n    # verified\n    payload = request.get_json()\n    handle_alert(payload)\n    return '', 200\n```\n\n### Go\n\n```go\nfunc verifyWebhook(r *http.Request, secret []byte) ([]byte, error) {\n    sigHeader := r.Header.Get(\"X-Webhook-Signature-V2\")\n    ts        := r.Header.Get(\"X-Webhook-Timestamp\")\n    if sigHeader == \"\" || ts == \"\" {\n        return nil, errors.New(\"missing signature\")\n    }\n\n    // replay protection\n    tsInt, err := strconv.ParseInt(ts, 10, 64)\n    if err != nil || math.Abs(float64(time.Now().Unix()-tsInt)) > 300 {\n        return nil, errors.New(\"timestamp too old\")\n    }\n\n    // \"sha256=<hex>\" → <hex>\n    if !strings.HasPrefix(sigHeader, \"sha256=\") {\n        return nil, errors.New(\"invalid signature format\")\n    }\n    provided := strings.TrimPrefix(sigHeader, \"sha256=\")\n\n    raw, _ := io.ReadAll(r.Body)\n    mac := hmac.New(sha256.New, secret)\n    mac.Write([]byte(ts + \".\" + string(raw)))\n    expected := hex.EncodeToString(mac.Sum(nil))\n\n    if !hmac.Equal([]byte(provided), []byte(expected)) {\n        return nil, errors.New(\"invalid signature\")\n    }\n    return raw, nil\n}\n```\n\n## Common pitfalls\n\n- **JSON re-parse**: parsing the body, re-serializing with `JSON.stringify()`, and then hashing breaks the signature. Whitespace and key order change. Always hash the raw body.\n- **Timing attacks**: do not compare signatures with `==`. Use constant-time comparison (`crypto.timingSafeEqual`, `hmac.compare_digest`). A timing-sensitive comparison lets an attacker learn the signature byte-by-byte by measuring response time.\n- **Clock skew**: if your server's clock drifts (for example, ten minutes fast), every request gets \"timestamp too old.\" Keep NTP sync active.\n- **Secrets in logs**: do not let `WEBHOOK_SECRET` leak into production logs. Use environment variables and never commit to source control.\n- **Reverse proxy modifying body**: some nginx or load balancer configurations compress or rewrite bodies. Use a proxy that preserves raw bytes, or verify the signature in the innermost layer.\n\n## Secret rotation\n\nIf your secret leaks:\n\n1. Generate a new secret in the webhook configuration.\n2. Update your endpoint to **verify against both the old and the new secret** (deploy this update before rotating).\n3. Wait for the old secret to be fully removed from UptimeWarden.\n4. Switch the endpoint to verify only against the new secret.\n\nThis pattern delivers zero-downtime secret rotation.\n\n## FAQ\n\n**Q: Is V1 still supported?**\nA: Yes. When a secret is configured, the legacy V1 header is sent on every request alongside the V2 headers and is kept permanently for backwards compatibility. Use V2 for verification in new integrations.\n\n**Q: Where should I store the secret instead of hardcoding it?**\nA: An environment variable (`process.env.WEBHOOK_SECRET`). If you use a secrets manager (Vault, AWS Secrets Manager, Kubernetes Secret), put it there. Never commit to source control.\n\n**Q: How do I test my verification locally with curl?**\nA: The dashboard's \"Test webhook\" button sends a signed test request using your secret. Note: the test request may not send the exact same set of headers as live alert delivery, so the most reliable way to test an endpoint that verifies the V2 headers is to trigger a real alert (for example, by briefly pausing and resuming a monitor). For ad-hoc testing with Postman or curl, you would need to compute the signature manually with your secret.\n\n## Related topics\n\n- [Webhook Configuration](/docs/webhook-configuration)\n- [Notification Channels](/docs/notification-channels)\n- [Getting Started](/docs/getting-started)","category":"notifications","tags":["webhook","security","hmac","signing"],"order":15,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Webhook Security. UptimeWarden Documentation","metaDescription":"Protect your webhook endpoint from spoofed requests with HMAC-SHA256 signing.","icon":"Bell","createdAt":"2026-10-12T22:06:41.825Z","updatedAt":"2026-10-12T22:06:41.825Z","publishedAt":"2026-10-12T22:06:41.825Z"},{"publicId":"01M4S2EP396P2R04ZYR5ZGSZ9D","locale":"en","translationGroup":"on-call","slug":"on-call","title":"On-Call Rotations","description":"Rotate on-call duty across your team, one person per day, with SMS and voice fallback when push isn't enough.","body":"# On-Call Rotations\n\nA monitor goes down at 2 AM. Who gets the page? Without a rotation, the answer is \"everyone with admin access\", which means everyone gets paged, half of them ignore it because \"someone else has it,\" and the actual on-call engineer is on vacation.\n\nOn-call rotations fix this: one person owns each day. The escalation policy pages that person through their preferred channels, push first, then SMS, then a phone call if they haven't acknowledged in five minutes.\n\n## Access\n\nOn-call rotations and escalation policies are managed from **Settings → Notifications → On-Call** tab, rotations and policies now live on one page. In settings, the rotation and policy editors open on **Hobby and up**; users on the Free plan see an upgrade prompt instead of the editors. (Admins always have access.)\n\n## Rotation shape\n\nUptimeWarden supports weekly day-of-week rotations. Each schedule has seven slots (one per day, Sunday through Saturday), and you assign one user per slot. Empty slots mean \"no on-call that day\", the [escalation ladder](/docs/escalation-policies) records a tier skip and advances.\n\nThis is a deliberate simplification, there are no intra-day handoffs (\"Ayşe 09:00-17:00, Burak 17:00-09:00\") today. If you need that today, layer two schedules and switch the policy mid-shift.\n\n## Defining a rotation\n\nOpen **Settings → Notifications → On-Call → New schedule**:\n\n1. **Name**, `Weeknights`, `Payments-Team`, `Platform-Primary`.\n2. **Timezone**, day boundaries are computed in this zone. UTC is the default; pick the zone where your team actually lives so \"Tuesday\" means Tuesday for them.\n3. **Members**, pick a user for each day. Leave weekends empty to keep on-call business-hours only.\n\nThe rotation is owned by the user who created it. Escalation policies reference rotations by a stable internal identifier, so renaming a rotation doesn't break anything that points to it.\n\n## Attaching a rotation to a monitor\n\nRotations are not attached directly to monitors. Instead, an escalation policy references a rotation as one of its tier targets. See [Escalation Policies](/docs/escalation-policies) for the full attach flow.\n\n```\nMonitor → Escalation Policy → Tier 1: schedule \"Weeknights\"\n                              Tier 2: user \"Ebru (team lead)\"\n                              Tier 3: user \"Fatih (CTO)\"\n```\n\nWhen Tier 1 fires, UptimeWarden looks up today's on-call from the `Weeknights` schedule and pages that one person.\n\n## SMS and voice fallback chain\n\nEach escalation tier picks a channel set, email, SMS, WhatsApp, voice, push, Slack, or Telegram. For wake-the-engineer scenarios, the recommended ladder is:\n\n| Tier | Channels | Wait |\n|---|---|---|\n| 1 | push + email | 5 min |\n| 2 | push + email + SMS | 5 min |\n| 3 | voice (phone call) | - |\n\nThe first tier respects do-not-disturb on the phone, push notifications are silenced overnight on most devices. The second tier adds SMS, which bypasses DND on iOS and Android. The third tier escalates to a voice call, which rings through silent mode in most operator configurations.\n\nWhen a tier picks Slack or Telegram, the on-call user must have their own Slack or Telegram connection. Escalation does not fall back to the team lead's connection.\n\n> **Roadmap:** vacation overrides, shift swaps, and intra-day rotation layers are not part of the product today. Workaround: layer two schedules and switch the policy mid-shift.\n\n## Acknowledgement\n\nPages include a one-click **Acknowledge** link in email and a button in push and SMS. When the on-call engineer acknowledges, the ladder stops and any later tier (Tier 2, Tier 3, and so on) is canceled, saving the team lead's sleep.\n\nThe acknowledgement link carries no personal information, can't be guessed, is protected against abuse, and stays valid until the incident resolves. See [Escalation Policies](/docs/escalation-policies) for the full acknowledgement flow.\n\n## Related topics\n\n- [Escalation Policies](/docs/escalation-policies): tier definitions and acknowledgement flow\n- [Notification Channels](/docs/notification-channels): channel availability per plan\n- [Push Notifications](/docs/push-notifications): wake-the-engineer push setup","category":"notifications","tags":["on-call","rotation","schedule","escalation"],"order":20,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"On-Call Rotations. UptimeWarden Documentation","metaDescription":"Define weekly on-call schedules with day-of-week assignments and a fallback chain that reaches sleeping engineers.","icon":"Bell","createdAt":"2026-10-12T22:06:41.769Z","updatedAt":"2026-10-12T22:06:41.769Z","publishedAt":"2026-10-12T22:06:41.769Z"},{"publicId":"01M4S2EPB6J8A8YMNW082PYR20","locale":"en","translationGroup":"smart-alert-grouping","slug":"smart-alert-grouping","title":"Smart Alert Grouping","description":"The first alert of a burst goes out at once; the rest of the burst arrives as one message that says what the monitors have in common. On every plan, with an AI-generated hint on Professional and Enterprise.","body":"# Smart Alert Grouping\n\nA bad deploy, a DNS change or a failed load balancer can take many monitors down in the same minute. If every one of them sends its own e-mail, SMS and push, the phone keeps buzzing and nobody can tell what actually broke.\n\nSmart alert grouping keeps the first alert and folds the rest of the burst into one message:\n\n- **The first alert goes out at once**, on every channel, exactly as it would without grouping.\n- **Alerts that follow within 60 seconds** for the same account and the same recipients are held.\n- **When the window ends they arrive as one message**: \"3 more monitors are down with the same error; 4 in total\", with what the monitors have in common.\n\nGrouping is on for every plan: Free, Hobby, Starter, Professional and Enterprise.\n\n## Flow: from a burst of alerts to two messages\n\n```mermaid\nflowchart LR\n    A1[Monitor 12, DOWN] --> First[First alert<br/>sent at once]\n    A2[Monitor 13, DOWN] --> Win\n    A3[Monitor 14, DOWN] --> Win\n    A4[Monitor 47, DOWN] --> Win\n    First --> Win[60-second window<br/>same account, same recipients]\n    Win --> Msg[One message:<br/>3 more monitors are down; 4 in total<br/>+ what they have in common]\n    Msg --> Decide{Professional or<br/>Enterprise?}\n    Decide -- No --> Out((Channels))\n    Decide -- Yes --> AI[Likely cause · AI-generated,<br/>verify before acting]\n    AI --> Out\n```\n\nIf only one monitor fails in the window, nothing else is sent: the first alert was the whole story.\n\n## Which alerts are grouped\n\nFour kinds of alert come in storms, because one broken dependency takes many monitors with it:\n\n- outages (`down`)\n- recoveries\n- certificate warnings\n- slow responses\n\nEach kind groups on its own: a certificate warning never joins a group of outages. Everything else always goes out on its own, as before: flapping notices, domain expiry, security grade drops and SLO burn alerts.\n\nThese are never held either: retries of an alert that failed to deliver, on-call escalation pages, and any alert whose grouping cannot be decided within a second (the setting cannot be read, the account or its recipients cannot be resolved). In doubt, the alert goes out on its own, at once. Grouping never drops an alert.\n\n## Who shares a window\n\nAlerts share a window when they belong to the same account and would reach the same people the same way: the same channels, the same recipients and the same chat webhooks. Monitors that notify different people never share a message.\n\nThe error is **not** part of the key. Behind one dead load balancer some checks time out, some are refused and some get a 502. Keyed on the error, that storm would open a window per error, each with its own immediate alert. Instead you get the first alert and one message with the rest, and the message says whether they failed the same way.\n\n## The window\n\nThe window starts with the first alert and lasts 60 seconds. Alerts that arrive in it are held; when it ends, they go out as one message. An alert that arrives after the window has ended starts a new window, and it goes out at once as that window's first alert.\n\nThe windows are shared by all of UptimeWarden's notification servers, so a burst that is processed on several of them still produces one message.\n\n## What the grouped message says\n\n- **The headline**, for example \"3 more monitors are down with the same error; 4 in total\", or \"5 more monitors are back up; 6 in total\" for recoveries.\n- **The first alert**, the one you already received.\n- **The other monitors**, by name (the first 20, then \"and 12 more\").\n- **What they have in common**: the same error, status code, host, IP address, CDN, certificate issuer, checking region or service group, a dependency you declared, or a link on your service map, each with how many of the monitors share it (\"3 of 4\"). A value is shown when all of the monitors or a clear majority share it. When nothing is shared, the message says so, so two unrelated failures in the same minute are not presented as one.\n- **Verification**: for outages, what the other checking regions saw.\n\nAll of this is computed from your monitors and their results, not guessed.\n\n## Per channel\n\n| Channel | What you get |\n|---|---|\n| E-mail, Slack, Teams, Discord | The first alert, then at most one grouped message per window |\n| SMS, WhatsApp, push, Telegram | The first alert, then at most one grouped message per window |\n| Voice | A call for the first alert only; the group never calls |\n| PagerDuty, Opsgenie, custom and generic webhooks | Every alert on its own, at once, because these systems track each incident by its own event |\n\nOn the channels that wake people up (SMS, WhatsApp, push, Telegram and voice), a burst therefore costs at most one extra message per window, and never a second call.\n\nQuiet hours apply to a group as they apply to its alerts: during your quiet hours a grouped outage reaches the waking channels only if you let outages through quiet hours.\n\n## AI hint (Professional and Enterprise)\n\nOn plans with AI alert summaries, the grouped message can carry a short hint about the likely cause and a suggested next step. Every place it appears, it is labelled **AI-generated, verify before acting**: it is a model's guess about a live outage, not a finding.\n\n- It is asked for only when the window ends, so the first alert never waits for it.\n- If the model does not answer within about 6 seconds, is over its budget or fails, the grouped message goes out without the hint.\n- It also needs your consent to AI processing and room in your monthly AI budget.\n\nWhat the model sees: the monitors' names, their error messages, status codes, hosts and checking regions, the cross-region verification verdict, what the monitors have in common, recent health prediction trends for those monitors, and how often a similar group has been seen before. It never sees request or response bodies or logs.\n\n## Turning grouping off\n\nWhen grouping is on for your account, the dashboard shows a short banner about it:\n\n- **Dismiss (×)**: hides the banner in this browser. Grouping stays on.\n- **Turn off**: turns grouping off for your account. Every alert then goes out on its own, as it arrives, and the banner disappears.\n\nThere is no self-serve switch to turn it back on yet. To turn grouping on again for your account, contact [support@uptimewarden.online](mailto:support@uptimewarden.online).\n\n## Viewing past groups (roadmap)\n\nEvery grouped message is recorded for audit. A dashboard view of them is on the roadmap; the records are kept now so the history is there when it ships.\n\n## Limitations\n\n- **The window is fixed at 60 seconds.** It cannot be changed.\n- **Grouping is per account, not per monitor.** Monitors that notify different recipients or channels never share a message, which is the way to keep a monitor's alerts separate.\n- **Kinds do not mix.** An outage storm and a certificate storm in the same minute produce two groups.\n\n## FAQ\n\n**Q: Does grouping delay my alerts?**\nA: Not the first one: it goes out at once, the same as without grouping. The alerts that follow within the window arrive together when it ends, at most a minute after the first.\n\n**Q: Will I get a phone call for every monitor in an outage?**\nA: No. Voice calls for the first alert of a burst only; the rest arrives as one message on your other channels.\n\n**Q: Does PagerDuty or Opsgenie get the grouped message?**\nA: No. They get every alert on its own, at once, so each incident opens and resolves on their side as before.\n\n**Q: What if the AI hint is wrong?**\nA: It is a hint, labelled as AI-generated, and never replaces the facts above it. Check it before acting on it.\n\n## Related topics\n\n- [Escalation Policies](/docs/escalation-policies): per-tier dispatch for multi-step on-call\n- [Maintenance Windows](/docs/maintenance-windows): suppress alerts during planned downtime\n- [Evidence-First Recommendations](/docs/evidence-first-recommendations). Recommendations tied to visible evidence","category":"notifications","tags":["grouping","alert-storm","ai","noise-reduction"],"order":20,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Smart Alert Grouping. UptimeWarden Documentation","metaDescription":"When many monitors fail at once, get the first alert immediately and the rest as one message: what failed, what the monitors share, and on Professional an AI-generated hint.","icon":"Bell","createdAt":"2026-10-12T22:06:42.022Z","updatedAt":"2026-10-12T22:06:42.022Z","publishedAt":"2026-10-12T22:06:42.022Z"},{"publicId":"01M4S2EP3HKEPKNY5GSV63AGYQ","locale":"en","translationGroup":"webhook-configuration","slug":"webhook-configuration","title":"Webhook Configuration","description":"Send notifications to any HTTP endpoint. Discord, OpsGenie, your own backend, a Zapier workflow, with signed payloads and automatic retries.","body":"# Webhook Configuration\n\nEmail is fine for humans. Webhooks are for **everything else**: your incident management tool, your custom dashboard, Discord, OpsGenie, PagerDuty, Zapier, n8n, or that internal Slack bot you wrote last quarter. Any HTTP endpoint that accepts JSON can be a UptimeWarden notification target.\n\nThis page walks through setup, payload shape, retry behavior, and security. For signature verification details, read [Webhook Security](/docs/webhook-security) first, it is the receiver-side companion to this guide.\n\n## Setup\n\n**Settings → Notifications → Webhooks → New Webhook**:\n\n1. **Name**, internal label (`OpsGenie alerts`, `Discord channel #ops`, `Internal incident bot`).\n2. **URL**, the destination. HTTPS is strongly recommended; we block requests targeting private network ranges by default.\n3. **Method**, `GET`, `POST` (default), `PUT`, `PATCH`, or `DELETE`.\n4. **Auth method**, `none`, `bearer`, `basic`, or `custom` (custom headers). HMAC signing is a separate, orthogonal feature (the HMAC secret field) that works regardless of the auth method you pick.\n5. **Headers**, custom headers as JSON: `{\"X-API-Key\": \"…\", \"X-Tenant-ID\": \"acme\"}`.\n6. **Alert types**, pick which alert types fire this webhook (`down`, `recovery`, `ssl`, `high_response`, etc.).\n7. **Monitor types**, restrict by monitor type (HTTP only, all types, etc.).\n8. **Quiet hours**, optional window when only critical alerts fire.\n9. **HMAC secret**, see [Webhook Security](/docs/webhook-security).\n\nSave the configuration, then attach it to the monitors you want to trigger it. One webhook configuration can serve many monitors, define `OpsGenie alerts` once and reuse it across your fleet.\n\n## Payload shape\n\nUptimeWarden ships a default payload that covers the common case:\n\n```json\n{\n  \"event\": \"down\",\n  \"timestamp\": \"2026-04-27T03:12:00Z\",\n  \"monitor\": {\n    \"id\": \"01HABC...\",\n    \"name\": \"Payment API\",\n    \"type\": \"http\",\n    \"url\": \"https://api.example.com/health\"\n  },\n  \"alert\": {\n    \"type\": \"down\",\n    \"message\": \"Connection refused\",\n    \"severity\": \"critical\"\n  },\n  \"data\": {\n    \"status\": \"down\",\n    \"responseTime\": 0,\n    \"statusCode\": 0,\n    \"errorMessage\": \"Connection refused\",\n    \"sslExpiry\": null,\n    \"daysRemaining\": 0\n  },\n  \"metadata\": {\n    \"source\": \"UptimeWarden\",\n    \"version\": \"1.0\",\n    \"sentAt\": \"2026-04-27T03:12:01Z\"\n  }\n}\n```\n\nThe top-level `event` carries the alert type (`down`, `recovery`, `ssl`, `high_response`, etc.), `timestamp` is an RFC3339 string, and `alert.severity` is derived from the alert type.\n\n## Custom payloads (templates)\n\nIf your endpoint expects a different shape. Discord wants `{\"content\": \"…\"}`, OpsGenie wants `{\"message\": \"…\", \"priority\": \"P1\"}`, define a notification template:\n\n**Settings → Notifications → Templates → New Template**:\n\n1. **Type**, `webhook`.\n2. **Webhook configuration**, link to the configuration above.\n3. **Alert type**, pick one (or `default` for the catch-all).\n4. **Template content**. JSON or text with variable interpolation.\n\n:::tip Variables use flat names\nTemplate variables use flat names like `{{monitor_name}}`, there are no nested or dotted variants such as `{{monitor.name}}`. The variables you can interpolate include: `{{monitor_id}}`, `{{monitor_name}}`, `{{monitor_url}}`, `{{monitor_type}}`, `{{status}}`, `{{response_time}}`, `{{status_code}}`, `{{error_message}}`, `{{incident_message}}`, `{{incident_type}}`, `{{timestamp}}`, `{{iso_timestamp}}`, `{{ssl_expiry}}`, `{{ssl_expiry_days}}`, `{{days_remaining}}`, `{{threshold}}`, `{{downtime_duration}}`, `{{recovery_time}}`, `{{webhook_name}}`.\n:::\n\nExample Discord template:\n\n```json\n{\n  \"content\": \"**{{monitor_name}}** is **{{incident_type}}** - {{error_message}}\"\n}\n```\n\n## Retry policy\n\nUptimeWarden does not give up on transient failures. After the initial dispatch, **3 retries** are attempted; if all three fail, the message is set aside for manual inspection.\n\n| Attempt | Delay | Trigger |\n|---|---|---|\n| Initial fire | immediate | dispatch |\n| Retry 1 | ~5 seconds | timeout, 5xx, network error |\n| Retry 2 | ~30 seconds | same |\n| Retry 3 | ~5 minutes | same |\n| Given up | - | after 3 retries |\n\n4xx responses (signature failures, your own validation rejections) are **not retried**, they are treated as terminal. Retries use exponential backoff with jitter, so a flaky receiver does not cause a synchronized retry storm across many failed monitors.\n\n## Replay window\n\nThe webhook signature includes a **timestamp** (Unix seconds) covered by HMAC. Receivers should reject requests whose timestamp is more than **5 minutes old** to defeat replay attacks. UptimeWarden never sends stale requests, so a delayed payload is suspicious.\n\nThe signature contract:\n\n```\nsigned_payload = \"<timestamp>.<raw_body>\"\nsignature      = HMAC-SHA256(secret, signed_payload)\nheader         = \"X-Webhook-Signature-V2: sha256=<hex>\"\n```\n\nSee [Webhook Security](/docs/webhook-security) for verification snippets in Node.js, Python, and Go.\n\n## Circuit breaker\n\nEach webhook configuration has its own circuit breaker. After repeated failures (5xx, timeouts), the breaker opens and the configuration is skipped for a cooldown period, preventing a single broken endpoint from clogging the entire dispatch pipeline. The breaker auto-resets when the receiver recovers.\n\n## SSRF protection\n\nWebhook URLs are validated before dispatch:\n\n- Private network ranges are **blocked** by default.\n- Cloud metadata endpoints are blocked.\n- Loopback and link-local addresses are blocked.\n- DNS rebinding is mitigated: we resolve the hostname once and reuse the resulting IP for the actual request.\n\nThese checks run in production. If you need to reach an internal endpoint inside your own network, contact support, we can opt you in on a per-account basis. Cloud metadata, loopback, and link-local addresses remain blocked regardless.\n\n## Testing\n\nUse the **Test webhook** button on the configuration page. UptimeWarden fires a sample `down` payload with all the right headers (signature included), so your endpoint's verification path runs identically to production.\n\n## Related topics\n\n- [Webhook Security (HMAC V2)](/docs/webhook-security): signature verification snippets\n- [Notification Channels](/docs/notification-channels): full channel matrix\n- [Integrations](/docs/integrations): third-party platforms via webhook\n- [GitHub Actions](/docs/developers-github-actions): CI/CD heartbeat workflow","category":"notifications","tags":["webhook","integrations","http","hmac"],"order":30,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Webhook Configuration. UptimeWarden Documentation","metaDescription":"Set up outbound webhooks with custom payloads, HMAC v2 signing, retry policy, and delivery guarantees.","icon":"Bell","createdAt":"2026-10-12T22:06:41.777Z","updatedAt":"2026-10-12T22:06:41.777Z","publishedAt":"2026-10-12T22:06:41.777Z"},{"publicId":"01M4S2EP3R8WEGRVG7NTCK22HQ","locale":"en","translationGroup":"push-notifications","slug":"push-notifications","title":"Push Notifications","description":"Get UptimeWarden alerts on your phone, silent at night, urgent for critical incidents, with one-tap acknowledge from the lock screen.","body":"# Push Notifications\n\nThe mobile app is where on-call engineers actually live. When a monitor goes down, a push notification arrives with a swipe-to-acknowledge action, no need to open the app, no login prompt, no friction at 3 AM.\n\nThis page covers mobile setup, per-device controls, and the push features that go beyond \"the dashboard sends a notification.\"\n\n## Plan availability\n\nPush notifications are available on **every plan, including Free** (Free includes up to 100 push notifications per month). Mobile push (iOS and Android) is available today; web push is on the roadmap.\n\nThe mobile app organises notifications into categories, incidents, monitors, system, general, so you can mute each category independently from your phone's notification settings.\n\n## How it works\n\n```mermaid\nflowchart LR\n    Monitor[Monitor fails] --> Alert[Alert dispatcher]\n    Alert --> Push[Push delivery]\n    Push --> iOS[iOS device]\n    Push --> Android[Android device]\n```\n\nWhen an alert fires, UptimeWarden looks up your active mobile devices and pushes the notification to each one through the same delivery channel iOS and Android use for any other app.\n\n## First-time setup (mobile)\n\n1. Install the UptimeWarden mobile app from the iOS App Store or Google Play.\n2. Sign in with your UptimeWarden account.\n3. Grant permission when prompted. iOS asks once; Android 13 and above asks via the system permission sheet.\n4. That's it. Your device registers automatically. The dashboard's **Settings → Notifications → Push** page lists the device with platform icon and last-used time.\n\nIf you skip the permission prompt, push won't work. Re-enable it in **iOS Settings → Notifications → UptimeWarden** or **Android Settings → Apps → UptimeWarden → Notifications**.\n\n## Per-device control\n\nEach registered device has its own preference set:\n\n| Alert type | Default | Disable per-device |\n|---|---|---|\n| Down | on | yes |\n| Recovery | on | yes |\n| SSL expiry | on | yes |\n| Slow response | on | yes |\n| Slow response recovery | on | yes |\n\nToggle from **Settings → Notifications → Push** on the device, or from the dashboard. A user with two phones can keep down alerts on the work phone and turn them off on the personal phone.\n\n## Mute and unmute\n\nTwo ways to silence push without removing your device:\n\n- **Quiet hours (per account)**: a daily time window (start time, end time, timezone) configured on your notification settings. While active, it applies to your account, not to a single device.\n- **Maintenance windows**: to suppress alerts for a specific monitor across every channel (not just push), schedule a maintenance window on that monitor. This is the supported way to silence a monitor for a planned period.\n\nMaintenance windows are per monitor; quiet hours are per account. Together they cover both \"silence this one monitor\" and \"don't page me overnight.\"\n\n## Alert grouping\n\nPush notifications group by monitor on Android. Five alerts about the same Payment API collapse into a single expandable notification, not five separate buzzes.\n\niOS achieves the same effect with thread IDs: notifications sharing the same monitor stack into a single group on the lock screen and in the notification centre. Tap the stack to expand it.\n\n## Action buttons\n\nDown alerts ship with two action buttons:\n\n- **Acknowledge**: one-click acknowledge with no login. The escalation ladder stops, and the on-call team is told you're on it.\n- **View**: deep-links into the mobile app's incident page.\n\nThe buttons render on the lock screen on iOS and in the notification shade on Android, so you don't need to unlock the device to act.\n\n## Team-wide alerts\n\nPush delivery is recipient-based: when an alert fires, UptimeWarden looks up the active mobile devices of the monitor's recipients and pushes to each device individually. To page a whole team, add the relevant teammates as recipients on the monitor (or via an escalation policy / on-call rotation) so their registered devices each receive the notification.\n\n## Web push (roadmap)\n\nBrowser push for Chrome, Firefox, and Safari is on the roadmap. UptimeWarden is already built to support browsers as a device type. Track the [public roadmap](https://uptimewarden.online/roadmap) for an ETA.\n\nIn the meantime, the mobile app is the recommended path. Browser tabs aren't a great notification target anyway, they get closed.\n\n## Live Activities (iOS 16.1+)\n\nCritical-severity incidents can start an iOS Live Activity, a persistent banner on the lock screen showing duration, status, and an acknowledge action. The mobile app handles this transparently; no setup is required beyond enabling Live Activities in iOS Settings.\n\nActivities end automatically when the incident resolves or is acknowledged.\n\n## Multi-language templates\n\nPush notification templates are delivered in your account language. Templates that adapt to each recipient's preferred language are on the roadmap.\n\n## Troubleshooting\n\n| Symptom | Likely cause |\n|---|---|\n| App registered but no push arrives | Permission was revoked at the OS level, re-enable in iOS or Android settings |\n| Push arrives but actions don't work | App version is too old, update from the store |\n| Duplicate push for one alert | Old device tokens left over, remove unused devices from **Settings → Push** |\n| Push delayed by 5+ minutes | Operator throttling. UptimeWarden sends pushes at high delivery priority and routes down alerts through a high-importance Android channel and recovery through a normal-importance one |\n\n## Related topics\n\n- [Push Templates](/docs/push-templates): customize the title and body\n- [Notification Channels](/docs/notification-channels): full channel matrix\n- [Escalation Policies](/docs/escalation-policies): multi-tier paging through push, SMS, and voice\n- [On-Call Rotations](/docs/on-call): rotate which device gets paged","category":"notifications","tags":["push","mobile","ios","android"],"order":40,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Push Notifications. UptimeWarden Documentation","metaDescription":"Mobile push setup, per-device controls, mute and unmute, alert grouping, and lock-screen action buttons for incident triage on the go.","icon":"Bell","createdAt":"2026-10-12T22:06:41.785Z","updatedAt":"2026-10-12T22:06:41.785Z","publishedAt":"2026-10-12T22:06:41.785Z"},{"publicId":"01M4S2EP40T67PM5A8FADKV2V0","locale":"en","translationGroup":"integrations","slug":"integrations","title":"Integrations","description":"Connect UptimeWarden to status pages, sales tools, automation platforms, and CI/CD beyond the 9 native channels.","body":"# Integrations\n\nThe 9 native [notification channels](/docs/notification-channels) cover most \"page my team\" cases. Integrations are the **everything else**, status pages, sales follow-ups, automation graphs, CI/CD pipelines. They're built on the same primitives (webhooks, API tokens, public events) but solve product-shaped problems instead of channel-shaped ones.\n\n## Status page subscribers\n\nPublic status pages let visitors subscribe with their email, without any UptimeWarden account.\n\n- **How it works**: visitors enter their email in the **Subscribe** form on the status page, and the address is stored as a subscriber on that page.\n- **Double opt-in**: a verification email is sent at sign-up; the subscriber only starts receiving incident and maintenance emails after clicking the link.\n- **Unsubscribe**: every notification includes a one-click unsubscribe link; clicking it ends the subscription and the subscriber record is retained for audit.\n\nSee [Status Page Subscribers](/docs/status-page-subscribers) for the full subscription flow and template customization.\n\n## Calendly (sales)\n\nOn the marketing site, the **Talk to sales** button is a simple booking CTA. When a Calendly booking link is configured, the button opens it in a new tab; otherwise it scrolls to the contact form at the bottom of the page.\n\nThis is a marketing-only link, there is no backend booking pipeline, no sales-channel webhook, and no lead tagging in the product. Prospects only see the booking link or the contact form.\n\n## Zapier (planned)\n\nZapier integration is on the roadmap (Q3 2026). When shipped:\n\n- **Triggers**, `monitor.down`, `monitor.recovery`, `incident.opened`, `incident.acknowledged`, `incident.resolved`.\n- **Actions**, `create_monitor`, `update_monitor_url`, `pause_monitor`, `resolve_incident`.\n- **Authentication**: OAuth 2.0 with scoped API tokens (`monitors:create`, `incidents:update`, etc., see [API Tokens](/docs/api-tokens)).\n\nUntil Zapier ships natively, the same patterns work via [webhooks](/docs/webhook-configuration) → Zapier \"Catch Hook\" trigger. You lose the polished Zap setup wizard but gain the same plumbing.\n\n## n8n / Make / custom orchestration\n\nThese platforms work today via webhook-out and API-in:\n\n- **Outbound**: UptimeWarden webhook → n8n webhook node → your workflow.\n- **Inbound**: n8n HTTP node → UptimeWarden API (`POST /api/monitors`, `PATCH /api/incidents/:id/status`) with a scoped API token.\n\nFor HMAC verification on the n8n side, see [Webhook Security](/docs/webhook-security), the verification snippets work in any Node-friendly environment.\n\n## GitHub Actions\n\nUptimeWarden ships a set of first-party GitHub Actions for CI/CD integration. All seven are implemented; today they are referenced from the repository as local composite Actions, and listing them on the GitHub Marketplace is planned:\n\n- **Check**: a one-shot multi-region uptime check that needs **no UptimeWarden account** — it authenticates with your workflow's GitHub OIDC token. Useful as a post-deploy smoke test or a pre-merge gate.\n- **Heartbeat**: Call this from your deploy workflow to push a heartbeat after a successful release. Useful for \"is the deploy still healthy five minutes after rollout?\" checks.\n- **Sync Monitors**: Declarative \"monitoring as code.\" Define your monitors in a YAML file checked into the repo and reconcile them from CI. (PRs get the plan, a push to `main` applies it. The action installs the `@uptimewarden/cli` package, which is not on npm yet, so until it is published the action needs the CLI built from source.)\n- **Notify Deploy (start / finish)**: Fire a custom alert from a workflow (for example, \"build failed for the third time\") into your notification channels.\n- **Check Incidents**: Query open incidents and block a deploy if a critical one is active.\n- **Postmortem Link**: Attach the postmortem URL to incident metadata after closure.\n\nFull reference: [GitHub Actions](/docs/developers-github-actions). The Actions use scoped API tokens (`monitors:create`, `monitors:update`), generate one in **Settings → API Tokens** and pick the **Monitor Manager** preset (or **Monitor Viewer** for read-only, **Incident Manager** for incident lifecycle). See [API Tokens](/docs/api-tokens).\n\n## Mobile push integrations\n\nThe mobile app delivers push notifications. Because of that, you also get standard OS-level behavior for free:\n\n- **Apple Watch / Wear OS**: push notifications mirror to a paired smartwatch automatically, the same as any other phone notification.\n\nThese are not UptimeWarden-built features, they are side effects of the mobile push system. There is no first-party iOS Shortcuts/Siri, watchOS, or Wear OS integration. Configure notification mirroring in your phone's settings.\n\n## Compliance / SIEM forwarding\n\nFor audit-heavy environments:\n\n- **Structured server logs**: UptimeWarden ships with structured logging that can be forwarded to your SIEM via the standard log-shipping integrations of your observability stack.\n- **Splunk / Datadog**: webhook channel → forward to HTTP Event Collector or Datadog logs intake.\n- **Audit log API**, `GET /api/audit-logs` (admin token) returns CRUD events, auth events, and monitor lifecycle events. See [Audit Logging](/docs/audit-logging).\n\n## Picking the right integration\n\n| Need | Use |\n|---|---|\n| \"Tell my customers when we're down\" | Status page subscribers |\n| \"Tell my team in Slack\" | Slack channel ([Notification Channels](/docs/notification-channels)) |\n| \"Custom workflow / automation\" | Webhook → Zapier / n8n / Make |\n| \"CI/CD reports build success\" | GitHub Actions ([developers-github-actions](/docs/developers-github-actions)) |\n| \"Incident management tool\" | Generic webhook → your tool's inbound URL (native OpsGenie / PagerDuty formatters are seeded but disabled / \"Coming Soon\") |\n| \"SIEM / compliance\" | Webhook → SIEM intake or audit log API |\n\n## Related topics\n\n- [Notification Channels](/docs/notification-channels): native channel matrix\n- [Webhook Configuration](/docs/webhook-configuration): outbound HTTP setup\n- [API Tokens](/docs/api-tokens): scoping for integrations\n- [GitHub Actions](/docs/developers-github-actions): CI/CD reference\n- [Status Page Subscribers](/docs/status-page-subscribers): public subscriber flow","category":"notifications","tags":["integrations","zapier","github-actions","status-page","calendly"],"order":50,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Integrations. UptimeWarden Documentation","metaDescription":"Wire UptimeWarden to status page subscribers, Calendly, Zapier (planned), and GitHub Actions for end-to-end visibility.","icon":"Bell","createdAt":"2026-10-12T22:06:41.792Z","updatedAt":"2026-10-12T22:06:41.792Z","publishedAt":"2026-10-12T22:06:41.792Z"},{"publicId":"01M4S2EP47Q08ZMTE0W38AX4FR","locale":"en","translationGroup":"telegram","slug":"telegram","title":"Telegram","description":"Get UptimeWarden alerts in Telegram, direct messages, group chats, or topics, via your own bot in under five minutes.","body":"# Telegram\n\nTelegram is the personal-mobile chat client of choice for many engineering teams, fast, free, and it puts notifications in the same place as your other chats. UptimeWarden configures Telegram as a **Webhook** that calls your bot's Telegram Bot API `sendMessage` endpoint directly, with proper Markdown formatting.\n\nThis page walks through bot creation, setup, group chat support, and message formatting.\n\n## Plan availability\n\nTelegram is available on every plan, **including Free**. Messages are sent as webhooks, so each one counts against your plan's monthly webhook quota (1,000 webhook sends per month on Free). Telegram's own rate limits apply on top. See [Notifications](/docs/notifications-overview) for every plan's quotas.\n\n## How it works\n\n```\nUptimeWarden                  Telegram Bot API\n─────────────                ──────────────────\nMonitor down ──> bot_token + chat_id ──> sendMessage\n                                          │\n                                          ▼\n                                    Your chat\n```\n\nEach user owns their own bot. UptimeWarden does not provide a shared bot, which keeps you in control of the rate limits and avoids the \"1 bot, 1000 customers\" rate-limit ceiling that Telegram enforces.\n\n## Step 1. Create a bot via @BotFather\n\n1. Open Telegram, search for **@BotFather**, and start a chat.\n2. Send `/newbot`.\n3. Pick a display name: `Acme Monitoring`. This is the name your messages appear under.\n4. Pick a username ending in `bot`: `acme_monitoring_bot`. The username must be unique across Telegram.\n5. BotFather replies with a token like `123456789:AAFq3ZNn-fakebut-like-this-shape`. Save this, it's your bot token.\n\nThe bot token is a credential. Anyone with it can send messages as your bot, so treat it like a password.\n\n## Step 2. Get a chat ID\n\nFor direct messages to yourself:\n\n1. Open a chat with **@userinfobot**.\n2. Send any message; it replies with your numeric user ID. That's your chat ID.\n\nFor a group chat:\n\n1. Add your bot to the group.\n2. Send `/start` in the group, or any message tagging the bot.\n3. Open `https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates` in a browser.\n4. Look for `\"chat\": {\"id\": -1001234567890, ...}`. The negative number is the group's chat ID.\n\n## Step 3. Configure in UptimeWarden\n\nTelegram is added as a webhook under **Settings → Notifications → Webhooks**, there is no longer a separate \"Telegram\" screen. Use **Add webhook** (or the webhook wizard) and pick the Telegram type:\n\n1. **URL**, `https://api.telegram.org/bot<BOT_TOKEN>/sendMessage`. Replace `<BOT_TOKEN>` with the token from BotFather.\n2. **Chat ID**, enter the chat ID from Step 2. It is stored as the `x-telegram-chat-id` header.\n3. **Parse mode / message format**. Markdown (default), HTML, or MarkdownV2. Markdown is the most forgiving with monitor names.\n4. **Save**.\n\nClick **Send test**. You should receive a test message in Telegram within a few seconds. If you don't, make sure you've sent at least one message to the bot first. Telegram blocks bots from messaging users who haven't initiated the conversation.\n\n## Encryption at rest\n\nYour bot token is encrypted before storage. Even if someone gained access to the database file, they would not be able to read the raw token. The encryption is automatic, you paste, we encrypt, and only the live application can decrypt for delivery.\n\nNever paste the bot token into a comment field, log line, or audit log entry, those paths aren't encrypted.\n\n## Message preview\n\nDefault message format for a `down` alert:\n\n```\n🚨 *Service Down Alert*\n\n*Monitor:* Payment API\n*URL:* https://api.example.com\n*Error:* HTTP 503\n*Time:* 2026-04-27 03:12:00 UTC\n\nPlease investigate immediately.\n```\n\nCustomize this with a notification template, see [Push Templates](/docs/push-templates) for the variable interpolation pattern. Telegram supports the same flat placeholders such as `{monitor_name}`, `{monitor_url}`, `{error_message}`, `{response_time}`, and `{ssl_expiry_days}`. Both `{single}` and `{{double}}` brace styles work.\n\n## Multiple chats per user\n\nYou can target specific chats per monitor. On the monitor edit form, the **Telegram → Chat IDs** field (comma-separated) points a monitor at one or more specific chats. This is useful when:\n\n- Production monitors go to your `#prod-alerts` group.\n- Dev monitors go to your personal DM only.\n- Customer-facing monitors go to a customer-shared group with a different bot.\n\nIf the Chat IDs field is left empty, UptimeWarden uses your default chat ID.\n\n## Group chat etiquette\n\nTelegram bots can post in group chats but cannot read messages by default. Privacy Mode is on. To turn it off (so your bot can respond to slash commands like `/status` inside the group):\n\n1. Open BotFather and send `/setprivacy`.\n2. Pick your bot and choose **Disable**.\n\nUptimeWarden's bot only sends messages, so leave Privacy Mode on for security. Disable it only if you're building custom inbound handling.\n\n## Rate limits\n\nTelegram enforces:\n\n- 30 messages per second per bot across different chats\n- 1 message per second per chat or group\n\nUptimeWarden respects these limits. Burst alerts are queued by [Smart Alert Grouping](/docs/smart-alert-grouping) before they hit the bot, so you won't hit the cap during a multi-monitor outage.\n\n## Troubleshooting\n\n| Symptom | Fix |\n|---|---|\n| `Forbidden: bot was blocked by the user` | Open the bot chat and send any message to unblock it |\n| `Bad Request: chat not found` | Double-check the chat ID, normal groups start with `-` and supergroups start with `-100` |\n| Markdown formatting broken | Special characters such as `*`, `_`, `[` need escaping in MarkdownV2; switch to HTML mode |\n| Test message works but real alerts don't | The monitor isn't subscribed to Telegram, check the channel grid on the monitor edit page |\n\n## Related topics\n\n- [Notification Channels](/docs/notification-channels): channel availability matrix\n- [Push Templates](/docs/push-templates): template authoring patterns\n- [Webhook Configuration](/docs/webhook-configuration): fallback if you can't run a native bot\n- [Smart Alert Grouping](/docs/smart-alert-grouping): burst control for chat channels","category":"notifications","tags":["telegram","bot","chat","integrations"],"order":60,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Telegram Notifications. UptimeWarden Documentation","metaDescription":"Connect UptimeWarden to Telegram by creating a bot via BotFather, configuring the bot token and chat ID, and previewing message format.","icon":"Bell","createdAt":"2026-10-12T22:06:41.800Z","updatedAt":"2026-10-12T22:06:41.800Z","publishedAt":"2026-10-12T22:06:41.800Z"},{"publicId":"01M4S2EP4ESWHKNC3VMSN09RWP","locale":"en","translationGroup":"push-templates","slug":"push-templates","title":"Push Templates","description":"Customize the push notification body per alert type, with variable interpolation.","body":"# Push Templates\n\nDefault push notifications are good. Custom push notifications are better, your monitor name in bold, a severity emoji, the response time inline, and \"Tap to acknowledge\" in your team's house style.\n\nThis page covers template authoring and variable interpolation.\n\n:::warning Administered feature\nPush template authoring is managed by UptimeWarden administrators. End users can see their devices and toggle alert types per device, but template editing is restricted. If you'd like a custom template for your account, file a support request.\n\nThis document is reference material for operators and partners with elevated access.\n:::\n\n## Template anatomy\n\nA push template has these parts:\n\n| Part | Purpose | Example |\n|---|---|---|\n| Channel | Always push for this template type | push |\n| Alert type | Which alert this fires for | down, recovery, ssl, high_response, high_response_recovery |\n| Message content | The notification body (the only editable field) | `🔴 {{monitor_name}} is down - {{incident_message}}` |\n\nThe title is not editable; it is generated automatically from the alert type (e.g. `🔴 <monitor_name> is Down` for down).\n\nThe render engine looks up templates by channel, alert type, and user. User-specific overrides win first, then defaults, then a built-in fallback.\n\n## Authoring\n\nOpen **Settings → Push Notifications → Templates → New Template**:\n\n1. **Type**, pick down, recovery, ssl, and so on.\n2. **Message content**, the notification body. Keep it short; the UI recommends 178 characters or fewer.\n3. **Variables**, interpolate values from the alert (see below).\n4. **Save**, the template activates immediately.\n\nThere is no separate Title field, the title is generated automatically from the alert type. The body is the only editable field.\n\nTemplates you create belong to your own account. System (default) templates that apply to everyone can only be created with an admin role; there is no workflow to override a template for a specific user by typing their ID.\n\n## Variable interpolation\n\nTemplates support flat `{{variable_name}}` interpolation:\n\n| Variable | Type | Example value |\n|---|---|---|\n| `{{monitor_name}}` | text | Payment API |\n| `{{monitor_url}}` | text | https://api.example.com/health |\n| `{{response_time}}` | number (ms) | 1240 |\n| `{{status}}` | text | up, down |\n| `{{status_code}}` | number | 503 |\n| `{{incident_message}}` | text | Connection refused |\n| `{{ssl_expiry_days}}` | number | 7 |\n| `{{threshold}}` | number (ms) | 2000 |\n| `{{incident_type}}` | text | down, recovery, etc. |\n| `{{timestamp}}` | localized date/time | 4/27/2026, 3:12:00 AM |\n| `{{iso_timestamp}}` | ISO 8601 | 2026-04-27T03:12:00Z |\n\nThe render engine only substitutes variables that are present; an unrecognized token (for example, a name not in the list above) is left as-is in the output. Numeric variables such as `response_time` always have a value, they default to `0` on connection failures, so `Response: {{response_time}}ms` renders as `Response: 0ms`.\n\n> The render engine does not resolve dotted paths such as `{{monitor.name}}` or `{{stats.uptime_24h}}`. Stick to the flat names listed above.\n\n## Default templates\n\nOut of the box, push fires with messages along these lines:\n\n- Down: `<monitor_name> is currently down. Error: <incident_message>`\n- Recovery: `<monitor_name> is back online. Response time: <response_time>ms`\n- SSL expiry: `SSL certificate for <monitor_name> expires in <ssl_expiry_days> days`\n- Slow response: `<monitor_name> is responding slowly (<response_time>ms > <threshold>ms)`\n- Slow response recovery: `<monitor_name> response time is back to normal (<response_time>ms)`\n\nThe renderer accepts both single-brace `{var}` and double-brace `{{var}}` for backwards compatibility. Author new templates with double-brace.\n\n## Custom vs system templates\n\nTemplates you create belong to your own account. System (default) templates that apply to everyone can only be created with an admin role. When a system template is marked as default, other system defaults for the same channel-and-alert-type key are deactivated automatically, so two competing defaults can't fire at once. User templates cannot be marked as default.\n\nIf no row matches, the built-in default runs. Defaults are guaranteed to render even in edge cases, they're a safety net, not a fallback you should rely on for branding.\n\n## Action buttons\n\niOS and Android push notifications show **Acknowledge** and **View** action buttons. These buttons are not declared in templates, they are controlled by the mobile app. Acknowledge calls `/api/incidents/<publicId>/acknowledge` for the related incident; View opens the app via the `uptimewarden://incident/<publicId>` deep link.\n\n## Related topics\n\n- [Push Notifications](/docs/push-notifications): device setup and per-device control\n- [Notification Channels](/docs/notification-channels): channel availability matrix\n- [Telegram](/docs/telegram): uses the same template engine for chat formatting","category":"notifications","tags":["push","templates","customization"],"order":70,"parentSlug":"notifications","published":true,"version":1,"metaTitle":"Push Notification Templates. UptimeWarden Documentation","metaDescription":"Author push notification templates with variable interpolation. Managed by UptimeWarden administrators.","icon":"Bell","createdAt":"2026-10-12T22:06:41.807Z","updatedAt":"2026-10-12T22:06:41.807Z","publishedAt":"2026-10-12T22:06:41.807Z"},{"publicId":"01KJ7Q9ZSQ3T5J2R39PS2QV27F","locale":"en","translationGroup":"incidents-overview","slug":"en-incidents","title":"Incident Management","description":"Incident list, detail page, resolution process, and update guide","body":"# Incident Management\n\nIncident management covers the process of tracking, updating, and resolving issues detected in your monitors. Incidents are created automatically and remain active until you resolve them or the system closes them automatically.\n\n## Incident Types\n\nIncidents are classified by alert types:\n\n| Alert Type | Description | Severity |\n|------------|-------------|----------|\n| **Service Down** | Service is completely unreachable | Critical |\n| **Service Recovery** | Service is accessible again | Info |\n| **SSL Expiring** | SSL certificate is about to expire | Warning |\n| **SSL Renewed** | SSL certificate has been renewed | Info |\n| **High Response Time** | Response time exceeds threshold | Warning |\n| **Response Recovered** | Response time returned to normal | Info |\n| **Domain Expiring** | Domain registration is about to expire | Warning |\n| **Domain Renewed** | Domain registration has been renewed | Info |\n\n> Alert types are managed by the database and can be customized from the admin panel.\n\n## Severity Levels\n\n| Level | Description |\n|-------|-------------|\n| **Critical** | Service is completely down, immediate action required |\n| **Major** | Significant performance loss |\n| **Minor** | Small issue, close monitoring sufficient |\n\n## Incident Statuses\n\n| Status | Description |\n|--------|-------------|\n| **Investigating** | Issue detected, being investigated |\n| **Identified** | Root cause identified |\n| **Monitoring** | Fix applied, being observed |\n| **Resolved** | Issue resolved |\n\n## Incident List\n\nThe **Incidents** page lists all incidents in two sections:\n\n### Active Incidents\nUnresolved incidents are shown at the top of the page.\n\n### Incident History\nBelow that, the full incident history is listed with pagination (20 per page).\n\n### Information on Each Incident Card\n\n- **Alert type badge**: Downtime, Slow Response, SSL Warning, etc.\n- **Severity badge**: Critical, Major, Minor\n- **Status badge**: Investigating, Identified, Monitoring, Resolved\n- **Duration**: How long it has been active or when it was resolved\n- **Title**\n- **Monitor name** (clicking goes to the monitor detail page)\n- **User**: Who created it (automatic ones show \"System\")\n- **Description** (if any, limited to 2 lines)\n- **Update count** (expandable)\n\n### Filters\n\n| Filter | Options |\n|--------|---------|\n| **Time range** | Time picker for different periods |\n| **Severity** | All, Critical, Major, Minor |\n| **Status** | All, Investigating, Identified, Monitoring, Resolved |\n| **Alarm Type** | All, Service Down, High Response Time, SSL Expiring, Domain Expiring |\n\n## Incident Detail Page\n\nClick an incident to open its detail page.\n\n### Top Section\n\n- Severity and status badges\n- Incident title\n- Description (if any)\n- **\"Resolve Incident\"** button (if not yet resolved)\n\n### Incident Information\n\n| Field | Description |\n|-------|-------------|\n| **Monitor** | Associated monitor (clickable link) |\n| **Created By** | Creator user or \"System\" |\n| **Started At** | Start date/time + how long ago |\n| **Resolved At** | Resolution date (if resolved) + how long ago |\n| **Duration** | Total duration |\n\n### Updates and Timeline\n\nWhile the incident is active, you can add updates:\n1. Enter your update note in the text field\n2. Click the **\"Post Update\"** button\n\nAll updates are displayed in a vertical timeline. For each update:\n- Date and time\n- Status badge\n- Message content\n- How long ago it was added\n\n### Post-Incident Checklist\n\nAfter the incident is resolved, a checklist is shown:\n\n1. Document the root cause analysis\n2. Update the status page with the final report\n3. Notify affected customers\n4. Review monitoring thresholds\n5. Plan a team post-mortem meeting\n\nThis list is a reminder, and completed items can be checked locally.\n\n## Resolving an Incident\n\nTo resolve an incident:\n\n1. Click the **\"Resolve\"** button in the incident list or detail page\n2. Enter your **resolution message** (required field)\n3. Confirm\n\nAfter resolution, the incident status updates to **Resolved**.\n\n## Automatic Closure Rules\n\nSome incidents are automatically closed when certain conditions are met:\n\n| Incident Type | Auto-Close Condition |\n|---------------|---------------------|\n| **Service Down** | 3 consecutive successful checks |\n| **High Response Time** | 3 consecutive checks below threshold |\n| **SSL Expiring** | Certificate renewed (30+ days remaining) |\n\nChecks run every 5 minutes.\n\n## Tips\n\n1. **Add updates regularly**: Keep the team informed by adding regular updates to active incidents\n2. **Write detailed resolution messages**: Specify the root cause and actions taken\n3. **Use filters**: Use filters to find specific types of incidents\n4. **Complete post-incident tasks**: Follow the checklist steps after resolution\n5. **Go to monitor details**: Click the monitor name to understand the incident context","category":"incidents","tags":["incidents","management","resolution","timeline","updates"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Incident list, detail page, resolution process, and update guide","icon":"AlertTriangle","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTG6T9KFY993D848B44","locale":"en","translationGroup":"incident-analytics","slug":"en-incident-analytics","title":"Incident Analytics and Reporting","description":"Incident statistics, resolution times, and trend analysis guide","body":"# Incident Analytics and Reporting\n\nThe **Incident Analytics** page helps you analyze outage data to identify trends and areas for improvement.\n\n## Accessing the Analytics Page\n\nClick **Reports** in the left menu or use the analytics link in the incident list.\n\n## Summary Cards\n\n4 summary cards at the top of the page:\n\n| Card | Description |\n|------|-------------|\n| **Total Incidents** | Total outage count in the selected time range |\n| **Avg Resolution Time** | Average resolution time (in minutes) |\n| **Active Incidents** | Currently ongoing outage count |\n| **Resolved** | Resolved outage count |\n\n## Time Series Chart\n\nThe main chart shows outages over time for the selected period:\n\n- **Total** (dashed line): Sum of all outages\n- **Down**: Service outages\n- **Timeout**: Timeout-related outages\n- **SSL**: SSL certificate issues\n- **Other**: Other outage types\n\n## Resolution Metrics\n\nCard showing your resolution performance:\n\n- **Resolution rate**: Percentage of resolved incidents (with progress bar)\n- **Active incident count**: Still ongoing outages\n- **MTTR performance**: Assessment of your average resolution time:\n  - **Excellent**: Under 30 minutes\n  - **Good**: 30-60 minutes\n  - **Needs Improvement**: Over 60 minutes\n\n## Most Affected Monitors\n\nList of monitors with the most outages in the selected period. Outage count is shown as a badge for each monitor.\n\n## Incident Type Distribution\n\nDistribution of outages by type, shown as percentage and count: down, timeout, SSL, high_response, etc.\n\n## Filtering\n\n| Filter | Options |\n|--------|---------|\n| **Time range** | Last 24 hours, 7 days, 30 days, 90 days |\n| **Grouping** | By hour or day |\n| **Custom date** | Start and end date selection |\n\n## Data Export\n\nUse the **\"Export\"** button to download the most affected monitors' data in CSV format.\n\n## Tips\n\n1. **Track MTTR**: Mean Time To Resolve is an important SLA metric\n2. **Analyze recurring outages**: If the same monitor has frequent outages, investigate the underlying cause\n3. **Extend the time range**: Look at 30 or 90 day data to see trends\n4. **Share reports**: Use CSV export for team meetings","category":"incidents","tags":["analytics","reports","incidents","metrics","mttr"],"order":2,"parentSlug":"incidents","published":true,"version":1,"metaTitle":null,"metaDescription":"Incident statistics, resolution times, and trend analysis guide","icon":"AlertTriangle","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EP9MJW12JZNDN77G55FD","locale":"en","translationGroup":"incident-lifecycle","slug":"incident-lifecycle","title":"Incident Lifecycle","description":"Every state an incident moves through, open, acknowledged, resolved, plus multi-region verification and the cascade-suppressed branch.","body":"# Incident Lifecycle\n\nAn incident. UptimeWarden's record of a real-world disruption, moves through a defined set of states from the first failed check to the moment you close it. Each transition is triggered either by a person taking action or by the system reacting to an event. This page lays out every state and what causes the transition.\n\n## All states at a glance\n\n| State | Meaning |\n|---|---|\n| `open` | Newly opened, awaiting acknowledgement |\n| `acknowledged` | A responder owns it |\n| `investigating` | Active triage |\n| `monitoring` | Fix applied, watching |\n| `resolved` | Service recovered or manually closed |\n| `pending_verification` | Multi-region verification in flight (notifications deferred) |\n| `rejected` | Multi-location consensus failed (false alarm) |\n| `suppressed_cascade` | An upstream dependency is already down, no notifications, no escalation, no status-page entry |\n\n## State diagram\n\n```mermaid\nstateDiagram-v2\n    [*] --> PendingVerification: Monitor DOWN<br/>(verification eligible)\n    [*] --> Open: Monitor DOWN<br/>(no verification)\n    [*] --> SuppressedCascade: Upstream<br/>cascade window open\n    PendingVerification --> Open: Consensus<br/>confirmed\n    PendingVerification --> Rejected: Consensus<br/>failed\n    Open --> Acknowledged: User clicks \"Acknowledge\"<br/>(email link / dashboard)\n    Open --> Resolved: Monitor recovery<br/>(automatic)\n    Acknowledged --> Resolved: Monitor recovery<br/>OR user \"Resolve\"\n    SuppressedCascade --> Open: Promotion sweep<br/>(planned / coming soon)\n    SuppressedCascade --> Resolved: Recovery\n    Resolved --> [*]: Postmortem<br/>auto-prefill\n    Rejected --> [*]\n    Acknowledged --> Open: Recovery, then<br/>fails again (re-open)\n```\n\n## Who triggers what\n\n| Transition | Trigger | Automatic? | Effect |\n|---|---|---|---|\n| `→ pending_verification` | Failure signal, verification eligible | yes | Notification deferred |\n| `pending_verification → open` | Cross-region consensus reached | yes | Notifications start |\n| `pending_verification → rejected` | Consensus not reached | yes | No notification fires |\n| `→ suppressed_cascade` | Upstream incident inside the 60-second window | yes | No notification, no escalation |\n| `→ open` | Failure signal (verification off) | yes | Notifications start |\n| `open → acknowledged` | On-call responder | manual | Triage begins, escalation halts |\n| `open → resolved` | Monitor recovery | yes | Recovery notification + postmortem draft |\n| `acknowledged → resolved` | Recovery or user action | both | Postmortem draft |\n| `suppressed_cascade → open` | Upstream resolves, monitor still down (planned / coming soon) | - | Notifications start |\n| `acknowledged → open` | Re-fails after the 60-second dedup window | yes | Resume triage |\n\n## The cascade-suppressed branch\n\nIf an upstream dependency (a database, for example) already has an open incident inside the cascade window (default 60 seconds):\n\n- The system runs a cascade check before opening the new incident\n- The new incident is recorded with state `suppressed_cascade`, linked to the upstream incident\n- Notifications, escalation, and the status-page entry are **all skipped**\n- Planned (coming soon): when the upstream resolves, a promotion sweep will flip suppressed incidents that are still failing to `open` and the normal notification pipeline will kick in\n\nThe incident detail page shows a banner pointing to the upstream incident. Use the \"Include suppressed\" toggle in the list to surface them.\n\nCascade Suppression is opt-in: your team admin enables it from the admin panel. See [Incidents](/docs/incidents-overview).\n\n## Multi-region verification\n\nIf a monitor runs from multiple regions (for example Sweden Central + East Asia + Phoenix), a single failure signal does not open an incident immediately:\n\n1. The incident is recorded with state `pending_verification`.\n2. Other regions are asked to run the same check.\n3. If consensus is reached → `open` (notifications start).\n4. If consensus fails → `rejected` (no notification).\n\nSee [Multi-Location Consensus](/docs/multi-location-consensus).\n\n## How acknowledge works\n\nThree entry points, all producing the same state transition:\n\n1. **The \"Acknowledge\" link in the email**, one click, no login required (the link is signed and time-limited)\n2. **The incident detail page on the dashboard**, \"Acknowledge\" button\n3. **Mobile push action**, swipe the notification, tap \"Ack\"\n\nFirst acknowledgement wins; later clicks are no-ops, but who acknowledged is always logged.\n\n## How resolve works\n\nTwo paths:\n\n1. **Automatic**, when the monitor reports recovery, the incident closes itself. This is the default and the recommended path.\n2. **Manual**, deliberately marking an incident \"done\" when the monitor is producing false positives.\n\nIf a manually resolved monitor keeps failing, a **new** incident is opened once the 60-second deduplication window has passed.\n\n## Webhook notifications\n\nWebhooks deliver an alert payload when a monitor changes state. The payload's `incident.type` field carries the alert type that fired:\n\n- `down`, monitor went down\n- `recovery`, monitor recovered\n- `ssl_warning`. SSL certificate approaching expiry\n- `high_response`, response time above threshold for N checks in a row (default 3)\n\nEach webhook subscribes to the alert types you enable (default: `down`, `recovery`, `ssl_warning`, `high_response`). Payloads are HMAC-SHA256 signed.\n\nWhen an incident reaches `resolved`, the system auto-drafts a postmortem; this is an internal step, not a webhook you can subscribe to.\n\nFor webhook security, see [Webhook Security](/docs/webhook-security).\n\n## Resolution metrics\n\n- **MTTR** (mean time to resolve): the mean of `resolvedAt − createdAt` across resolved incidents. Surfaced per monitor and as an average resolution time across your incidents.\n\nThe incident analytics dashboard, trend charts, resolution rate, and MTTR analysis over 1/7/30/90-day ranges, is available on every plan, including Free.\n\n## Related\n\n- [Escalation Policies](/docs/escalation-policies): how the on-call ladder climbs when nobody acknowledges\n- [Smart Alert Grouping](/docs/smart-alert-grouping): collapsing alert storms into a single incident\n- [Multi-Location Consensus](/docs/multi-location-consensus): how `pending_verification` is settled\n- [Maintenance Windows](/docs/maintenance-windows): keeping planned downtime out of the incident log","category":"incidents","tags":["incident","lifecycle","state-machine","cascade-suppression","on-call"],"order":10,"parentSlug":"incidents","published":true,"version":1,"metaTitle":"Incident Lifecycle. UptimeWarden Documentation","metaDescription":"The UptimeWarden incident state machine: open → acknowledged → resolved transitions, multi-region verification, and Cascade Suppression.","icon":"AlertTriangle","createdAt":"2026-10-12T22:06:41.973Z","updatedAt":"2026-10-12T22:06:41.973Z","publishedAt":"2026-10-12T22:06:41.973Z"},{"publicId":"01M4S2ENXB16WJTX5ARVZAQ12A","locale":"en","translationGroup":"incidents-overview","slug":"incidents-overview","title":"Incidents","description":"Incident lifecycle, cascade suppression, postmortems, and on-call essentials in UptimeWarden.","body":"# Incidents\n\nThe moment one of your monitors fails, UptimeWarden opens an **incident**. The incident is the single record that drives alerting, on-call escalation, status page updates, and the postmortem you write afterwards. Everything in this section explains how that record behaves from the first failed check until you close the book on it.\n\n## What this section covers\n\n- **Incident lifecycle**: every state an incident moves through and what triggers each transition\n- **Cascade Suppression**: keeping a single upstream failure from triggering 50 alerts\n- **Maintenance Windows**: silencing planned downtime so real alerts stay trustworthy\n- **Postmortem Workflow**: turning a resolved incident into a written record the whole team learns from\n\n## Which monitors open incidents\n\nEvery monitor type can produce an incident. The five most common sources:\n\n- **HTTP / HTTPS**: endpoint down, 5xx responses, timeouts, slow responses\n- **SSL**: certificate about to expire (or recovery)\n- **TCP**: port unreachable\n- **Heartbeat**: an expected ping is late or never arrived\n- **Ping (ICMP)**: host doesn't respond\n\n## The lifecycle in one line\n\n```\nopen → acknowledged → investigating → monitoring → resolved\n```\n\n| State | Meaning | What's happening |\n|---|---|---|\n| `open` | Just opened, no one has owned it yet | On-call escalation is running |\n| `acknowledged` | Someone is on it | Escalation halts |\n| `investigating` | Root cause work is in progress | Banner appears on the status page |\n| `monitoring` | A fix has been applied, you're watching | Status page is updated |\n| `resolved` | Service recovered or you closed it manually | Recovery notification fires and a postmortem draft is started |\n\nTwo extra states cover multi-region verification:\n\n- `pending_verification`, one location reports failure, others are still checking (notifications wait)\n- `rejected`, the verification threshold was not met, false alarm dismissed\n\nA sixth state appears when Cascade Suppression is on:\n\n- `suppressed_cascade`, an upstream dependency is already down. The incident sends no notifications and stays off the status page (details below).\n\nSee [Incident Lifecycle](/docs/incident-lifecycle) for the full state machine.\n\n## Who opens an incident\n\nIncidents open automatically the moment a monitor reports failure. The system performs a few safety checks first, it confirms the monitor isn't inside a maintenance window, isn't suppressed by an upstream incident, and (where eligible) waits for multi-region consensus. Only then does the incident move to `open` and notifications go out.\n\nYou can also open an incident manually from `Incidents → New Incident`, useful for recording planned maintenance after the fact or logging an outage you noticed before UptimeWarden did.\n\n## Severity and priority\n\nEvery incident carries two independent classifications.\n\n**Severity**, how big the impact is:\n- `minor`, some users affected\n- `major`, many users affected\n- `critical`, full outage\n\n**Priority**, how urgent the response is:\n- `low`, `medium`, `high`, `critical`\n\nSeverity is assigned automatically by alarm type: a down incident is critical, a slow-response incident is a warning, and SSL or domain incidents are scored by the number of days left until expiry. Priority is set by you or by your escalation policy.\n\n## Acknowledging an incident\n\nEvery notification carries an **Acknowledge** link. One click and:\n\n- No login is needed: the link is signed and time-limited\n- The incident moves to `acknowledged`\n- Escalation halts immediately\n- The audit log records who acknowledged it\n\nSee [Incident Lifecycle](/docs/incident-lifecycle) for the full picture.\n\n## Cascade Suppression\n\nWhen a database goes down, the 50 monitors that depend on it usually go down too. Opening 50 separate incidents and sending 50 SMS messages is noisy and misleading. **Cascade Suppression** quietly handles it:\n\n- UptimeWarden keeps a dependency map of your monitors\n- While the database incident is open (default 60-second window), new failures on downstream monitors land with the `suppressed_cascade` state\n- Suppressed incidents send **no notifications, don't appear on the status page, and don't trigger escalation**\n- When the upstream resolves, any monitors still failing are promoted to `open` automatically\n\nThe result: **1 incident** in the foreground, **49** quietly tracked in the background. Use the \"Include suppressed\" toggle in the incident list to audit them.\n\n:::note Opt-in feature\nCascade Suppression is **off** by default. Your team admin enables it from the admin panel. Once on, dependencies up to 10 hops deep are tracked.\n:::\n\n## Postmortem flow\n\nWhen an incident is resolved, UptimeWarden drafts a postmortem for you:\n\n1. The system gathers the timeline, affected monitors, and resolution time (MTTR, mean time to repair).\n2. An AI model writes the first draft: what happened, what was impacted, and suggested action items.\n3. Editor and admin users open the **Postmortem** tab on the incident, refine the draft (Markdown supported), and click **Publish**.\n4. The published postmortem becomes your team's canonical record of the incident.\n\nCascade-suppressed incidents do not generate postmortems. Postmortem drafts are included on every plan with a monthly allowance: 1 on Free and Hobby, 3 on Starter, and no monthly count on Professional and Enterprise.\n\nSee [Postmortem Workflow](/docs/postmortem-workflow).\n\n## Maintenance windows\n\nTo avoid an alert storm during planned maintenance, define a **maintenance window**:\n\n- Schedule it for specific monitors, recurring weekly or one-time\n- While the window is open, failures don't open incidents: but checks keep recording, so your charts stay accurate\n- Recovery signals always pass, even mid-window\n\nSee [Maintenance Windows](/docs/maintenance-windows).\n\n## API access\n\n```bash\n# List active incidents (status: active | resolved | all)\ncurl -H \"Authorization: Bearer $UPTIMEWARDEN_TOKEN\" \\\n  \"https://app.uptimewarden.online/api/v1/incidents?status=active\"\n\n# Mark an incident as resolved\ncurl -X PATCH \\\n  -H \"Authorization: Bearer $UPTIMEWARDEN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"status\":\"resolved\",\"resolutionMessage\":\"Service recovered\"}' \\\n  \"https://app.uptimewarden.online/api/v1/incidents/{publicId}\"\n\n# Add a comment to an incident\ncurl -X POST \\\n  -H \"Authorization: Bearer $UPTIMEWARDEN_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"message\":\"Root cause identified\"}' \\\n  \"https://app.uptimewarden.online/api/v1/incidents/{publicId}/comments\"\n```\n\nYou'll need the `incidents:read` (30-day window) and `incidents:update` permissions. See [API Tokens](/docs/api-tokens).\n\n## Next steps\n\n- [Incident Lifecycle](/docs/incident-lifecycle)\n- [Postmortem Workflow](/docs/postmortem-workflow)\n- [Maintenance Windows](/docs/maintenance-windows)\n- [Escalation Policies](/docs/escalation-policies)","category":"incidents","tags":["incidents","lifecycle","cascade-suppression","postmortem","on-call"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Incidents. UptimeWarden Docs","metaDescription":"How UptimeWarden handles incidents, from the first failed check through acknowledgement, resolution, and postmortem.","icon":"AlertTriangle","createdAt":"2026-10-12T22:06:41.579Z","updatedAt":"2026-10-12T22:06:41.579Z","publishedAt":"2026-10-12T22:06:41.579Z"},{"publicId":"8c5ec428d8554d48974fa930d1","locale":"en","translationGroup":"maintenance-windows","slug":"en-maintenance-windows","title":"Maintenance Windows","description":"Silence monitors during planned maintenance so the team can sleep through expected downtime without losing trust in real alerts.","body":"# Maintenance Windows\n\nYou restart the server every Tuesday at 02:00 for weekly maintenance. Every time, the team gets paged \"DOWN,\" wakes up, shrugs (\"oh, it's the Tuesday thing\") and goes back to bed. Two weeks in, nobody takes the page seriously — and **the next real outage goes unanswered**.\n\nMaintenance windows solve this: tell the system in advance \"my monitor may be down during this time,\" and it won't produce alarms. When the window closes, normal operation resumes.\n\n## When to use\n\n- **Planned deploys**: CI/CD deploys to prod every Thursday 22:00; response time wobbles for 15 minutes.\n- **Weekly DB maintenance**: Saturday 03:00 Postgres vacuum + index rebuild; 10 minutes of elevated query latency.\n- **Certificate rotation**: Monthly cert renewal with a 30-second HAProxy reload skipping one check tick.\n- **Seasonal campaigns**: Black Friday midnight config flip.\n\n## One-time vs recurring\n\nTwo kinds of windows:\n\n| Type | Use | Example |\n|---|---|---|\n| **One-time** | A specific single date | \"2026-04-20 14:00 — 14:30\" |\n| **Recurring** | Weekly/daily repeat | \"Every Tuesday 03:00 — 03:30 UTC\" |\n\nRecurring windows don't use cron syntax — just a simple weekly rhythm: days of week + start/end time + timezone.\n\n## Creating a window\n\nOpen the monitor's detail page → **Maintenance Windows** card → **New Window**:\n\n1. **Name**: A label meaningful to your team (e.g. `Saturday DB maintenance`).\n2. **Type**: `One-time` or `Recurring`.\n3. **Start / End**:\n   - One-time: Pick date + time from the calendar.\n   - Recurring: Pick weekdays (Mon–Sun checkboxes) + start/end time.\n4. **Timezone**: The zone the window is evaluated in. Use your team's zone; the system normalizes to UTC internally.\n5. **Description** (optional): Helpful future-you when editing the same window later.\n6. **Save**.\n\n## What happens when a window is open?\n\nIf the monitor would trigger a status change:\n\n- **Normally**: Incident opens, notifications go out, on-call pager rings.\n- **Window open**: The status change is NOT converted to an incident (`isMaintenanceSuppressed` guard). Check results are still recorded (visible in charts), but the alarm path stops.\n\n```mermaid\nflowchart LR\n    Check[Check fails] --> Suppress{\"Maintenance<br/>window<br/>open?\"}\n    Suppress -->|Yes| Record[Record + log<br/>no alarm]\n    Suppress -->|No| Incident[Open incident<br/>fire alarm]\n\n    classDef suppress fill:#fef7e0,stroke:#f2c336\n    classDef alarm fill:#ffebee,stroke:#c62828\n    class Record suppress\n    class Incident alarm\n```\n\nChecks **don't stop** during the window — they just don't produce alarms. That's why monitor health reflects accurately as soon as the window closes.\n\n## Recovery behavior\n\nIf the monitor is down during the window and is still down when the window closes:\n\n1. The transient \"was down in window\" state is discarded.\n2. The next failing check (now that the window is closed) → incident opens **at that moment**.\n3. The alarm follows the normal pipeline.\n\nSo you don't get a \"catch-up\" alarm at window close; the system behaves as if monitoring restarts fresh from the next check.\n\n## Multiple windows\n\nA monitor can have several windows. Any open window suppresses (OR logic):\n\n```\nWindow A: Tuesday 03:00–03:30 (DB maintenance)\nWindow B: 2026-04-20 14:00–14:30 (one-time deploy)\nWindow C: Friday 22:00–22:30 (weekly release)\n```\n\nAt Tuesday 03:15, A is checked first — it's open, so alarm is suppressed (B and C don't need to be evaluated).\n\n## Group-level maintenance\n\nBig deploy affecting every API service? Instead of adding a window to each monitor individually:\n\n1. Put related monitors in a **group** (e.g. `api-services`).\n2. Register one bulk window against the group (upcoming bulk UI; today you still add per-monitor).\n\n> Group-level maintenance UI is roadmap; for now each monitor needs its own window.\n\n## Status page integration\n\nIf you publish a public status page, maintenance windows auto-surface:\n\n- Before start: \"Planned maintenance: Tuesday 03:00 — 03:30 UTC\"\n- During: \"Maintenance in progress\"\n- After: \"Maintenance completed\"\n\nCustomers who check the status page see \"this is planned, not an outage.\"\n\n## FAQ\n\n**Q: Can I override a window and still get paged for a critical class of alert?**\nA: A per-monitor \"critical\" flag would override — it's a roadmap item; today all alerts are suppressed equally during a window.\n\n**Q: I forgot about a window; my monitor stayed silent for 2 hours.**\nA: One-time windows have a hard end time — they don't linger. Recurring windows close at the chosen end time. There's no such thing as a \"permanently open\" window left behind.\n\n**Q: Does the dashboard mark the monitor as under maintenance?**\nA: Yes — the monitor list shows a \"scheduled maintenance\" badge. Incident analytics separate windowed downtime as \"planned\" so it's excluded from your SLA %%.\n\n**Q: Can I do a dry-run check of traffic during the window?**\nA: Raw check results are still stored; you can inspect the charts any time. Production-like signal flows through at normal volume — only the alarm path is paused.\n\n## Related topics\n\n- [Incident Management](/docs/en-incidents-overview)\n- [Notification Channels](/docs/en-notification-channels)\n- [Creating a Status Page](/docs/en-status-page-creation)","category":"incidents","tags":["maintenance","suppression","planning"],"order":20,"parentSlug":"incidents","published":true,"version":2,"metaTitle":"Maintenance Windows — UptimeWarden Documentation","metaDescription":"Avoid alert fatigue during planned maintenance with time-bounded monitor suppression.","icon":"AlertTriangle","createdAt":"2026-04-19T00:06:52.889Z","updatedAt":"2026-04-19T00:16:16.629Z","publishedAt":"2026-04-19T00:06:52.889Z"},{"publicId":"01M4S2EP2RKDN96Z15Y7D27YN0","locale":"en","translationGroup":"maintenance-windows","slug":"maintenance-windows","title":"Maintenance Windows","description":"Silence monitors during planned maintenance. The maintenance page shows what is running now and what is coming up, so the team can sleep through expected downtime without losing trust in real alerts.","body":"# Maintenance Windows\n\nYou restart the server every Tuesday at 02:00 for weekly maintenance. Every time, the team gets paged \"DOWN,\" wakes up, shrugs (\"oh, it's the Tuesday thing\"), and goes back to bed. Two weeks in, nobody takes the page seriously, and **the next real outage goes unanswered**.\n\nMaintenance windows solve this. Tell UptimeWarden in advance \"my monitor may be down during this time,\" and it won't open incidents during that period. When the window closes, normal operation resumes.\n\n## When to use one\n\n- **Planned deploys**: your release pipeline ships to production every Thursday at 22:00 and response times wobble for 15 minutes.\n- **Weekly database maintenance**: Saturday 03:00 vacuum and index rebuild, ten minutes of elevated query latency.\n- **Certificate rotation**: a monthly cert renewal with a 30-second load-balancer reload that skips one check tick.\n- **Seasonal campaigns**: a Black Friday midnight config flip.\n\n## How a window is described\n\nEach maintenance window is one of two shapes:\n\n**Recurring**, repeats every week on a single day:\n\n| Field | Value |\n|---|---|\n| Type | Recurring |\n| Day | Day of week (Monday. Sunday) |\n| Start | `HH:MM` |\n| End | `HH:MM` |\n| Time zone | IANA zone (default `UTC`) |\n\nA recurring window whose end is at or before its start runs past midnight: Monday `22:00`–`04:00` lasts from Monday 22:00 to Tuesday 04:00. Times follow the wall clock of the window's time zone, also across daylight-saving changes. The form accepts a recurring window that crosses midnight too, and says **Ends next day at …** when it will.\n\n**One-time**, runs once, with explicit start and end timestamps:\n\n| Field | Value |\n|---|---|\n| Type | One-time |\n| Start | ISO-8601 timestamp |\n| End | ISO-8601 timestamp |\n| Time zone | IANA zone (default `UTC`) |\n\nOne-time windows read their start and end in the time zone you pick when you create them; the times are yours, not the server's. Windows that cross midnight are fine. A one-time window that has finished leaves the maintenance list instead of staying listed as if it were still scheduled.\n\n## Creating a window\n\n**Schedule maintenance** on the maintenance page opens the form in a side sheet. In that form:\n\n1. Choose the **Window type**: **Recurring** or **One-time**.\n2. For a recurring window, pick the day of week and the `HH:MM` start and end; when it crosses midnight the form says **Ends next day at …**. For a one-time window, pick the start and end date and time; those times are read in the time zone you choose.\n3. Set the time zone (your own zone is the default).\n4. Pick the monitors; you can search the list by name, URL, tag or group. The same window is added to every monitor you select.\n5. Optionally write a reason. The reason is shown in the dashboard only; it is never shown on a status page.\n\nYou can also add a window from a single monitor's form: open the **Maintenance windows** section, click **Add**, pick the day of week and the `HH:MM` times, set the time zone and save the monitor. Recurring windows in this UI cover a single day; add separate windows for each day you need.\n\n:::note One-time windows are read-only in the monitor form\nThe monitor form **only creates recurring windows**. One-time windows are defined from the maintenance page's form, via API or in the mobile app; the form renders them as a compact read-only label and preserves them on save.\n:::\n\n## The maintenance windows page\n\nThe maintenance page opens on what is happening now; the create form sits behind the **Schedule maintenance** button instead of filling the page:\n\n- **Now**: windows running at this moment. A running one-time window has an **End now** button to close it early.\n- **Next 14 days**: every window that will actually happen in the next 14 days, grouped by day, with recurring and one-time windows told apart.\n- **Schedules**: the recurring rules you have defined, with the next run time. The same rule applied to several monitors is merged into one row.\n- **Past windows**: a collapsed record of the last 30 days.\n\nThe list uses the same reading as the maintenance gate, so a window shown here is one that really holds alerts. Times are shown in your zone; a window set in another zone also names its own.\n\n## What happens while a window is open\n\nUptimeWarden checks the maintenance gate on every alert-shaped event:\n\n- **Window closed**: the incident opens, notifications go out, the on-call pager rings.\n- **Window open**: failure signals (DOWN, SSL warning, slow response, domain expiring) are **not** turned into incidents. Check results are still recorded so your charts stay accurate, and recovery signals always pass through so a pre-window incident can still close.\n\n```mermaid\nflowchart LR\n    Check[Check fails] --> Suppress{\"Maintenance<br/>window<br/>open?\"}\n    Suppress -->|Yes| Record[Record + log<br/>no incident]\n    Suppress -->|No| Incident[Open incident<br/>fire alarm]\n\n    classDef suppress fill:#fef7e0,stroke:#f2c336\n    classDef alarm fill:#ffebee,stroke:#c62828\n    class Record suppress\n    class Incident alarm\n```\n\n:::warning Checks keep running, only incident creation is paused\nChecks **don't stop** during the window. Recovery events always pass through so an incident that opened before the window can still resolve.\n:::\n\nThe maintenance gate always runs first, ahead of Cascade Suppression and Smart Alert Grouping.\n\n## Recovery behaviour\n\nIf a monitor is failing during the window and is still failing when the window closes:\n\n1. The transient in-window failures are discarded, no incident was ever opened.\n2. The next failing check (now that the window is closed) opens an incident **at that moment**.\n3. The alarm follows the normal pipeline.\n\nYou won't get a \"catch-up\" alarm at window close.\n\nThe same holds for a slow response: a slow-response alert that was raised inside the window and held by it opens after the window if the monitor is still slow. Suppression does not swallow it forever. The incident starts at the first slow check of the run, or at the moment the window ended if the run began inside it (the window's time is not slow time).\n\n## Multiple windows\n\nA monitor can have several windows. Any open window suppresses (OR logic):\n\n```text\nWindow A: Tuesday 03:00-03:30 (database maintenance)\nWindow B: 2026-04-20 14:00-14:30 (one-time deploy)\nWindow C: Friday 22:00-22:30 (weekly release)\n```\n\nAt Tuesday 03:15, A is open, so no incident is opened.\n\nA monitor can hold at most **20 windows** (the form UI caps the list at 5; more are added via the API).\n\n## Group / team maintenance\n\nYou can open a window for several monitors at once; the maintenance page opens with those monitors already selected:\n\n- **From a group**: the **Maintenance** action on a group page opens the form with every monitor in that group selected. See [Monitor Groups](/docs/groups).\n- **From the monitors list**: select the monitors there and click **Maintenance**; the selection is carried into the form.\n\nFill the form once and apply it, and the window is added to every monitor you selected.\n\n## Status page integration\n\nA monitor's maintenance windows show on every public status page the monitor is on:\n\n- **While a window is open**, the component shows **Under maintenance** instead of Down or Degraded, with the time the maintenance ends. A component down inside its window does not turn the page banner red; the banner says scheduled maintenance is in progress. A component that is down outside a window is still reported as down.\n- **Windows starting in the next seven days** are listed under **Upcoming maintenance**, with the components they cover, in the visitor's local time.\n\nOnly the timing is published. The window's reason and where it came from (UI, API, CI) are never shown. The page refreshes within about 15 seconds of a window opening or closing.\n\nUptime figures on the status page still count every check, maintenance included. The [SLO error budget](/docs/slo-error-budgets) is the place where maintenance is left out.\n\nSubscribers are not emailed about a monitor's maintenance windows. To email the people who subscribed to maintenance updates, post a **status-page incident with the `maintenance` severity** (for example \"Planned maintenance: Tuesday 03:00-03:30 UTC\") and resolve it when the work is done.\n\n## SLO error budget\n\nChecks inside a maintenance window are left out of the monitor's SLO: they neither spend the error budget nor trigger burn-rate alerts, and the budget is sized on the time outside maintenance. See [SLOs and Error Budgets](/docs/slo-error-budgets#maintenance-windows-are-left-out). The uptime report does not exclude maintenance.\n\n## FAQ\n\n**Can I override a window and still get paged for a critical alert?**\nThere is no per-monitor \"critical\" override today. While a window is open, all alarm-shaped events are suppressed. Recovery events still flow.\n\n**I forgot about a window, my monitor stayed silent for two hours.**\nRecurring windows respect the configured start and end times; one-time windows have a hard end timestamp. There is no such thing as a permanently open window. Windows opened via the API or mobile app are capped at **240 minutes (4 hours)**, longer work requires re-opening the window.\n\n**Does the dashboard mark the monitor as under maintenance?**\nIn the mobile app, yes: the monitor card shows a \"Maintenance\" chip while a one-time window is active. Public status pages show \"Under maintenance\" for any open window. The web dashboard does not have a dedicated maintenance indicator yet. Because in-window events are suppressed, they are never recorded as incidents, so incident analytics have no separate \"planned downtime\" breakdown.\n\n**Are checks still running during the window?**\nYes, checks keep running uninterrupted; only incident creation is paused. Results are visible in the charts.\n\n## Related\n\n- [Incidents](/docs/incidents-overview)\n- [Notification Channels](/docs/notification-channels)\n- [Creating a Status Page](/docs/creating-status-page)","category":"incidents","tags":["maintenance","suppression","planning"],"order":20,"parentSlug":"incidents","published":true,"version":1,"metaTitle":"Maintenance Windows. UptimeWarden Documentation","metaDescription":"Avoid alert fatigue during planned maintenance with time-bounded monitor suppression. The page lists what is running now, what is scheduled, and what has passed.","icon":"AlertTriangle","createdAt":"2026-10-12T22:06:41.752Z","updatedAt":"2026-10-12T22:06:41.752Z","publishedAt":"2026-10-12T22:06:41.752Z"},{"publicId":"01M4S2EP9WF340Y2VK2Z37XXRB","locale":"en","translationGroup":"postmortem-workflow","slug":"postmortem-workflow","title":"Postmortem Workflow","description":"How a postmortem draft is generated, edited, and published once an incident is resolved: what v1 covers today and what is planned for v2.","body":"# Postmortem Workflow\n\nA postmortem is the document you write **after** an incident is resolved, not to assign blame, but to capture what happened, who was hurt, and how the team will keep it from biting again. UptimeWarden's postmortem lives next to the incident itself: same page, same timeline, same data, just one extra tab once the dust has settled.\n\n:::note Release scope\nUptimeWarden supports **creating, editing, publishing, and externally sharing** postmortems. The **Share** action produces a read-only link (`/shared/postmortems/<token>`) that requires no account, with an optional expiry. The following are still on the roadmap:\n\n- Public mode on the status page\n- Push delivery to chat tools and email\n- A standalone action-item API (today, action items live as structured fields inside the postmortem document)\n:::\n\n## Plan availability\n\nPostmortem drafts are included on **every plan**, with a monthly allowance. Automatic and manual drafts count together:\n\n| Plan | Drafts per month |\n|---|---|\n| Free | 1 |\n| Hobby | 1 |\n| Starter | 3 |\n| Professional | No monthly count |\n| Enterprise | Unlimited |\n\nThe month is your AI credit month: it starts on your subscription's monthly anniversary, or on the first day of the calendar month (UTC) if you have no subscription, so drafts and AI credits come back on the same day. Automatic drafts do not use your AI credits; drafts you generate or regenerate by hand do. One incident is one draft: regenerating a report replaces it and does not use a second draft, although it still costs AI credits. The Postmortems page and the Postmortem tab show how many drafts are left this month.\n\nRead-on-downgrade policy: the postmortems you already have remain readable, editable, and publishable after a downgrade; only new drafts count against the new plan.\n\nCascade-suppressed incidents do not generate postmortems.\n\n## The flow at a glance\n\n```mermaid\nsequenceDiagram\n    participant Inc as Incident\n    participant System as UptimeWarden\n    participant UI as Dashboard\n    participant Author as Editor+\n    Inc->>System: status → resolved\n    System->>System: AI prefill draft\n    System-->>UI: Postmortem tab visible\n    Author->>UI: Edit draft\n    Author->>UI: Click Publish\n    UI->>Inc: postmortem status='published'\n```\n\nFour steps:\n\n1. **Resolve**, when the incident reaches `resolved`, UptimeWarden automatically requests a postmortem draft. Our AI engine drafts the prefill and saves it as a draft on the incident.\n2. **Manual regenerate** (optional), an editor or admin clicks **Generate** on the **Postmortem** tab. Regeneration replaces the current draft rather than adding a second one; read [What happens when you regenerate](#what-happens-when-you-regenerate) before you use it on a postmortem you have already edited.\n3. **Edit**, the author refines the draft on the same tab. Last write wins, and the original AI draft is preserved separately so nothing is lost.\n4. **Publish**, clicking **Publish** flips the postmortem from `draft` to `published`, and records who published it and when.\n\n## When automatic generation is triggered\n\nYou **don't have to do anything** to get the first draft. The moment an incident is resolved, UptimeWarden requests the draft itself:\n\n- **However the incident is resolved**, a draft is requested: whether the monitor recovers on its own and the incident auto-closes, or an editor marks it resolved by hand.\n- **It runs in the background.** The draft appears on the **Postmortem** tab seconds after resolution; it never slows down your resolve flow. If the tab is open, the draft shows up on its own the moment it is ready, no manual refresh needed.\n- **It's separate from notifications.** The recovery notification (email, Slack, webhook, etc.) and the postmortem draft don't wait for each other; both proceed on their own path right after resolution.\n- **It has a few conditions.** An automatic draft is written only when the incident lasted **five minutes or more**, the incident's owner has turned on **AI processing** in their profile, this month's drafts are not used up, and the feature is on. If one of these is not met, no automatic draft is written. You can create one later with **Generate**; that also needs AI processing to be on and counts against the same monthly allowance.\n- **Suppressed incidents are excluded.** No automatic draft is generated for incidents suppressed by Chain Suppression.\n\nAutomatic generation runs **once per incident**. If the same incident is resolved, reopened, and resolved again, the existing postmortem is left exactly as it is, including any edits you have made in the meantime. Automation never overwrites your work; only the **Generate** button does, and only when you press it.\n\n## What happens when you regenerate\n\n**Generate** is a replace, not an append. Pressing it produces a fresh AI draft and writes it over the current one:\n\n- **Your edits are discarded.** The edited text is cleared and the tab shows the new AI draft. Copy anything you want to keep before you regenerate.\n- **A published postmortem returns to draft** and its version number increases by one. This matters if you shared it: a public link only serves published postmortems, so the link starts returning \"not found\" until you press **Publish** again. The share token itself is kept, so republishing restores the same URL, you don't have to send a new link to anyone.\n- **Each run costs AI credits.** Regeneration calls the model again. It does not use a second draft from your monthly allowance, because the report is replaced rather than added. If your AI credits are used up, the button says so and the existing draft stays untouched.\n\nThere is no cooling-off period between two presses. Treat the button as a deliberate action: regenerate when the incident data has genuinely changed, for example after a late timeline entry or a corrected resolution time, rather than as a way to reroll the wording.\n\n## What gets prefilled automatically\n\nThe AI draft populates these fields:\n\n- **Summary**: a short paragraph describing what happened\n- **Timeline**: detection, acknowledgement, escalations, mitigation attempts, resolution, plus any custom entries\n- **Root cause analysis**: the most likely cause based on the incident data\n- **Impact assessment**: duration, monitors affected, severity, estimated downtime, customer impact, and SLO budget burned\n- **Contributing factors**: things that made the incident worse or harder to detect\n- **Action items**: concrete follow-ups with owner, priority, and status\n- **Evidence references**: links back to monitor results, correlated incidents, and recommendations\n\nThe author writes only what a machine can't infer: **what happened in human terms**.\n\n## Evidence trail: every claim shows its source\n\nCausal claims in the AI draft don't stand as unsourced narrative. An **evidence trail** is generated with the draft: each claim is linked to the timeline entries and check results it was drawn from. The **Evidence** section on the Postmortem tab lists every claim together with the source excerpts it cites (type, timestamp, and a short quote).\n\nThe honesty rule: when the model could not cite a source for a claim, the claim is not hidden, it is marked **\"uncited\"**. Verify uncited claims yourself before relying on the analysis.\n\nIf your account has a Prometheus-compatible telemetry source connected, live metric summaries from the incident window can join the evidence pool as well. Details: [Telemetry Sources](/docs/telemetry-sources).\n\n## Action items (v1)\n\nAction items live as structured fields inside the postmortem document. Each item has:\n\n- A unique ID\n- The text of the action\n- An owner (optional but recommended)\n- A priority (low / medium / high)\n- A status (open / done)\n\nEach item is edited from the Postmortem editor. **A standalone action-item API is not part of v1**, it's planned for v2.\n\n## Stale flag\n\nIf an incident reopens after a postmortem was generated, the postmortem is marked **stale**. The dashboard shows a \"stale, re-generate\" banner; clicking **Generate** refreshes the draft.\n\n## Audit trail\n\nEvery postmortem action is recorded in the audit log: when it was viewed, generated, edited, and published, and by whom. See [Audit Log Retention](/docs/audit-log-retention).\n\n## Blameless approach\n\nWrite the postmortem to fix systems, not to blame people. Replace any \"X should have…\" with \"the system should have prevented X from being able to…\". This isn't soft, it's how you stop the same outage from happening to a different person next quarter.\n\n## Anti-patterns to avoid\n\n- **Writing the postmortem during the incident.** Resolve first, document second.\n- **Naming individuals as the root cause.** A symptom and a cause are different things.\n- **Action items with no owner.** If nobody volunteers, the on-call who closed the incident owns it by default.\n- **Skipping \"what went well.\"** If you only document failures, you erode the practices that already work.\n\n## Related\n\n- [Incident Lifecycle](/docs/incident-lifecycle): the state machine the postmortem hangs off\n- [Maintenance Windows](/docs/maintenance-windows): planned downtime stays out of the postmortem queue\n- [Audit Log Retention](/docs/audit-log-retention): how long postmortems and audit rows live\n- [SLO & Error Budgets](/docs/slo-error-budgets): SLO budget burn ties into the postmortem's impact section","category":"incidents","tags":["incident","postmortem","blameless","retrospective","sla"],"order":30,"parentSlug":"incidents","published":true,"version":1,"metaTitle":"Postmortem Workflow. UptimeWarden Documentation","metaDescription":"How UptimeWarden's v1 postmortem flow works, auto-prefill on resolve, editor refinement, publish, audit trail.","icon":"AlertTriangle","createdAt":"2026-10-12T22:06:41.981Z","updatedAt":"2026-10-12T22:06:41.981Z","publishedAt":"2026-10-12T22:06:41.981Z"},{"publicId":"01KJ7Q9ZSW7T28XBX2QM47QYBW","locale":"en","translationGroup":"health-predictions","slug":"en-health-predictions","title":"AI Insights and Health Predictions","description":"AI-powered health predictions, trend analysis, anomaly detection, and proactive recommendations guide","body":"# AI Insights and Health Predictions\n\nThe AI Insights page analyzes your monitors' health data to predict potential future issues and provides proactive recommendations.\n\n## Accessing AI Insights\n\nClick **AI Insights** from the left menu. This feature is active on paid plans.\n\n## Health Trend Summary\n\nFour summary cards at the top show the overall health distribution of your monitors:\n\n| Card | Color | Description |\n|------|-------|-------------|\n| **Critical** | Red | Monitors in critical condition |\n| **Degrading** | Orange | Monitors with declining performance |\n| **Improving** | Green | Monitors showing improvement |\n| **Stable** | Blue | Monitors running steadily |\n\nClick any card to filter the list by that status.\n\n## Controls and Filters\n\n- **Search**: Search by monitor name\n- **Time range**: 24 Hours, 3 Days, 7 Days, 15 Days\n- **Refresh button**: Re-runs the analysis (4-hour cache limit)\n- **AI Summary button**: Opens the detailed AI summary modal\n- **More Actions menu**: Trend Analysis, Cross-Monitor Pattern Detection, Report Download\n\n## View Modes\n\nThree views are available:\n\n### Grid View\n\nMonitors are displayed in compact card format. Each card shows:\n- Monitor name and trend icon\n- Current uptime percentage (color-coded)\n- Average response time\n- AI summary (for monitors requiring attention)\n- 24-hour and 7-day predicted uptime percentages\n- Confidence level (with progress bar)\n- Anomaly count badge\n- Recommendations (expandable)\n- **\"View Full Analysis\"** button\n\n### List View\n\nMonitors displayed in detailed list format. Same information as Grid in a wider layout.\n\n### Monitor-Focused View\n\nThree time window cards displayed side by side (24 hours, 7 days, 15 days):\n\nEach window shows:\n- Number of days analyzed\n- Total monitored monitors\n- Status badge (Critical / Degrading / Healthy)\n- Average uptime percentage\n- SLA compliance percentage\n- AI-generated window summary\n- **Top issues** list (monitor name, uptime, response time, anomaly count, primary issue, recommended action)\n\n## Proactive AI Recommendations\n\nAt the bottom, recommendations generated from cross-monitor analysis are presented in two categories:\n\n### High Priority Recommendations\n\n- Source monitor name\n- Issue description\n- Confidence percentage badge\n- AI-generated recommendation (highlighted)\n- ROI metrics (if available): ROI percentage, payback period, estimated savings\n- Expected impact value\n- **\"Apply\"** action button\n\n### Optimization Opportunities\n\nLower-priority improvement recommendations listed in similar format.\n\n## AI Summary Modal\n\nOpened by clicking the **AI Summary** button:\n\n- Overall health score and risk level\n- Short summary text\n- Detailed AI report\n- Common patterns and recurrence counts\n- Prioritized recommendations\n- Download options: TXT, JSON, HTML format reports\n\n## Trend Analysis Modal\n\nOpened from the More Actions menu:\n\n- Health trend charts\n- Confidence distribution bar chart\n- Response time trend chart\n- Prediction accuracy comparison (predicted vs actual)\n\n## Cross-Monitor Pattern Detection\n\nDetects common patterns affecting multiple monitors:\n\n- Pattern type and importance\n- Title and description\n- Recommendation and estimated impact\n- Number of affected monitors\n- Confidence score\n\n## Detailed Monitor Analysis\n\nOpened by clicking a monitor's **\"View Full Analysis\"** button:\n\n- Full uptime analysis\n- Outage patterns (recurring, random, scheduled)\n- Anomalies and their severity (response time spikes, SSL expiration, performance drops)\n- Comparison with previous periods\n- SLA compliance metrics\n- Comprehensive AI recommendations\n- Response time threshold violation details\n- Incident history (with duration and severity)\n- Service correlation analysis\n\n## Insufficient Data Warning\n\nA warning is displayed for monitors not monitored for more than 24 hours. These monitors are excluded from analysis scope due to insufficient data.\n\n## Tips\n\n1. **Check regularly**: AI recommendations become more accurate over time\n2. **Change time ranges**: Compare trends across different periods using 7 and 15-day analyses\n3. **Apply high-priority recommendations**: Recommendations with ROI metrics can provide tangible savings\n4. **Download AI summary**: Use reports in TXT or HTML format for team meetings\n5. **Use cross-pattern detection**: Identify common issues affecting multiple monitors\n6. **Try monitor-focused view**: See the most critical issues across different time windows on one screen","category":"ai-prediction","tags":["ai","prediction","health","analytics","insights","proactive"],"order":3,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"AI-powered health predictions, trend analysis, anomaly detection, and proactive recommendations guide","icon":"Brain","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EP7Q8SYYA63XSB3AP3PQ","locale":"en","translationGroup":"health-prediction-overview","slug":"health-prediction-overview","title":"Health Prediction Overview","description":"A next-day (24-hour) and next-week (7-day) uptime forecast and recommendations for every monitor, powered by statistics, anomaly detection, and AI reasoning.","body":"# Health Prediction Overview\n\nSome problems build up slowly. Response time drifts upward for days, the error rate creeps from 0.1% to 0.9%, a certificate gets close to expiry. A human watching the chart would notice, but no one is watching every chart all the time. Health Prediction is the layer that does it for you. Sudden outages, such as a crash or a bad deploy, give no warning and are not predicted.\n\nEvery few hours, UptimeWarden takes a fresh window of each monitor's data, runs statistical and anomaly analysis, asks our AI engine to summarise the findings, and stores a forward-looking forecast you can act on.\n\n## What you see in a prediction\n\nEach prediction surfaces:\n\n| Signal | Meaning |\n|---|---|\n| Current uptime | Uptime measured over the analysis window |\n| Average response time | Mean response time across the window |\n| Response-time variance | How stable response time was |\n| Performance trend | Stable, improving, or degrading |\n| Predicted trend | Stable, improving, degrading, or critical |\n| Next-day uptime | 24-hour forward uptime forecast |\n| Next-week uptime | 7-day forward uptime forecast |\n| Confidence | 0-100, how much signal the model had to work with |\n| Anomalies | Unusual data points with severity and timestamp |\n| Downtime patterns | Recurring patterns by hour or day of week |\n| Recommendations | What to do, with evidence (see linked doc) |\n| Summary | A natural-language description of the situation |\n| Critical issues | Number of critical issues detected |\n| Data points | How many checks were used in the analysis |\n\nPredictions are graded against reality. After the prediction window passes, UptimeWarden compares the forecast to actual measurements (was the trend right, was the uptime estimate close) and tracks accuracy per monitor over rolling 7-, 30-, 90-day, and all-time windows. You can see how well the system has been calling your monitors.\n\nEvery prediction also carries its true generation time (\"updated X ago\"). When you trigger a manual refresh, the recompute is queued in the background; the UI says so explicitly and the new result appears when it is ready, stale data is never presented as \"just computed\".\n\n## Incident risk signal\n\nInstead of mentally inverting an uptime forecast into \"how much risk is that?\", the prediction card can show the risk level the current signals point to, with the reasons behind it. This display is on for every account.\n\nEach prediction also carries:\n\n| Field | Meaning |\n|---|---|\n| Risk level | Low, medium, or high |\n| Reasons | The concrete signals behind the level (for example an uptime shortfall, a degrading trend, the anomaly count) |\n| Validated accuracy | The historically measured forecast accuracy for this monitor, shown only when a real measurement exists |\n\nThe risk level is not a probability and does not say when an outage will happen. It reflects problems that are already building up; a sudden outage gives no warning and cannot be predicted.\n\nAn important honesty rule: all of these values are derived **deterministically** from the stored prediction data. No AI text generation runs on this path and no number can be fabricated; when no historical accuracy measurement exists, the \"validated accuracy\" field is simply not shown.\n\n## How a prediction is built\n\nThere are five stages:\n\n1. **Data collection**, the last several hours of check results are loaded. The window is bounded by your plan's data retention.\n2. **Statistical analysis**, rolling averages, deviation bands, linear trend, change-point detection.\n3. **Anomaly detection**, seasonal decomposition, outlier detection, burst detection. Each anomaly gets a severity.\n4. **AI reasoning**, our AI engine reads the aggregated findings and writes the summary plus recommendations.\n5. **Publish**, the prediction lands on the dashboard, and the UI updates.\n\nThe statistical layer is deterministic. The data sent to the AI engine contains only aggregated numbers (percentile response times, slope, anomaly counts, monitor type, redacted URL), never raw logs, request bodies, or headers.\n\n## Plan availability\n\n| Plan | Health Prediction |\n|---|---|\n| Free | Off |\n| Hobby / Starter | Off (can be enabled on a custom plan) |\n| Professional | On |\n| Enterprise | On |\n\nUpgrades take effect immediately, your existing monitors become eligible on the next prediction cycle.\n\n## When predictions are generated\n\nThere are two triggers:\n\n- **Automatic**: predictions refresh on a multi-hour cadence. Shorter intervals don't help, because most signals need that window of data to move.\n- **Manual**: any user with access to the feature can force a regeneration for a single monitor without waiting for the next cycle.\n\n## Where you find predictions\n\nThe dashboard's **Insights** row lists generated predictions. If your plan doesn't include Health Prediction, you'll see an upgrade prompt instead. The full list and the grouped view live on the **Forecasts** page (formerly AI Insights).\n\nThe list always starts with the most urgent monitor. Ordering uses a multi-stage urgency comparison derived from the same real data: first the incident-risk level and the score behind it (when enabled), then the severity of the predicted trend, the anomaly count, and how far the uptime forecast sits below 99%. When the risk signal is on, the card's leading badge is the risk level and the raw trend becomes a secondary label next to it, so a single card never shows you contradicting signals.\n\nIn the prediction detail you can also mark **known-good baseline periods**: recording a time window where you know the monitor behaved healthily improves threshold accuracy and reduces false alerts.\n\n### The summary on the Forecasts page\n\nThe summary at the top of the Forecasts page comes from the page's own numbers, and it comes in two forms:\n\n- **Rule-based summary** (the default): derived deterministically from the numbers on the page; no model call is made.\n- **Model-written summary**: when you ask for it, the AI engine writes a summary from the counts and rows the page shows. It uses only numbers the page holds, refuses to write a number the page does not show, keeps the monitors it names as evidence, and once the page's numbers move the stored text is no longer shown.\n\nThe model-written summary draws on your account's monthly AI credits (you ask for it) and needs your AI processing consent. Without consent or with the feature off, the page keeps the rule-based summary.\n\n### How AI-written text is labelled\n\nEvery piece of text the product shows as AI output carries one line underneath it: it says a model wrote the text, how many sources it cites, that sensitive values are masked before sending, and how many AI uses this month are on your account; the **How we use AI** link opens the policy. Rule-based text instead says \"Rule-based · no AI used\" and never wears the AI label: text is marked as AI only when a model wrote it.\n\n## Service templates\n\nBuilt-in service templates map common service types (databases, caches, web servers, runtimes, CDNs) to the health signals that actually matter for that kind of service. When the service type is auto-detected from the response, the prediction picks up the right signal set, so a database monitor won't be analysed as if it were a frontend.\n\nTemplates are read-only today; admin overrides are on the roadmap.\n\n## FAQ\n\n**Are predictions deterministic?**\nThe statistical layer is, the anomaly list and risk score will be the same on identical input. The natural-language summary may be phrased slightly differently between runs, but the underlying findings stay anchored to the data.\n\n**I just upgraded my plan. When will I see predictions?**\nOn the next prediction cycle. If you need it immediately, regenerate it manually from the monitor.\n\n**What does the AI see?**\nAggregated numbers, the monitor type, the matched service template, and URL placeholders. Never raw logs, request or response bodies, or headers. See [PII Redaction](/docs/pii-redaction) for the full policy.\n\n**Can the AI be wrong?**\nThe natural-language summary can phrase things more strongly than the data warrants. The UI deliberately shows the evidence chart next to the text, read the summary as a hypothesis and the measurements as the ground truth.\n\n**Is the incident risk signal AI-generated text too?**\nNo. The level, reasons, and accuracy fields are computed deterministically from the stored prediction data; no language model runs on that path. The same input always produces the same result.\n\n## Related topics\n\n- [Evidence-First Recommendations](/docs/evidence-first-recommendations), how each recommendation links back to the data behind it\n- [Monitor Dependencies](/docs/monitor-dependencies): adds dependency context to predictions\n- [Telemetry Sources](/docs/telemetry-sources): live metrics that enrich prediction reasons\n- [PII Redaction](/docs/pii-redaction): what never reaches the AI\n- [Guardrailed Auto-Fix](/docs/guardrailed-auto-fix): rule-based fix plans that wait for your approval","category":"ai-prediction","tags":["health","prediction","ai","anomaly"],"order":10,"parentSlug":"health-predictions","published":true,"version":1,"metaTitle":"Health Prediction Overview. UptimeWarden Documentation","metaDescription":"An introduction to UptimeWarden Health Prediction, statistics, anomaly detection, and AI reasoning combined into a single forward-looking signal.","icon":"Brain","createdAt":"2026-10-12T22:06:41.911Z","updatedAt":"2026-10-12T22:06:41.911Z","publishedAt":"2026-10-12T22:06:41.911Z"},{"publicId":"01M4S2ENXS620W5G49DE8CXX66","locale":"en","translationGroup":"health-predictions","slug":"health-predictions","title":"Health Predictions","description":"Health Predictions in UptimeWarden: multi-horizon forecasting, evidence-backed recommendations, and fix plans that wait for your approval.","body":"# Health Predictions\n\nHealth Predictions is UptimeWarden's early-warning feature. It analyzes each monitor's history for trends and anomalies, lists the problems that are building up gradually (a response time that keeps creeping up, a certificate close to expiry), and pairs each one with a recommendation. Sudden outages give no warning and are not predicted.\n\n:::tip Plan availability\nHealth Predictions is included on **Professional** and **Enterprise** plans. Free, Hobby, and Starter users see a preview, but no predictions are generated for their monitors.\n:::\n\n## What this section covers\n\n- **Health Prediction Overview**: how multi-horizon forecasting works\n- **Evidence-First Recommendations**: every suggestion comes with citations and a confidence score\n- **Guardrailed Auto-Fix**: rule-based fix plans of reversible steps that wait for your approval\n- **Monitor Dependencies**: feed dependency awareness into Cascade Suppression and predictions\n- **Ask Wardy**: query your monitoring data in natural language\n- **Telemetry Sources**: connect your Prometheus-compatible metrics to the AI features\n\n## Multi-horizon forecasting\n\nThe forecast window matches the time range you select on the dashboard, analysis window equals forecast horizon (1:1):\n\n| Selected range | Analysis | Forecast horizon |\n|---|---|---|\n| 7 days | Last 7 days | Next 7 days |\n| 15 days | Last 15 days | Next 15 days |\n| 30 days | Last 30 days | Next 30 days |\n\nEvery prediction also carries a **24-hour immediate horizon** for short-term risk. See [Health Prediction Overview](/docs/health-prediction-overview).\n\n## Primary and fallback models\n\nAnalysis runs on a primary AI model. If the primary is unavailable, a fallback model takes over. The routing mode is set from the admin panel:\n\n- **Auto** (default): try the primary, fall back on failure\n- **Primary only**\n- **Fallback only**\n\nWhichever model runs, personal data is redacted before the prompt is sent. See [PII Redaction](/docs/pii-redaction).\n\n## Evidence-first recommendations\n\nEach recommendation shows the evidence behind it:\n\n```\nRecommendation: \"Increase HTTP timeout from 5s to 10s\"\nEvidence:\n- Over the last 7 days, 12% of requests took between 4s and 5s\n- The pattern correlates with the 14:00-16:00 daily traffic peak\n- One check region reported 320ms average network jitter in the same window\nConfidence: 0.83\n```\n\nEvery recommendation comes with:\n\n- **Citations**: which monitor, which window, which metric\n- A **confidence score** between 0 and 1\n- **Estimated impact and trigger reason**: why the recommendation was generated and the expected gain\n\nSee [Evidence-First Recommendations](/docs/evidence-first-recommendations).\n\n## Guardrailed auto-fix\n\nAuto-fix turns a recommendation into a rule-based plan. The plan is restricted to:\n\n- **Reversible** changes: only three safe actions: threshold tuning, check-interval optimization, and maintenance windows\n- **Bounded blast radius**: for example, a single monitor's threshold\n\nEvery plan waits for an editor's approval. Applying the approved steps is **switched off by default**: while it is off, approving records the decision and you make the change yourself. If it is turned on for your account:\n\n1. Before-and-after snapshots are captured and recorded in the execution history.\n2. The change can be rolled back manually at any time; a rollback is triggered with a stated reason.\n3. A narrow set of plans (low risk, confidence of 0.80 or higher, every step automation-ready) can run without a human approver.\n\nSee [Guardrailed Auto-Fix](/docs/guardrailed-auto-fix).\n\n## Monitor dependencies\n\nPredictions also take the **dependency graph** between monitors into account:\n\n- Manual definition (`db → api → frontend`)\n- Correlation hints from shared hostnames, IP addresses, and timing; these are informational and do not become dependencies on their own\n- Cascade context: when `db` has an open incident, you can see that `api` and `frontend` depend on it\n\nThe same graph drives [Cascade Suppression](/docs/incidents-overview): once dependencies are known, downstream incidents stay quiet automatically. Up to 10 dependency hops are tracked.\n\nSee [Monitor Dependencies](/docs/monitor-dependencies).\n\n## Noisy-monitor detection\n\nUptimeWarden flags monitors that flap without a real underlying problem. The signals are:\n\n- High down/recovery cycle frequency\n- Very short downtime spans (typically network jitter)\n- Failures localized to a single region (one region is fine, another is flaky)\n\nMonitors flagged as \"noisy\" appear on the dashboard with concrete recommendations: raise the check interval from 30s to 60s, switch to 2-of-3 multi-location consensus, or lock the monitor to a single region.\n\n## Outcome learning\n\nAfter each prediction or recommendation, the dashboard's **Outcome Prompt** asks: \"Did the recommendation help?\" Your answer (helpful / partially / not helpful) is saved with the recommendation and counted in the recommendation statistics. It does not retrain the forecasts on its own.\n\n## API access\n\n```bash\ncurl -H \"Authorization: Bearer $UPTIMEWARDEN_TOKEN\" \\\n  \"https://app.uptimewarden.online/api/v1/health/monitors/123/predictions\"\n```\n\nYou'll need the `health:predictions:read` permission. See [API Tokens](/docs/api-tokens).\n\n## Next steps\n\n- [Health Prediction Overview](/docs/health-prediction-overview)\n- [Evidence-First Recommendations](/docs/evidence-first-recommendations)\n- [Guardrailed Auto-Fix](/docs/guardrailed-auto-fix)\n- [Monitor Dependencies](/docs/monitor-dependencies)\n- [Ask Wardy](/docs/ask-wardy)\n- [Telemetry Sources](/docs/telemetry-sources)","category":"ai-prediction","tags":["ai","health-predictions","predictions","recommendations"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Health Predictions. UptimeWarden Docs","metaDescription":"Early warnings for problems that build up slowly, evidence-first recommendations, approval-gated fix plans, and dependency-aware analysis for your monitors.","icon":"Brain","createdAt":"2026-10-12T22:06:41.593Z","updatedAt":"2026-10-12T22:06:41.593Z","publishedAt":"2026-10-12T22:06:41.593Z"},{"publicId":"01M4S2EP7ZBXS2AKV8GPMXYRKJ","locale":"en","translationGroup":"monitor-dependencies","slug":"monitor-dependencies","title":"Monitor Dependencies (Context Engine)","description":"Tell UptimeWarden that one monitor depends on another: API to database, CDN to origin. Dependencies add context to explanations, drive Cascade Suppression, and feed the Service Map.","body":"# Monitor Dependencies (Context Engine)\n\nA 500 on your API is rarely the root cause. The API depends on a database, which depends on a replica, which depends on a network link, which depends on a DNS record. When something turns red, the *root* is usually one or two hops away from the alerting monitor.\n\nUptimeWarden lets you model that topology explicitly. The graph feeds three things:\n\n1. **Explanations**. Health forecasts, recommendations and grouped-alert hints read your dependencies, so a hint can say \"its database dependency is also down\" instead of guessing. It stays a hint to check, not a verdict.\n2. **Cascade Suppression**, while the root is firing, downstream incidents are opened in a suppressed state. They don't trigger notifications or escalations.\n3. **Service Map**, a visual rendering of the graph.\n\n## What you describe per monitor\n\nFor each monitor you can record:\n\n| Field | Values |\n|---|---|\n| Environment | Production, staging, development, or test |\n| Service category | API, database, cache, queue, CDN, or storage |\n| Dependency group | Free-form label, e.g. `payment-stack`, `auth-chain` |\n| Criticality | Critical, high, medium (default), or low |\n| Business tags | Free-form labels (up to 20, each up to 50 characters) |\n| Deployment metadata | Free-form details (provider, region, type, etc.) |\n| Detected stack | Auto-populated from response headers (server, runtime, CDN, etc.) |\n\nCascade Suppression and the explanations use the dependency group as a fast lookup, so consistent labelling pays off.\n\n## What you describe between monitors\n\nA dependency is a directed edge from one monitor to another:\n\n| Field | Values |\n|---|---|\n| Monitor | The dependent monitor (the consumer) |\n| Depends on | The monitor it depends on (the provider) |\n| Dependency type | Runtime (default), data, or network |\n\nA monitor can't depend on itself, and the same dependency can't be added twice. Deeper cycles are detected when the suppression algorithm walks the graph, and suppression is refused if a cycle exists.\n\n## Setting it up\n\n### Per-monitor context\n\nOn a monitor's detail page, open the **Context** tab:\n\n- Pick environment, service category, and criticality.\n- Add a dependency-group label (Cascade Suppression scopes itself to the group inside your account).\n- Add business tags and deployment metadata as needed.\n\nThe detected-stack field is read-only. UptimeWarden populates it when an HTTP monitor probes the endpoint.\n\n### Adding a dependency\n\nA directed dependency edge (\"A depends on B\") is added from the dependent monitor: on Monitor A's page, go to **Context → Dependencies → Add**, pick Monitor B, and save.\n\nThe Service Map also has a **Link Mode** toggle, turn it on, then click two nodes to record a manual *correlation* between them. A correlation is a related-monitors hint, not a directed dependency edge; use the Context tab when you specifically want \"A depends on B.\"\n\n## How dependencies improve explanations\n\nWhen an incident opens or a forecast is generated, the explanation step receives:\n\n- The failing monitor's **direct dependencies** (one hop).\n- For each dependency: current status, latest response time, whether it has an open incident.\n- **Sibling monitors** in the same dependency group (how many of them are also failing).\n\nWith that context, \"API X is failing with 503; its database dependency Y is also down; its cache dependency Z is green\" is a much better starting point than \"API X is failing with 503.\"\n\n## Cascade Suppression\n\nCascade Suppression is shipped and runs in the background. The rules:\n\n- **Global on/off**: your account admin can disable it globally.\n- **Two switches, both off by default**: a global on/off your account admin turns on, plus a per-plan setting enabled in your plan's settings (off by default for all plans at launch).\n- **Search depth**: the algorithm walks the dependency graph up to 10 hops.\n- **Silence window**: a downstream failure that arrives within 60 seconds of an upstream resolving is still treated as part of the cascade.\n- **Cycle refusal**: if the proposed parent depends on the child, the suppression is refused.\n\nSuppressed incidents land with a \"suppressed cascade\" status, with a pointer to the upstream incident, the cascade depth, and the moment of the decision. Notifications, escalations, and status-page publishing are **all skipped** for suppressed incidents.\n\n> **Coming soon:** automatic promotion of a still-down child back to an open incident once its upstream resolves (the promotion sweep) is planned but not yet shipped. For now, review suppressed incidents in the timeline if an upstream recovers while a child stays down.\n\n## Auto-detection (roadmap)\n\nToday, dependencies are user-maintained. Auto-detection from traffic patterns (\"the API consistently fails 30 seconds after the database, infer an edge\") is on the roadmap.\n\nUptimeWarden already records timing-based and URL-based correlations between monitors and surfaces them as informational hints. They aren't yet promoted into automatic dependency edges.\n\n## Similar monitors\n\nDependencies describe what you know about your system. **Similar monitors** shows what the data noticed on its own: monitors whose behaviour moves together, whether or not you have declared a link between them.\n\nYou'll find it inside the prediction detail, open a monitor's card on the **Forecasts** page and look for the **Similar monitors** panel. It is shown for monitors whose predicted trend is not stable, because that is when a shared cause is worth ruling out.\n\nEach entry lists the other monitor, a similarity score, and three bars showing where the resemblance comes from: **response time**, **uptime** pattern, and **incident** timing. The score is a weighted blend, response time and uptime carry the most weight, followed by incident timing, with error-message overlap and time-of-day profile contributing the remainder. Only pairs scoring 0.6 and above are listed, and the panel labels them as moderate (0.6-0.8) or strong (0.8 and above). A strong pair is flagged with a cascade-risk note, which reads as: *these two go down together often enough that they probably share something, a database, a gateway, a network path, worth checking before you treat them as separate problems.*\n\nA worked example: your checkout API and your search API are separate monitors with no declared dependency, yet they score 0.87. Neither is \"causing\" the other; both sit behind the same load balancer. The panel makes that visible without you having modelled it, and the fix is to add the dependency so [Cascade Suppression](#cascade-suppression) can act on it in future.\n\nScores are recalculated after each health-prediction analysis run, not on every page load, so a newly created monitor needs at least one analysis cycle before it appears. Until then the panel honestly reports that no correlations have been found yet rather than showing an empty list as if it meant \"no relationship\". The whole calculation is statistical, no language model is involved.\n\n## Service Map\n\nThe Service Map page renders your dependency graph:\n\n- Nodes are sized by criticality and coloured by current status.\n- Edges are labelled by dependency type.\n- Available on Starter and above.\n\nIf your plan doesn't include the Service Map, you'll see an upgrade prompt instead.\n\n## FAQ\n\n**Q: How many edges should I add?**\nA: Only where there's a *real* dependency, a failure of B usually downs A. One to three outbound edges per service is the practical upper bound; over-modelling turns the graph into noise.\n\n**Q: Are dependencies used even if I don't fill in environment?**\nA: Yes, dependencies on their own add context. But environment and criticality narrow it down. A production-critical database failure is interpreted differently from a staging-low one.\n\n**Q: My service uses a managed database (RDS, Cloud SQL) that I don't actively monitor. Can I still add it as a dependency?**\nA: Create a low-frequency ping or TCP monitor against the endpoint (every 10 minutes is plenty). It becomes the dependency target and shows up on the graph.\n\n**Q: Cascade Suppression silenced the wrong incident, there really was a separate problem.**\nA: The suppressed incident still appears in the timeline, with a timeline entry explaining the suppression (the upstream incident it was attributed to, the cascade depth, and that notifications/escalation were skipped). If the suppression was wrong, the edge between those monitors is wrong; correct it.\n\n## Related topics\n\n- [Health Prediction Overview](/docs/health-prediction-overview): uses the context engine\n- [Evidence-First Recommendations](/docs/evidence-first-recommendations), the dependency chain shows up in the evidence\n- [Multi-Location Consensus](/docs/multi-location-consensus): false-alarm reduction that complements dependencies\n- [Service Map](/docs/service-map): the visual rendering of the graph","category":"ai-prediction","tags":["dependencies","context","correlation","root-cause","cascade-suppression"],"order":20,"parentSlug":"health-predictions","published":true,"version":1,"metaTitle":"Monitor Dependencies. UptimeWarden Documentation","metaDescription":"Model the real topology of your services so explanations get accurate context and downstream alerts are suppressed while the upstream is down.","icon":"Brain","createdAt":"2026-10-12T22:06:41.920Z","updatedAt":"2026-10-12T22:06:41.920Z","publishedAt":"2026-10-12T22:06:41.920Z"},{"publicId":"01M4S2EP87KRSSYYQVGCJSFECJ","locale":"en","translationGroup":"evidence-first-recommendations","slug":"evidence-first-recommendations","title":"Evidence-First Recommendations","description":"Every recommendation ships with structured evidence and outcome tracking, metric, threshold, trend, confidence. We measure which recommendations actually worked.","body":"# Evidence-First Recommendations\n\nA recommendation such as \"upstream database memory pressure\" is only useful if it is true. So each recommendation **shows its evidence**, and UptimeWarden then **measures whether the suggestion actually worked**.\n\nIn UptimeWarden every recommendation ships with structured evidence, and the result of applying it is recorded. You read the numbers, not the prose, before you decide. The apply-rate plus outcome metrics close the quality feedback loop.\n\n## What a recommendation actually contains\n\nEvery recommendation carries:\n\n| Field | Meaning |\n|---|---|\n| Text | The recommendation itself, written in natural language |\n| Category | Performance, reliability, security, cost, configuration, monitoring, or infrastructure |\n| Priority | Critical, high, medium, or low |\n| Confidence | 0-100, based on how much signal the model had |\n| Evidence | The data points that justify the recommendation (see below) |\n| Estimated impact | Plain-language description of the expected effect |\n| Trigger reason | Summary of the condition that produced the recommendation |\n| Action type | Auto, manual, or review-required |\n\nEach piece of evidence carries:\n\n| Field | Meaning |\n|---|---|\n| Metric | Which signal (response time, uptime, error rate, etc.) |\n| Current value | The current reading |\n| Threshold | The threshold that was crossed (when applicable) |\n| Trend | Improving, stable, or degrading |\n| Data points | How many checks were used in the calculation |\n| Time range | The window the evidence covers (e.g. \"last 24 hours\") |\n\nThe evidence is built from pre-computed statistics, not free-form AI output, the recommendation is constructed from the numbers, not the other way around.\n\n## Tracking outcomes\n\nEvery active recommendation carries a feedback record:\n\n- **Rating**: helpful, partially helpful, or not helpful\n- **Note**: optional free text from you\n- **Applied**: you marked \"I applied this\", along with the timestamp\n- **Dismissed**: you dismissed it, with a reason (out of budget, not relevant, already done, too complex, other)\n- **Outcome**: success, partial, failed, not applied, or pending\n- **Outcome note**: optional free text on the outcome\n- **Metrics before / after**: response time, uptime, error rate, and health score around the apply moment\n- **Actual improvement**: the calculated improvement percentage\n\nWhen you mark a recommendation as **applied**, UptimeWarden snapshots the metrics. Over the following window, it re-measures and records the actual delta. You either delivered an improvement or you didn't, and the system remembers.\n\n## Reading evidence critically\n\nThe narrative can over-commit. The evidence can't lie, but it can mislead if you read it carelessly:\n\n- **Does the current value actually cross the threshold?** If it's still below, the recommendation is built on a hypothesis, not a measurement.\n- **Is the trend solid?** \"Degrading\" with 5 data points is weak; with 200 it is strong.\n- **Is confidence low?** Below 50, treat the recommendation as a note to investigate, not advice. The next cycle will gather more data.\n- **Is the category sensible for the monitor type?** A \"security\" recommendation on a database TCP monitor is probably a sign the monitor type was misclassified.\n\n## Where you see them\n\nThe dashboard's **Proactive Insights** card lists recommendations per at-risk monitor, with category, priority, and confidence badges. Drilling into one shows the evidence as coloured bands on the chart.\n\nAction buttons:\n\n- **Helpful / Partially / Not Helpful**: sets your rating.\n- **Apply**: marks it applied and snapshots the current metrics.\n- **Dismiss**: requires a reason from the dropdown.\n- **Record outcome**: after applying, set success / partial / failed and capture the metrics.\n\n## Quality metrics\n\nPer category, the system rolls up:\n\n- Total / applied / successful / helpful counts\n- Success rate among applied recommendations\n- Application rate over total recommendations\n- Helpful-vote percentage\n- Average improvement on successful applications\n\nCategories with low success rates trigger an internal review, and we revise which signals they watch or how the recommendation is worded.\n\n## Limitations\n\n- **A recommendation is a second opinion, not the final word.** Plans wait for approval, and applying approved steps is switched off unless it is turned on for your account; see [Guardrailed Auto-Fix](/docs/guardrailed-auto-fix) for the one narrow exception.\n- **Evidence is point-in-time.** The chart doesn't update live after the prediction is generated. Open the monitor's live view if you need fresh numbers.\n- **Outcome statistics need time to mature.** A new account's first few recommendations have no calibration data; helpful and success rates only become meaningful over months.\n- **The written explanation can still be wrong.** It comes from a language model and is the most fragile part. Always cross-check against runbooks you already trust.\n\n## FAQ\n\n**Q: I see the recommendation text, but no evidence. Why?**\nA: An empty evidence list means the recommendation came directly from the model's summary rather than from the measured metrics. We filter those out of the interface; if you spot one, please flag it via the feedback note.\n\n**Q: A recommendation suggests an action that would cause an outage. What now?**\nA: Dismiss with reason \"not relevant\" or \"other\" plus a free-text note. High dismiss rates per category trigger a product review.\n\n**Q: Can I turn recommendations off for a single monitor?**\nA: Not per-monitor, only at the account-plan level. Admins can disable it on a custom plan.\n\n**Q: Why show low-confidence recommendations at all?**\nA: Low confidence is itself a useful signal, \"investigate, don't fully trust.\" Hiding them costs you information.\n\n## Related topics\n\n- [Health Prediction Overview](/docs/health-prediction-overview): the pipeline that produces the evidence\n- [Monitor Dependencies](/docs/monitor-dependencies): context that enriches the evidence\n- [Guardrailed Auto-Fix](/docs/guardrailed-auto-fix): the next step after accepting\n- [Audit Logging](/docs/audit-logging): record of feedback changes","category":"ai-prediction","tags":["ai","evidence","recommendations","trust","transparency","feedback"],"order":30,"parentSlug":"health-predictions","published":true,"version":1,"metaTitle":"Evidence-First Recommendations. UptimeWarden Documentation","metaDescription":"How recommendations are structured, how feedback flows, and how outcomes are measured for UptimeWarden Health Prediction output.","icon":"Brain","createdAt":"2026-10-12T22:06:41.927Z","updatedAt":"2026-10-12T22:06:41.927Z","publishedAt":"2026-10-12T22:06:41.927Z"},{"publicId":"01M4S2EP8FPVFNA7CX6BKKQWRW","locale":"en","translationGroup":"guardrailed-auto-fix","slug":"guardrailed-auto-fix","title":"Guardrailed Auto-Fix","description":"Approval-gated remediation. The system proposes a plan, a human picks and approves the steps, the executor runs them with before/after snapshots, and you can roll any step back.","body":"# Guardrailed Auto-Fix\n\nFully autonomous remediation is a foot-gun. UptimeWarden Auto-Fix sits between \"the system suggests, a human does\" and \"the system does, a human reviews logs later\", **the system proposes a remediation plan, a human picks and approves steps (with a blast-radius limit), every step runs with a before/after snapshot, and any step can be rolled back to its captured pre-execution state.**\n\n## How a plan is generated\n\nPlans are **rule-based**: steps are selected from predefined safe templates according to the monitor type and the detected problem class. A plan written by a language model is switched off, so every plan you see comes from these rules.\n\n:::note Applying plans is off by default\nApproving a plan records your decision. Applying the approved steps is switched off unless it has been turned on for your account; while it is off, you make the change yourself, and the banner on the **Auto-Fix** page says so.\n:::\n\n## Workflow at a glance\n\nA plan moves through four stages:\n\n1. **Request a plan.** Triggered from an at-risk health prediction or an open incident.\n2. **Review and approve.** Pick the steps you want to run, set the blast radius, leave a review note.\n3. **Execute.** The selected steps run in order, each one snapshotted before and after.\n4. **Verify.** Compare the before/after snapshots and metric deltas in the execution history.\n\n## Approval requests\n\nA pending or approved plan carries:\n\n| Field | Meaning |\n|---|---|\n| Monitor | The monitor the plan targets |\n| Incident | Optional, the open incident that triggered the plan |\n| Requested by | The person who asked for the plan (not the system) |\n| Approved by | The user who approved the plan (may be empty) |\n| Status | Pending, approved, rejected, or expired |\n| Plan | The ordered steps with action, parameters, and expected impact |\n| Selected steps | Which steps the approver actually green-lit |\n| Blast-radius limit | Single monitor (default), dependency group, or all |\n| Risk level | Low (default), medium, or high |\n| Expires at | When the request expires |\n| Review note | Free text from the approver |\n\n## Execution history\n\nEach executed step records:\n\n- The step index and the action that ran\n- Status: pending, running, success, failed, or rolled back\n- Before/after snapshots of monitor state\n- Before/after metrics (response time, uptime, etc.)\n- Duration and error message (if any)\n- Whether a rollback was performed and why\n- Start and completion timestamps\n\n## End user: step by step\n\nYou meet Auto-Fix and remediation in three different places. They all behave differently, don't mix them up.\n\n### Path 1. Auto-Fix Approvals page (actually applies the change)\n\nThis is where you approve and run the safe remediation suggestions the system generated.\n\n1. **Open the page.** In the left nav, go to **Auto-Fix** (`/auto-fix`). If your plan isn't Professional or Enterprise you'll see the \"Auto-Fix requires Professional\" screen; **Upgrade to Professional** to unlock it.\n2. **Read the banner.** The top of the page reminds you that every fix is guardrailed, only low-risk configuration steps auto-apply, riskier steps need your explicit approval. If execution is disabled on the deployment, the banner says so too: approving then only records the decision, and you apply the changes manually.\n3. **Review pending requests.** On the **Pending** tab, each card shows: the target monitor, a status badge, a risk badge (Low / Medium / High), the created time, and \"{N} remediation steps\", with a \"{M} auto-applicable\" badge when relevant. With nothing queued you'll see \"No pending auto-fix requests.\"; a request appears here whenever the system generates a remediation suggestion. You can also ask Wardy \"do I have any pending auto-fix requests?\" to get the list.\n4. **Verify the monitor.** Click the monitor link in the card header to confirm what will be affected.\n5. **Approve or reject.**\n   - **Approve All:** a confirmation dialog opens first; once you confirm, the steps are queued for execution and you'll get an \"Auto-fix approved and queued for execution\" toast.\n   - **Reject:** closes the request; nothing changes.\n6. **Track the outcome.** Switch to the **History** tab; every approved, rejected, executed, and rolled-back request, your paper trail, is listed there.\n\n:::note Which settings change automatically\nThe executor only changes three safe, reversible monitor settings: threshold, check interval, and maintenance window. Restart or scale steps may appear as advice only, the system never runs them automatically.\n:::\n\n### Path 2. Runbook tab on the incident detail (you apply it manually)\n\nThis one is advisory: **nothing executes from this page**.\n\n1. **Open the incident.** Go to an incident's detail and switch to the **Runbook** tab.\n2. **Wait for the plan.** The system generates an incident-specific, rule-based runbook; the header shows the **risk level** and **estimated recovery time**, plus a \"Manual approval required\" badge when relevant. The **confidence percentage** is shown only when it is backed by a real health prediction; without one the field stays empty, no fabricated value is displayed.\n3. **Apply the steps.** Each step carries a **command** and, where needed, a **rollback command**. Copy the command and run it yourself in your own environment.\n4. **Refresh if needed.** If the plan is stale, use **Regenerate** to get an up-to-date suggestion.\n5. **Roll back.** If a step makes things worse, run its **rollback command**.\n\n### Path 3. Auto-Remediation webhook (triggers your own automation)\n\nThis path triggers **your own automation endpoint** (AWS Lambda, a GitHub Action, or your own script) when an incident opens. UptimeWarden still **runs nothing on your infrastructure**, it only sends a signed, advisory-only plan; your endpoint decides what to do.\n\n1. **Create an endpoint.** Go to **Settings → Webhooks** and add a webhook whose type is \"remediation\" (URL, optional custom headers, auth, and a signing secret). This is separate from notification webhooks and is never used as a notification channel.\n2. **Attach it to a monitor.** On the monitor create/edit form (also in monitor settings and the add-monitor wizard), find the **Auto-Remediation** card, it carries an \"Advisory\" badge, and tick the endpoint. If you have none, use **Add remediation endpoint**. The card is available on every plan. Remediation endpoints are webhook configs, so each one counts toward your plan's webhook config limit. Remediation deliveries do not use the monthly webhook quota and still go out when that quota is used up.\n3. **What happens when an incident opens.** When an incident opens on the attached monitor, the system sends your endpoint a signed (HMAC) JSON marked `advisoryOnly: true`. It contains a `remediation.suggested` event, the monitor and incident details, an `errorSignature` for routing/dedupe, and a **plan** selected by monitor type. The same signed body goes to every attached endpoint independently; a slow or failing endpoint never blocks the others.\n4. **Verify the signature.** Validate the HMAC signature on your endpoint before acting, so you know the body genuinely came from UptimeWarden.\n5. **Run your automation.** Apply the plan with your own script (for example, restart or scale); you stay fully in control.\n\n:::note When delivery is skipped\nIf an endpoint is inactive, inside quiet hours, or its circuit breaker has opened after repeated failures, that delivery is skipped. Repeated failures are recorded in your webhook stats.\n:::\n\n### Verifying the result\n\nFor executed steps (Path 1), the before/after snapshot diff and metric delta are listed in the monitor's **execution history** view, the full timeline of what changed, when, and how.\n\n## Blast radius\n\nThe blast-radius limit caps what a plan can touch:\n\n- **Single monitor** (default): only the targeted monitor.\n- **Dependency group**: monitors sharing the same dependency group (for example, a payment-stack group).\n- **All**: unrestricted. Only Enterprise admins should choose this.\n\nThe blast-radius limit is recorded with the approval. In practice each step executes against the targeted monitor only.\n\n## Plan availability\n\nAuto-Fix is available on Professional and Enterprise plans. Health Prediction must also be on, since its recommendations are the input. Free, Hobby, and Starter users see evidence-first recommendations but can't generate a plan.\n\n## Not supported today\n\n- **Runbook-driven agents.** No agent reads your markdown or PDF runbook step by step. Plans are generated from evidence and the matched service template; your internal docs aren't ingested.\n- **Cross-cloud actions.** The executor only changes monitor settings: it runs exactly three action types: threshold tuning, check-interval optimization, and maintenance-window scheduling. Restart and scale steps may appear as advisory recommendations in a plan, but they are never automation-ready and the system never executes them. Reaching into your AWS, Azure, or GCP console requires a custom integration.\n- **Fully unattended execution.** Most plans start as pending and wait for a human approver. There is one narrow auto-approve path, and it only runs where applying plans is turned on: a plan that is low-risk, has confidence of at least 0.8, requires no manual approval, and whose every step is automation-ready is approved and run by the system without a human. All other plans require human approval.\n- **Auto-fix-specific audit log entries.** Plan, approval, and execution writes show up in the audit log as generic create/update entries rather than dedicated action types. For a full timeline, the execution-history view is the source of truth.\n\n## FAQ\n\n**Q: Can I undo a fix after the fact?**\nA: Yes, if the step captured a before-snapshot. The execution-history row exposes a rollback button.\n\n**Q: What if the fix triggers a cascading failure?**\nA: You roll the affected step back yourself from the execution-history row, which restores the monitor to its captured pre-execution state. Cascades that emerge seconds later are caught by your normal monitors and alerts; you'd manually roll back the remaining steps too.\n\n**Q: Does the plan generator know my infrastructure?**\nA: Only as far as your monitor configuration, declared dependencies, and the matched service template. It has no access to your cloud console, your code, or your runbooks.\n\n**Q: Can I route approval to someone else?**\nA: Not directly today, the request appears in the queue for the monitor's owners and admins. A two-person rule (for example, requiring a second approver on high-risk plans) is on the roadmap.\n\n## Related topics\n\n- [Evidence-First Recommendations](/docs/evidence-first-recommendations), input to plan generation\n- [Health Prediction Overview](/docs/health-prediction-overview): the signals that trigger a plan\n- [Monitor Dependencies](/docs/monitor-dependencies): the foundation for blast-radius scoping","category":"ai-prediction","tags":["auto-fix","remediation","ai","approval","rollback"],"order":40,"parentSlug":"health-predictions","published":true,"version":1,"metaTitle":"Guardrailed Auto-Fix. UptimeWarden Documentation","metaDescription":"The system proposes a remediation plan, humans approve it, the executor runs it with snapshots and manual rollback, the UptimeWarden Auto-Fix flow.","icon":"Brain","createdAt":"2026-10-12T22:06:41.935Z","updatedAt":"2026-10-12T22:06:41.935Z","publishedAt":"2026-10-12T22:06:41.935Z"},{"publicId":"01KJ7Q9ZSY8GA5A5XHG05X3RXN","locale":"en","translationGroup":"security-headers","slug":"en-security-headers","title":"Security Header Analysis","description":"Guide to analyzing your website's security headers, scoring, recommendations, and configuration","body":"# Security Header Analysis\n\nSecurity Header Analysis evaluates your web application's security posture by analyzing HTTP response headers and provides improvement recommendations.\n\n## Access\n\nClick **Security Headers** from the left menu.\n\n> This feature is active on **Starter** plans and above. On the Free plan, an upgrade message is displayed.\n\n## Summary Cards\n\nFour summary cards are displayed at the top:\n\n| Card | Description |\n|------|-------------|\n| **Overall Score** | Average security score of all monitors (0-100) |\n| **Critical Issues** | Number of findings with critical severity |\n| **High Risk Issues** | Number of findings with high severity |\n| **Grade A+/A** | Number of monitors with excellent security grade |\n\n## Scoring System\n\n### Letter Grades\n\nA letter grade is assigned to each monitor:\n\n| Grade | Color | Meaning |\n|-------|-------|---------|\n| **A+ / A** | Green | Excellent security |\n| **B** | Yellow | Good security |\n| **C** | Orange | Medium-level security |\n| **D / F** | Red | Weak security |\n\n### Numeric Score\n\nA numeric score from 0-100 is also shown on each monitor card.\n\n## Analysis Modes\n\nYou can switch between two analysis modes in the top-right corner:\n\n| Mode | Description |\n|------|-------------|\n| **Basic** | Relaxed scoring for blogs, portfolios, personal sites (default) |\n| **Modern** | Strict scoring for banking, finance, and enterprise applications |\n\nBoth modes check the same headers but apply different weights and severity levels.\n\n## Monitor Cards\n\nA card is displayed for each monitor in the main view:\n\n- Letter grade and numeric score\n- Monitor name and URL\n- Critical and high severity finding counts\n- Last check time\n- History button (trend tracking)\n\n## Checked Headers\n\n### Transport Security\n\n| Header | Description |\n|--------|-------------|\n| **Strict-Transport-Security (HSTS)** | Header enforcing HTTPS usage |\n| **Expect-CT** | Certificate Transparency check |\n\n### Content Security\n\n| Header | Description |\n|--------|-------------|\n| **Content-Security-Policy (CSP)** | XSS and code injection protection |\n| **Content-Security-Policy-Report-Only** | CSP report mode |\n| **X-Content-Type-Options** | MIME type sniffing protection |\n| **X-XSS-Protection** | Browser XSS filter |\n\n### Framing Protection\n\n| Header | Description |\n|--------|-------------|\n| **X-Frame-Options** | Clickjacking protection |\n\n### Referrer Policy\n\n| Header | Description |\n|--------|-------------|\n| **Referrer-Policy** | Referrer information sharing control |\n\n### Feature Policy\n\n| Header | Description |\n|--------|-------------|\n| **Permissions-Policy** | Browser API access control |\n\n### Cross-Origin Headers\n\n| Header | Description |\n|--------|-------------|\n| **Cross-Origin-Embedder-Policy (COEP)** | Resource loading policy |\n| **Cross-Origin-Opener-Policy (COOP)** | Window isolation |\n| **Cross-Origin-Resource-Policy (CORP)** | Resource sharing policy |\n\n### Reporting\n\n| Header | Description |\n|--------|-------------|\n| **NEL** | Network Error Logging |\n| **Report-To** | Security reporting endpoint |\n\n## Header Details and Recommendations\n\nClick a monitor card to open the detail modal. For each header:\n\n- **Status**: Present (green) or missing (red)\n- **Description**: What the header does\n- **Current value** (if present)\n- **Severity level** (color-coded)\n\nClick a header to see recommendation details:\n\n- Issue title and description\n- Security impact\n- Current value vs recommended value comparison\n- Server configuration examples (tabbed):\n  - **Nginx**\n  - **Apache**\n  - **Cloudflare**\n  - **HTML Meta**\n- One-click configuration copy\n\n## AI Security Analysis\n\nClick the **\"AI Insights\"** button for AI-powered security assessment:\n\n- Overall security evaluation\n- List of critical security vulnerabilities\n- Numbered security recommendations\n- Common issues across monitors with severity levels\n\n## Filtering and Search\n\n| Filter | Options |\n|--------|---------|\n| **Search** | By monitor name or URL |\n| **Severity** | Critical, High, Medium, Low |\n| **Category** | Transport, Content, Framing, Referrer, Feature |\n\n## History and Trends\n\nTrack the security score trend over time with each monitor's history button.\n\n## Tips\n\n1. **Use Modern mode**: Prefer strict scoring mode for enterprise or financial applications\n2. **Fix critical findings first**: Start with red-colored findings\n3. **Start with CSP**: Content-Security-Policy is the most effective security header\n4. **Use Report-Only mode**: Test with `Content-Security-Policy-Report-Only` before enforcing CSP\n5. **Copy configuration examples**: Use the server configuration examples directly from the detail modal\n6. **Track trends**: Verify your security score is improving with the history button\n7. **Leverage AI analysis**: Use AI Insights to detect cross-monitor security issues","category":"security","tags":["security","headers","analysis","recommendations","web-security","https"],"order":4,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Guide to analyzing your website's security headers, scoring, recommendations, and configuration","icon":"Shield","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EPBDE152VF4E6VBK62XG","locale":"en","translationGroup":"audit-logging","slug":"audit-logging","title":"Audit Logging","description":"Every security-sensitive action is recorded, who did what, when, from where, and what changed. Retention scales with your plan, and high-impact events are kept indefinitely.","body":"# Audit Logging\n\nThe audit log answers who changed what, and when. You need that for compliance reviews and for working out what happened after something breaks. UptimeWarden writes an audit entry for every security-sensitive action: sign-ins, monitor and resource changes, team updates, API token management, settings toggles, and more.\n\n## What's recorded\n\nEach audit entry captures:\n\n| Field | Description |\n|---|---|\n| Action | A short label describing the event (for example, \"monitor created\" or \"password changed\"). |\n| Resource | The kind of object the action touched (monitors, users, webhooks, and so on). |\n| Record | The specific item that was affected, identified by its public ID in the dashboard. |\n| Actor | The user who performed the action. Each user only ever sees their own entries. |\n| Before / After | A side-by-side view of what changed, when applicable. |\n| Severity | One of low, medium, high, or critical. |\n| Request context | IP address, browser/user agent, and session identifier. |\n| Description | A human-readable summary of the event. |\n| Timestamp | The exact moment the event was recorded. |\n\n## Events we log\n\nUptimeWarden records security-sensitive events across these categories:\n\n- **Sign-in activity**: successful sign-ins, failed attempts, blocked sign-ins, account lockouts, denied access, password resets, and password changes.\n- **Resource changes**: creating, updating, and deleting items, including bulk operations.\n- **Permissions and teams**: granting and revoking permissions, role changes, and team join/leave/invite events.\n- **Subscriptions**: when a subscription is created, updated, or cancelled.\n- **API tokens**: token creation, revocation, and regeneration.\n- **Webhooks**: creating, updating, deleting, or testing a webhook endpoint.\n- **Monitor lifecycle**: when a monitor is created, updated, deleted, paused, or resumed.\n- **Settings**: notification settings, security settings, system configuration, and feature toggles.\n- **Data operations**: exports, imports, and deletions.\n- **Security violations**: anything that triggers a security policy.\n\n> Sign-ins via Google or GitHub are recorded as a sign-in event with the sign-in method noted in the entry's metadata. Account-deletion and consent events are tracked in operational logs today; surfacing them as audit entries is on the roadmap.\n\n## Who sees what\n\nToday, **every user sees only their own audit entries**. There is no admin override that exposes another user's activity. Cross-account visibility (an admin viewing the entire workspace, or a team admin viewing their team) is on the roadmap; the current behaviour is intentionally conservative.\n\n## Retention by plan\n\nAudit-log access is a **Professional and Enterprise** feature, the Free, Hobby, and Starter plans don't include the audit log. For the plans that have it, how long entries are kept depends on your plan:\n\n| Plan | Retention |\n|---|---|\n| Professional | 90 days |\n| Enterprise | 365 days |\n\n**High-impact events are kept indefinitely**, regardless of plan. That covers actions like deletions, permission revocations, failed sign-ins, API token revocations, and security or system configuration changes, anything classified as high or critical severity stays on the record so you can always reconstruct what happened.\n\n## Viewing the log\n\nOpen **Settings → Audit log** to:\n\n- Filter by action, severity, or date range.\n- Search descriptions in free text.\n- Page through results (50 per page by default, up to 100).\n- Switch between a flat list and a view grouped by action type.\n- **Jump from a log entry to the entity**: the entry's `Record` field is a clickable link when the affected entity is a monitor or an incident, opening its detail page directly. Other tables and legacy (numeric) record ids stay as plain text.\n\n## Programmatic access\n\n```http\nGET /api/audit-logs?startDate=2026-04-01&endDate=2026-04-30&limit=100&page=1\nAuthorization: Bearer uptw_...\n```\n\nThe response is paginated: `{ logs: [...], pagination: { page, limit, total, totalPages, hasNext, hasPrev } }`. Supported query parameters are `page`, `limit` (1-100), `action`, `tableName` (the resource/table to filter by), `severity`, `startDate` and `endDate` (ISO 8601), and `search`. The default page size is **50**, the maximum is **100**.\n\nA companion endpoint, `GET /api/audit-logs/types`, returns the distinct action types currently present for your account.\n\n## What we don't log\n\n- **Read operations**: viewing a page doesn't write an audit entry (it would create too much noise).\n- **Plaintext passwords**: passwords are never stored in plaintext, and the audit log records only that a password change happened, never the value.\n- **Notification content**: message bodies live in your notification history, not in the audit log. The audit log records *whether* an alert was sent, not its text.\n- **Sensitive field values**: when a sensitive field changes (for example, a password hash), we record that the change happened without storing the value.\n\n## Tamper resistance\n\nEntries are append-only, neither the dashboard nor the API allows deletion or editing. Combined with indefinite retention for high-severity events, deliberate removal of high-value records is detectable.\n\nEnterprise customers who require write-once, read-many (WORM) storage can request streaming of the audit log to an append-only external bucket (S3 Object Lock, Azure Blob Immutable).\n\n## Required by\n\n- **KVKK** (Türkiye): data-processing activity records.\n- **GDPR** (EU): processing register, Art. 30.\n- **SOC 2**: CC 6.2, audit of logical access.\n- **PCI DSS** (payments): the payment audit trail is a separate, stricter log stream.\n\n## FAQ\n\n**Q: I created a monitor last month and I don't see it in the log.**\nA: On the Professional plan, retention is 90 days. Upgrading to Enterprise extends retention going forward, it doesn't recover entries that have already aged out.\n\n**Q: Can I forward the audit log to Splunk or Datadog?**\nA: Yes, poll `GET /api/audit-logs` on a schedule and ingest the JSON. Streaming webhooks are on the roadmap.\n\n**Q: Can I see another user's log?**\nA: No, every user sees only their own entries today. There is no admin override.\n\n## Related topics\n\n- [API Tokens](/docs/api-tokens): token creation and revocation events\n- [Subscription Plans](/docs/subscription-plans): retention by plan\n- [GDPR Data Export & Account Deletion](/docs/gdpr-export-delete): deletion flow","category":"security","tags":["audit","logging","compliance","security","admin"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Audit Logging. UptimeWarden Documentation","metaDescription":"Filterable, paginated history of sign-in events, configuration changes, settings toggles, and security actions.","icon":"Shield","createdAt":"2026-10-12T22:06:42.029Z","updatedAt":"2026-10-12T22:06:42.029Z","publishedAt":"2026-10-12T22:06:42.029Z"},{"publicId":"01M4S2ENY0RF0641RWDMVHSYAH","locale":"en","translationGroup":"security-headers","slug":"security-headers","title":"Security Headers","description":"Analysis of nine HTTP security headers for your monitors. HSTS, CSP, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and the cross-origin headers, with a 0-100 score and an A+ to F grade.","body":"# Security Headers\n\nUptimeWarden HTTP and HTTPS monitors don't only check status codes, they also analyse the **security headers** in the response. A misconfigured header (a missing HSTS, for example) can go unnoticed for days; security header analysis closes that gap.\n\n## The first answer: \"Is my site unsafe?\"\n\nThe page answers that question first. The first line says your sites work and how many of them are missing the key browser protections; when all are set, it says every site has them. The line below says plainly what that means: nothing is broken; these are extra protections that reduce the risk of attacks such as clickjacking. Three protections are the key ones: HTTPS only (Strict-Transport-Security), script restrictions (Content-Security-Policy) and framing protection (X-Frame-Options).\n\nGrades and the header-by-header detail come after that answer: sites missing a key protection are listed first, worst grade first, then all sites with their grades (\"All sites, worst first\"), and the collapsed header reference sits at the bottom. If nothing has been scanned yet, the first line reads \"No sites scanned yet\" and tells you to add an HTTPS monitor; your site is then scanned daily.\n\n## The nine headers we analyse\n\nUptimeWarden scores nine headers.\n\n### The classic five\n\n**Strict-Transport-Security (HSTS)**. Tells browsers \"only call this domain over HTTPS.\" We evaluate `max-age` (one year or longer is recommended), `includeSubDomains`, and `preload`.\n\n**Content-Security-Policy (CSP)**. The strongest defence against XSS. We check that the header is present, flag `unsafe-inline` and `unsafe-eval`, and recognise the report-only variant.\n\n**X-Frame-Options**. Clickjacking protection. We validate `DENY` and `SAMEORIGIN`.\n\n**X-Content-Type-Options**, `nosniff` is required; it blocks MIME-sniffing attacks.\n\n**Referrer-Policy**. Limits referrer information sent to third-party sites (`no-referrer`, `same-origin`, `strict-origin`, `strict-origin-when-cross-origin`, and so on).\n\n### The modern four\n\n**Permissions-Policy**. Restricts browser API access (camera, microphone, geolocation, and so on).\n\n**Cross-Origin-Embedder-Policy (COEP)**. Blocks cross-origin resources from being embedded without opt-in.\n\n**Cross-Origin-Opener-Policy (COOP)**. Blocks cross-origin `window.opener` leaks.\n\n**Cross-Origin-Resource-Policy (CORP)**. Resource isolation against Spectre-class cross-origin reads.\n\n## Standard vs Strict modes\n\nThe same set of headers is scored at two strictness levels; you pick one of the two profiles in the dashboard:\n\n| Mode | Target audience | Penalty for missing the modern four |\n|---|---|---|\n| **Standard** | Blogs, portfolios, personal sites | None (missing = 0 points) |\n| **Strict** | Banking, finance, enterprise apps | Between -6 and -12 points each |\n\nYou can also run a side-by-side dual-mode comparison to see how the same site scores in each mode.\n\n## Score and grade\n\nEach analysis produces a **0-100 numeric score** and a letter grade:\n\n| Score | Grade |\n|---|---|\n| 90 or above | A+ |\n| 80-89 | A |\n| 65-79 | B |\n| 45-64 | C |\n| 25-44 | D |\n| Below 25 | F |\n\nIf HTTPS is not enforced, the score starts with a -20 penalty (HSTS is meaningless over HTTP anyway). Each header then applies a mode-specific delta.\n\n## Scan progress and filters\n\nThe progress of a scan started with \"Scan now\" is honest: the page cannot see which step an agent is on, so it never shows a made-up percentage. It says \"Starting security scans…\", then \"Running security scans…\", then \"Waiting for agents to report results…\"; when results arrive it ends with \"Scan complete.\", and when it stops waiting with \"Stopped waiting for results.\". The progress bar does not pretend either; it only shows that a scan is running.\n\nFilters always leave a way out. If the search, monitor or grade filter leaves no site, the empty state offers \"Show all sites\"; if nothing has been scanned yet, it offers \"Scan now\". A \"Show all sites\" button also appears below the header whenever a filter is active.\n\n## \"Write the config for your server\"\n\nWhenever a site is missing a header, its \"View fixes\" panel includes \"Write the config for your server\"; when nothing is missing, the section does not appear. Pick your server — nginx, Apache, Caddy, Express, Next.js, IIS or Cloudflare — and copy the rule-based configuration, built from the scan in your browser. It uses the recommended value for each missing header.\n\nWith AI on, \"Write config with AI\" tailors the same configuration to your site: the model takes your site's address, the headers it already sends (which the configuration must not touch) and HTTPS enforcement into account, and says in one sentence what to check before deploying. The answer is checked against the scan: it must set every missing header and no other security header. An answer that does not match is not used, and the rule-based configuration stays.\n\n- AI writes only when you ask; it draws on your account's monthly AI credits and needs your AI processing consent. Asking again for the same site, server and scan is served from cache and costs nothing extra.\n- If the feature is off, consent is missing or the monthly credits are used up, the rule-based configuration stays as it is.\n- The AI-written configuration carries the same one-line note as every other AI-written text in the product: it says the text was written by AI, that sensitive values are masked before sending, and how much AI you have used this month ([PII Redaction](/docs/pii-redaction)).\n\n> **Note**: UptimeWarden never changes your server for you; it writes the configuration for you to apply.\n\n## Plan tier\n\nSecurity header analysis is available on every plan, including Free. See [Subscription Plans](/docs/subscription-plans).\n\n## API access\n\n```bash\ncurl -H \"Authorization: Bearer $UPTIMEWARDEN_TOKEN\" \\\n  \"https://app.uptimewarden.online/api/v1/security/monitors/{id}/analysis\"\n```\n\nRequires the `security:analysis:read` (or `security:analysis:monitor`) scope. The response is wrapped as `{ success: true, data: { ... } }`, where `data` contains `monitorId`, `monitorName`, `url`, `overallGrade`, `score`, `headers: [...]`, `lastChecked`, `httpsEnforced`, and `recommendations: [...]`. Each missing header includes example NGINX, Apache, Cloudflare, and `<meta>` configurations.\n\n## Compliance use cases\n\n- **PCI DSS 4.0**: continuous validation of required HTTP headers.\n- **OWASP ASVS L2/L3**: security header requirements.\n- **SOC 2**: production configuration controls.\n- **KVKK / GDPR**: mandatory HTTPS and HSTS on endpoints handling personal data.\n\n## Next steps\n\n- [Audit Logging](/docs/audit-logging)\n- [Webhook Security](/docs/webhook-security)\n- [SSO & OAuth](/docs/sso-oauth)","category":"security","tags":["security","headers","hsts","csp","x-frame-options","http"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Security Headers. UptimeWarden Docs","metaDescription":"Analyse the security response headers on your HTTP monitors with a 0-100 score, an A+ to F grade, the Standard and Strict modes, and per-header guidance.","icon":"Shield","createdAt":"2026-10-12T22:06:41.601Z","updatedAt":"2026-10-12T22:06:41.601Z","publishedAt":"2026-10-12T22:06:41.601Z"},{"publicId":"01M4S2EPBVB36QJAYARQ661568","locale":"en","translationGroup":"sso-oauth","slug":"sso-oauth","title":"SSO with Google & GitHub","description":"Sign in to UptimeWarden with Google or GitHub. The auto-link flow is hardened against email-takeover attacks.","body":"# SSO with Google & GitHub\n\nUptimeWarden supports single sign-on through Google and GitHub. New users can create accounts without setting a password; existing email-and-password users can link a sign-in identity for faster logins.\n\n## Which providers\n\n| Provider | Sign up | Sign in | Link to existing |\n|---|---|---|---|\n| **Google** | Yes | Yes | Yes (conditional, see below) |\n| **GitHub** | Yes | Yes | Yes (conditional, see below) |\n\nMicrosoft, Okta, and generic SAML / OIDC are not available today. Enterprise customers who need federation can contact support for a scoped integration.\n\n## New-user signup via SSO\n\n1. On the sign-in page, click **Sign in with Google** (or **GitHub**).\n2. You're redirected to the provider's consent screen.\n3. Approve the requested scopes:\n   - **Google**, `profile`, `email`.\n   - **GitHub**, `user:email` (works with private emails, only the verified primary email is accepted).\n4. You're returned to UptimeWarden and a new account is provisioned:\n   - Email: the provider's verified email, lower-cased. If the provider doesn't assert that the email is verified, we treat it as unverified.\n   - Name: the provider's display name.\n   - We set a randomly-generated placeholder password that you cannot use to sign in. Until you set a real password through the **Forgot password** flow, SSO is your only sign-in path.\n5. You land on the onboarding wizard to pick a plan and create your first monitor.\n\n## Auto-linking to existing accounts\n\nUptimeWarden does not blindly link a Google or GitHub identity to an existing email-and-password account, this is a deliberate defence against email-takeover attacks.\n\nWhen the email returned by the provider already matches an existing UptimeWarden account, auto-link only goes through if **one** of these conditions holds:\n\n1. The provider's user ID is already recorded on that account (the same SSO user is simply signing in again), **or**\n2. **Both** the provider asserts that the email is verified **and** your existing UptimeWarden account also has a verified email.\n\nIf neither condition holds, the SSO sign-in is refused. To link the provider, first sign in with your password and make sure your UptimeWarden email is verified, then sign in again with the same provider button. This blocks an attacker who controls an unverified address at the provider from taking over your UptimeWarden account with a single SSO click.\n\n## Linking a provider to an existing account\n\nThere is no separate \"link\" button in settings. Linking happens through the normal sign-in buttons: when you click **Sign in with Google** (or **GitHub**) and the provider's email matches an existing UptimeWarden account, the identity is attached to that account automatically, but only when the auto-link rules above are satisfied (the provider asserts a verified email **and** your UptimeWarden email is already verified). If your email isn't verified yet on UptimeWarden, verify it first, then sign in with the provider again.\n\n## What UptimeWarden stores\n\nFor each linked identity:\n\n- The provider's stable user ID (Google ID or GitHub ID).\n- The email at the time of linking.\n- A refresh token, used only to re-issue access tokens. Tokens are encrypted at rest with industry-standard encryption.\n\nYour avatar URL is captured from the provider when you first link it (or when your account is first created via SSO) and stored on your profile. It isn't re-fetched on every subsequent sign-in.\n\n## Security notes\n\n- **HTTPS only**: production SSO callbacks must be HTTPS.\n- **State token**: every SSO flow carries a one-time state value that's verified on return; mismatched state is rejected.\n- **Session handling**: SSO sign-ins use the same session and token policies as password sign-ins, including rate limiting and account-lockout policies.\n- **Revocation**: revoking UptimeWarden's access on the provider side (for example, in your Google account settings) invalidates the refresh token, and the next sign-in goes through a fresh consent flow.\n- **Placeholder password**: new SSO users get a randomly-generated placeholder password that cannot be guessed. The local-password sign-in surface is effectively unreachable until you set a real password.\n\n## Audit events\n\nThe SSO sign-in flow produces:\n\n- A sign-in entry in the audit log, with the sign-in method (Google or GitHub) recorded in the entry's metadata.\n- Failed callbacks redirect to the failure page; auto-link refusals and unverified-email rejections are recorded.\n\n> There isn't a separate audit action for SSO link or unlink. SSO events are recorded under the standard sign-in action with the sign-in method noted in metadata. See [Audit Logging](/docs/audit-logging).\n\n## Callback URLs\n\nThe SSO callback URL depends on your environment and uses the **`/api/auth/<provider>/callback`** path:\n\n| Environment | Callback |\n|---|---|\n| Production | `https://app.uptimewarden.online/api/auth/google/callback` and `.../api/auth/github/callback` |\n| Local development | `http://localhost:5000/api/auth/google/callback` |\n| Custom domain | `https://<yourdomain>/api/auth/google/callback` |\n\nFor a self-hosted deployment (Enterprise), configure your OAuth apps at both [Google Cloud Console](https://console.cloud.google.com/apis/credentials) and [GitHub Developer Settings](https://github.com/settings/developers) with these callback URLs.\n\n## FAQ\n\n**Q: My GitHub email is private, does SSO still work?**\nA: Yes, we request `user:email`, which returns your verified primary email. If the provider doesn't assert that the email is verified, we treat it as unverified and the auto-link rules above apply.\n\n**Q: What if my two providers have different primary emails?**\nA: Accounts are stored per-email. If your Google primary email and GitHub primary email differ, UptimeWarden treats them as two accounts. To attach both providers to one account, set both providers' primary email to the same verified address before signing in with the second one (see \"Linking a provider to an existing account\" above).\n\n**Q: Do SSO users count against team-size limits?**\nA: Yes. SSO only changes how you sign in, not your subscription model.\n\n## Related topics\n\n- [Audit Logging](/docs/audit-logging): sign-in events and sign-in method metadata\n- [Subscription Plans](/docs/subscription-plans): user and team limits\n- [API Tokens](/docs/api-tokens): programmatic auth for scripts","category":"security","tags":["sso","oauth","google","github","auth","login"],"order":20,"parentSlug":null,"published":true,"version":1,"metaTitle":"SSO with Google & GitHub. UptimeWarden Documentation","metaDescription":"Single sign-on through Google and GitHub, hardened auto-link rules and encrypted refresh tokens.","icon":"Shield","createdAt":"2026-10-12T22:06:42.044Z","updatedAt":"2026-10-12T22:06:42.044Z","publishedAt":"2026-10-12T22:06:42.044Z"},{"publicId":"01M4S2EPBM7F9WVBTQV4F8D1VH","locale":"en","translationGroup":"pii-redaction","slug":"pii-redaction","title":"PII Redaction for AI Prompts","description":"Eighteen pattern classes scrubbed from every AI prompt, private keys, database connection strings, tokens, cloud secrets, emails, and more, restored only in the response.","body":"# PII Redaction for AI Prompts\n\nWhen your monitor fails and UptimeWarden's AI asks \"why?\", the prompt needs *enough* context to produce a useful answer. But that context is often full of data you don't want leaving your security perimeter: connection strings with passwords in them, bearer tokens in error headers, private IPs of internal services, customer emails embedded in log lines.\n\nUptimeWarden runs every AI prompt through a pattern-based redactor first. Sensitive values are replaced with stable placeholders (`[EMAIL_1]`, `[DB_URI_1]`, `[PRIVATE_KEY_3]`), the redacted prompt is sent to the AI engine, and the placeholders in the response are restored locally, the AI engine never sees the raw values.\n\n## Applies to every AI surface\n\nAny time content is sent to our AI engine, we redact personal information first. That means Health Prediction, Postmortem, Ask Wardy, and Auto-Fix all share the same redactor, there is no opt-out toggle.\n\n## What gets redacted\n\n**Eighteen pattern classes**, applied in a deliberate order (high-confidence specifics first, generic catch-alls last):\n\n### High-confidence specific matches (run first)\n\n| Type | Placeholder | What it catches |\n|---|---|---|\n| Private keys | `[PRIVATE_KEY_n]` | PEM-encoded RSA, EC, and OpenSSH private keys (up to 5,000 characters in length). |\n| Database connection strings | `[DB_URI_n]` | `postgres://`, `mysql://`, `mongodb://`, `redis://`, `amqp://` URIs with embedded credentials. |\n| JSON Web Tokens | `[JWT_n]` | Three-segment tokens beginning with `eyJ`. |\n| AWS access keys | `[AWS_KEY_n]` | `AKIA*` and `ASIA*` (permanent and session keys). |\n| AWS secret keys | `[AWS_SECRET_n]` | Detected by surrounding context (for example, `aws_secret_access_key=...`). |\n| Payment-provider API keys | `[PAYMENT_SECRET_n]` | `sk_live_`, `sk_test_`, `rk_live_`, `rk_test_`. |\n| Slack tokens | `[SLACK_TOKEN_n]` | `xoxb-`, `xoxp-`, `xoxa-`, `xoxr-`, `xoxs-`. |\n| GitHub personal access tokens | `[GITHUB_TOKEN_n]` | `ghp_`, `gho_`, `ghu_`, `ghs_`, `ghr_`. |\n\n### Generic identifiers\n\n| Type | Placeholder | What it catches |\n|---|---|---|\n| URLs | `[URL_n]` | `http://` and `https://` URLs (up to 2,048 characters). |\n| Email addresses | `[EMAIL_n]` | `local@domain.tld` patterns. |\n| IPv4 addresses | `[IP_n]` | Four-octet dotted-quad addresses. |\n| API keys / generic secrets | `[SECRET_n]` | Key, token, secret, password, and apikey values with at least a 16-character payload. |\n| Infrastructure hostnames | `[HOST_n]` | Conventional patterns such as `ip-`, `host-`, `srv-`, `node-`, `db-`, `redis-`, `cache-`, `queue-`, `worker-`, `web-`, `api-`, `app-`, `proxy-`, `lb-`, `gw-`, `k8s-`, `pod-`, `aks-`. |\n| Internal hostnames | `[HOST_n]` | `*.internal`, `*.local`, `*.corp`, `*.lan`, `*.private`, `*.intranet`, `*.cluster.local`. |\n| Public domains | `[DOMAIN_n]` | Generic public domain fragments. |\n\n### Catch-alls (run last)\n\n| Type | Placeholder | What it catches |\n|---|---|---|\n| Bearer tokens | `[BEARER_n]` | `Bearer <token>` in authorization headers and log lines. |\n| Credit card numbers | `[CC_n]` | 13-19 digit numbers, with optional space or dash separators. |\n| Phone numbers | `[PHONE_n]` | International numbers in `+<country>...` format. |\n\n## How replacement works\n\nEach redaction goes into a per-request **map**: `{ \"[EMAIL_1]\": \"ali@example.com\", \"[DB_URI_1]\": \"postgres://...\" }`. Counters are per-type and per-request, so **the same email appearing twice gets the same placeholder (`[EMAIL_1]`) on both occurrences**, no new number is allocated.\n\nAfter the AI engine responds, placeholders in the response are restored by looking them up in the map. So if the response says \"Check the connection to [DB_URI_1]\", you'll see \"Check the connection to postgres://...\" in the final output.\n\n**The map never leaves the request.** It lives in memory for the duration of one AI call and is then discarded. There's no database persistence and no logging of values.\n\n## What doesn't get redacted\n\nThe redactor is a best-effort scrubber, not a proof-level guarantee. Things it **won't** catch:\n\n- Proprietary trade secrets encoded as arbitrary strings (company names, project codenames).\n- Numeric data that looks like a normal ID rather than a credit card or phone number.\n- Secrets in unusual formats (custom-prefixed tokens, base64-obfuscated values, and so on).\n- Values broken up across multiple lines in unusual ways.\n\nFor very sensitive workloads, the recommendation is to use a deployment that keeps prompts inside your own data boundary so even the redacted prompt doesn't leave your compliance perimeter. Talk to us about Enterprise options.\n\n## Pattern safety\n\nEvery pattern is designed so that a malicious input can't slow the redactor down or exhaust resources to cause a denial-of-service attack. Redaction runs near-instantly on every request and adds no noticeable delay.\n\nThe order of patterns matters: the private-key pattern must run before the email pattern, because PEM and JWT content can contain `@`-shaped noise that would confuse the email detector. High-confidence specifics always run first.\n\n## Always on\n\nRedaction is always on for every AI call, there is **no way to turn it off** from the dashboard. Enterprise customers running a self-hosted deployment can request a custom integration with a different data-handling profile under written agreement.\n\n## For compliance reviews\n\nSummary for your legal and InfoSec teams:\n\n- Every AI prompt passes through the redactor before being sent to the AI engine.\n- 18 pattern classes cover the most common credential and identifier formats.\n- Restoration happens locally inside the request; the AI engine never sees the mapping.\n- Redaction is always on for every AI call; the mapping is discarded when the request ends, never persisted to the database, and no values are logged.\n- The AI engine is Microsoft Azure. AI requests go only there, never directly to the companies that develop the models. The AI service does not store prompts or outputs, and they are not used to train AI models.\n- AI features run only after a user turns on AI processing in their profile.\n\nA pre-signed data-processing agreement (DPA) is available on request for EU customers.\n\n## FAQ\n\n**Q: How do I know redaction ran on my specific request?**\nA: Redaction is always on for every AI call and cannot be disabled, every prompt, without exception, passes through the redactor before it reaches the AI engine. Per-request logging is intentionally off, logging the raw redacted values would defeat the purpose.\n\n**Q: My error message was over-redacted and lost meaning. What now?**\nA: If a redacted placeholder collapsed context the AI actually needed (for example, `[URL_1]` lost the domain that identified the service), the suggested action might be generic. Try again after enriching the monitor's context, fields like service category and environment give the AI alternative context, so it doesn't need the URL.\n\n**Q: Is redaction applied to tool results inside an AI flow?**\nA: Yes, the same redactor runs on any tool output before it's sent back to the AI as observed context.\n\n## Related topics\n\n- [Health Prediction Overview](/docs/health-prediction-overview): the largest AI surface\n- [KVKK Compliance](/docs/kvkk-compliance): Turkish data protection alignment\n- [Audit Logging](/docs/audit-logging): what security events get recorded","category":"security","tags":["pii","privacy","ai","security","redaction","gdpr"],"order":30,"parentSlug":null,"published":true,"version":1,"metaTitle":"PII Redaction. UptimeWarden Documentation","metaDescription":"What UptimeWarden scrubs before any prompt reaches our AI engine, and how it's safely restored.","icon":"Shield","createdAt":"2026-10-12T22:06:42.036Z","updatedAt":"2026-10-12T22:06:42.036Z","publishedAt":"2026-10-12T22:06:42.036Z"},{"publicId":"01M4S2EPC36DBY6QSJBT2HMDTR","locale":"en","translationGroup":"security-gdpr-export-delete","slug":"gdpr-self-service","title":"GDPR Data Export & Account Deletion","description":"Export your full data (GDPR Art. 20 portability) or request permanent account deletion with a 30-day grace period. Audit logs are anonymised, not deleted.","body":"# GDPR Data Export & Account Deletion\n\nGDPR Art. 20 (\"right to data portability\") and Art. 17 (\"right to erasure\") translate to two concrete flows in UptimeWarden: **export** and **delete**. Both are self-serve, no support ticket, no waiting in a queue.\n\n## Data export (GDPR Art. 20)\n\nEvery signed-in user can pull a full JSON copy of their own data.\n\n### What's included\n\n- **User profile**: username, email, names, phone, email-verification status, profile image, timestamps.\n- **Monitors**: name, URL, type, status, interval, and creation date for every monitor you own.\n- **Consent history**: every consent grant and revocation, with timestamps and version numbers.\n- **Monitor count**: a convenience aggregate.\n\n### What's not included\n\nThe export is **user-scoped personal data**, not the full operational dataset:\n\n- Raw monitor check results (too large for a portability export; use the dedicated CSV data export instead).\n- Incident history (exportable as CSV from the **Incident Analytics** page on every plan).\n- Notification history (sensitive and large; available on request through support).\n- Team members and teams that you don't own.\n\nFor the full operational dataset, use the export dialog on the **Monitors** page (CSV, JSON, or Excel, available on all plans).\n\n### How to run the export\n\nProgrammatic:\n\n```http\nGET /api/account/data-export\nAuthorization: Bearer <session or api token>\n```\n\nThe response is a JSON file delivered as an attachment. The filename pattern is `uptimewarden-data-export-<userId>-YYYY-MM-DD.json`. The endpoint only requires authentication; there is no special per-user rate limit on it.\n\n### What the response looks like\n\n```json\n{\n  \"exportDate\": \"2026-04-22T10:00:00.000Z\",\n  \"exportType\": \"GDPR_DATA_PORTABILITY\",\n  \"user\": {\n    \"username\": \"ayse\",\n    \"email\": \"ayse@example.com\",\n    \"firstName\": \"Ayşe\",\n    \"lastName\": \"Yılmaz\",\n    \"phone\": \"+90555...\",\n    \"emailVerified\": true,\n    \"createdAt\": \"2024-10-15T08:00:00.000Z\",\n    \"lastLoginAt\": \"2026-04-22T09:45:00.000Z\",\n    \"profileImageUrl\": \"https://...\"\n  },\n  \"monitors\": [\n    { \"name\": \"api prod\", \"url\": \"https://api.example.com\", \"type\": \"http\", \"status\": \"up\", \"interval\": 180, \"createdAt\": \"...\" }\n  ],\n  \"consents\": [\n    { \"type\": \"privacy_policy\", \"version\": \"2025-09-11\", \"granted\": true, \"grantedAt\": \"...\", \"revokedAt\": null }\n  ],\n  \"monitorCount\": 12\n}\n```\n\n## Account deletion (GDPR Art. 17)\n\nDeletion runs with a **30-day grace period**. During that window your account is:\n\n- Soft-deleted: checks continue to run, but the account is flagged as pending deletion.\n- **Reversible**: cancel any time within the 30 days and the deletion is called off.\n\n:::warning Extra step for team owners\nIf you own a non-personal team, your account will not be removed when the 30 days elapse; instead the request is flagged as **blocked: ownership transfer required**. To proceed, transfer ownership of the team to another member, or delete the team first.\n:::\n\n:::danger Permanent deletion is irreversible\nAfter the 30-day grace period, and once any team-ownership block has been resolved, your account record is permanently deleted along with everything that depends on it. **Audit log entries are not deleted, they are anonymised**: personal fields are nulled but the entry shape is preserved so we can prove deletion happened in a compliance audit. Payment records are retained as required by tax law. There is no recovery past this point.\n:::\n\n### How to start deletion\n\nProgrammatic:\n\n```http\nPOST /api/account/delete-request\n{ \"reason\": \"...\", \"exportData\": true }\n```\n\nBoth `reason` and `exportData` are optional. The response returns a request ID, a status of `pending`, the scheduled deletion date (today plus 30 days), and `gracePeriodDays: 30`. If a request is already pending, the endpoint returns `409`.\n\n### Cancelling\n\n```http\nPOST /api/account/cancel-deletion\n```\n\nThe pending-deletion flag clears and the account resumes normal operation.\n\n### Checking status\n\n```http\nGET /api/account/deletion-status\n```\n\nIf **no** request is pending, the response indicates that no deletion is scheduled. If a request **is** pending, you receive the scheduled deletion date, the request creation timestamp, and whether a data export was requested and completed.\n\n```json\n{\n  \"hasPendingRequest\": true,\n  \"status\": \"pending\",\n  \"scheduledDeletionAt\": \"2026-05-22T10:00:00.000Z\",\n  \"createdAt\": \"2026-04-22T10:00:00.000Z\",\n  \"dataExportRequested\": true,\n  \"dataExportCompleted\": true\n}\n```\n\n### What's retained after permanent deletion\n\n- **Payment records**: retained as required by statute (Türkiye Tax Law, EU VAT regulation). Email and name on historical payment-transaction records are **not** redacted; the law requires those identifying fields.\n- **Anonymised audit log entries**: your user ID and personal fields are nulled, but the action, timestamp, and resource type remain. This preserves the compliance-audit proof that deletion happened. Anonymising audit entries is a deliberate design choice, physically deleting them would lose the auditability of the deletion itself.\n\nEverything else is purged irreversibly.\n\n## Consent records\n\nEvery consent (privacy policy, terms of service, marketing email opt-in, cookie category acceptance) is recorded with:\n\n- The consent type: one of: privacy policy, terms of service, marketing, analytics, or one of the cookie categories (essential, analytics, marketing).\n- The document version at the time the consent was given.\n- A boolean flag indicating grant or revocation; revocations are stored as separate entries.\n- IP address, browser/user agent, and timestamp for audit context.\n\nProgrammatic:\n\n```http\nGET  /api/compliance/consents              # list\nPOST /api/compliance/consents              # grant or revoke\n     { \"consentType\": \"marketing\", \"version\": \"2025-09-11\", \"granted\": false }\n```\n\n## Cookie categories and the cookie banner\n\nUptimeWarden runs a three-category cookie consent banner across the dashboard, marketing site, and documentation:\n\n- **Essential**: required for sign-in sessions and CSRF protection. Always on.\n- **Analytics**: anonymous product usage metrics. Optional; we honour your opt-out.\n- **Marketing**: cross-site retargeting. Off by default.\n\nCategories are set on first visit through the banner and editable later under **Privacy → Cookies**. Each toggle is recorded as a consent entry.\n\n## Controller vs processor\n\nUptimeWarden plays a **dual role** in data processing:\n\n- **Data controller** for our own users: registered profile data, usage data, billing. We define the processing purposes here.\n- **Data processor** for the data the customer pushes into the platform: monitor URLs, recipient email and phone lists, webhook payloads. The customer defines the purposes; UptimeWarden processes on instruction.\n\nThis split matters for KVKK and GDPR questions: our own users' rights (export, deletion, consent) are covered by the self-service flows on this page, while the rights of *the customer's own* downstream data subjects are fulfilled **by the customer**, with UptimeWarden providing processor-level support.\n\nSee [KVKK Compliance](/docs/kvkk-compliance) for DPO contact and the data-processing agreement.\n\n## FAQ\n\n**Q: Can I export only part of my data (just monitors, just consents)?**\nA: The GDPR export is all-or-nothing by design, that's what regulators expect. For finer-grained exports, use the export dialog on the **Monitors** page (CSV, JSON, or Excel of monitor performance data) and the **Incident Analytics** CSV export.\n\n**Q: I own a team, can I delete my account?**\nA: Not directly, the team-ownership transfer rule applies. Transfer the team to another user (Settings → Team → Transfer owner) or delete the team first, then re-submit your deletion request.\n\n**Q: How do I cancel deletion within the 30 days?**\nA: Call `POST /api/account/cancel-deletion`, or use the **Cancel** button on the **Privacy → Data** settings page, both go through the same endpoint.\n\n**Q: After permanent deletion, can I sign up again with the same email?**\nA: Yes, the user record is gone and the email is free. Note that anonymised audit entries still record the prior deletion event (without identifying fields).\n\n**Q: Does deleting my account cancel my subscription?**\nA: The account-deletion flow does not cancel billing on its own, it anonymises your audit logs and hard-deletes your account record once the 30-day grace period ends. If you have an active paid subscription, cancel it separately through your subscription settings (or contact support) before requesting deletion.\n\n## Related topics\n\n- [KVKK Compliance](/docs/kvkk-compliance): Turkish KVKK 6698 alignment, controller/processor split\n- [Audit Logging](/docs/audit-logging): post-deletion anonymisation\n- [PII Redaction](/docs/pii-redaction): what never reaches our AI engine","category":"security","tags":["gdpr","kvkk","compliance","data-portability","account-deletion","privacy"],"order":40,"parentSlug":null,"published":true,"version":1,"metaTitle":"GDPR Data Export & Account Deletion. UptimeWarden Documentation","metaDescription":"Self-serve data portability and account deletion flows, matching GDPR Art. 17 and Art. 20.","icon":"Shield","createdAt":"2026-10-12T22:06:42.052Z","updatedAt":"2026-10-12T22:06:42.052Z","publishedAt":"2026-10-12T22:06:42.052Z"},{"publicId":"01KJ7Q9ZTR1TXR219X7HMRBEJK","locale":"en","translationGroup":"invoicing","slug":"en-invoicing","title":"Billing and Payment Management","description":"Guide to managing payment methods, adding billing addresses, and viewing payment history","body":"# Billing and Payment Management\n\nFrom the **Billing** page, you can manage your payment methods, add billing addresses, view active add-ons, and review your payment history.\n\n## Payment Methods (Cards)\n\n### Adding a Card\n\n1. Go to the **Billing** page\n2. Click the **\"Add Card\"** button\n3. Enter your card details:\n   - Card number\n   - Expiration date\n   - CVV/CVC\n   - Card nickname (e.g., \"Work Card\")\n4. Complete 3D Secure verification\n\n### Card Management\n\nFor each saved card:\n- **Card brand**: Visa, Mastercard, Amex icon\n- **Card nickname**: The alias you assigned\n- **Masked number**: `•••• •••• •••• 1234`\n- **Expiration date**: Warning badge for expired cards\n- **Default card**: The card used for automatic payments\n- **Last used**: When the card was last used\n\nFrom the three-dot menu on a card:\n- **Set as default**: Set this card as the default payment method\n- **Delete**: Remove the card\n\n## Billing Addresses\n\n### Adding an Address\n\n1. Click the **\"Add Address\"** button\n2. Fill in your billing information:\n   - Full name\n   - Company name (optional)\n   - Address line 1 and 2\n   - City, district, postal code, country\n   - Phone (optional)\n   - Tax ID (optional)\n3. Save\n\n### Address Management\n\nFrom the address card menu:\n- **Edit**: Update address details\n- **Set as default**: Use this address on invoices\n- **Delete**: Remove the address\n\n## Active Add-ons\n\nActive add-ons and quota usage are shown on the Billing page. For detailed information, see the **Add-on Purchase** documentation.\n\n## Payment History\n\nAll payment transactions are listed chronologically. For each transaction:\n\n- **Status icon**: Successful, failed, or pending\n- **Amount**: Amount paid\n- **Transaction type**: Normal payment, refund, or cancellation\n- **Card number**: Masked number of the payment card\n- **Date and time**: Transaction timestamp\n\n### Detailed View\n\nClick a transaction to see expanded details:\n- Transaction ID\n- Card details\n- Transaction creation and confirmation times\n- Installment information (if applicable)\n- Currency conversion details (if applicable)\n- Error message (for failed transactions)\n\nNavigate through payment history with **\"Previous\"** and **\"Next\"** buttons.\n\n## Tips\n\n1. **Add multiple cards**: A backup card can be used if the default is declined\n2. **Update expiring cards**: An expired card will block automatic payments\n3. **Keep billing address current**: E-invoices are generated based on this address\n4. **Check payment history**: Regularly monitor failed transactions","category":"billing","tags":["billing","payment","credit-card","invoice","transaction"],"order":1,"parentSlug":"subscriptions","published":true,"version":1,"metaTitle":null,"metaDescription":"Guide to managing payment methods, adding billing addresses, and viewing payment history","icon":"CreditCard","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTR0HTPRYWN75X2Q0ZM","locale":"en","translationGroup":"addon-purchase","slug":"en-addon-purchase","title":"Add-on Purchase and Management","description":"Guide to purchasing, managing, and canceling UptimeWarden add-on packages","body":"# Add-on Purchase and Management\n\nAdd-ons are purchasable packages that add extra capacity without changing your current subscription plan. Instead of upgrading your plan, you can purchase the relevant add-on to increase the resource you need.\n\n## What is an Add-on?\n\nAdd-ons are additional capacity packages added to your plan:\n\n- **Extra monitor capacity**: Additional monitor creation quota\n- **Extra SMS credits**: SMS notification sending capacity\n- **Extra WhatsApp credits**: WhatsApp notification sending capacity\n- **Extra Voice (call) credits**: Voice notification capacity\n- **Extra agent slots**: Additional private agent installation quota\n- **Extra AI prediction capacity**: AI Health Prediction analysis capacity\n- **Extra AI security scan**: AI Security Scan capacity\n\n> **Tip**: Add-ons are added **on top of** your plan's base limits. For example, if your plan supports 10 monitors and you purchase a 5-monitor add-on, you can create a total of 15 monitors.\n\n## Add-on Categories\n\nAdd-ons are grouped by resource type:\n\n| Resource Type | Description |\n|---------------|-------------|\n| **sms** | SMS notification credits |\n| **whatsapp** | WhatsApp notification credits |\n| **voice** | Voice call notification credits |\n| **monitor** | Extra monitor capacity |\n| **agent** | Extra private agent slots |\n| **aiPrediction** | AI Health Prediction capacity |\n| **aiSecurityScan** | AI Security Scan capacity |\n\n## Purchasing an Add-on\n\n### Steps\n\n1. Go to the **Settings → Add-ons** page (or click **Add-ons** from the menu)\n2. Browse available add-ons by category (SMS, WhatsApp, Voice, Monitor, Agent, AI)\n3. Click the **\"Purchase\"** button for the desired add-on\n4. In the payment dialog, select your saved payment method\n5. Confirm by clicking **\"Pay\"**\n\n### Payment\n\nAdd-on payments are processed independently of your subscription payment:\n\n- **3D Secure**: All credit card payments are secured with 3D Secure\n- **Instantly active**: The add-on is available immediately upon payment confirmation\n- **Auto-renewal**: Add-ons renew automatically at the end of the period\n\n## Viewing Add-ons\n\nView your active add-ons from the **Add-ons** page:\n\n- Add-on name and description\n- Purchase date\n- Next renewal date\n- Status (active/expired/canceled)\n- Quantity\n\n## Canceling an Add-on\n\nTo cancel an add-on:\n\n1. Go to the **Add-ons** page\n2. Click the **\"Cancel Add-on\"** button next to your active add-on\n3. Confirm\n\nThe canceled add-on remains active until the end of the current period. Once the period ends, the added capacity is removed.\n\n## How Can I See My Current Limits?\n\nYou can see your current usage on the Dashboard or **Subscription** page:\n\n```\nMonitors:        12 / 15 (plan: 10 + add-on: 5)\nSMS Credits:     45 / 100\nWhatsApp Credits: 20 / 50\nVoice Credits:    8 / 10\nAgents:           1 / 2\nAI Predictions:   5 / 10\n```\n\n## Frequently Asked Questions\n\n### What's the difference between an add-on and a plan upgrade?\n\n| | Plan Upgrade | Add-on |\n|---|---|---|\n| **Scope** | All limits increase | Only selected resource increases |\n| **Price** | Fixed monthly fee | Per-resource fee |\n| **Flexibility** | Plan change | Add/remove anytime |\n| **Features** | May unlock new features | Only increases capacity |\n\n### Can I buy multiple of the same add-on?\n\nYes, you can purchase multiple of the same add-on. Each one adds to your capacity.\n\n### Can I upgrade an add-on?\n\nAdd-ons are fixed packages. For more capacity, you can purchase additional units of the same add-on or choose a larger package.\n\n## Best Practices\n\n1. **Evaluate your needs**: Compare whether a plan upgrade or add-on is more suitable\n2. **Track your usage**: Add an add-on before limits are reached for uninterrupted usage\n3. **Cancel unused add-ons**: Don't pay for capacity you're not using\n4. **Track renewal dates**: Know when your renewals are due","category":"billing","tags":["addon","extension","purchase","limit","capacity"],"order":2,"parentSlug":"subscriptions","published":true,"version":1,"metaTitle":null,"metaDescription":"Guide to purchasing, managing, and canceling UptimeWarden add-on packages","icon":"CreditCard","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZT0BMAFP4K55MQYM9JZ","locale":"en","translationGroup":"subscriptions-overview","slug":"en-subscriptions","title":"Subscription Plans and Management","description":"Subscription plans, plan changes, usage tracking, and cancellation processes guide","body":"# Subscription Plans and Management\n\nUptimeWarden offers flexible subscription plans tailored to different needs. You can view your current plan, change plans, and track your usage from the **Subscription** page.\n\n## Current Subscription Page\n\nThe **Subscription** page displays:\n\n- **Plan name** and price (with icon)\n- **Status** badge: Active, Trial Active, etc.\n- **Next billing date**\n- **Trial period** (if active, with end date)\n\n### Plan Features Summary\n\nFeatures included in your current plan are shown:\n\n- Number of monitors (count or unlimited)\n- Number of teams (count or unlimited)\n- SSL monitoring (active/inactive)\n- API access (active/inactive)\n\n### Usage Statistics\n\nResource usage is tracked with progress bars:\n\n| Resource | Display |\n|----------|---------|\n| **Monitors** | Used / Limit |\n| **Agents** | Used / Limit |\n| **Teams** | Used / Limit |\n| **Team Members** | Used / Limit |\n\nProgress bar colors:\n\n- **Green**: Below 75%\n- **Orange**: 75-90%\n- **Red**: 90% and above\n\n### Active Add-ons and Quotas\n\nActive add-on packages and SMS, WhatsApp, Voice quota usage are also shown on the same page.\n\n## Plan Comparison\n\nAll plans are compared side by side on the **Subscription Plans** page.\n\n### Pricing Options\n\n- **Monthly** and **yearly** billing toggle buttons\n- Discount for annual payment (typically 20%, may vary by plan)\n- Supported currencies: ₺ (TRY), € (EUR), £ (GBP), $ (USD), ₽ (RUB)\n- Free plans show \"Free\", Enterprise plans show \"Contact Us\"\n\n### Information on Each Plan Card\n\n- Plan name and description\n- Price (monthly/yearly)\n- Monitor limit\n- Minimum check interval\n- Supported protocols (HTTP, TCP, UDP, WebSocket, gRPC, MCP)\n- Email notifications\n- SMS and WhatsApp notifications\n- Custom webhooks\n- SSL certificate monitoring\n- Security header analysis\n- API access\n- Team and agent limits\n- Incident management\n- Advanced reporting and analytics\n- Data retention period\n- Priority support status\n\n### Comparison Table\n\nA detailed comparison table of all plans and features is at the bottom of the page. Each feature row shows ✓ or ✗ per plan.\n\n### FAQ Section\n\n8 frequently asked questions and answers:\n\n1. How does monitoring work?\n2. What monitor types are supported?\n3. How fast are outage notifications?\n4. Can I change plans?\n5. What happens if the monitor limit is exceeded?\n6. Is there an annual billing discount?\n7. How does SSL certificate monitoring work?\n8. Is there a setup fee or contract?\n\n## Changing Plans\n\n### Upgrade\n\n1. Go to the **Subscription** or **Change Plan** page\n2. Your current plan is marked with a **\"Current Plan\"** badge\n3. Click the **\"Upgrade\"** button on the desired plan\n4. Review features and pricing\n5. Enter or use your saved payment information\n\nAfter upgrading, new features and limits are activated **immediately**.\n\n### Downgrade\n\n1. Click the **\"Downgrade\"** button on the target plan\n2. Your current usage is compared against the new plan's limits\n3. A warning is shown if limits are exceeded (e.g., \"You need to delete 3 monitors\")\n4. Complete with **\"Confirm Change\"** in the confirmation dialog\n\n### Enterprise Plan\n\nThe **\"Contact Us\"** button is shown for Enterprise plans. Custom pricing and limits are determined with the sales team.\n\n## Payment System\n\n### Supported Payment Methods\n\n- Credit/debit card (Visa, Mastercard, Amex)\n- 3D Secure verification\n- Re-payment with saved cards\n- Card tokenization (secure storage)\n\n### Successful Payment\n\nShown after a successful payment:\n\n- Transaction ID\n- Amount paid\n- Card info (last 4 digits)\n- Transaction date\n- Plan activation details and next billing date\n- Included features (Enhanced Monitoring, Team Collaboration, Instant Alerts)\n\n### Failed Payment\n\nOn the failed payment page:\n\n- Error message (card declined, insufficient funds, expired card, invalid CVV, transaction timeout, etc.)\n- Transaction reference number (if available)\n- Recovery suggestions:\n  - Try a different payment method\n  - Check card details\n  - Contact your bank\n- **\"Try Again\"** and **\"View All Plans\"** buttons\n\n## Subscription Cancellation\n\nCancellation is done via the **\"Cancel Subscription\"** button on the **Subscription** page (only shown for active paid plans).\n\n### Cancellation Options\n\nThe system automatically determines the appropriate cancellation option based on your situation:\n\n| Option | Condition | Description |\n|--------|-----------|-------------|\n| **30-Day Money-Back Guarantee** | First subscription, within 30 days | Full refund |\n| **14-Day Right of Withdrawal** | Within 14 days | Consumer withdrawal right |\n| **End-of-Period Cancellation** | Default | Switch to Free plan at period end |\n\nAfter cancellation, the plan is downgraded to Free at the end of the current period.\n\n## Tips\n\n1. **Track your usage**: Consider upgrading when progress bars turn red\n2. **Prefer annual payment**: Provides significant savings\n3. **Check before downgrading**: Ensure your current usage fits within the new plan's limits\n4. **Export before canceling**: Access to data will be limited by Free plan limits after cancellation\n5. **Add multiple cards**: Add backup cards from the Billing page to prevent payment interruptions","category":"billing","tags":["subscription","plans","upgrade","downgrade","billing","pricing"],"order":3,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Subscription plans, plan changes, usage tracking, and cancellation processes guide","icon":"CreditCard","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EP96Q9S2D3JTYKM1H2BW","locale":"en","translationGroup":"subscription-plans","slug":"subscription-plans","title":"Subscription Plans & Limits","description":"What every UptimeWarden plan includes, monitors, regions, notification channels, AI features, and history retention per tier.","body":"# Subscription Plans & Limits\n\nUptimeWarden's plans are managed centrally, every limit and every feature is configured behind the scenes, so two things matter for you:\n\n- Upgrades take effect immediately. Your next monitor or notification already sees the new limit.\n- Custom plans (negotiated tiers for larger teams) can be issued without any waiting.\n\n## At a glance\n\nWe offer five publicly listed plans: **Free**, **Hobby**, **Starter**, **Professional**, and **Enterprise**. They differ in monitor count, shortest check interval, number of regions you can run from, data retention, and which features unlock.\n\n:::tip Current numbers live in one place\nPrices and plan limits (monitor ceiling, check interval, data retention, etc.) change from time to time, so we don't keep exact numbers in these docs. For the current comparison, see the [pricing page](https://uptimewarden.online/pricing). Your account's exact limits always render live on the dashboard's **Billing → Plan details** page.\n:::\n\n## What a \"limit\" is\n\nEach limit is a named allowance that controls one aspect of your account. The most common ones are:\n\n| Limit | Meaning |\n|---|---|\n| Monitors | Concurrent active monitors. |\n| Regions | How many regions your monitors can run from. Choosing a region is available on Professional (up to 5 regions) and Enterprise (all regions); on Free, Hobby and Starter monitors run from the default region. |\n| Verification regions | Multi-location consensus witness ceiling. |\n| Data retention | How many days of monitor history we keep online. |\n| Minimum check interval | Tightest check cadence allowed. Free is every 3 minutes; higher plans go faster. |\n| Minimum response-time threshold | Smallest response-time alarm threshold you can set. Free starts at 5000 ms; higher plans reach lower thresholds. |\n| Notification channels | Active channels per user. |\n| API tokens | Number of API tokens allowed. |\n| Webhook channels | Number of webhook configs you can create. Free allows 3. |\n| Domain monitoring | WHOIS-based domain expiry monitors. |\n| Status pages | How many status pages your account can create: Free 1, Hobby 2, Starter 3, Professional 10, Enterprise unlimited. Pages above the limit, for example after a downgrade, keep working and stay published; only creating a new page is refused. |\n| Monthly AI credits | Monthly cap on the AI work you start yourself: Wardy questions, postmortem drafts you generate, the security header analysis and status page drafts. Automatic drafts and hints do not use it. On Free it covers about 60 Wardy questions a month. |\n| Wardy questions | Questions a day you can ask Wardy: Free 10, Hobby 15, Starter 25, Professional 50, Enterprise unlimited. The day resets at 00:00 UTC. |\n| Postmortem drafts | Drafts a month, automatic and manual together: Free 1, Hobby 1, Starter 3; Professional and Enterprise have no monthly count. Drafts you generate by hand use AI credits; automatic ones do not. |\n\n## Feature access\n\nBeyond numeric limits, certain product capabilities are unlocked at higher tiers:\n\n| Feature | Description |\n|---|---|\n| SSL monitoring | SSL certificate expiry alerts. |\n| Security headers | Security-header analysis page. |\n| Health predictions | Health forecasts built from each monitor's check history (Professional and above). |\n| API access | API tokens and programmatic access (available on all plans, including Free). |\n| Advanced notifications | SMS, WhatsApp, and voice channels. |\n| Custom branding | Branded emails and status pages. |\n| Reporting | PDF and CSV reports. |\n| Priority support | Your support requests are handled first (Professional and above). No response-time guarantee (SLA) is offered; Enterprise contracts can discuss custom terms. |\n| Multiple alert channels | Parallel dispatch across channels. |\n| Custom webhooks | Custom webhook templates. |\n| Data export | Full data export (CSV, JSON, Excel). |\n| Audit logs | Audit log access. |\n| White-label | White-label and managed-services branding. |\n| Region selection | Choose the region each monitor runs from: up to 5 regions on Professional, all regions on Enterprise. |\n| Grouped-alert hints | A likely-cause hint on grouped alerts, written from the errors your monitors returned; the alert goes out without it if it is not ready (Professional and above). |\n| Postmortem drafts | A first draft of the postmortem once an incident is resolved, with a timeline and a likely cause linked to its evidence (every plan, counted per month). |\n| Cascade suppression | Service-dependency cascade suppression. |\n| Ask Wardy | Ask about your monitoring data in plain language (every plan, counted per day). |\n| SLO tracking | SLO tracking with multi-window burn-rate alerts (Professional and above). |\n| Predictive insights | Risk levels and trends on the dashboard (Professional and above). Sudden outages cannot be predicted. |\n| Telemetry | Telemetry sources (Prometheus-compatible metric endpoints), OpenTelemetry ingest and observability evidence for incident analysis (Professional and above). |\n| Custom domains | Status page on your own domain (Professional and above). |\n| Auto-fix | Rule-based fix plans that wait for your approval. Applying them is switched off unless it is turned on for your account (Professional and above). |\n| Service map | Service dependency map page. |\n| Branding settings | Branding configuration page. |\n\nFeature access is updated centrally; changes from administrators reach your account within about 15 minutes.\n\n## Notification usage\n\nNotifications cost the platform money to deliver (especially SMS, voice, and WhatsApp), so usage limits are monthly per user:\n\n| Channel | Default |\n|---|---|\n| Email | Plan-dependent. Free includes 250/mo; unlimited on Enterprise. |\n| SMS | Plan-dependent. Free does not include SMS (Hobby includes 25/mo). |\n| WhatsApp | Plan-dependent. |\n| Voice | Plan-dependent. |\n| Push | Plan-dependent. Free includes 100/mo. |\n| Webhooks | Plan-dependent. Free includes 1,000 sends/mo. Slack, Microsoft Teams, Telegram and Discord sends count here too. |\n\nWhen a plan's quota is exhausted, **new sends on that channel are skipped until the billing period ends**, and each attempt is recorded. The account owner gets one notice email per quota per period. Other channels keep running until their own quotas run out. The dashboard's **Usage** page shows your live remaining quota and consumption rate.\n\n## Add-on packs\n\nYour effective limit is the plan allowance plus everything your active add-on packs add. Add-on packs are extras you can purchase to add monitors, agents, or notification quota (SMS, WhatsApp, voice, AI predictions, AI security scans) without changing your plan. For example, adding a +25-monitor pack raises your effective monitor ceiling by 25 on top of your plan's allowance.\n\nOpen **Settings → Billing → Add-ons** to see available packs and how each one changes your numbers.\n\n## Custom plans\n\nEnterprise and managed-services accounts often receive a custom plan with bespoke numbers. These are not listed in the public pricing comparison; once a custom plan is assigned, you see it on your own dashboard.\n\n## Upgrading and downgrading\n\nOpen **Settings → Billing → Change plan**. The upgrade flow is:\n\n1. Choose the new plan.\n2. Confirm the prorated amount for the current billing cycle.\n3. Payment is captured immediately through our secure payment provider.\n4. The new limits are **live immediately**, no waiting for the next billing cycle.\n\nDowngrades are scheduled for the end of your billing cycle; you keep the higher tier's features until then. **If your current usage exceeds the lower plan's limits** (for example, moving to a plan with a lower monitor ceiling), the flow flags the excess and asks you to reduce usage before confirming.\n\n## Free-tier philosophy\n\nFree is not a stripped-down demo, it is a real \"challenger\" plan. Specifically:\n\n- **Two regions check every failure**: a second region repeats the check. If it also sees the site down, the alert says the outage is confirmed; if it reaches the site, the alert is still sent, labelled unverified, because with only two regions a split cannot say which one is right.\n- **Email, push, and webhook channels are on**: included with monthly quotas (Slack, Microsoft Teams, Telegram and Discord run through webhooks). SMS, WhatsApp, and voice are not.\n- **30-day retention**: enough for weekly retros.\n- **3-minute checks**: tight enough for real monitoring, not a teaser.\n\n- **Wardy and postmortem drafts are included**: 10 Wardy questions a day (the plan's AI credits cover about 60 a month) and one postmortem draft a month.\n\nWhat Free does not include: SMS, WhatsApp, and voice; on-call rotations (from Hobby); health forecasts, the audit log, and custom branding (from Professional).\n\n## FAQ\n\n**Q: Why is the consensus threshold fixed on Free and Hobby?**\nA: Every plan re-checks a failure from other regions; Free and Hobby keep the default threshold. On Hobby, when most regions reach the site, the alert is held and checked again five minutes later. On Free, with two regions, a split is still sent, labelled unverified. Starter and above can change the threshold, for example from 2 of 3 to 3 of 3 or 1 of 3.\n\n**Q: I hit my notification quota. What happens?**\nA: Further sends on that channel are skipped until the billing period ends, and each attempt is recorded; other channels keep running until their own quotas run out. The account owner gets one email per quota per period. The dashboard shows live remaining quota.\n\n**Q: Wardy or a postmortem draft says my allowance is used up.**\nA: Every plan has a daily Wardy allowance and a monthly draft allowance, and the plan's monthly AI credits cap Wardy and the drafts you generate by hand. The message says which one ran out and when it comes back: Wardy questions at 00:00 UTC, drafts and AI credits on your credit month's renewal day. You can wait, move to a larger plan, or buy an AI credit pack.\n\n**Q: Where can I see my payments?**\nA: **Billing → Payment history** lists every completed transaction (amount, payment method, date, and status). Your billing profile (individual/corporate details, tax number, tax office) is kept under **Billing**. Refunds are handled by support; see the 30-day money-back guarantee (first-time subscribers) / 14-day withdrawal (returning subscribers).\n\n:::note Coming soon\nDownloadable PDF invoices (with e-Fatura/e-Arşiv delivery and VAT breakdown) are planned but not yet available. For now, use the payment history above for your records.\n:::\n\n## Related topics\n\n- [Multi-Location Consensus](/docs/multi-location-consensus): witness limits per plan\n- [API Tokens](/docs/api-tokens): token allowance per plan\n- [Audit Logging](/docs/audit-logging): retention by plan\n- [Ask Wardy](/docs/ask-wardy): daily questions per plan\n- [Postmortem Workflow](/docs/postmortem-workflow): monthly drafts per plan","category":"billing","tags":["plans","pricing","limits","billing","free","hobby","starter","professional","enterprise"],"order":10,"parentSlug":"subscriptions","published":true,"version":1,"metaTitle":"Subscription Plans. UptimeWarden Documentation","metaDescription":"Free, Hobby, Starter, Professional, and Enterprise, what changes at each tier.","icon":"CreditCard","createdAt":"2026-10-12T22:06:41.959Z","updatedAt":"2026-10-12T22:06:41.959Z","publishedAt":"2026-10-12T22:06:41.959Z"},{"publicId":"01M4S2ENY84CN7Y004DDMBPM8D","locale":"en","translationGroup":"subscriptions-overview","slug":"subscriptions-overview","title":"Subscriptions","description":"Five plan tiers (Free, Hobby, Starter, Professional, Enterprise), limits, features, add-on packs, plan changes, and the 7-day grace period.","body":"# Subscriptions\n\nUptimeWarden ships five publicly listed plans. Every limit and feature is configurable from the admin panel without a deploy, so plans can be tuned per account where needed.\n\n## The five plan tiers\n\n| Plan | Audience |\n|---|---|\n| **Free** | Personal projects, evaluation |\n| **Hobby** | Side projects, indie sites |\n| **Starter** | Early-stage startups, small teams |\n| **Professional** | Mid-size teams, SaaS companies |\n| **Enterprise** | Large orgs, regulated industries |\n\nLive prices, limits, and features for every tier are detailed in [Subscription Plans](/docs/subscription-plans).\n\n:::tip Custom plans\nEnterprise can run as an invisible custom plan, negotiated through sales, with prices and limits tuned per account. These plans never show up in the public pricing comparison.\n:::\n\n## Plan limits at a glance\n\nNumeric limits such as monitor count, minimum check interval, and data retention vary by plan and change from time to time (especially at Starter and above), so we don't keep exact numbers here. See the [pricing page](https://uptimewarden.online/pricing) for current values; your account's exact values render live on the dashboard's **Billing → Plan details** page.\n\nKey features unlocked by plan, read live from the plan catalogue, so an\nadmin enabling a feature on a tier is reflected here without a docs deploy:\n\n:::plan-features\n\nFor the full feature list and notification-channel quotas see [Subscription Plans](/docs/subscription-plans).\n\n## Notification quotas\n\nPer-channel monthly quotas are enforced from your notification history:\n\n- **Email**: per-plan monthly quota; unlimited on Enterprise. See the [pricing page](https://uptimewarden.online/pricing) for current quotas.\n- **Webhook**: per-plan monthly quota; unlimited on Enterprise. Slack, Microsoft Teams, Telegram and Discord draw from this quota too: they are all webhook deliveries and only differ in payload format. No plan turns these channels off.\n- **Push**: per-plan monthly quota; on for every plan including Free, unlimited on Enterprise.\n- **SMS / WhatsApp / Voice**: plan-dependent. Disabled by default on Free; paid plans unlock them in increments. Each quota is shared by the whole account, and one unit is one phone number reached: a message counts when it is sent successfully, a call only when it is answered. See [Notification Channels](/docs/notification-channels) for how units are counted and how many numbers one alert reaches on each plan.\n\nCrossing a quota is a hard limit: sends on that channel are skipped for the rest of the billing period, and each attempt is recorded. The account owner gets one warning email per quota per period. Live usage is visible under **Subscription → Usage**.\n\n## AI credits\n\nThe AI work you start yourself draws from one shared monthly allowance:\nquestions you ask Wardy, postmortem drafts you generate or regenerate, the\nsecurity header analysis and status page drafts. Each request is charged by\nwhat it actually costs, so a long question uses more than a short one. A Wardy\nquestion averages about 1.5 credits; on Free, the monthly credits cover about\n60 questions. The Wardy panel shows both of its limits in one line, for\nexample \"7 of 10 questions left today, about 60 this month\": on the smaller\nplans the credits can run out before the daily questions do.\n\nAI that runs on its own is **included in your plan and uses no credits**:\n\n- the postmortem draft written when an incident resolves (it still counts\n  toward your plan's monthly draft allowance),\n- the hint on a grouped alert,\n- the explanation of why a monitor is flapping,\n- health notes on monitors and the account health summary.\n\nEach of these has a daily limit per account. Past it, the feature falls back\nto its version without AI for the rest of that day, for example the grouped\nalert without the hint. Nothing that alerts you depends on it.\n\nYour credit allowance depends on your plan and resets **on your subscription\nrenewal date**, not on the first of the calendar month. It is monthly on annual\nbilling too, it refreshes on your renewal day each month. **Unused plan\ncredits do not roll over.** Purchased add-on packs do carry over: they sit on\ntop of your plan allowance and last until spent.\n\nWhen credits run out, Wardy and the other features you start yourself pause\nuntil the renewal day; automatic drafts and hints, monitoring, alerting and\nincident recording carry on as normal.\n\nIf Wardy runs out of credits part-way through a long question, the answer is\ncompleted from what it had gathered and tells you why it stopped early.\n\nYour balance is shown under **Subscription → Usage** and can be topped up with\nan add-on pack. The AI usage panel on your profile lists what used your credits\nthis month and, separately, the automatic AI that was included.\n\n## Add-on packs\n\nIf your base plan isn't enough, you can buy add-on packs (extra monitors, agents, SMS/WhatsApp/Voice quota, AI credits). Your effective limit is always your base plan limit plus the total of any active add-on packs:\n\n```text\neffective limit = base plan limit + sum of active add-on packs\n```\n\nA new pack takes effect immediately. See [Add-On Purchase](/docs/addon-purchase) for the catalogue and checkout flow.\n\n## Plan changes\n\nFrom **Settings → Billing → Change plan**:\n\n- **Upgrade**: applies immediately. The current cycle is **prorated**: you're charged the difference between the new plan and the unused portion of the current plan.\n- **Downgrade**: scheduled for the end of the current billing cycle. You keep the higher tier's features until then. If your current usage exceeds the downgraded plan (e.g. 80 monitors on a plan that allows 50), the flow asks you to reduce usage before confirming.\n\nPlan transitions are recorded for audit. See [Billing & Payments](/docs/invoicing) for your payment-transaction history and billing profile.\n\n## Grace period (failed payment)\n\nIf a recurring charge fails, the subscription enters a 7-day grace period:\n\n1. **Day 0, payment fails.** A card-decline email goes out and a retry is scheduled.\n2. **Days 1-7, grace period active.** All paid features stay on; the account is marked past due. A banner appears in the dashboard prompting a card update.\n3. **Day 7, grace period ends.** If payment still hasn't succeeded, the subscription is suspended: no new checks, but data isn't deleted.\n\nDuring the grace window you can update your card from **Settings → Billing** and trigger a fresh charge.\n\n## Cancellation\n\nYou can cancel any time from **Settings → Billing → Cancel subscription**. Cancellation automatically selects the best applicable policy: a **30-day money-back guarantee** for first-time subscribers, a **14-day withdrawal** refund for returning subscribers, or otherwise an **end-of-period** cancellation (you keep paid features until the end of the current billing cycle, no prorated refund). When a refund applies, it is issued automatically back to your original payment method.\n\n## Payment methods\n\nCard payments are processed securely through our payment provider. A saved card is kept as a token, which is what renewals are charged to; we don't store your full card number.\n\nSee [Billing & Payments](/docs/invoicing) for your payment-transaction history.\n\n## Related\n\n- [Subscription Plans](/docs/subscription-plans): full per-tier limit and feature breakdown\n- [Add-On Purchase](/docs/addon-purchase): extra capacity packs\n- [Billing & Payments](/docs/invoicing): payment-transaction history and billing profile\n- [Audit Log Retention](/docs/audit-log-retention)\n- [Roles & Permissions](/docs/roles-permissions)","category":"billing","tags":["subscriptions","plans","billing","pricing","limits","grace-period"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Subscriptions. UptimeWarden Docs","metaDescription":"Pricing, limits, and feature rules for the five UptimeWarden plans, plus add-on packs and the 7-day grace period.","icon":"CreditCard","createdAt":"2026-10-12T22:06:41.608Z","updatedAt":"2026-10-12T22:06:41.608Z","publishedAt":"2026-10-12T22:06:41.608Z"},{"publicId":"01M4S2EP5N0EDT7CJG0Y576GY1","locale":"en","translationGroup":"invoicing","slug":"invoicing","title":"Invoicing","description":"Your payment history, billing profile, currency handling, and the refund flow.","body":"# Invoicing\n\nUptimeWarden charges subscription renewals, plan upgrades, and add-on pack purchases through our secure payment provider. This page explains where to see your payment records, how to keep your billing profile, how currency works, and how refunds flow back.\n\n> Looking for plan prices instead? See [Subscription Plans](/docs/subscription-plans). For purchasing extra capacity, see [Add-on Purchase](/docs/addon-purchase).\n\n## Payment history\n\nEvery successful charge creates a payment record. You can view your payment history from the billing section of the dashboard, and fetch it programmatically (paginated) from `GET /api/payments/history`. Each record includes the amount, currency, date, and transaction status.\n\nFor the details of a single transaction, use `GET /api/payments/transaction/:id`.\n\n## Billing profile\n\nYou keep your billing details under **Settings → Billing**. You can choose an individual or corporate profile; corporate accounts can fill in fields such as tax number, tax office, and country. This information stays attached to your account and is used for your payments.\n\n## Currency and exchange rates\n\nPlans and add-ons are priced in **USD**, but charges are settled in **Turkish Lira (TRY)**. The conversion is performed at payment time using the current market exchange rate. So the USD amount you see on the plan page is converted to TRY at that day's rate when the charge is captured.\n\n## Plan changes and pro-ration\n\n- **Upgrade**: when you upgrade mid-cycle, a prorated difference for the remaining days of the current period is charged immediately.\n- **Downgrade**: not pro-rated and does not produce an immediate refund. Your existing tier runs to the end of the cycle, and the cheaper plan starts on the next renewal. (A downgrade is allowed only if your current usage fits within the target plan's limits.)\n\n## Refunds\n\nRefunds are processed through our secure payment provider and run through the cancellation policy. The system automatically selects the most favorable option for your account:\n\n- **30-day money-back guarantee**: for first-time subscribers, a full refund within 30 days of the original charge.\n- **14-day withdrawal**: for returning subscribers (those who previously cancelled).\n- **End-of-period cancellation**: for all customers; the subscription downgrades to Free at the end of the period.\n\nFor refund or cancellation requests, contact billing support at **[support@uptimewarden.online](mailto:support@uptimewarden.online)**. Approved refunds are sent to the original payment method, and funds typically settle in a few business days depending on your bank.\n\n## Failed payments\n\nIf a recurring charge fails, your subscription is not closed immediately. A **7-day** grace period applies, during which the payment is retried several times. If payment still cannot be collected by the end of that window, the subscription downgrades to Free.\n\n## Coming soon\n\nFormal invoice (PDF) generation, sequential invoice numbers, e-Fatura / e-Arşiv integration, and KDV/VAT breakdowns are **not currently part of the product**, these are planned roadmap features. For now, for legal invoicing needs and special arrangements (such as wire-transfer payment on enterprise contracts), contact **[support@uptimewarden.online](mailto:support@uptimewarden.online)**, or **[sales@uptimewarden.online](mailto:sales@uptimewarden.online)** for Enterprise.\n\n## Related\n\n- [Subscription Plans](/docs/subscription-plans): base prices per tier\n- [Add-on Purchase](/docs/addon-purchase): extra monitors and channels\n- [Frequently Asked Questions](/docs/frequently-asked-questions): billing FAQ entries","category":"billing","tags":["invoicing","payment history","refund","billing"],"order":20,"parentSlug":"subscriptions","published":true,"version":1,"metaTitle":"Invoicing. UptimeWarden Documentation","metaDescription":"Everything about UptimeWarden billing, payment history, billing profile, currency, and refund processing.","icon":"CreditCard","createdAt":"2026-10-12T22:06:41.845Z","updatedAt":"2026-10-12T22:06:41.845Z","publishedAt":"2026-10-12T22:06:41.845Z"},{"publicId":"01M4S2EP5V1390V306ZV3MRSKP","locale":"en","translationGroup":"addon-purchase","slug":"addon-purchase","title":"Add-on Purchase","description":"Buy extra monitors, notification quota, agents, or AI packs without changing your plan. Pricing, billing cycle, and cancellation rules.","body":"# Add-on Purchase\n\nSometimes the plan you are on is exactly right except for one number. Maybe you need 25 more monitors or another 50 SMS each month. **Add-on packs** solve that without forcing a full plan upgrade.\n\n> Add-on packs sit on top of your plan; they do not replace it. Your effective limit is the plan's allowance plus everything your active add-on packs add.\n\n## How it works\n\nEach pack increases the allowance for one type of resource, monitors, agents, SMS, WhatsApp messages, voice calls, AI health predictions, or AI security scans, and renews on its own billing cycle. Your effective limit is calculated live from your plan plus every active pack.\n\n## Where to buy\n\nOpen **Settings → Billing → Add-ons**. The catalogue shows every pack your account is eligible for. Some packs require a minimum plan tier, see *Eligibility* below.\n\nFor each pack you see:\n\n- A short description in English and Turkish.\n- The resource it adds (for example, \"extra monitors\") and the quantity.\n- Price, currency, and billing cycle (monthly, yearly, or one-time).\n- A *Popular*, *Best value*, or *New* badge when applicable.\n- A *Buy* button, or *Manage* if you already own one.\n\n## Pack types\n\nThe catalogue is updated centrally, what you see on the dashboard is always current. Common categories:\n\n| Category | What it adds | Billing cycle |\n| --- | --- | --- |\n| **Monitor packs** | +5 / +10 / +25 active monitors | Monthly |\n| **SMS packs** | +10 / +50 / +200 SMS per month | Monthly |\n| **WhatsApp packs** | +10 / +50 / +100 WhatsApp messages | Monthly |\n| **Voice packs** | +5 / +20 / +50 voice calls | Monthly |\n| **Agent packs** | +1 / +3 / +5 self-hosted agents | Monthly |\n| **AI prediction packs** | +50 / +200 health predictions | Monthly |\n| **AI security scan packs** | +25 / +100 security scans | Monthly |\n\nThe dashboard shows each pack's current price.\n\n## Eligibility\n\nSome packs require a minimum plan tier. For example:\n\n- The smaller SMS and WhatsApp packs (+10 / +50 SMS, +10 / +50 WhatsApp) are available on all plans; the largest SMS (+200) and WhatsApp (+100) packs require Starter or above.\n- Voice packs require Starter or above; the largest pack (+50) requires Professional.\n- Agent packs, AI prediction packs, and AI security scan packs require Professional or higher.\n\nWhen a pack is locked, the *Buy* button shows *Upgrade required* and links to the matching plan.\n\n## Pricing and pro-ration\n\nWhen you buy mid-cycle, billing works like this:\n\n- **First charge**: the full pack price, taken from your saved card when you buy. The pack runs for one billing cycle from that moment, not from your plan's renewal date.\n- **Renewals**: full price on the cycle anniversary.\n- **Stacking**: packs that allow it can be bought multiple times; quantities add up.\n\nExample: buying a 50-SMS pack on day 12 of a 30-day cycle charges you for 18 of 30 days. The next renewal on day 30 charges the full price for the next 30 days.\n\n## Activation timing\n\nAdd-ons activate **immediately**. Your next monitor or notification sees the new effective limit, there is no waiting for the next billing cycle.\n\n```text\nBefore:  50 of 50 monitors used → creating a new monitor fails (limit reached)\nBuy +25 monitor pack\nAfter:   50 of 75 monitors used → next monitor creates successfully\n```\n\n## Removing an add-on\n\nWhat happens depends on when you cancel and whether the pack has been used:\n\n- **Within 24 hours of purchase and unused**: the add-on ends immediately and the full price goes back to the card you paid with. \"Unused\" means nothing has been drawn from the pack: no SMS, WhatsApp or voice message sent after buying a notification pack, no monitor or agent created after buying a monitor or agent pack, no AI spend after buying an AI credit pack.\n- **Anything else**: the add-on stays active until the **end of the current billing period**, so you keep what you paid for, and it does not renew.\n\nRefunds outside that window are handled by [support](mailto:support@uptimewarden.online).\n\nIf your usage exceeds the new effective limit when the pack ends, monitor creation or notification dispatch is paused on that resource until you reduce usage or buy again. When a notification quota runs out, the account owner gets one notice email for that quota per billing period. No earlier warning email is sent as you approach the limit, so keep an eye on remaining quota on the **Usage** page.\n\n## How notification quotas are consumed\n\nNotification packs (SMS, WhatsApp, voice) **stack monthly with your plan's allowance**. Only successfully delivered messages count, failed messages do not consume your quota.\n\nThe order of consumption is:\n\n1. Plan allowance.\n2. Add-on packs, oldest purchase first.\n\nWhen all your SMS quota is exhausted, the next notification on that channel is **skipped** (it is not re-routed to another channel); your other channels keep sending unaffected (see [Subscription Plans](/docs/subscription-plans) → Notification usage). The dashboard's **Usage** page shows live remaining quota per channel.\n\n## Custom packs\n\nEnterprise and managed-services accounts can request custom packs (for example, \"+250 monitors at a discount\"). These do not appear in the public catalogue but show up in your *Owned* list once assigned. Talk to sales.\n\n## Programmatic access\n\nAdd-on management is currently dashboard-only; programmatic listing and purchase are on the roadmap. Your current effective-limit snapshot is available through the account limits endpoint when your plan includes API access, so automation can read your real-time capacity.\n\n## Related\n\n- [Subscription Plans](/docs/subscription-plans): plan allowances before add-ons\n- [Invoicing](/docs/invoicing): payment history, currency, and the refund flow\n- [Frequently Asked Questions](/docs/frequently-asked-questions): common add-on questions","category":"billing","tags":["addons","monitors","notifications","agents","billing"],"order":30,"parentSlug":"subscriptions","published":true,"version":1,"metaTitle":"Add-on Purchase. UptimeWarden Documentation","metaDescription":"Extend your UptimeWarden plan with add-on packs, extra monitors, SMS / WhatsApp / voice quota, agents, and AI packs. Stackable, instant, cancel any time.","icon":"CreditCard","createdAt":"2026-10-12T22:06:41.852Z","updatedAt":"2026-10-12T22:06:41.852Z","publishedAt":"2026-10-12T22:06:41.852Z"},{"publicId":"01KJ7Q9ZTVVPBF4GKKT40722R5","locale":"en","translationGroup":"status-page-creation","slug":"en-creating-status-page","title":"Creating and Managing Status Pages","description":"Guide to creating, customizing, and managing public status pages with UptimeWarden","body":"# Creating and Managing Status Pages\n\nStatus pages allow you to transparently display your service status to customers and team members. With UptimeWarden, you can create a professional status page in minutes.\n\n## What is a Status Page?\n\nA status page is a **publicly accessible** page showing the real-time status of your monitored services. Your customers can visit this page to:\n\n- See the current status of your services\n- Review ongoing or past incidents\n- Subscribe to status updates via email\n\n## Creating a Status Page\n\n### 1. New Status Page\n\nGo to the **Status Pages** menu and click the **\"New Status Page\"** button.\n\nFill in the following information:\n\n| Field | Description | Example |\n|-------|-------------|---------|\n| **Page Name** | Status page title | \"Acme Service Status\" |\n| **Slug** | Short name used in the URL | \"acme-status\" |\n| **Description** | Page description (optional) | \"Live status of Acme services\" |\n\n### 2. Adding Monitors\n\nAdd the monitors you want to display on the status page:\n\n- **Monitor selection**: Choose from your existing monitors\n- **Display name**: Define how the monitor appears on the status page (e.g., \"Main Site\" instead of \"Website\")\n- **Ordering**: Arrange the display order of monitors\n\n### 3. Monitor Grouping\n\nYou can create logical groups on the status page by assigning **group names** to monitors. Enter a group name for each monitor (e.g., \"Web Services\", \"API Services\") and monitors with the same group name will be displayed together.\n\n## Status Page Appearance\n\n### Status Indicators\n\n| Status | Color | Description |\n|--------|-------|-------------|\n| **Operational** | 🟢 Green | All services running smoothly |\n| **Degraded Performance** | 🟡 Yellow | Service running but with reduced performance |\n| **Partial Outage** | 🟠 Orange | Some parts of the service are affected |\n| **Major Outage** | 🔴 Red | Service is completely down |\n| **Maintenance** | 🔵 Blue | Scheduled maintenance in progress |\n\n### Uptime History\n\nThe status page visually displays uptime history for up to the last 90 days. For each day:\n- Green bar: No issues\n- Red bar: Outage occurred\n- Gray bar: No data available\n\n## Incident Management\n\nYou can create manual incidents on the status page. Automatic outages from monitors are also displayed.\n\n### Incident Severity Levels\n\n- **Maintenance**: Scheduled maintenance\n- **Minor**: Small impact\n- **Major**: Large impact\n- **Critical**: Critical outage\n\n### Incident Statuses\n\n- **Investigating**: Issue detected, being investigated\n- **Identified**: Root cause identified\n- **Monitoring**: Fix applied, being monitored\n- **Resolved**: Issue resolved\n\n## Subscriber Management\n\n### Email Subscription\n\nIf the **\"Allow Subscriptions\"** option is enabled in status page settings, visitors can subscribe to status updates by entering their email address.\n\nAfter email verification, subscribers can:\n\n- Choose to receive incident notifications\n- Choose to receive maintenance notifications\n- Unsubscribe at any time\n\n## Customization\n\n### Appearance Settings\n\nIn the **Appearance** step of the status page creation form:\n\n- **Logo URL**: Add your company logo\n- **Favicon URL**: Browser tab icon\n- **Primary color**: Brand-appropriate primary color\n- **Background color**: Page background\n- **Text color**: Font color\n- **Dark mode**: Dark theme\n- **Custom CSS**: Fully customized styling\n\n### Features\n\n- **Subscriptions**: Allow visitors to subscribe via email\n- **Show history**: Display uptime history (1-365 days)\n- **Show response time**: Display response time metrics\n- **Show uptime**: Display uptime percentage\n\n### Security\n\n- **Password protection**: Require a password to access the status page\n- **Custom HTML/JavaScript**: Add tracking code or custom widgets\n\n## Best Practices\n\n1. **Create early**: Prepare your status page before an outage occurs\n2. **Add all critical services**: Include every service your users depend on\n3. **Use meaningful names**: Set monitor display names in terms your customers understand\n4. **Keep subscriptions active**: Let your customers be informed about outages\n5. **Keep it simple**: Avoid technical jargon — write in language your users understand","category":"status-pages","tags":["status-page","public","uptime","communication","subscribers"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Guide to creating, customizing, and managing public status pages with UptimeWarden","icon":"Globe","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EP6MYKT74ZN2ZB97SV6G","locale":"en","translationGroup":"status-page-creation","slug":"creating-status-page","title":"Creating a Status Page","description":"End-to-end status page setup, name, theme, services, visibility, subscribers, custom domain, and incident posting.","body":"# Creating a Status Page\n\nA status page is the public surface where your customers see whether your services are up. UptimeWarden status pages are real-time, brandable, and can run on your own subdomain. This walkthrough takes you from \"I have monitors\" to \"customers can see them\" in a single sitting.\n\n> Already have a page and just want a custom domain? Skip to [Custom Domain Setup](/docs/custom-domain-setup). Want visitors to subscribe by email? See [Status Page Subscribers](/docs/status-page-subscribers).\n\n## Step 1. Create the page\n\n1. Open **Status Pages → New status page**.\n2. Fill in:\n   - **Name**: internal label.\n   - **Title**: public heading shown at the top of the page.\n   - **Slug**: appears in the default URL `app.uptimewarden.online/status/<slug>`.\n   - **Description**: short tagline shown above the timeline.\n   - **Logo**: square image, 512×512 recommended.\n3. Click **Create**.\n\nThe page is live at the default URL the moment you mark it public. Empty pages render a \"No services yet\" placeholder until you attach monitors.\n\nHow many pages you can create depends on your plan: Free 1, Hobby 2, Starter 3, Professional 10, Enterprise unlimited. At the limit, creating another page is refused. Pages you already have above the limit, for example after a downgrade, keep working and stay published.\n\n## Step 2. Pick a theme\n\nOpen **Status Page → [page] → Branding** to control the visual identity. The available customization fields are:\n\n| Setting | Effect |\n| --- | --- |\n| **Primary color** (`primaryColor`) | Accent for headings, badges, links. Default `#3b82f6`. |\n| **Background color** (`backgroundColor`) | Page background. Default `#0f172a` (dark navy). |\n| **Text color** (`textColor`) | Body text. Default `#1f2937`. |\n| **Dark mode** (`darkMode`) | Toggle to flip the default light palette. |\n| **Custom CSS** (`customCss`) | Free-form CSS injected into the page for fine-grained tweaks. |\n| **Logo / Favicon URL** | Hosted image URLs (must be HTTPS). |\n\nYou can also add custom `<meta>` tags (for OpenGraph, Twitter cards, etc.) and free-form HTML in a dedicated content slot. When your organization has saved white-label branding (Enterprise plans), the public page renders an organization footer with a support contact and an \"Operated by [your brand]\" line; without branding, no footer is shown.\n\n## Step 3. Attach services\n\nA status page is a curated view of your monitors, not all of them. Open **Status Page → [page] → Services**:\n\n1. Click **Add service**.\n2. Pick a **group name** (e.g. *API*, *Dashboard*, *Database*), services are visually grouped by this label.\n3. Select a monitor to back this service.\n4. Set a **display name** to override the monitor's internal name on the public page (optional).\n5. Choose a **display order** to control where this row appears.\n6. Save.\n\nEach monitor's latest result drives the displayed status: up → green/operational, down → red/outage, missing data → unknown.\n\n:::tip Keep services customer-facing\nCustomers don't care that you split *API gateway* into *us-east* and *eu-west* monitors, they care that *API* is up. Group accordingly.\n:::\n\n## Step 4. Visibility\n\nOpen **Status Page → [page] → Settings → Visibility**:\n\n| Mode | Who can see it |\n| --- | --- |\n| **Public** | Anyone with the URL. |\n| **Password-protected** | Public URL, but visitors must enter a shared password. The password is stored securely, never in plain text. |\n| **Private** | Disabled for public traffic, only shows up in the owner's dashboard. |\n\nWhen the page is private, both the slug-based URL and any custom domain return a 403. Private mode is the right call for staging or pre-launch pages.\n\n## Step 5. Subscribers (optional)\n\nIf subscriptions are enabled on the page, the public site renders a **Subscribe** button so visitors can opt in to email notifications when incidents are posted. Each new subscriber is created in an unverified state and receives a one-time link to confirm their email; they also get a one-click unsubscribe link.\n\nSubscriber notifications are live: a verification email is sent at sign-up, and verified subscribers receive incident and maintenance emails for the services on the page. See [Status Page Subscribers](/docs/status-page-subscribers) for the full lifecycle.\n\n## Step 6. Custom domain (optional)\n\nReplace `app.uptimewarden.online/status/acme` with `status.acme.com`:\n\n1. Open **Status Page → [page] → Custom Domain** and enter your domain. It must be at least a third-level subdomain (e.g. `status.acme.com`); apex domains like `acme.com` are not supported.\n2. UptimeWarden generates a verification token and shows you the TXT record to add at your DNS provider.\n3. Add the TXT record, then click **Verify Domain** in the dashboard.\n\nCustom domains are available on Professional and Enterprise plans. Full walkthrough: [Custom Domain Setup](/docs/custom-domain-setup).\n\n## Step 7. Custom incidents\n\nWhen something breaks (or you're pre-announcing a known issue), post a custom incident from **Status Page → [page] → Incidents → New incident**:\n\n| Field | Notes |\n| --- | --- |\n| **Title** | One line, customer-facing, *Elevated error rates on API*. |\n| **Description** | Full markdown body. |\n| **Severity** | `maintenance`, `minor`, `major`, or `critical`. |\n| **Status** | `investigating` → `identified` → `monitoring` → `resolved`. |\n| **Affected services** | Optional list of services on the page that are impacted. |\n| **Updates** | Append-only timeline you post as the situation evolves, each entry carries a message, status, and timestamp. |\n\nThe incident and update composers may show a **Draft with AI** button: our AI engine drafts calm, non-technical customer-facing copy that matches the incident's phase and severity; you edit and publish it yourself. A draft is never published on its own; the button is available when your plan includes status page drafts and you have granted AI processing consent in your profile, and it draws on your account's monthly AI credits. When it cannot run, the button says why and what to do next.\n\nIncidents you post manually live alongside automatic incidents created when a monitor goes down, both render on the page in the same timeline.\n\n## Which incidents the page lists\n\nA status page does not always show its services' system incidents the same way; it is a page setting. In edit mode, **Incidents from your monitors** offers three choices:\n\n| Choice | What a visitor sees |\n| --- | --- |\n| **None** | Only incidents you post on the page. Your services' system incidents are not listed. |\n| **Outages** *(default)* | Incidents you post + \"down\" incidents lasting longer than the minimum you set. |\n| **All** | Incidents you post + every public monitor incident, SSL and slow-response incidents included. |\n\nWith **Outages** you set a minimum length (5 minutes by default, 0–1440): outages shorter than that never enter the incident list, so the page does not read as \"always broken\". The minimum applies to the page's incident list only, not to subscriber emails: see [Status Page Subscribers](/docs/status-page-subscribers).\n\nIncidents you post on the page always show. When you lose access to a monitor (a team share is removed, or you leave the team), that monitor is removed from the page; its status, uptime and incidents are no longer public.\n\n## The uptime a visitor sees\n\nVisitors see uptime per service for the period they pick: the period selector offers 1, 7, 15, 30 and 90 days, and times are shown in the visitor's own time zone.\n\nThe display rule is strict: **\"100\" is printed only when the value really is 100**. Anything below is cut to two decimals, never rounded up, with trailing zeros dropped (99.97 → 99.97, 99.996 → 99.99, 99.7 → 99.7). An outage can therefore never read as \"100%\".\n\nWhen the selected period holds no checks at all (a paused monitor, or one added moments ago) the page shows **—** instead of a number: that means \"no reading\", not \"perfect\".\n\n## Going-live checklist\n\n- [ ] Title, description, and logo set.\n- [ ] Services attached and grouped.\n- [ ] Visibility set correctly; password configured if you want a soft gate.\n- [ ] Subscriptions enabled if you plan to use the subscriber list.\n- [ ] Custom domain verified (if using).\n- [ ] First test incident posted, then moved to `resolved` (proves the flow).\n- [ ] History window set to a sensible range.\n\n## Related\n\n- [Custom Domain Setup](/docs/custom-domain-setup), `status.acme.com` end-to-end\n- [Status Page Subscribers](/docs/status-page-subscribers): email subscription lifecycle\n- [White-Label Branding](/docs/white-label-branding): Enterprise full rebrand\n- [Subscription Plans](/docs/subscription-plans): what each tier unlocks for status pages","category":"status-pages","tags":["status-page","creation","theme","subscribers","custom-domain","incidents"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Creating a Status Page. UptimeWarden Documentation","metaDescription":"Build an UptimeWarden status page from scratch, pick a theme, attach services, set visibility, gather subscribers, and post incidents.","icon":"Globe","createdAt":"2026-10-12T22:06:41.876Z","updatedAt":"2026-10-12T22:06:41.876Z","publishedAt":"2026-10-12T22:06:41.876Z"},{"publicId":"01M4S2EPCBKB6STTNMYSN8302G","locale":"en","translationGroup":"status-page-subscribers","slug":"status-page-subscribers","title":"Status Page Subscribers","description":"Let visitors to your public status page subscribe by email, sign-up flow, double opt-in tokens, and one-click unsubscribe.","body":"# Status Page Subscribers\n\nYour public status page tells everyone who visits *today* whether things are working. Most users don't actually check. Subscribers get the signal pushed to them by email when something breaks. This page covers the data model, the sign-up form, verification, email delivery, and the unsubscribe flow.\n\n:::info Double opt-in is enforced\nA subscriber only receives incident and maintenance emails after clicking the verification link sent at sign-up. Unverified rows are stored but never emailed.\n:::\n\n## What a subscriber looks like\n\nEach status page keeps its own subscriber list. Every subscriber row carries:\n\n- **Email**: unique per page. Stored verbatim and normalized to lowercase.\n- **Verification status**: flipped to verified when the visitor clicks the verification link (double opt-in).\n- **Verification token**: a random 48-character token sent in the verification email. Cleared once verified.\n- **Unsubscribe token**: a random 48-character token included in every notification. Powers one-click unsubscribe.\n- **Incident opt-in**: receive incident open/update/resolve notifications.\n- **Maintenance opt-in**: receive scheduled maintenance start/end notifications.\n- **Subscribed services**: optional filter; an empty list means \"all services on this page.\"\n- **Sign-up and unsubscribe timestamps**: lifecycle audit trail.\n\nThe page owner controls whether subscriptions are even possible by toggling **Allow subscriptions** on the page.\n\n## Subscribing\n\nOn a public status page with subscriptions enabled, the **Subscribe** button opens a small form:\n\n1. Email address.\n2. Optional per-service selection, only services actually on the page can be selected; submitting an out-of-scope service is rejected.\n3. Incident / maintenance toggles (both default to on).\n4. Submit.\n\nThe endpoint:\n\n```http\nPOST /api/public/status/:slug/subscribe\nContent-Type: application/json\n{\n  \"email\": \"user@example.com\",\n  \"subscribeToIncidents\": true,\n  \"subscribeToMaintenance\": true,\n  \"monitorPublicIds\": [\"01HX...\"]\n}\n```\n\nWhat happens server-side:\n\n- The page is looked up by slug; subscriptions must be enabled on it.\n- The email is lowercased and trimmed.\n- Each service is resolved against the page's service list: out-of-scope services fail the request.\n- A new subscriber row is created with fresh verification and unsubscribe tokens.\n- Duplicate subscribes are friendly: re-subscribing with the same email returns 200 with `\"This email is already subscribed to this status page.\"` instead of failing, safe to call repeatedly.\n\nThe endpoint responds with `Subscription successful. Please check your email to verify.` A verification email is sent right away; until the visitor clicks the link, the row stays unverified and receives no notifications.\n\n## Verifying\n\nThe verification email carries a link of the form:\n\n```text\nhttps://status.acme.com/verify?token=<verification-token>\n```\n\nThe frontend calls:\n\n```http\nGET /api/public/status/subscribe/verify?token=<verification-token>\n```\n\nThat endpoint flips the row to verified and stamps the verification timestamp. Invalid tokens return 404.\n\n## Unsubscribing\n\nEvery notification email includes a one-click unsubscribe link backed by the per-row unsubscribe token:\n\n```http\nPOST /api/public/status/subscribe/unsubscribe\nContent-Type: application/json\n{ \"token\": \"<unsubscribe-token>\" }\n```\n\nA backwards-compatible alias also exists at `POST /api/public/status/unsubscribe`.\n\nThe endpoint stamps the unsubscribe timestamp and the row stops receiving any future notifications. Tokens are single-purpose, they don't authenticate the user for anything else.\n\n## Sending rules\n\nSubscribers receive an email when:\n\n- A system incident the page's **Incidents from your monitors** setting lists opens or resolves. With the page set to **None**, monitor incidents send no subscriber email; incidents and updates you post on the page always do.\n- A custom incident on the page is created or updated (announcements posted with the `maintenance` severity go to maintenance subscribers; all other severities go to incident subscribers).\n\nFor each qualifying subscriber, delivery:\n\n- Skips the row if it has been unsubscribed.\n- Skips the row if it hasn't been verified yet (double opt-in).\n- Skips the row if the change is on a service not in the subscriber's filter (when one is set).\n- Sends via email: the only subscriber channel today.\n\nSubscriber emails are written for an external audience: they state the affected service, the human-readable status, and the time. They never include operator internals such as raw monitor URLs, status codes, or error strings.\n\n## Admin view (coming soon)\n\nA dedicated subscriber-management view is not live yet. Once it ships, it is expected to list each subscriber row with:\n\n- Email, verification state, service filter, and sign-up date.\n- Filters by verified / unverified, by service filter, by sign-up date.\n- Manual remove for abuse or bounce reasons.\n- Bulk export to CSV.\n\nFor now, subscribers are persisted and emailed automatically, but there is no dashboard screen that lists or manages them.\n\n## Roadmap\n\n- **SMS / WhatsApp subscribers**: additional opt-in channels for critical-infrastructure pages, gated by plan notification quotas.\n- **Digest mode**: weekly summary instead of per-incident for low-activity pages.\n- **Bulk CSV import / export**: for migrating from another status page provider.\n- **Subscriber management dashboard**: see above.\n\n## FAQ\n\n**Q: A visitor subscribed but reports they aren't getting emails.**\nA: Check, in order: (1) they clicked the verification link, unverified subscribers receive nothing; (2) the email isn't in their spam folder; (3) they haven't unsubscribed; (4) the affected service is on the status page and inside their service filter, if they set one.\n\n**Q: Can I filter per-service on my end, not the subscriber's?**\nA: Yes, hide services from the public page by simply not adding them via **Status Page → Services**. A hidden service doesn't appear to subscribers and can't be selected during sign-up.\n\n**Q: Do subscribers count against my notification quota?**\nA: No, status-page subscriber emails are delivered separately and do not consume your per-user notification quota.\n\n## Related\n\n- [Creating a Status Page](/docs/creating-status-page): full setup walkthrough including the **Allow subscriptions** toggle\n- [Custom Domain Setup](/docs/custom-domain-setup): host the page on `status.acme.com` so verification links match your brand\n- [Subscription Plans](/docs/subscription-plans): notification quotas and channel availability per tier\n- [Notifications Overview](/docs/notifications-overview): how the broader notification engine works","category":"status-pages","tags":["status-pages","subscribers","email","incidents","double-opt-in"],"order":20,"parentSlug":null,"published":true,"version":1,"metaTitle":"Status Page Subscribers. UptimeWarden Documentation","metaDescription":"Email subscription flow for status pages, verification token model, per-monitor filtering, and one-click unsubscribe.","icon":"Globe","createdAt":"2026-10-12T22:06:42.059Z","updatedAt":"2026-10-12T22:06:42.059Z","publishedAt":"2026-10-12T22:06:42.059Z"},{"publicId":"01M4S2EPCR5052BS4BZ7XMZXBZ","locale":"en","translationGroup":"custom-domain-setup","slug":"custom-domain-setup","title":"Custom Domain Setup","description":"Map your status page to a domain you own (e.g. status.acme.com) using a TXT verification record. Served over HTTP.","body":"# Custom Domain Setup\n\nEvery public status page is served by default at `https://app.uptimewarden.online/status/<slug>`. If you want the page to live under your own brand URL, you can map a subdomain you own (for example `status.acme.com`) to your status page.\n\nThe result: visitors hit `http://status.acme.com`, see your monitors, incident history, and brand.\n\n:::info Served over HTTP\nCustom domains are served over **HTTP**. This is the operator's deliberate choice, we do not maintain per-customer TLS certificates. A status page carries no credentials, so HTTP is fine for it. UptimeWarden's own surfaces (`app.uptimewarden.online`) continue to run over TLS as always.\n:::\n\n## Requirements\n\n- A subdomain you control on a domain you own; the recommended pattern is `status.<your-domain>`. The hostname must be at least a third-level subdomain (bare apex domains like `acme.com` are not supported).\n- Access to your DNS provider (Cloudflare, Route 53, GoDaddy, Namecheap: whichever you use).\n- An existing status page in UptimeWarden.\n\n## Flow at a glance\n\nFour steps:\n\n1. **Add the domain to your status page**. UptimeWarden issues a unique verification token.\n2. **Add a TXT verification record to your DNS**, proves the domain is yours.\n3. **Click \"Verify Domain\"**. UptimeWarden checks your DNS for the TXT record live and records the outcome.\n4. **Add an A or CNAME record in your DNS**, routes traffic to UptimeWarden.\n\nThe moment step 3 succeeds, requests to `http://status.acme.com` start reaching your status page.\n\n## How verification works\n\nUptimeWarden uses TXT-record-based ownership verification. When you attach a domain to a status page, a unique token is generated and you are asked to publish it as a TXT record:\n\n| Field | Value |\n| --- | --- |\n| Type | `TXT` |\n| Host / Name | `_uptimewarden-verify.<your-domain>` |\n| Value | `uptimewarden-site-verification=<token>` |\n| TTL | `300` (5 minutes) |\n\nThe token is unique per status page. If you change the domain, the token is regenerated; the old TXT record becomes invalid and you must publish the new one.\n\n## Step 1. Add the custom domain\n\n1. Open **Status Pages → [your page] → Custom Domain**.\n2. Enter the full subdomain (e.g. `status.acme.com`).\n3. Save. UptimeWarden generates the verification token and shows you the TXT record you need to publish.\n\nThe page moves to **Pending** and stays there until the TXT record is found.\n\n## Step 2. Add the TXT record\n\nOpen your DNS provider's panel and create the record exactly as shown. Most panels ask for these fields:\n\n- **Type:** `TXT`\n- **Host / Name:** `_uptimewarden-verify.status.acme.com` (some providers auto-append the parent domain, so `_uptimewarden-verify.status` may also work)\n- **Value:** `uptimewarden-site-verification=<token>`, paste as-is, no surrounding quotes\n- **TTL:** `300` (5 minutes); anything up to an hour is fine\n\nSome providers automatically add or strip quotes around TXT values. Paste it as shown in the panel; if verification fails due to a formatting issue, the panel will tell you the value the system actually saw.\n\n## Step 3. Verify\n\nOnce the TXT record is published (DNS propagation usually takes a few minutes), click **Verify Domain** in the panel. UptimeWarden checks your DNS for the TXT record at `_uptimewarden-verify.<domain>` live and records the outcome:\n\n| Status | Meaning |\n| --- | --- |\n| **Unconfigured** | No custom domain set yet. |\n| **Pending** | The TXT record hasn't been found yet. DNS may still be propagating, try again in a few minutes. |\n| **Verified** | The TXT record matched. The domain is now active and ready to receive traffic. |\n| **Failed** | A TXT record exists but the value doesn't match (or another DNS error occurred). Check the record and verify again. |\n\nYou can sanity-check the record from your terminal before clicking Verify:\n\n```bash filename=\"check-txt.sh\"\ndig TXT _uptimewarden-verify.status.acme.com +short\n# expected: \"uptimewarden-site-verification=<your-token>\"\n```\n\n## Step 4. Route traffic\n\nOnce the domain is verified, you need to add an A record (or CNAME) for `status.acme.com`. UptimeWarden provides the target value:\n\n- **A record:** the IP address UptimeWarden gives you.\n- **CNAME record:** a stable hostname UptimeWarden assigns to you (in some deployments).\n\nWhich one to use depends on the value UptimeWarden support gives you. The setup steps in the panel show the value explicitly.\n\nOnce DNS propagates, `http://status.acme.com` starts serving your status page.\n\n## What traffic the custom domain can carry\n\nRequests arriving on your custom domain pass through a security filter:\n\n- **Public** paths, `/`, `/assets/*`, `/api/public/status/*`, `/api/branding/public`, `/health/*`, pass through. The status page fetches its data through these.\n- Everything else (`/api/auth/*`, `/dashboard`, `/api/admin/*`, etc.) is **301-redirected** to `https://app.uptimewarden.online`. If a visitor tries to log in via the custom domain, they end up on UptimeWarden's TLS host, credentials never travel in plaintext over the custom domain.\n\n## Removing the custom domain\n\nOpen **Settings → Status Pages → [page] → Custom Domain → Remove**. The custom domain is cleared from the status page and the page reverts to `app.uptimewarden.online/status/<slug>` immediately. Your DNS records on the provider side become dead and harmless, delete them whenever you like.\n\n## Troubleshooting\n\n### Status stayed Pending after adding the TXT\n\nDNS hasn't propagated, or the host is misnamed. Check with `dig TXT _uptimewarden-verify.<domain> +short`. If the record doesn't appear, your DNS provider's UI may have appended the parent domain twice, drop the trailing `.<domain>` and save again.\n\n### Verification returns Failed\n\nThe TXT value doesn't match. Two common causes:\n\n1. The panel token was regenerated, every time you change the domain, the token is reissued. Copy the current value from the panel and paste it again.\n2. Your DNS provider auto-wrapped the value in quotes. Remove the quotes, or use the exact value shown in the panel.\n\n### `http://status.acme.com` returns 404\n\nThe domain hasn't reached **Verified + Mapped** state yet. Check the status in the Custom Domain panel; if it's **Pending** or **Failed**, redo Step 3. If verification succeeded but you still see 404, confirm your A/CNAME record points to the right IP / hostname.\n\n### The page opens over HTTP but HTTPS doesn't work\n\nCustom domains are HTTP-only; UptimeWarden does not issue TLS certificates for them. If you need HTTPS, put your custom domain behind a TLS-terminating CDN such as Cloudflare, visitors connect to the CDN over HTTPS and the CDN proxies HTTP to UptimeWarden.\n\n## Related topics\n\n- [Creating a Status Page](/docs/creating-status-page): full setup guide\n- [Status Page Subscribers](/docs/status-page-subscribers): let visitors subscribe to incident email\n- [White-Label Branding](/docs/white-label-branding): logo, colors, email envelope, footer, and custom CSS\n- [Subscription Plans](/docs/subscription-plans): which plan unlocks custom domain","category":"status-pages","tags":["status-page","custom-domain","dns","txt-record"],"order":30,"parentSlug":null,"published":true,"version":1,"metaTitle":"Custom Domain Setup. UptimeWarden Documentation","metaDescription":"Point status.acme.com at your UptimeWarden status page. TXT verification record, live DNS check, and serving over HTTP.","icon":"Globe","createdAt":"2026-10-12T22:06:42.073Z","updatedAt":"2026-10-12T22:06:42.073Z","publishedAt":"2026-10-12T22:06:42.073Z"},{"publicId":"01M4S2EPCJRJ7Z3PZZT0SZNR53","locale":"en","translationGroup":"embed-status-widget","slug":"embed-status-widget","title":"Embedding Status on Your Site","description":"Surface UptimeWarden status on your own site via the public JSON API today, a drop-in widget is on the roadmap.","body":"# Embedding Status on Your Site\n\nYou want the answer to \"is it up?\" right where customers already are, your homepage, your docs, or your app. UptimeWarden exposes a public, read-only JSON API so you can render an \"All systems operational\" badge or a full timeline on your own surfaces.\n\n:::info Drop-in script-tag widget on the roadmap\nA single-line `<script src=\"…\">` widget is on the roadmap but **not shipped yet**. Until it lands, the public status API below is the supported way to embed status on third-party sites.\n:::\n\n## The public status API\n\nEvery public status page exposes a JSON snapshot at:\n\n```http\nGET /api/public/status/:slug\n```\n\nWhere `:slug` is the slug you set when creating the page. No authentication is required for public pages. The same payload powers our in-product status page UI.\n\nExample:\n\n```bash\ncurl https://app.uptimewarden.online/api/public/status/acme-status | jq\n```\n\nResponse shape (abbreviated):\n\n```json\n{\n  \"page\": {\n    \"slug\": \"acme-status\",\n    \"domain\": \"status.acme.com\",\n    \"title\": \"Acme Status\",\n    \"description\": \"Live status for the Acme platform\",\n    \"logoUrl\": \"https://...\",\n    \"theme\": { \"primaryColor\": \"#3b82f6\", \"darkMode\": false },\n    \"allowSubscriptions\": true,\n    \"showHistory\": true,\n    \"historyDays\": 30\n  },\n  \"monitors\": [\n    {\n      \"monitor\": {\n        \"name\": \"API Gateway\",\n        \"type\": \"http\",\n        \"status\": \"up\",\n        \"responseTime\": 142,\n        \"uptime\": 100,\n        \"lastCheckedAt\": \"2026-04-27T08:30:00.000Z\"\n      }\n    }\n  ],\n  \"incidents\": [\n    {\n      \"title\": \"Elevated latency on API\",\n      \"severity\": \"minor\",\n      \"status\": \"monitoring\",\n      \"startedAt\": \"2026-04-27T07:15:00.000Z\",\n      \"updates\": [\n        { \"message\": \"Investigating root cause\", \"status\": \"investigating\", \"createdAt\": \"2026-04-27T07:15:00.000Z\" }\n      ]\n    }\n  ],\n  \"passwordProtected\": false\n}\n```\n\nThe endpoint is cached for 5 seconds (`Cache-Control: public, max-age=5`), so polling from the browser is safe and won't overload our servers.\n\n### Password-protected pages\n\nIf the page is password-protected, the endpoint returns `401` until you supply the password via the `x-status-page-password` header:\n\n```http\nGET /api/public/status/:slug\nx-status-page-password: <shared-password>\n```\n\n### Custom domains\n\nWhen the page is mapped to a verified custom domain, you can hit the domain resolver instead, useful when you don't want to hardcode the slug:\n\n```http\nGET /api/public/status/by-domain/current?domain=status.acme.com\n```\n\nThe resolver returns the same payload, but only after the domain has reached the verified state.\n\n## Building a badge yourself\n\nHere's a minimal React example that consumes the public API and renders a status badge:\n\n```tsx filename=\"StatusBadge.tsx\"\nimport { useEffect, useState } from 'react'\n\ntype Status = 'operational' | 'degraded' | 'outage' | 'unknown'\n\nfunction deriveOverallStatus(monitors: Array<{ monitor: { status: string } }>): Status {\n  if (!monitors.length) return 'unknown'\n  const states = monitors.map((m) => m.monitor.status)\n  if (states.every((s) => s === 'up')) return 'operational'\n  if (states.every((s) => s === 'down')) return 'outage'\n  return 'degraded'\n}\n\nexport function StatusBadge({ slug }: { slug: string }) {\n  const [status, setStatus] = useState<Status>('unknown')\n\n  useEffect(() => {\n    let cancelled = false\n    async function load() {\n      const res = await fetch(`https://app.uptimewarden.online/api/public/status/${slug}`)\n      if (!res.ok) return\n      const data = await res.json()\n      if (!cancelled) setStatus(deriveOverallStatus(data.monitors || []))\n    }\n    load()\n    const id = setInterval(load, 60_000)\n    return () => {\n      cancelled = true\n      clearInterval(id)\n    }\n  }, [slug])\n\n  const label = {\n    operational: 'All systems operational',\n    degraded: 'Partial degradation',\n    outage: 'Active outage',\n    unknown: 'Status unavailable',\n  }[status]\n\n  return (\n    <a\n      href={`https://app.uptimewarden.online/status/${slug}`}\n      data-status={status}\n      className=\"uw-status-badge\"\n    >\n      {label}\n    </a>\n  )\n}\n```\n\nAdd a small CSS file to color the badge by `data-status` (`operational` → green, `degraded` → amber, `outage` → red).\n\nThe same pattern works in plain JS, Vue, Svelte, or server-rendered HTML, it's just `fetch` plus a DOM update.\n\n## Per-monitor status trend\n\nIf you want to render a sparkline or last-N-days dots like the in-product page, fetch per-monitor history:\n\n```http\nGET /api/public/status/:slug/monitors/:monitorPublicId/status-trend?days=30\n```\n\nThe response is the same trend data the dashboard uses, cached for 5 minutes server-side.\n\n## Three states, three colors\n\nMost embeds collapse the page into one of three states, derived from the worst monitor:\n\n- **Operational** (green): every monitor is up.\n- **Degraded** (amber): at least one monitor is down but others are up, or a custom incident is open at `minor` or `major` severity.\n- **Outage** (red): every monitor is down, or a `critical`-severity incident is open.\n\nPer-monitor detail lives on the status page itself, the badge is just a summary.\n\n## Security and CORS\n\n- The public status API is read-only. There's no POST equivalent that mutates state.\n- CORS is open for the public endpoint: any origin may fetch it.\n- If the page is set to private, the endpoint returns `403`.\n- For password-protected pages, validation is per-request: the `x-status-page-password` header is the only way to authenticate (no cookie, no session).\n\n## Roadmap\n\n- **Drop-in script tag widget**: single-line `<script src=\"…\">` install, configurable via `data-*` attributes (theme, position, label).\n- **Inline timeline embed**: full incident history embedded as a component with no iframe.\n\nWhen these ship, this page will be updated with the official snippet.\n\n## Related\n\n- [Creating a Status Page](/docs/creating-status-page): full setup walkthrough\n- [Custom Domain Setup](/docs/custom-domain-setup): host the status page on `status.acme.com`\n- [Status Page Subscribers](/docs/status-page-subscribers): let visitors subscribe by email","category":"status-pages","tags":["status-page","embed","badge","public-api"],"order":40,"parentSlug":null,"published":true,"version":1,"metaTitle":"Embed Status. UptimeWarden Documentation","metaDescription":"Show UptimeWarden status on your own site using the public status JSON API. A packaged drop-in script tag widget is on the roadmap.","icon":"Globe","createdAt":"2026-10-12T22:06:42.066Z","updatedAt":"2026-10-12T22:06:42.066Z","publishedAt":"2026-10-12T22:06:42.066Z"},{"publicId":"01KJ7Q9ZTVFYPE02QY3YZWZQ5N","locale":"en","translationGroup":"team-management","slug":"en-team-management","title":"Team Management and Roles","description":"Guide to adding team members, assigning roles, and managing permissions in UptimeWarden","body":"# Team Management and Roles\n\nUptimeWarden provides powerful team management capabilities for collaborative work. Add team members, assign roles, and control what each member can see and do in detail.\n\n## Adding Team Members\n\n### Sending Invitations\n\n1. Go to the **Team Members** menu\n2. Click the **\"Invite Member\"** button\n3. Enter the invitee's **email address**\n4. Select a **role**\n5. Click the **\"Send Invite\"** button\n\nThe invited person is notified via email. They join your team when they accept the invitation.\n\n### Invitation Statuses\n\n| Status | Description |\n|--------|-------------|\n| **Pending** | Invitation sent, not yet accepted |\n| **Accepted** | Person accepted the invitation and joined the team |\n| **Expired** | Invitation not accepted within 7 days |\n\n> **Tip**: You can resend expired invitations.\n\n## Roles and Permissions\n\nUptimeWarden has predefined roles.\n\n### Default Roles\n\n#### Admin\n- Full access to all pages and operations\n- Manage team members\n- Billing and subscription management\n- Change system settings\n- Create, edit, and delete monitors\n- Incident management\n\n#### Editor\n- Create and edit monitors\n- Manage incidents\n- Modify notification settings\n- Status page updates\n- **Cannot**: Team management, billing, system settings\n\n#### Reader\n- View dashboard and monitors\n- Review incident history\n- View reports\n- **Cannot**: Make any changes\n\n### Customizing Role Permissions\n\nCustomize default role permissions from the **Settings → Role Permissions** page. Define separate `read`, `write`, `delete`, `admin` permissions for each role by resource (monitors, settings, teams, etc.).\n\n## Page Permissions\n\nControl which roles can access which pages from the **Settings → Page Permissions** page:\n\n| Page | Description |\n|------|-------------|\n| **Dashboard** | Main control panel |\n| **Monitors** | Monitor list and details |\n| **Incidents** | Outage management |\n| **Status Pages** | Status pages |\n| **AI Insights** | AI analysis and recommendations |\n| **Teams** | Team member management |\n| **Settings** | System and notification settings |\n| **Billing** | Billing and subscription |\n\n## Team Collaboration\n\n### Monitor Sharing\n\nAll team members can view or edit monitors based on their roles. Monitors are shared across the team — there are no private/personal monitors.\n\n### Incident Management\n\n- Any editor/admin can add updates to an incident\n- Incident resolution (resolve) can be done by all editors and admins\n- The activity log records who did what and when\n\n### Notification Preferences\n\nEach team member can independently set their own notification preferences:\n- Choose which channels to receive notifications from\n- Specify which monitors to receive notifications for\n- Define quiet hours\n\n## Activity Logs (Audit Logs)\n\nTrack team activities from the **Audit Logs** page:\n\n- Who created/modified/deleted which monitor\n- Who resolved which incident\n- Team member add/remove operations\n- Settings changes\n\nAudit logs can be filtered and searched within specific date ranges.\n\n## Tips\n\n1. **Have at least two admins**: Assign multiple admins to prevent account access issues\n2. **Principle of least privilege**: Give each member only the permissions they need\n3. **Review regularly**: Remove departed team members promptly\n4. **Customize role permissions**: Adjust default role permissions to fit your needs","category":"teams","tags":["teams","roles","permissions","collaboration","users"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Guide to adding team members, assigning roles, and managing permissions in UptimeWarden","icon":"Users","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EP6VRESYZ49B4B3FW1E5","locale":"en","translationGroup":"team-management","slug":"team-management","title":"Team Management","description":"Create teams, invite and manage members, share monitors, and set seat limits in UptimeWarden.","body":"# Team Management\n\nTeams are how UptimeWarden groups the people who share monitors, incidents, and a status page. This page covers the day-to-day mechanics: how a team comes into being, how to add or remove members, what makes a personal workspace different, and how seat limits map to your plan.\n\n> Looking for invite specifics? See [Invite Flow](/docs/invite-flow). For the role capability matrix, see [Roles and Permissions](/docs/roles-permissions). For visual customization, see [White-Label Branding](/docs/white-label-branding).\n\n## Personal workspace vs shared team\n\nEvery account starts with a **personal workspace**. It is your private context, solo monitors live there, and you are the only member. You do not need to set it up; it is created automatically the moment you sign up.\n\n**Shared teams** are created explicitly when you want to collaborate. Each shared team has its own name, its own member list, and its own collection of shared monitors. A single user can belong to many teams at once and switch between them from the sidebar.\n\n## Creating a team\n\nOpen **Settings → Team → New team**. Pick a name (1-100 characters), a **team URL code** (a short slug of lowercase letters, numbers, and hyphens, at least 3 characters and globally unique), and an optional short description, then confirm. The team is created instantly and you become its first **Admin**.\n\nNames must be unique within your account so people can recognize the team in the switcher. You can rename a team later without affecting members or shared monitors.\n\n## Viewing teams and members\n\nThe team list in **Settings → Team** shows every team you belong to, your role in each, and the current member count against the seat limit. Opening a team reveals its members, their roles, and the status of any pending invitations.\n\n## Inviting members\n\nOpen the team and choose **Invite member**. Enter an email address, pick a role (Admin, Editor, or Reader), and optionally add a short note that goes into the invitation email.\n\nWhat happens next depends on whether the person already has an UptimeWarden account:\n\n- **They already have an account**: they are added to the team immediately and receive a notification email letting them know.\n- **They are new to UptimeWarden**: they receive an invitation email with a link valid for 7 days. Opening the link lets them create an account and join the team in one step.\n\nOnly Admins can send invitations. See [Invite Flow](/docs/invite-flow) for the complete lifecycle, including resend and revoke.\n\n## Removing a member\n\nIn the member list, open the action menu next to the person and choose **Remove from team**. Removal is immediate. The person keeps their UptimeWarden account, their other team memberships, and any monitors they personally own, they simply lose access to this team's shared monitors and incidents.\n\nYou cannot remove yourself this way; that prevents accidental lockouts. If you want to leave a team you do not own, ask another Admin to remove you.\n\n## Changing a member's role\n\nAdmins can promote or demote any member from the action menu next to their name. Role changes take effect immediately. The valid roles are **Admin**, **Editor**, and **Reader**, see [Roles and Permissions](/docs/roles-permissions) for the full capability matrix.\n\n## Sharing monitors with a team\n\nMonitors are owned by a single user. Sharing a monitor with a team makes it visible to teammates and lets them act on it without transferring ownership.\n\nFrom any monitor's settings, open **Sharing**, pick the team, and choose whether the team gets read-only or edit access. Only the monitor's owner can share it with a team. Removing a monitor from a team can be done by any team Admin or Editor, not just the owner. Editors and Admins on the team can act on shared monitors; Readers can view them.\n\nA monitor can be shared with multiple teams at once, which is useful when one underlying service matters to several groups.\n\n> **Plan transparency:** A shared monitor is governed by its owner's subscription, plan-gated features (AI insights, SSL analysis, SLO…) follow the **owner's plan**, not each member's. The monitor detail page shows a \"Team shared · read only / can edit\" badge as a reminder. If the owner downgrades or leaves, shared monitors are affected for everyone.\n\n## Seat limits per plan\n\nEvery plan includes a maximum number of team members. The team creator counts toward the limit.\n\n| Plan         | Max team members |\n| ------------ | ---------------- |\n| Free         | 3                |\n| Hobby        | 3                |\n| Starter      | 5                |\n| Professional | 20               |\n| Enterprise   | Unlimited        |\n\nThe seat count shown against your plan is a guideline for the members each plan is intended to support; if you need more seats, remove a member or upgrade your plan.\n\n## Coming features\n\nA few flows you might expect are not available today and are tracked on the roadmap:\n\n- **Transferring account ownership**: there is no way to hand the account itself to another user yet.\n- **Deleting or archiving a team**: teams persist for the lifetime of the account.\n- **Suspending a member**: demote their role to Reader or remove them instead.\n- **Bulk member import (CSV)**: invitations are sent one address at a time today.\n\nIf your workflow depends on any of these, let us know, we prioritize roadmap work based on customer demand.\n\n## Related\n\n- [Invite Flow](/docs/invite-flow): the two invitation paths and edge cases\n- [Roles and Permissions](/docs/roles-permissions): the capability matrix\n- [White-Label Branding](/docs/white-label-branding): logo, colors, custom CSS\n- [Subscription Plans](/docs/subscription-plans): seat limits and feature tiers","category":"teams","tags":["team","members","workspace","collaboration","settings"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Team Management. UptimeWarden Documentation","metaDescription":"How UptimeWarden teams work: personal workspaces, shared teams, member management, monitor sharing, and seat limits per plan.","icon":"Users","createdAt":"2026-10-12T22:06:41.884Z","updatedAt":"2026-10-12T22:06:41.884Z","publishedAt":"2026-10-12T22:06:41.884Z"},{"publicId":"01M4S2EPD0TT63RJH7MHFXAADF","locale":"en","translationGroup":"invite-flow","slug":"invite-flow","title":"Invite Flow","description":"How an UptimeWarden team invitation works, silent add for existing users, accept link for new users.","body":"# Invite Flow\n\nA single **Invite member** action in UptimeWarden produces one of two outcomes depending on who is on the other side. People who already have an UptimeWarden account are added to the team silently and notified by email. Everyone else receives an invitation link that creates their account and team membership in a single step.\n\nThis page walks through both paths, the defaults that apply, and how to manage pending invitations.\n\n> For what each role actually does, see [Roles and Permissions](/docs/roles-permissions). For broader team mechanics, see [Team Management](/docs/team-management).\n\n## Sending an invitation\n\nOpen **Settings → Team**, choose the team, and click **Invite member**. You will be asked for:\n\n- **Email address**: the only required field.\n- **Role**: Admin, Editor, or Reader. Defaults to Reader, the safest choice for a new collaborator.\n- **Message**: an optional short note shown in the invitation email.\n\nOnly an Admin of the team can send invitations.\n\n## Path A, they already have an UptimeWarden account\n\nIf the email already belongs to an UptimeWarden user, they are added to the team immediately. There is no acceptance step. They receive a notification email letting them know you added them, and the new team appears in their sidebar switcher right away.\n\nIf the person is already a member of this team, the action is rejected with a clear error so you do not create duplicate memberships.\n\n## Path B, they are new to UptimeWarden\n\nIf the email does not match an existing user, UptimeWarden creates a secure, pending invitation and emails them a link in this form:\n\n```text\nhttps://app.uptimewarden.online/register?invitation=...&email=...\n```\n\nThe link is valid for **7 days**. When the recipient opens it, they land on the tabbed sign-in/sign-up page that collects their name and password (or routes them through Google or GitHub sign-in). On submit, their account is created and they join the team in a single step. The pending invitation is then marked as accepted.\n\nIf a pending invitation already exists for this email and team, sending again is rejected, use **Resend** instead.\n\n## Default role is Reader\n\nIf you do not pick a role, Reader is applied. Reader is the safest default for a fresh collaborator: full visibility, no write access. The picker is shown explicitly in the UI so most invitations land on the role you chose; the default exists as a guardrail.\n\nThe three roles are:\n\n- **Admin**: full team management.\n- **Editor**: creates and edits monitors, incidents, and status pages.\n- **Reader**: read-only.\n\n## Pending invitations\n\nThe team's **Pending invitations** list shows every invitation that has not yet been accepted: the recipient's email, the role you chose, the message, when it was sent, and when it expires. From here you can resend or cancel each pending invitation.\n\n## Resending an invitation\n\nIf the recipient lost the email or did not open it before it expired, click **Resend** on the pending invitation. UptimeWarden:\n\n- Extends the expiry by another 7 days from now.\n- Keeps the same invitation link, role, and message.\n- Sends a fresh email from the original inviter.\n\nOnly Admins can resend.\n\n## Revoking an invitation\n\nClick **Cancel** (the trash icon) next to a pending invitation to cancel it. The invitation is deleted outright; its link stops working immediately. If the recipient tries to open it afterwards, they see an \"invalid or expired invitation\" page. Only Admins can revoke.\n\n## What is not part of the invite flow today\n\nTo keep expectations grounded, a few patterns that are sometimes assumed are not implemented today:\n\n- No bulk import from a CSV file: invitations are sent one address at a time.\n- No domain allowlist enforced at invite time: you can invite any valid email address.\n- The invitation flow does not trigger a password reset: that is a separate, independent feature.\n\nIf any of these matter for your team, treat them as roadmap items.\n\n## Related\n\n- [Roles and Permissions](/docs/roles-permissions): what Admin, Editor, and Reader can do\n- [Team Management](/docs/team-management): full team lifecycle\n- [White-Label Branding](/docs/white-label-branding): customizing the invitation email\n- [Subscription Plans](/docs/subscription-plans): seat limits per plan","category":"teams","tags":["team","invite","onboarding","email","role"],"order":20,"parentSlug":null,"published":true,"version":1,"metaTitle":"Invite Flow. UptimeWarden Documentation","metaDescription":"Two invitation paths in UptimeWarden: existing users are added silently, new users get a 7-day accept link. Resend, revoke, and edge cases.","icon":"Users","createdAt":"2026-10-12T22:06:42.080Z","updatedAt":"2026-10-12T22:06:42.080Z","publishedAt":"2026-10-12T22:06:42.080Z"},{"publicId":"01M4S2EPD7A3NASPBN1Q47JVQC","locale":"en","translationGroup":"roles-permissions","slug":"roles-permissions","title":"Roles and Permissions","description":"The three UptimeWarden team roles. Admin, Editor, Reader, and what each one can and cannot do.","body":"# Roles and Permissions\n\nUptimeWarden has exactly three team roles: **Admin**, **Editor**, and **Reader**. Every member of every team carries one of these roles. New invitations default to Reader if the inviter does not pick a role.\n\n> Roles are independent of your subscription plan. Your plan governs **how many seats** you can fill (see [Subscription Plans](/docs/subscription-plans)) and which **features** are unlocked (see [Subscriptions Overview](/docs/subscriptions-overview)). Roles only govern who, within a given seat, is allowed to do what.\n\n## Three concepts on three different axes\n\nIt is easy to confuse three role-shaped things in UptimeWarden. They are unrelated:\n\n- **Team role**: Admin, Editor, or Reader. Controls actions inside a single team. The subject of this page.\n- **Plan tier**: Free, Hobby, Starter, Professional, or Enterprise. Controls which features and limits apply to your account.\n- **Internal staff access**: a separate concept used by Zenigma employees for staff-only support and admin pages. It does not apply to customer team membership.\n\nThere is no \"Owner\" team role and no \"Viewer\" team role. The only team roles are the three listed above.\n\n## Capability matrix\n\n| Capability                                  | Admin | Editor | Reader |\n| ------------------------------------------- | ----- | ------ | ------ |\n| View team, members, monitors, incidents     | Yes   | Yes    | Yes    |\n| Create or edit monitors                     | Yes   | Yes    | No     |\n| Delete monitors                             | Yes   | Yes    | No     |\n| Create or edit incidents                    | Yes   | Yes    | No     |\n| Create or edit status pages                 | Yes   | Yes    | No     |\n| Share or unshare a monitor with the team    | Yes   | Yes    | No     |\n| Invite a member                             | Yes   | No     | No     |\n| Remove a member                             | Yes   | No     | No     |\n| Change a member's role                      | Yes   | No     | No     |\n| Resend or revoke an invitation              | Yes   | No     | No     |\n| View pending invitations                    | Yes   | No     | No     |\n| Manage notification channels                | Yes   | Yes    | No     |\n| Configure white-label branding              | Yes   | No     | No     |\n| Manage billing and plan                     | Yes   | No     | No     |\n| Create API tokens (within their own scope)  | Yes   | Yes    | Yes    |\n\n## What each role is for\n\n**Admin** runs the team. Admins invite and remove members, configure branding, manage status pages, and are the only role allowed to touch billing and plan settings. The person who creates the team becomes its first Admin automatically. A team can have multiple Admins; account ownership itself cannot be transferred today.\n\n**Editor** does the day-to-day operational work. Editors create monitors, open and close incidents, build status pages, and manage notification channels. They cannot bring people in or out of the team and cannot touch branding or billing.\n\n**Reader** observes. Readers see dashboards, browse monitor history, and read incident timelines, useful for executives, customer-facing PMs, or auditors. Readers still receive any notifications they are subscribed to; \"read-only\" refers to the write surface, not to alerts.\n\n## Changing a role\n\nOpen the member list in **Team → Team Members**, find the person, and pick a new role from the action menu. The change takes effect immediately. Only Admins can change roles.\n\n## Constraints worth knowing\n\n- Every team needs at least one Admin in practice. The team creator starts as Admin, and there is no flow that automatically removes the last Admin.\n- You cannot remove yourself from a team through the Remove action; that is intentional, to prevent accidental lockouts. Use **Leave team** instead, or ask another Admin.\n- Editors can create API tokens, but a token's permissions are bounded by the issuing user's permissions, an Editor's token cannot perform Admin-only actions.\n- Plan tier is a separate axis. An Admin on the Free plan still cannot configure white-label branding because that feature is not included in the plan, regardless of role.\n- **Account ownership cannot be transferred today.** The original account holder remains the billing owner. If you need to migrate an account between owners, contact support.\n\n## Related\n\n- [Invite Flow](/docs/invite-flow): how a role gets assigned at invite time\n- [Team Management](/docs/team-management): full team lifecycle and seat limits\n- [Subscriptions Overview](/docs/subscriptions-overview): plan tiers, separate from team roles\n- [White-Label Branding](/docs/white-label-branding): Admin-only customization","category":"teams","tags":["team","role","permissions","rbac"],"order":30,"parentSlug":null,"published":true,"version":1,"metaTitle":"Roles and Permissions. UptimeWarden Documentation","metaDescription":"Capability matrix for UptimeWarden team roles: Admin, Editor, Reader. How they relate to your plan tier and to internal staff access.","icon":"Users","createdAt":"2026-10-12T22:06:42.087Z","updatedAt":"2026-10-12T22:06:42.087Z","publishedAt":"2026-10-12T22:06:42.087Z"},{"publicId":"01M4S2EPDEKWDHD5QNZGB9PR4B","locale":"en","translationGroup":"white-label-branding","slug":"white-label-branding","title":"White-Label Branding","description":"Configure your logo, brand name, colors, email envelope, support details, and custom CSS in one profile. Teammates on a verified email domain inherit it automatically.","body":"# White-Label Branding\n\nUptimeWarden lets you put your own brand on top of the dashboard, status pages, and notification emails. Configure branding once; every place your teammates and visitors see UptimeWarden chrome will show your brand instead.\n\nThis page walks through what each field on **Settings → Branding** does, when the branding is applied, and how it flows to teammates on the same verified email domain.\n\n## How it works, at a glance\n\nYour account's branding profile is **a single row**. That row is reached through three different channels:\n\n1. **Your personal profile**, your own branding, visible only to you.\n2. **Verified organization email domain**, claim `acme.com` and every UptimeWarden user with a verified `@acme.com` address will inherit the profile read-only.\n3. **Verified status-page custom domain**, visitors arriving via `status.acme.com` see the same profile's public projection (logo, colors, brand name, login CSS).\n\nThe owner can switch the whole brand off with a single toggle without losing any saved settings (master on/off).\n\n## Branding profile fields\n\nThe **Settings → Branding** screen lays out the following blocks from top to bottom.\n\n### Master on/off switch\n\nThe **\"Branding is live\" / \"Branding is off\"** switch at the top of the form controls whether the profile applies to any surface. When off:\n\n- The dashboard sidebar reverts to \"UptimeWarden\" with the default logo.\n- Inheriting teammates also fall back to default chrome.\n- Outgoing emails go out under `\"UptimeWarden\" <...>` again.\n- The status-page footer hides the support details.\n\nSaved values (logo URL, colors, custom domain, etc.) stay in the profile until you flip the switch back on, nothing is deleted.\n\n### Visual identity\n\n- **Brand name**: used in the sidebar, in the email envelope, and in inheritance banners. Empty falls back to \"UptimeWarden\".\n- **Logo URL**: image rendered in the sidebar and mobile header. Host the asset on your own CDN and paste the URL.\n- **Favicon URL**: the tab icon. Swapped automatically when the page loads.\n- **Primary color**: applied as the interface's main accent color. Accepts hex (`#2563EB` or `#25E`).\n- **Accent color**: the secondary accent color. Same format.\n\nColors apply to both light and dark mode. If your hex needs to differ between modes, use the custom CSS block to handle that.\n\n### Email\n\n- **Email \"from\" name**: the display name shown in the envelope of outgoing notifications. Empty falls back to **Brand name**, which in turn falls back to \"UptimeWarden\". The sending address does not change; only the display name.\n- **Email footer HTML**: appended to the end of each notification email. Up to 5,000 characters. If your template contains a `{{brandFooter}}` placeholder, the HTML is placed there; otherwise it lands at the bottom automatically.\n\n### Support details\n\n- **Support email**: rendered as a `mailto:` link in the public status-page footer.\n- **Support URL**: rendered alongside as a \"Visit support\" link in the same footer.\n\nIf both are empty the support block does not render; setting either one shows that link alone.\n\n### Custom CSS\n\n- **Custom dashboard CSS**: applied to the dashboard you see after signing in. Up to 10,000 characters.\n- **Custom login CSS**: applied to the login / register / forgot screens only when they are reached via a custom domain.\n\nCSS is stored verbatim and not sanitized. If you pull external resources with `@import` or `@font-face url(...)`, the browser fetches them.\n\n### Organization email domain claim\n\nThis field lifts branding from per-user to per-team. The flow:\n\n- Type your email domain (`acme.com`) into the profile and save.\n- Three conditions must be met before the claim is written:\n  1. The domain must match your account email's domain.\n  2. Your email address must be **verified** (`Settings → Account → Verify email`).\n  3. The domain must not already be claimed by another user.\n- If all three pass, the claim is written. From that moment on, every UptimeWarden user with a verified `@acme.com` address will:\n  - Inherit your profile read-only.\n  - Land on Settings → Branding with a \"Branding for @acme.com is managed by a teammate\" banner.\n  - See your brand on their dashboard, in their notification emails, and on their status pages.\n\n**Personal email providers. Gmail, Outlook, Yahoo, and similar, are not claimable** as an organization.\n\nWhen the owner releases the claim (clears the field and saves), another `@acme.com` member can claim it. If the owner deletes the profile entirely, the domain becomes unclaimed again.\n\n### Status-page custom domain (`customDomain`)\n\nA separate field for status-page hosting. When you enter a hostname (`status.acme.com`) and verify it via DNS TXT, your public status page becomes available at that URL. Setup steps are in a dedicated guide: [Custom Domain Setup](/docs/custom-domain-setup).\n\nThis field is independent of the email-domain claim, you can claim `acme.com` as your organization AND host your status page at `status.acme.com`. They use different verification methods.\n\n## When the branding applies\n\n| Surface | Trigger |\n| --- | --- |\n| Sidebar + mobile header | A signed-in user lands on the main UptimeWarden address; the interface loads your profile |\n| Email envelope + body | When a notification is sent; the **sender's** profile is used, not the recipient's |\n| Public status-page footer | Visiting `app.uptimewarden.online/status/<slug>` or a verified custom domain |\n| Custom-domain pre-auth (login) | Reaching a custom address like `status.acme.com/auth`; the brand is resolved from the address |\n\nIf the master switch is off, none of the above apply, the visitor or user sees the default UptimeWarden chrome.\n\n## Ownership states\n\nThe settings page renders one of three states:\n\n- **Owner**: you authored the profile. Every field is editable. A \"Other @acme.com users see this brand\" note appears.\n- **Inherited**: a teammate on the same `@acme.com` domain authored the profile. Every field is read-only. A \"managed by a teammate\" banner shows at the top.\n- **None**: neither you nor your organization has a profile yet. The form is empty; if your email is verified, a \"Set up branding for @acme.com, your team will inherit this\" CTA banner appears. Saving from this state also writes the claim.\n\n## Plan coverage\n\nWhich branding blocks are available depends on your plan. The interface keeps the blocks your plan grants editable, and shows the blocks your plan does not grant as an upgrade prompt. See [Subscription Plans](/docs/subscription-plans) for the breakdown.\n\n> **\"On but ineffective\" state:** a white-label toggle (hide \"Powered by\") you enabled on a higher plan, or a custom domain you saved, can remain visibly \"on\" in settings after a downgrade. The effective value is computed server-side from your plan: the badge reappears on the public page, and saving changes to a page with a custom domain is rejected. The status-page form shows an explicit warning next to the field in this state, what you're seeing is the plan gate, not a bug.\n\n## Related topics\n\n- [Custom Domain Setup](/docs/custom-domain-setup): host the status page on your own hostname\n- [Subscription Plans](/docs/subscription-plans): which plan unlocks which field\n- [Team Management](/docs/team-management): users and roles","category":"teams","tags":["branding","white-label","logo","css","organization"],"order":40,"parentSlug":null,"published":true,"version":1,"metaTitle":"White-Label Branding. UptimeWarden Documentation","metaDescription":"Configure brand name, logo, favicon, colors, email envelope, support details, and custom CSS in UptimeWarden. Teammates on the same verified email domain inherit automatically.","icon":"Users","createdAt":"2026-10-12T22:06:42.095Z","updatedAt":"2026-10-12T22:06:42.095Z","publishedAt":"2026-10-12T22:06:42.095Z"},{"publicId":"01KJ7Q9ZTP84YMJNE5FH5T4Q7V","locale":"en","translationGroup":"api-getting-started","slug":"en-api-getting-started","title":"API Usage Guide - Getting Started","description":"Getting started with the UptimeWarden API","body":"# Getting Started with UptimeWarden API\n\nThe UptimeWarden API lets you programmatically manage your monitors, retrieve data, and build automations. This RESTful API gives you access to monitor management, incident tracking, SSL status, security analysis, and AI health predictions.\n\n## API Endpoint\n\n```\nhttps://app.uptimewarden.online/api/v1\n```\n\nAll API requests must be made over HTTPS. HTTP requests will be rejected.\n\n## Authentication\n\nThe UptimeWarden API uses Bearer token authentication. You must include the `Authorization` header with every request.\n\n### Creating an API Token\n\n1. Log in to the Dashboard\n2. Go to **Settings > API Tokens**\n3. Click **Create New Token**\n4. Give the token a descriptive name\n5. Select the required permissions (detailed below)\n6. Set an expiration date (optional)\n7. Click **Create**\n\n> ⚠️ **Important**: Copy the token and store it securely. You will not be able to see the token again!\n\n### Using the API Token\n\n```bash\ncurl -H \"Authorization: Bearer YOUR_API_TOKEN\" \\\n  https://app.uptimewarden.online/api/v1/monitors\n```\n\n## Permission System\n\nAPI tokens use granular permissions. Select the appropriate permissions when creating a token:\n\n### Monitor Permissions\n\n| Permission | Description |\n|-----------|-------------|\n| `monitors:read` | View monitor configurations and status |\n| `monitors:create` | Create new monitors |\n| `monitors:delete` | Delete monitors |\n| `monitors:results:read` | View check results (max 7 days) |\n\n### Incident Permissions\n\n| Permission | Description |\n|-----------|-------------|\n| `incidents:read` | View incidents (max 30 days) |\n| `incidents:update` | Update incident status (resolve) |\n| `incidents:comment` | Add comments to incidents |\n\n### SSL & Security Permissions\n\n| Permission | Description |\n|-----------|-------------|\n| `ssl:status:read` | View SSL certificate status |\n| `security:analysis:read` | View security analysis results |\n| `security:analysis:monitor` | Run security analysis on monitors |\n| `security:analysis:website` | Run security analysis on any URL |\n\n### Other Permissions\n\n| Permission | Description |\n|-----------|-------------|\n| `health:predictions:read` | View AI health predictions |\n| `admin` | Full access (includes all permissions) |\n\n### Pre-built Permission Groups\n\nPre-defined permission groups for quick token creation:\n\n| Group | Included Permissions |\n|-------|---------------------|\n| **Monitor Viewer** | `monitors:read`, `monitors:results:read`, `ssl:status:read` |\n| **Monitor Manager** | Monitor Viewer + `monitors:create`, `monitors:delete` |\n| **Incident Manager** | `incidents:read`, `incidents:update`, `incidents:comment` |\n| **Security Analyst** | `security:analysis:read`, `security:analysis:monitor`, `security:analysis:website`, `ssl:status:read` |\n| **Health Monitor** | `monitors:read`, `health:predictions:read` |\n\n## Rate Limiting\n\nAPI requests are rate-limited per endpoint:\n\n| Endpoint Group | Limit Per Minute |\n|----------------|------------------|\n| Monitor listing | 120/min |\n| Monitor creation/deletion | 60/min |\n| Monitor results and stats | 120/min |\n| Incident listing | 120/min |\n| Incident update/comment | 60/min |\n| SSL status | 60/min |\n| Security analysis (read) | 30/min |\n| Security analysis (run) | 10/min |\n| Health predictions | 60/min |\n\nMonthly total API call limits are determined by your subscription plan.\n\n### Rate Limit Exceeded\n\nWhen the limit is exceeded, you receive a `429 Too Many Requests` error:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"RATE_LIMIT_EXCEEDED\",\n    \"message\": \"API rate limit exceeded\"\n  }\n}\n```\n\n## Time Restrictions\n\nSome endpoints have time-based restrictions:\n\n| Data Type | Maximum History |\n|-----------|-----------------|\n| Monitor results (`/monitors/:id/results`) | 7 days |\n| Monitor statistics (`/monitors/:id/stats`) | 7 days |\n| Incident list (`/incidents`) | 30 days |\n\nWhen exceeded, a `403 Forbidden` response is returned:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"TIME_RANGE_EXCEEDED\",\n    \"message\": \"Time range exceeds maximum allowed for this API token\",\n    \"details\": [\"Requested: 10 days\", \"Maximum allowed: 7 days\"]\n  }\n}\n```\n\n## Response Format\n\nAll API responses are in JSON format.\n\n### Success Response (Single Item)\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    // Requested data\n  }\n}\n```\n\n### Success Response (List + Pagination)\n\n```json\n{\n  \"success\": true,\n  \"data\": [...],\n  \"pagination\": {\n    \"page\": 1,\n    \"limit\": 20,\n    \"total\": 45,\n    \"totalPages\": 3,\n    \"hasNextPage\": true,\n    \"hasPrevPage\": false\n  }\n}\n```\n\n### Error Response\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"VALIDATION_ERROR\",\n    \"message\": \"Missing required fields\",\n    \"details\": [\"name, url, and type are required\"]\n  }\n}\n```\n\n## Pagination\n\nList endpoints support pagination:\n\n```bash\nGET /api/v1/monitors?page=2&limit=50\n```\n\n### Pagination Parameters\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `page` | integer | 1 | Page number |\n| `limit` | integer | 20 | Items per page (max: 100) |\n\n## HTTP Status Codes\n\n| Code | Meaning |\n|------|---------|\n| 200 | OK - Request successful |\n| 201 | Created - Resource created |\n| 400 | Bad Request - Validation error |\n| 401 | Unauthorized - Invalid or missing API token |\n| 403 | Forbidden - Insufficient permissions or time restriction exceeded |\n| 404 | Not Found - Resource not found |\n| 429 | Too Many Requests - Rate limit exceeded |\n| 500 | Internal Server Error |\n\n## Quick Examples\n\n### 1. List Monitors\n\n```bash\ncurl -X GET https://app.uptimewarden.online/api/v1/monitors \\\n  -H \"Authorization: Bearer YOUR_API_TOKEN\"\n```\n\n### 2. Create a Monitor\n\n```bash\ncurl -X POST https://app.uptimewarden.online/api/v1/monitors \\\n  -H \"Authorization: Bearer YOUR_API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"API Endpoint\",\n    \"url\": \"https://api.example.com/health\",\n    \"type\": \"http\",\n    \"interval\": 300,\n    \"timeout\": 30\n  }'\n```\n\n**Supported monitor types:** `http`, `tcp`, `udp`, `ssl`, `websocket`, `mcp`, `grpc`\n\n### 3. Delete a Monitor\n\n```bash\ncurl -X DELETE https://app.uptimewarden.online/api/v1/monitors/42 \\\n  -H \"Authorization: Bearer YOUR_API_TOKEN\"\n```\n\n### 4. Get Monitor Results (7-Day Limit)\n\n```bash\n# Last 24 hours\ncurl -X GET \"https://app.uptimewarden.online/api/v1/monitors/42/results?timeRange=24h\" \\\n  -H \"Authorization: Bearer YOUR_API_TOKEN\"\n```\n\n### 5. List Incidents (30-Day Limit)\n\n```bash\ncurl -X GET \"https://app.uptimewarden.online/api/v1/incidents?status=active\" \\\n  -H \"Authorization: Bearer YOUR_API_TOKEN\"\n```\n\n### 6. Resolve an Incident\n\n```bash\ncurl -X PATCH https://app.uptimewarden.online/api/v1/incidents/123 \\\n  -H \"Authorization: Bearer YOUR_API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"status\": \"resolved\",\n    \"resolutionMessage\": \"Server restarted\"\n  }'\n```\n\n## Error Handling\n\n### Retry Strategy\n\n```javascript\nasync function apiCall(url, options, retries = 3) {\n  for (let i = 0; i < retries; i++) {\n    try {\n      const response = await fetch(url, options);\n\n      if (response.status === 429) {\n        await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));\n        continue;\n      }\n\n      if (response.ok) {\n        return await response.json();\n      }\n\n      throw new Error(`API Error: ${response.status}`);\n    } catch (error) {\n      if (i === retries - 1) throw error;\n      await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));\n    }\n  }\n}\n```\n\n## Best Practices\n\n### 1. Token Security\n- Never hardcode tokens in source code\n- Use environment variables\n- Rotate tokens regularly\n- Create tokens with minimum required permissions\n\n### 2. Error Handling\n- Implement retry logic\n- Respect rate limits\n- Handle timeouts properly\n\n### 3. Performance\n- Use pagination parameters\n- Avoid unnecessarily large `limit` values\n- Minimize request count\n\n## Next Steps\n\n- [API Endpoint Reference](/docs/en-api-endpoints) — Detailed documentation for all endpoints","category":"api","tags":["api","authentication","quickstart"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Getting started with the UptimeWarden API","icon":"Code","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EP585NBXREXZ058NKQR8","locale":"en","translationGroup":"api-getting-started","slug":"getting-started","title":"API Getting Started","description":"Onboarding for the UptimeWarden Public API v1, token creation, base URL, auth header, response envelope, error codes, and the time-bounded data window.","body":"# API Getting Started\n\nThis page is the onboarding entry point for any developer integrating with UptimeWarden. By the end you will have a working API token, you will know how to authenticate, and you will recognise the response and error shapes used by every v1 endpoint.\n\n> Already shipping? Jump to [API Quick Start](/docs/quickstart) for the five-minute curl walkthrough, or open [API Endpoints](/docs/endpoints) for the full reference.\n\n## What the Public API gives you\n\nThe Public API lives under `/api/v1/` and exposes **14 endpoints** across five resource groups: monitor management, incident triage, SSL inspection, security analysis, and AI Health Predictions. The canonical schema is published at [`/api/docs/v1-openapi.json`](https://app.uptimewarden.online/api/docs/v1-openapi.json) (OpenAPI 3.0) and rendered as an interactive Swagger UI at [`/api/docs`](https://app.uptimewarden.online/api/docs).\n\n| Capability | Endpoint family |\n| --- | --- |\n| Monitor CRUD + results + stats | `/api/v1/monitors/*` |\n| Incident read / update / comment | `/api/v1/incidents/*` |\n| SSL status (overview + per-monitor) | `/api/v1/ssl/*` |\n| Security analysis (cached + on-demand) | `/api/v1/security/*` |\n| AI Health Predictions | `/api/v1/health/*` |\n\n## Step 1. Create a token\n\n1. Sign in to [the dashboard](https://app.uptimewarden.online).\n2. Open **API Portal → API Tokens**.\n3. Click **Create API Token**, give it a name, choose a permission preset, and copy the token. It is shown **once**.\n\nTokens are prefixed `uptw_` so you can spot one in logs without leaking the secret. See [API Tokens](/docs/api-tokens) for the full permission catalogue and rotation guidance.\n\n```bash\nexport API_TOKEN=uptw_xxxxxxxxxxxxxxxxxxxxxxxx\n```\n\n:::tip Pick the smallest preset that works\nStart with **Monitor Viewer** for read-only scripts, **Monitor Manager** for CI deploys, **Incident Manager** for paging integrations, **Security Analyst** for compliance scans. **Full Access** exists but should be reserved for break-glass automation.\n:::\n\n## Step 2. Make your first call\n\nEvery request needs the `Authorization: Bearer <token>` header. The base URL is `https://app.uptimewarden.online`.\n\n```bash\ncurl -sS \"https://app.uptimewarden.online/api/v1/monitors?limit=1\" \\\n  -H \"Authorization: Bearer $API_TOKEN\"\n```\n\nA successful list response is wrapped in this envelope:\n\n```json\n{\n  \"success\": true,\n  \"data\": [ /* array of monitors */ ],\n  \"pagination\": {\n    \"page\": 1,\n    \"limit\": 1,\n    \"total\": 42,\n    \"totalPages\": 42,\n    \"hasNextPage\": true,\n    \"hasPrevPage\": false\n  }\n}\n```\n\nDetail and single-resource calls return `{ success, data }`. Mutations (POST/PATCH/DELETE) often add a `message` field.\n\n## Rate limits and quotas\n\nRate limits are **per token, per minute**, with the cap depending on the endpoint:\n\n| Endpoint family | Cap |\n| --- | --- |\n| `GET /api/v1/monitors`, `GET /api/v1/monitors/:id/results`, `GET /api/v1/monitors/:id/stats`, `GET /api/v1/incidents` | 120 req/min |\n| `POST /api/v1/monitors`, `DELETE /api/v1/monitors/:id`, `PATCH /api/v1/incidents/:id`, `POST /api/v1/incidents/:id/comments`, `GET /api/v1/ssl/*` | 60 req/min |\n| `GET /api/v1/security/monitors/:id/analysis` | 30 req/min |\n| `POST /api/v1/security/monitors/:id/analyze`, `POST /api/v1/security/analyze` | 10 req/min |\n| `GET /api/v1/health/monitors/:id/predictions` | 60 req/min |\n\nEvery response includes the standard self-throttle headers:\n\n```text\nX-RateLimit-Limit: 120\nX-RateLimit-Remaining: 117\nX-RateLimit-Reset: 2026-04-27T10:31:00.000Z\n```\n\nExceeding the cap returns `429 Too Many Requests` with a `retryAfter` field (seconds). A separate **monthly API call cap** applies per subscription plan, exceeding it returns `MONTHLY_API_LIMIT_EXCEEDED`.\n\n## Response envelope\n\nEvery v1 endpoint returns either:\n\n```json\n{ \"success\": true, \"data\": ... }\n```\n\nor:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"TIME_RANGE_EXCEEDED\",\n    \"message\": \"Time range exceeds maximum allowed\",\n    \"details\": [\"Requested: 10 days\", \"Maximum allowed: 7 days\"]\n  }\n}\n```\n\n`details` is an optional array of clarifying strings. Authentication errors (`401`/`403`) may return the simpler `{ error, message }` shape, clients should treat the HTTP status as authoritative.\n\n## Error codes\n\n| HTTP | `error.code` | When it happens |\n| --- | --- | --- |\n| `400` | `VALIDATION_ERROR` | Required body field missing or wrong type. |\n| `400` | `INVALID_URL` | URL parameter is not a valid URI. |\n| `401` | - | Missing or malformed `Authorization` header, or token invalid/expired. |\n| `403` | - | Token lacks the required permission. |\n| `403` | `TIME_RANGE_EXCEEDED` | Asking for older data than the token tier allows (7 days for results, 30 days for incidents). |\n| `403` | `MONITOR_LIMIT_REACHED` | Subscription's monitor cap reached on a `POST /monitors`. |\n| `404` | `NOT_FOUND` | Resource missing or not visible to this token. |\n| `429` | - | Per-minute rate-limit cap exceeded. Look at `retryAfter`. |\n| `429` | `MONTHLY_API_LIMIT_EXCEEDED` | Plan's monthly API call quota exhausted. |\n| `500` | `INTERNAL_ERROR` | Server-side fault. |\n\n## Historical-data window\n\nAPI tokens are deliberately scoped to short windows so a leaked token cannot exfiltrate years of data:\n\n- `monitors:results:read`, at most **7 days** of check results.\n- `incidents:read`, at most **30 days** of incident history.\n\nBoth ceilings are enforced on every request, client-side pagination cannot bypass them. For longer windows, use the dashboard.\n\n## Versioning policy\n\n`v1` is stable. Breaking changes ship as `v2`; additive changes (new optional fields, new endpoints) land in `v1` without a version bump. The OpenAPI document at [`/api/docs/v1-openapi.json`](https://app.uptimewarden.online/api/docs/v1-openapi.json) is the source of truth, this docs site is derived from it.\n\n## Next steps\n\n- Walk through five working calls in [API Quick Start](/docs/quickstart).\n- Browse every endpoint in [API Endpoints](/docs/endpoints).\n- Manage tokens at scale in [API Tokens](/docs/api-tokens).\n- Try requests interactively at [`/api/docs`](https://app.uptimewarden.online/api/docs) (Swagger UI).","category":"api","tags":["api","onboarding","authentication","errors","v1"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":"API Getting Started. UptimeWarden Documentation","metaDescription":"Get onboarded with the UptimeWarden Public API v1: create a token, send your first authenticated request, and learn the response envelope, error codes, and historical-data limits.","icon":"Code","createdAt":"2026-10-12T22:06:41.832Z","updatedAt":"2026-10-12T22:06:41.832Z","publishedAt":"2026-10-12T22:06:41.832Z"},{"publicId":"01KJ7Q9ZTQNBXYNVDC78RM75QK","locale":"en","translationGroup":"api-endpoints","slug":"en-api-endpoints","title":"API Endpoint Reference","description":"Detailed documentation for all UptimeWarden API endpoints","body":"# API Endpoint Reference\n\nComplete reference for all UptimeWarden API v1 endpoints.\n\n> For basics (authentication, permissions, rate limits), see the [API Getting Started Guide](/docs/en-api-getting-started).\n\n**Base URL:** `https://app.uptimewarden.online/api/v1`\n\n---\n\n## Monitors\n\n### List Monitors\n\nLists all monitors belonging to the authenticated user.\n\n```http\nGET /api/v1/monitors\n```\n\n**Required Permission:** `monitors:read`\n**Rate Limit:** 120/min\n\n**Query Parameters:**\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `page` | integer | 1 | Page number |\n| `limit` | integer | 20 | Items per page (max: 100) |\n\n**Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 42,\n      \"name\": \"Production API\",\n      \"url\": \"https://api.example.com\",\n      \"type\": \"http\",\n      \"interval\": 60,\n      \"timeout\": 30,\n      \"status\": \"up\"\n    }\n  ],\n  \"pagination\": {\n    \"page\": 1,\n    \"limit\": 20,\n    \"total\": 45,\n    \"totalPages\": 3,\n    \"hasNextPage\": true,\n    \"hasPrevPage\": false\n  }\n}\n```\n\n---\n\n### Create Monitor\n\nCreates a new monitor.\n\n```http\nPOST /api/v1/monitors\n```\n\n**Required Permission:** `monitors:create`\n**Rate Limit:** 60/min\n\n> Subject to your subscription plan's monitor limit. Returns `403 MONITOR_LIMIT_REACHED` when exceeded.\n\n**Request Body:**\n\n```json\n{\n  \"name\": \"Production API\",\n  \"url\": \"https://api.example.com/health\",\n  \"type\": \"http\",\n  \"interval\": 300,\n  \"timeout\": 30\n}\n```\n\n**Required Fields:**\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `name` | string | Monitor name |\n| `url` | string | URL or address to monitor |\n| `type` | string | Monitor type |\n\n**Supported Monitor Types:** `http`, `tcp`, `udp`, `ssl`, `websocket`, `mcp`, `grpc`\n\n**Optional Fields:**\n\n| Field | Type | Default | Description |\n|-------|------|---------|-------------|\n| `interval` | integer | 300 | Check interval (seconds) |\n| `timeout` | integer | 30 | Response timeout (seconds) |\n\n**Response (201):**\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 43,\n    \"name\": \"Production API\",\n    \"url\": \"https://api.example.com/health\",\n    \"type\": \"http\",\n    \"interval\": 300,\n    \"timeout\": 30\n  }\n}\n```\n\n---\n\n### Delete Monitor\n\nPermanently deletes a monitor. Only the monitor owner can delete it.\n\n```http\nDELETE /api/v1/monitors/:id\n```\n\n**Required Permission:** `monitors:delete`\n**Rate Limit:** 60/min\n\n**Path Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | Monitor ID |\n\n**Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"message\": \"Monitor deleted successfully\"\n}\n```\n\n---\n\n### Monitor Results\n\nRetrieves historical check results for a monitor.\n\n```http\nGET /api/v1/monitors/:id/results\n```\n\n**Required Permission:** `monitors:results:read`\n**Rate Limit:** 120/min\n**Time Limit:** Maximum 7 days of historical data\n\n**Path Parameters:**\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `id` | integer | Monitor ID |\n\n**Query Parameters (Time Range):**\n\nUse one of the following methods to specify the time range:\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `timeRange` | string | Quick preset: `24h`, `7d` (default: `24h`) |\n| `startDate` | string | Start date (ISO 8601). Use with `endDate` |\n| `endDate` | string | End date (ISO 8601). Use with `startDate` |\n| `since` | string | Since this date (ISO 8601, max 7 days ago) |\n| `days` | integer | Number of days back (max: 7) |\n| `limit` | integer | Max results (max: 1000, default: 100) |\n\n**Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 1234,\n      \"monitorId\": 42,\n      \"status\": \"up\",\n      \"responseTime\": 245,\n      \"statusCode\": 200,\n      \"checkedAt\": \"2025-01-15T14:30:00Z\"\n    }\n  ],\n  \"meta\": {\n    \"monitorId\": 42,\n    \"timeRange\": \"24h\",\n    \"count\": 100,\n    \"limitation\": \"API tokens are limited to 7 days of historical data\"\n  }\n}\n```\n\n---\n\n### Monitor Statistics\n\nRetrieves uptime and performance statistics for a monitor.\n\n```http\nGET /api/v1/monitors/:id/stats\n```\n\n**Required Permission:** `monitors:results:read`\n**Rate Limit:** 120/min\n**Time Limit:** Maximum 7 days of historical data\n\nSupports the same time range parameters as the results endpoint.\n\n**Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"monitorId\": 42,\n    \"uptimePercentage\": 99.95,\n    \"averageResponseTime\": 245,\n    \"totalChecks\": 1440,\n    \"successfulChecks\": 1438,\n    \"failedChecks\": 2\n  }\n}\n```\n\n---\n\n## Incidents\n\n### List Incidents\n\nLists incidents for the user's monitors.\n\n```http\nGET /api/v1/incidents\n```\n\n**Required Permission:** `incidents:read`\n**Rate Limit:** 120/min\n**Time Limit:** Maximum 30 days of historical data\n\n**Query Parameters:**\n\n| Parameter | Type | Default | Description |\n|-----------|------|---------|-------------|\n| `status` | string | `all` | Status filter: `active`, `resolved`, `all` |\n| `page` | integer | 1 | Page number |\n| `limit` | integer | 20 | Items per page (max: 100) |\n| `timeRange` | string | `7d` | Quick preset: `24h`, `7d`, `30d` |\n| `startDate` | string | — | Start date (ISO 8601) |\n| `endDate` | string | — | End date (ISO 8601) |\n| `since` | string | — | Since this date (ISO 8601) |\n| `days` | integer | — | Days back (max: 30) |\n\n**Response (200):**\n\n```json\n{\n  \"success\": true,\n  \"data\": [\n    {\n      \"id\": 123,\n      \"monitorId\": 42,\n      \"monitorName\": \"Production API\",\n      \"status\": \"resolved\",\n      \"startedAt\": \"2025-01-15T10:00:00Z\",\n      \"resolvedAt\": \"2025-01-15T10:05:00Z\",\n      \"errorMessage\": \"Connection timeout\"\n    }\n  ],\n  \"pagination\": {\n    \"page\": 1,\n    \"limit\": 20,\n    \"total\": 8,\n    \"totalPages\": 1\n  },\n  \"meta\": {\n    \"limitation\": \"API tokens are limited to 30 days of historical data\"\n  }\n}\n```\n\n---\n\n### Update Incident\n\nUpdates an incident's status (e.g., resolving it).\n\n```http\nPATCH /api/v1/incidents/:id\n```\n\n**Required Permission:** `incidents:update`\n**Rate Limit:** 60/min\n\n**Request Body:**\n\n```json\n{\n  \"status\": \"resolved\",\n  \"resolutionMessage\": \"Server restarted, issue resolved\"\n}\n```\n\n| Field | Type | Description |\n|-------|------|-------------|\n| `status` | string | New status: `active` or `resolved` |\n| `resolutionMessage` | string | Resolution note (optional) |\n\n---\n\n### Add Incident Comment\n\nAdds an update/comment to an incident.\n\n```http\nPOST /api/v1/incidents/:id/comments\n```\n\n**Required Permission:** `incidents:comment`\n**Rate Limit:** 60/min\n\n**Request Body:**\n\n```json\n{\n  \"message\": \"Root cause analysis completed\"\n}\n```\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `message` | string | ✅ | Comment text |\n\n**Response (201):**\n\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"id\": 456,\n    \"incidentId\": 123,\n    \"message\": \"Root cause analysis completed\",\n    \"userId\": 1,\n    \"createdAt\": \"2025-01-15T10:10:00Z\"\n  }\n}\n```\n\n---\n\n## SSL Certificates\n\n### All SSL Status\n\nRetrieves SSL certificate information for all user's monitors.\n\n```http\nGET /api/v1/ssl/status\n```\n\n**Required Permission:** `ssl:status:read`\n**Rate Limit:** 60/min\n\n---\n\n### Monitor SSL Status\n\nRetrieves SSL certificate details for a specific monitor.\n\n```http\nGET /api/v1/ssl/monitors/:id\n```\n\n**Required Permission:** `ssl:status:read`\n**Rate Limit:** 60/min\n\n---\n\n## Security Analysis\n\n### Get Security Analysis Results\n\nRetrieves existing security analysis results for a monitor.\n\n```http\nGET /api/v1/security/monitors/:id/analysis\n```\n\n**Required Permission:** `security:analysis:read` or `security:analysis:monitor`\n**Rate Limit:** 30/min\n\n---\n\n### Run Security Analysis on Monitor\n\nRuns a fresh security analysis on a monitor's endpoint.\n\n```http\nPOST /api/v1/security/monitors/:id/analyze\n```\n\n**Required Permission:** `security:analysis:monitor`\n**Rate Limit:** 10/min\n\n---\n\n### Run Security Analysis on Any URL\n\nRuns security analysis on any provided URL (not limited to monitors).\n\n```http\nPOST /api/v1/security/analyze\n```\n\n**Required Permission:** `security:analysis:website`\n**Rate Limit:** 10/min\n\n**Request Body:**\n\n```json\n{\n  \"url\": \"https://example.com\"\n}\n```\n\n---\n\n## Health Predictions (AI)\n\n### Monitor Health Predictions\n\nRetrieves AI-powered health predictions and anomaly detection for a monitor.\n\n```http\nGET /api/v1/health/monitors/:id/predictions\n```\n\n**Required Permission:** `health:predictions:read`\n**Rate Limit:** 60/min\n\n> Health predictions require sufficient historical data. Predictions are generated automatically every 6 hours.\n\n---\n\n## Endpoint Summary Table\n\n| Method | Endpoint | Permission | Rate Limit | Time Limit |\n|--------|----------|------------|------------|------------|\n| `GET` | `/api/v1/monitors` | `monitors:read` | 120/min | — |\n| `POST` | `/api/v1/monitors` | `monitors:create` | 60/min | — |\n| `DELETE` | `/api/v1/monitors/:id` | `monitors:delete` | 60/min | — |\n| `GET` | `/api/v1/monitors/:id/results` | `monitors:results:read` | 120/min | 7 days |\n| `GET` | `/api/v1/monitors/:id/stats` | `monitors:results:read` | 120/min | 7 days |\n| `GET` | `/api/v1/incidents` | `incidents:read` | 120/min | 30 days |\n| `PATCH` | `/api/v1/incidents/:id` | `incidents:update` | 60/min | — |\n| `POST` | `/api/v1/incidents/:id/comments` | `incidents:comment` | 60/min | — |\n| `GET` | `/api/v1/ssl/status` | `ssl:status:read` | 60/min | — |\n| `GET` | `/api/v1/ssl/monitors/:id` | `ssl:status:read` | 60/min | — |\n| `GET` | `/api/v1/security/monitors/:id/analysis` | `security:analysis:read` | 30/min | — |\n| `POST` | `/api/v1/security/monitors/:id/analyze` | `security:analysis:monitor` | 10/min | — |\n| `POST` | `/api/v1/security/analyze` | `security:analysis:website` | 10/min | — |\n| `GET` | `/api/v1/health/monitors/:id/predictions` | `health:predictions:read` | 60/min | — |\n\n## Error Codes\n\n| Code | Description |\n|------|-------------|\n| `VALIDATION_ERROR` | Request body validation failed |\n| `NOT_FOUND` | Resource not found |\n| `ACCESS_DENIED` | No access to this resource |\n| `MONITOR_LIMIT_REACHED` | Subscription monitor limit reached |\n| `TIME_RANGE_EXCEEDED` | Time range exceeds allowed maximum |\n| `RATE_LIMIT_EXCEEDED` | Rate limit exceeded |\n| `INTERNAL_ERROR` | Server error |\n| `INVALID_URL` | Invalid URL format |","category":"api","tags":["api","endpoints","reference"],"order":2,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Detailed documentation for all UptimeWarden API endpoints","icon":"Code","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EP5FREGCJ9V7VFPJN4H5","locale":"en","translationGroup":"api-endpoints","slug":"endpoints","title":"API Endpoints","description":"Reference for all 14 v1 endpoints, method, path, required permission, query parameters, and response shape.","body":"# API Endpoints\n\nThe Public API exposes **14 endpoints** under `/api/v1/`. This page is a quick reference card; the canonical schema is published at [`/api/docs/v1-openapi.json`](https://app.uptimewarden.online/api/docs/v1-openapi.json) and rendered as an interactive Swagger UI at [`/api/docs`](https://app.uptimewarden.online/api/docs).\n\n> Make sure you have read [API Getting Started](/docs/getting-started) and have a token before continuing.\n\n## Conventions\n\n- Base URL: `https://app.uptimewarden.online`\n- Auth: `Authorization: Bearer <token>` (every v1 endpoint requires it).\n- Path parameters use the numeric monitor ID returned as `id` on list and detail responses.\n- Successful responses follow `{ success: true, data, pagination?, meta? }`.\n- Error responses follow `{ success: false, error: { code, message, details? } }`.\n\n## Monitors\n\n| Method | Path | Permission | Rate | Purpose |\n| --- | --- | --- | --- | --- |\n| `GET` | `/api/v1/monitors` | `monitors:read` | 120/min | Paginated list of monitors owned by the token user. Query: `?page&limit` (default 20, max 100). |\n| `POST` | `/api/v1/monitors` | `monitors:create` | 60/min | Create a monitor. Body: `{ name, url, type, interval?, timeout? }`. Subscription monitor cap enforced. |\n| `DELETE` | `/api/v1/monitors/:id` | `monitors:delete` | 60/min | Permanently delete a monitor and all its associated data. |\n| `GET` | `/api/v1/monitors/:id/results` | `monitors:results:read` | 120/min | Up to **7 days** of check results. Query: `?timeRange=24h\\|7d`, `?startDate&endDate`, `?since`, `?days=1..7`, `?limit=1..1000`. |\n| `GET` | `/api/v1/monitors/:id/stats` | `monitors:results:read` | 120/min | Uptime / response-time aggregates. Same time-range options as results. |\n\n`type` accepts `http`, `tcp`, `udp`, `ssl`, `websocket`, `mcp`, `grpc`. `interval` defaults to `300` seconds and must respect your plan's minimum check interval. `timeout` defaults to `30` seconds.\n\n```bash\ncurl -sS \"https://app.uptimewarden.online/api/v1/monitors?page=1&limit=20\" \\\n  -H \"Authorization: Bearer $API_TOKEN\"\n```\n\n```bash\ncurl -sS -X POST \"https://app.uptimewarden.online/api/v1/monitors\" \\\n  -H \"Authorization: Bearer $API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"name\":\"Production API\",\"url\":\"https://api.example.com/health\",\"type\":\"http\",\"interval\":300,\"timeout\":30}'\n```\n\nA v1 update endpoint (`PATCH /api/v1/monitors/:id`) is **not yet available**, to change a monitor's configuration, use the dashboard or recreate it via DELETE + POST.\n\n## Incidents\n\n| Method | Path | Permission | Rate | Purpose |\n| --- | --- | --- | --- | --- |\n| `GET` | `/api/v1/incidents` | `incidents:read` | 120/min | Incidents for monitors owned by the token user. Limited to **30 days**. Query: `?timeRange=24h\\|7d\\|30d`, `?status=active\\|resolved\\|all`, `?startDate&endDate`, `?since`, `?days=1..30`, `?page&limit`. |\n| `PATCH` | `/api/v1/incidents/:id` | `incidents:update` | 60/min | Update an incident. Body: `{ status?: \"active\"\\|\"resolved\", resolutionMessage?: string }`. Setting `status: \"resolved\"` stamps `resolvedAt`. |\n| `POST` | `/api/v1/incidents/:id/comments` | `incidents:comment` | 60/min | Append a timeline comment. Body: `{ message: string }` (required). |\n\n```bash\ncurl -sS -X PATCH \"https://app.uptimewarden.online/api/v1/incidents/$ID\" \\\n  -H \"Authorization: Bearer $API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"status\":\"resolved\",\"resolutionMessage\":\"Cache flushed, traffic restored\"}'\n```\n\n## SSL\n\n| Method | Path | Permission | Rate | Purpose |\n| --- | --- | --- | --- | --- |\n| `GET` | `/api/v1/ssl/status` | `ssl:status:read` | 60/min | Portfolio-wide SSL certificate summary for every monitor owned by the token user. |\n| `GET` | `/api/v1/ssl/monitors/:id` | `ssl:status:read` | 60/min | Per-monitor certificate detail (issuer, validFrom/validUntil, daysUntilExpiry, isValid). |\n\nThere is no API endpoint for forced refresh; SSL data is refreshed automatically. To trigger a manual refresh, use the dashboard.\n\n## Security analysis\n\n| Method | Path | Permission | Rate | Purpose |\n| --- | --- | --- | --- | --- |\n| `GET` | `/api/v1/security/monitors/:id/analysis` | `security:analysis:read` **or** `security:analysis:monitor` | 30/min | Latest cached analysis (headers, vulnerabilities, grade) for an owned monitor. |\n| `POST` | `/api/v1/security/monitors/:id/analyze` | `security:analysis:monitor` | 10/min | Trigger a fresh analysis run on the monitor's URL. |\n| `POST` | `/api/v1/security/analyze` | `security:analysis:website` | 10/min | One-shot analysis on an arbitrary URL. Body: `{ url: string }`. |\n\n```bash\ncurl -sS -X POST \"https://app.uptimewarden.online/api/v1/security/analyze\" \\\n  -H \"Authorization: Bearer $API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://example.com\"}'\n```\n\nReturned shape (abbreviated): `{ securityScore, grade, headers, vulnerabilities[], analyzedAt }`. See the `SecurityAnalysis` schema in the OpenAPI spec for the full structure.\n\n## AI Health Predictions\n\n| Method | Path | Permission | Rate | Purpose |\n| --- | --- | --- | --- | --- |\n| `GET` | `/api/v1/health/monitors/:id/predictions` | `health:predictions:read` | 60/min | Anomaly, trend, and forecast predictions for the monitor. Returns `{ success: true, data: null, message }` when there is not yet enough history. |\n\nHealth predictions are generated automatically every 6 hours and require sufficient historical data. See [Health Predictions](/docs/health-predictions) for details on the prediction model.\n\n## Common parameters\n\n| Param | Where | Notes |\n| --- | --- | --- |\n| `page` | List endpoints | 1-indexed, default `1`. |\n| `limit` | List endpoints | Default `20`, max `100` (monitors/incidents); default `100`, max `1000` (monitor results). |\n| `timeRange` | Results / stats / incidents | `24h\\|7d` for results/stats, `24h\\|7d\\|30d` for incidents. |\n| `startDate` + `endDate` | Results / stats / incidents | ISO 8601. Range capped at 7 days (results) or 30 days (incidents). |\n| `since` | Results / stats / incidents | ISO 8601. Same window cap as above. |\n| `days` | Results / stats / incidents | Integer 1-7 (results) or 1-30 (incidents). |\n| `status` | Incidents | `active`, `resolved`, `all` (default `all`). |\n\n## Try it interactively\n\nOpen [`/api/docs`](https://app.uptimewarden.online/api/docs), the Swagger UI lets you paste a token and call your real account from the browser. The same OpenAPI document feeds code generators (`openapi-generator`, `oazapfts`, etc.).\n\n## Related\n\n- [API Getting Started](/docs/getting-started): onboarding, base URL, errors\n- [API Quick Start](/docs/quickstart): five-minute curl walkthrough\n- [API Tokens](/docs/api-tokens): permission catalogue and rotation\n- [Subscription Plans](/docs/subscription-plans): plan-tier API call quota","category":"api","tags":["api","endpoints","reference","permissions","v1"],"order":2,"parentSlug":null,"published":true,"version":1,"metaTitle":"API Endpoints. UptimeWarden Documentation","metaDescription":"Complete v1 endpoint reference for the UptimeWarden Public API, monitors, incidents, SSL, security analysis, and AI Health Predictions.","icon":"Code","createdAt":"2026-10-12T22:06:41.839Z","updatedAt":"2026-10-12T22:06:41.839Z","publishedAt":"2026-10-12T22:06:41.839Z"},{"publicId":"01M4S2EP8Q67CAH7XZWS2ZYDY7","locale":"en","translationGroup":"api-quickstart","slug":"quickstart","title":"API Quick Start","description":"Make your first API call in 60 seconds, token, curl, list, create, read.","body":"# UptimeWarden API. Quick Start\n\nThe UptimeWarden Public API lives under `/api/v1/` and exposes 14 endpoints across Monitors, Incidents, SSL, Security, and AI Health Predictions. The deeper onboarding doc is [API Getting Started](/docs/getting-started); this page is the speed run.\n\n## 1. Create a token\n\nIn the dashboard go to **API Portal → API Tokens**, click **Create API Token**, give it a name, choose the **Monitor Manager** preset, and copy the token. Tokens are shown **once**.\n\n```bash\nexport API_TOKEN=uptw_xxxxxxxxxxxxxxxxxxxxxxxx\n```\n\nTokens are prefixed `uptw_` so they are recognisable in logs.\n\n## 2. Verify\n\n```bash\ncurl -sS \"https://app.uptimewarden.online/api/v1/monitors?limit=1\" \\\n  -H \"Authorization: Bearer $API_TOKEN\"\n```\n\nA `200 OK` with `{\"success\": true, \"data\": [...]}` confirms the token is valid and carries `monitors:read`.\n\n## 3. Create a monitor\n\n```bash\ncurl -sS -X POST \"https://app.uptimewarden.online/api/v1/monitors\" \\\n  -H \"Authorization: Bearer $API_TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"name\": \"Production API\",\n    \"url\": \"https://api.example.com/health\",\n    \"type\": \"http\",\n    \"interval\": 300,\n    \"timeout\": 30\n  }'\n```\n\nPermission required: `monitors:create`. `type` accepts `http`, `tcp`, `udp`, `ssl`, `websocket`, `mcp`, `grpc`. The response includes the new monitor's numeric `id`, keep it for the next two calls.\n\n## 4. Read results (last 7 days max)\n\n```bash\ncurl -sS \"https://app.uptimewarden.online/api/v1/monitors/$ID/results?timeRange=7d&limit=100\" \\\n  -H \"Authorization: Bearer $API_TOKEN\"\n```\n\nAPI tokens are capped at **7 days** of result history. Use the dashboard for longer windows.\n\n## 5. Stats\n\n```bash\ncurl -sS \"https://app.uptimewarden.online/api/v1/monitors/$ID/stats?timeRange=7d\" \\\n  -H \"Authorization: Bearer $API_TOKEN\"\n```\n\nReturns `{ uptime, avgResponseTime, totalChecks, latestResult }`.\n\n## Permission presets\n\nThese are one-click chips in the token-creation dialog:\n\n| Preset | Permissions |\n| --- | --- |\n| **Monitor Viewer** | `monitors:read`, `monitors:results:read`, `ssl:status:read` |\n| **Monitor Manager** | + `monitors:create`, `monitors:delete` |\n| **Incident Manager** | `incidents:read`, `incidents:update`, `incidents:comment` |\n| **Security Analyst** | `security:analysis:read`, `security:analysis:monitor`, `security:analysis:website`, `ssl:status:read` |\n| **Health Monitor** | `monitors:read`, `health:predictions:read` |\n| **Full Access** | All permissions (use with caution, defeats the granularity model) |\n\n## Error envelope\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"TIME_RANGE_EXCEEDED\",\n    \"message\": \"Time range exceeds maximum allowed for this API token\",\n    \"details\": [\"Requested: 10 days\", \"Maximum allowed: 7 days\", \"Your API token has limited historical data access\"]\n  }\n}\n```\n\nAuthentication errors (`401`/`403`) may return the simpler `{ error, message }` shape. Always treat the HTTP status as authoritative.\n\n## Next steps\n\n- **Interactive reference:** [`/api/docs`](https://app.uptimewarden.online/api/docs) (Swagger UI)\n- **OpenAPI JSON:** [`/api/docs/v1-openapi.json`](https://app.uptimewarden.online/api/docs/v1-openapi.json)\n- **Full endpoint reference:** [API Endpoints](/docs/endpoints)\n- **Token management:** [API Tokens](/docs/api-tokens)\n- **Onboarding:** [API Getting Started](/docs/getting-started)","category":"api","tags":["api","quickstart","curl","automation","v1"],"order":5,"parentSlug":null,"published":true,"version":1,"metaTitle":"API Quick Start. UptimeWarden Documentation","metaDescription":"Start using the UptimeWarden Public API v1 in 60 seconds. Create a token, authorize, list monitors, create one, and read its results.","icon":"Code","createdAt":"2026-10-12T22:06:41.943Z","updatedAt":"2026-10-12T22:06:41.943Z","publishedAt":"2026-10-12T22:06:41.943Z"},{"publicId":"01M4S2EP8X89K5D9XS504226M1","locale":"en","translationGroup":"api-tokens","slug":"api-tokens","title":"API Tokens","description":"Create, scope, rotate, and revoke UptimeWarden API tokens with granular permissions, time-bounded access, and pre-built permission groups.","body":"# API Tokens\n\nThe UptimeWarden API is consumed from scripts, CI pipelines, dashboards, the CLI, and third-party integrations. A single all-powerful key is convenient but dangerous, any leak hands the attacker full control. UptimeWarden solves this with **granular, permission-scoped tokens** plus built-in time bounds on the most sensitive reads.\n\n## Token format\n\nA token is a long, random string:\n\n- 32 random bytes, base64url-encoded.\n- Prefixed with `uptw_` so it is recognisable in logs.\n- The first 12 characters (e.g. `uptw_abcd123`) are stored as a public prefix you can reference; the remainder is hashed and **never** retrievable after creation.\n\n:::warning Tokens are shown once\nA token is shown **once** at creation time, copy it immediately. The dashboard cannot retrieve it later. If you lose it, revoke it and create a new one.\n:::\n\nThe prefix is what surfaces in the token-management UI, audit logs, and usage reports, so you can tell which token did what without exposing the secret.\n\n## Permission model\n\nPermissions follow a `<resource>:<action>` pattern. Each token carries a list of permissions; on every request, the API checks that the token holds the permission required by the endpoint.\n\n### Monitor permissions\n\n| Permission | Access | Limits |\n| --- | --- | --- |\n| `monitors:read` | List monitors and their status | None |\n| `monitors:create` | Create new monitors | Subscription monitor cap |\n| `monitors:delete` | Delete monitors | None |\n| `monitors:results:read` | Read check results and stats | **Capped at 7 days of history** |\n\n### Incident permissions\n\n| Permission | Access | Limits |\n| --- | --- | --- |\n| `incidents:read` | List incidents | **Capped at 30 days of history** |\n| `incidents:update` | Update status / resolution | None |\n| `incidents:comment` | Add timeline comments | None |\n\n### SSL permissions\n\n| Permission | Access | Limits |\n| --- | --- | --- |\n| `ssl:status:read` | Read SSL certificate status | None |\n\n### Security analysis permissions\n\n| Permission | Access | Limits |\n| --- | --- | --- |\n| `security:analysis:read` | Read cached analysis results | None |\n| `security:analysis:monitor` | Run analysis on owned monitors | 10 req/min |\n| `security:analysis:website` | Run analysis on any URL | 10 req/min |\n\n### Health prediction permissions\n\n| Permission | Access | Limits |\n| --- | --- | --- |\n| `health:predictions:read` | Read AI health predictions | Owned monitors only |\n\n### Deploy & maintenance permissions\n\nFor CI/CD pipelines (e.g. GitHub Actions deploy notifications):\n\n| Permission | Access | Limits |\n| --- | --- | --- |\n| `deploys:read` | List and inspect deploy markers on the timeline | None |\n| `deploys:write` | Record and finalise deploy markers | None |\n| `monitors:maintenance:read` | List active maintenance windows on owned monitors | None |\n| `monitors:maintenance:write` | Open and close maintenance (mute) windows on owned monitors | None |\n\n### Admin permission\n\n| Permission | Access | Limits |\n| --- | --- | --- |\n| `admin` | **Full access** to every v1 endpoint | None |\n\nReserve `admin` for break-glass automation. CI tokens should always be scoped to a preset.\n\n## Pre-built permission groups\n\nThe token-creation dialog offers one-click presets you can use as a starting point:\n\n| Group | Use case | Permissions |\n| --- | --- | --- |\n| **Monitor Viewer** | Read-only dashboards, status displays | `monitors:read`, `monitors:results:read`, `ssl:status:read` |\n| **Monitor Manager** | Infrastructure-as-code, automated provisioning | + `monitors:create`, `monitors:delete` |\n| **Incident Manager** | Ticketing integrations, on-call automation | `incidents:read`, `incidents:update`, `incidents:comment` |\n| **Security Analyst** | Compliance scans, security audits | `security:analysis:read`, `security:analysis:monitor`, `security:analysis:website`, `ssl:status:read` |\n| **Health Monitor** | AI prediction consumers | `monitors:read`, `health:predictions:read` |\n| **Deploy Manager** | CI/CD deploy markers and mute windows | `monitors:read`, `deploys:read`, `deploys:write`, `monitors:maintenance:read`, `monitors:maintenance:write` |\n| **Full Access** | Internal tooling, break-glass | All of the above |\n\nAfter picking a preset you can add or remove individual permissions before creating the token.\n\n## Time-bounded permissions\n\nTwo permissions carry built-in time limits, enforced on every request:\n\n- `monitors:results:read`, at most **7 days** of history.\n- `incidents:read`, at most **30 days** of history.\n\nAsking for a larger window returns `403 TIME_RANGE_EXCEEDED` with the requested-vs-allowed values in `details`. These caps are independent of your plan's data-retention setting, for longer windows, use the dashboard.\n\n## Creating a token\n\n1. Sign in to [the dashboard](https://app.uptimewarden.online).\n2. Open **API Portal → API Tokens**.\n3. Click **Create API Token**.\n4. Set:\n   - **Name**: a label for your own use (e.g. `GitHub Actions deploy pipeline`).\n   - **Permissions**: pick a preset chip or assemble manually.\n   - **Expiry (optional)**: leave blank for \"never expires\"; set a date to force rotation.\n5. Click **Create** and copy the token from the dialog. Once you close it, the secret is gone for good.\n\n## Authenticating\n\nPass the token in the `Authorization` header:\n\n```http\nGET /api/v1/monitors\nAuthorization: Bearer uptw_abcd1234...\n```\n\nThe `Bearer` prefix is required. Raw tokens or query-string authentication are rejected.\n\n## Viewing usage\n\nEvery API call made with a token is logged: endpoint, HTTP method, status code, response time, user agent, and IP address. The dashboard exposes per-token usage so you can spot misbehaving integrations and detect leaked tokens that suddenly start hitting unfamiliar endpoints. Default view is the last 30 days.\n\n## Rotating a token\n\nThere is no \"rotate\" button, you delete and recreate, ideally with overlap:\n\n1. Create a new token with the same permissions.\n2. Roll the new token out to every consumer.\n3. Watch the old token's usage drop to zero.\n4. Delete the old token.\n\nThis overlap prevents a single point of failure. If you must rotate instantly because a token leaked, delete it immediately and accept a brief outage while the new token rolls out.\n\n## Revoking a token\n\n`DELETE /api/user/api-tokens/:id` removes the token. In-flight requests complete; the next request on that token returns `401 Unauthorized`. Delete leaked tokens the same day you discover them.\n\n## Audit trail\n\nToken creation, permission changes, and deletion are recorded in the audit log alongside the actor, the token's public prefix, and the timestamp. See [Audit Logging](/docs/audit-logging) for the full event list.\n\n## Limits\n\n- The number of active tokens per user is gated by your plan.\n- Per-minute rate limits apply per token; caps vary by endpoint family: see [API Endpoints](/docs/endpoints).\n- A separate **monthly API call cap** applies to your account. Exceeding it returns `403 MONTHLY_API_LIMIT_EXCEEDED`.\n\n## FAQ\n\n**Can I share a token across services?**\nTechnically yes, but don't. Per-service tokens let you rotate and revoke independently, and the usage dashboard is far more useful when each token has one consumer.\n\n**My token says \"Forbidden\" but I think it should work.**\nThe error response names the missing permission. Cross-check it against the [API Endpoints](/docs/endpoints) reference.\n\n**Does the token carry my plan's limits?**\nYes, limits are enforced at the account level, not the token level. A monitor-creation request from any of your tokens counts against your subscription's monitor cap.\n\n**Where is the machine-readable list of endpoints and permissions?**\n[`/api/docs/v1-openapi.json`](https://app.uptimewarden.online/api/docs/v1-openapi.json), the canonical OpenAPI 3.0 spec.\n\n## Related\n\n- [Audit Logging](/docs/audit-logging): what is recorded about token use\n- [Subscription Plans](/docs/subscription-plans): token and call-quota limits per plan\n- [API Quick Start](/docs/quickstart): first `curl` call using a token\n- [API Endpoints](/docs/endpoints): permission required per endpoint","category":"api","tags":["api","tokens","auth","permissions","automation"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"API Tokens. UptimeWarden Documentation","metaDescription":"Issue, scope, rotate, and revoke UptimeWarden API tokens with fine-grained permissions and built-in time bounds.","icon":"Code","createdAt":"2026-10-12T22:06:41.950Z","updatedAt":"2026-10-12T22:06:41.950Z","publishedAt":"2026-10-12T22:06:41.950Z"},{"publicId":"01KJ7Q9ZTS2N0RFSTF11QBPJN3","locale":"en","translationGroup":"faq","slug":"en-frequently-asked-questions","title":"Frequently Asked Questions (FAQ)","description":"The most commonly asked questions and answers about UptimeWarden","body":"# Frequently Asked Questions (FAQ)\n\n## General Questions\n\n### What is UptimeWarden?\n\nUptimeWarden is an uptime monitoring platform that monitors your websites, APIs, and services 24/7. When your services experience downtime, you receive instant notifications, minimizing downtime and providing transparent status information to your customers.\n\n### What is a monitor?\n\nA monitor is a target service that is automatically checked at a defined interval. For example, checking `https://example.com` every 1 minute is a monitor.\n\n### How is uptime percentage calculated?\n\n```\nUptime % = (Total time - Downtime) / Total time × 100\n```\n\nFor example, if there were 43 minutes of downtime in a month (30 days = 43,200 minutes):\n- Uptime = (43,200 - 43) / 43,200 × 100 = **99.90%**\n\n### How long is data retained?\n\nMonitoring data is retained based on plan type:\n- **Free plan**: 30 days\n- **Starter**: 90 days\n- **Professional**: 365 days\n- **Enterprise**: Custom duration\n\n---\n\n## Monitoring Questions\n\n### What is a false positive and how to prevent it?\n\nA false positive is receiving an outage notification when your service is actually running. Temporary network issues, DNS delays, or server load can cause this.\n\n**Prevention methods:**\n1. **Add retries**: Set 2-3 retries in monitor settings\n2. **Increase timeout**: Too low timeout leads to false alarms\n3. **Use regional monitoring**: An alarm from a single region may be a local issue\n\n### How short should the check interval be?\n\nThis depends on your service's criticality:\n- **E-commerce, finance**: 30 seconds - 1 minute\n- **SaaS application**: 1-3 minutes\n- **Corporate website**: 3-5 minutes\n- **Blog/content site**: 5-10 minutes\n\n### Why does my monitor keep showing \"down\"?\n\nPossible reasons:\n1. **Firewall block**: Add our check servers' IP addresses to your whitelist\n2. **Low timeout**: Increase the timeout value\n3. **Wrong URL**: Check the monitor URL\n4. **Authentication issue**: Verify authentication credentials\n5. **Geographic restriction**: Ensure the check region can access your service\n\n### Can I monitor internal network services?\n\nYes! You can monitor internal network services by deploying a **Private Agent**. The agent runs inside your network and reports check results to UptimeWarden. See the **Regional Monitoring** documentation for details.\n\n---\n\n## Notification Questions\n\n### What notification channels are supported?\n\n- **Email**: On all plans\n- **SMS**: Via Twilio integration\n- **WhatsApp**: Via Twilio integration\n- **Voice Call**: Via Twilio integration\n- **Webhook**: On all plans\n- **Push Notification**: Via mobile app\n\n### Why am I not receiving notifications?\n\nChecklist:\n1. Is the notification channel properly configured?\n2. Is the notification type active on the monitor? (down, recovery, etc.)\n3. Are the recipient details (email, phone) correct?\n4. Are quiet hours active?\n5. Have you checked the spam/junk folder? (for email)\n\n### I'm getting too many notifications, how can I reduce them?\n\n1. **Increase retries**: Notifications won't fire for temporary issues\n2. **Increase check interval**: Less frequent checks means fewer notifications\n3. **Adjust notification channels**: Choose which channels are active per monitor\n\n---\n\n## Status Page Questions\n\n### Is the status page public?\n\nYes, status pages are public by default. You can optionally add password protection. They're accessed via a custom URL that you can share with your customers for transparent service status.\n\n### Can I create multiple status pages?\n\nYes, you can create separate status pages for different customer groups or service categories. Each status page can display different sets of monitors.\n\n---\n\n## Subscription and Billing Questions\n\n### How do I upgrade my plan?\n\n1. Go to the **Billing** menu\n2. Select your new plan\n3. Enter/confirm your payment details\n4. The upgrade is activated immediately\n\n### Can I downgrade my plan?\n\nYes, you can downgrade at the end of the current period. All features remain active during the current period. New plan limits apply at period end. Some monitors may be automatically paused if limits are exceeded.\n\n### What payment methods are available?\n\n- **Credit card**: Visa, Mastercard (3D Secure supported)\n- **Debit card**: All debit cards\n\n### Can I get an invoice?\n\nYes, an e-invoice is automatically generated after each payment. You can access past invoices from the **Billing** page.\n\n### What is an add-on?\n\nAdd-ons are purchasable packages that add extra capacity to your current plan. For example:\n- Extra monitor capacity\n- Additional SMS credits\n- Extra agent slots\n\nSee the **Add-on Purchase** documentation for details.\n\n---\n\n## Security Questions\n\n### Is my data safe?\n\n- All data is stored encrypted\n- HTTPS communication\n- European-based servers\n- Regular security audits\n\n### Is two-factor authentication (2FA) available?\n\nYes, you can enable two-factor authentication for account security. Enable 2FA from your **Profile** settings.\n\n### What should I do if my API key is compromised?\n\n1. Go to the **API Portal** page immediately\n2. Revoke the current key\n3. Create a new key\n4. Update the new key in your applications\n\n---\n\n## Technical Questions\n\n### What is the API rate limit?\n\nAPI requests are limited based on your plan:\n- **Free**: 60 requests/minute\n- **Starter**: 120 requests/minute\n- **Professional**: 300 requests/minute\n- **Enterprise**: Custom limit\n\n### What is the webhook payload format?\n\nWebhooks are sent in JSON format. See the **API Documentation** page for detailed information and example payloads.\n\n### How can I get support?\n\n- **Documentation**: Review these pages\n- **Email**: Send an email to our support team\n- **In-app**: Send feedback via the feedback button","category":"faq","tags":["faq","questions","help","support"],"order":1,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"The most commonly asked questions and answers about UptimeWarden","icon":"HelpCircle","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01KJ7Q9ZTT5MQCRQDF6MTP1GKJ","locale":"en","translationGroup":"troubleshooting","slug":"en-troubleshooting","title":"Troubleshooting Guide","description":"Common issues and resolution steps — monitoring, notification, and connection problems","body":"# Troubleshooting Guide\n\nThis guide covers common issues you may encounter while using UptimeWarden and their solutions.\n\n## Monitoring Issues\n\n### Monitor Keeps Showing \"Down\"\n\n**Possible Cause 1: Firewall Block**\n\nOur check servers' IP addresses may be blocked by your firewall.\n\n**Solution**: Allow UptimeWarden check server IP addresses in your firewall rules. Contact our support team for the current IP list.\n\n---\n\n**Possible Cause 2: Low Timeout Value**\n\nYour service is responding but exceeding the configured timeout.\n\n**Solution**:\n1. Go to monitor settings\n2. Increase the timeout value (e.g., 30 → 60 seconds)\n3. Check your service's normal response time\n\n---\n\n**Possible Cause 3: Geographic Restriction**\n\nYour service may be blocking requests from certain regions.\n\n**Solution**:\n- Change the check region to the one closest to your service\n- Review your geographic blocking rules\n- Use a private agent to check from your own network\n\n---\n\n**Possible Cause 4: SSL Certificate Issue**\n\nChecks will fail if you're using a self-signed or expired certificate.\n\n**Solution**:\n- Test environment: Enable \"Skip SSL verification\" in monitor settings\n- Production environment: Renew your certificate\n\n### Response Times Appear Very High\n\n**Possible Cause**: Distance between the check region and your service\n\n**Solution**:\n1. Check the monitor's check region\n2. Select the region closest to your service\n3. Adjust response time thresholds based on region\n\n### I'm Getting False Positives\n\n**Solution steps:**\n1. **Add retries**: Set 2-3 retries in monitor settings\n2. **Increase timeout**: Too low timeout causes false alarms on temporary delays\n3. **Change region**: Try a different check region\n4. **Remove content check**: Dynamic content changes may cause keyword matching issues\n\n---\n\n## Notification Issues\n\n### Email Notifications Not Arriving\n\n**Checklist:**\n\n1. **Check spam folder**: Emails may be caught by spam filters\n2. **Verify email address**: Check the recipient email address in monitor settings\n3. **Check notification channel**: Is the \"email\" notification channel active on the monitor?\n4. **Check notification type**: Are \"Down\" and \"Recovery\" notifications active?\n5. **Inbox full?**: Check your email account's storage space\n\n**Still not arriving?**\n- Check if emails from `noreply@` are being blocked\n- If using corporate email, consult your IT team\n\n### SMS Notifications Not Arriving\n\n**Checklist:**\n\n1. Is the phone number in the correct format? (Including country code: `+15551234567`)\n2. Is the SMS notification channel active on the monitor?\n3. Does your plan support SMS? (Starter and above)\n4. Is your SMS credit balance sufficient?\n\n### Webhook Not Working\n\n**Check steps:**\n\n1. **Is the URL accessible?**: Ensure the webhook URL is accessible from outside\n2. **Use HTTPS**: Prefer HTTPS webhook URLs for security\n3. **Timeout**: Your webhook endpoint must respond within 10 seconds\n4. **Status code**: Your endpoint must return a `200` or `2xx` status code\n5. **Payload**: Ensure you're correctly processing the request body\n\n**To test**: Use the \"Send Test\" button in webhook settings.\n\n### Getting Too Many Notifications\n\n**Solutions:**\n\n1. **Increase retry count**: Notifications won't trigger for temporary issues\n2. **Increase check interval**: Less frequent checks = fewer notifications\n3. **Use notification grouping**: Enable from settings\n4. **Define quiet hours**: Disable notifications during scheduled maintenance periods\n\n---\n\n## Account and Access Issues\n\n### Can't Log In\n\n1. **Reset your password**: Use the \"Forgot Password\" link\n2. **Clear browser cache**: Clear cookies and cache, then try again\n3. **Try a different browser**: Browser extensions may cause issues\n4. **2FA issue**: Check the code in your authenticator app\n\n### Page or Feature Not Visible\n\n**Possible Cause**: Permission restriction\n\nSome pages and features are subject to role-based access control. If you don't have access:\n1. Ask your team admin to assign the appropriate role\n2. Check which permissions are defined for which roles from the **Settings → Role Permissions** page\n\n### Plan Limit Exceeded Error\n\n**Solution:**\n1. Check your current usage from the Dashboard\n2. Delete or pause unnecessary monitors\n3. Upgrade your plan\n4. Purchase add-ons for extra capacity\n\n---\n\n## Status Page Issues\n\n### Status Page Not Updating\n\n1. **Check monitor connection**: Are the correct monitors added to the status page?\n2. **Check publish status**: Is the status page in \"published\" state?\n3. **Browser cache**: Hard-refresh the page (Ctrl+Shift+R)\n\n### Can't Access Status Page\n\n1. **Check URL**: Ensure access is with the correct slug\n2. **DNS settings**: If using a custom domain, verify the DNS CNAME record\n\n---\n\n## Agent Issues\n\n### Private Agent Not Connecting\n\n**Check steps:**\n\n1. **Is the token correct?**: Check the token in the agent configuration\n2. **Network access**: Can the agent server reach the UptimeWarden API?\n3. **Firewall**: Are outbound connections being blocked?\n4. **Docker status**: Is the container running? Check with `docker ps`\n5. **Check logs**: Inspect errors with `docker logs uptimewarden-agent`\n\n### Agent Shows \"Offline\"\n\nThe agent sends heartbeats at regular intervals. If heartbeats stop, the agent is marked as \"offline\".\n\n**Solution:**\n1. Ensure the agent container/process is running\n2. Check network connectivity\n3. Restart the agent\n\n---\n\n## Still Can't Find a Solution?\n\nIf the steps above didn't resolve your issue:\n\n1. **Create a support ticket**: Use the feedback button in the app\n2. **Send an email**: Write to our support email address with a detailed description\n3. **Include this information**:\n   - Your account email address\n   - Problem monitor name/ID\n   - When and how the error occurred\n   - Screenshot (if available)","category":"faq","tags":["troubleshooting","issues","errors","solutions","debug"],"order":2,"parentSlug":null,"published":true,"version":1,"metaTitle":null,"metaDescription":"Common issues and resolution steps — monitoring, notification, and connection problems","icon":"HelpCircle","createdAt":"2026-02-24T11:42:16.028Z","updatedAt":"2026-02-24T11:42:16.028Z","publishedAt":"2026-02-24T11:42:16.028Z"},{"publicId":"01M4S2EP637FVR3EFF7BTEYA4X","locale":"en","translationGroup":"faq","slug":"frequently-asked-questions","title":"Frequently Asked Questions","description":"The questions we hear most often, pricing, plan changes, refunds, regions, agents, KVKK / GDPR, mobile app, and API access.","body":"# Frequently Asked Questions\n\nThese are the questions we get most often from prospects and customers. If you cannot find your question here, see [Troubleshooting](/docs/troubleshooting) for operational issues, or open a support ticket from the dashboard.\n\n## Pricing and plans\n\n### What does UptimeWarden cost?\n\nFive publicly listed plans: **Free**, **Hobby**, **Starter**, **Professional**, and **Enterprise** (custom). Yearly billing is discounted. For current prices and the full breakdown see [Subscription Plans](/docs/subscription-plans).\n\n### Is there a free plan?\n\nYes. Free is not a stripped-down demo, it includes 20 monitors, 30-day retention, 3-minute checks, a second region that re-checks every failure (an alert it cannot confirm is still sent, labelled unverified), email, push, and webhook channels, 10 Wardy questions a day and one postmortem draft a month. SMS, WhatsApp, voice, and health forecasts are not included on Free.\n\n### How do I change plans?\n\nOpen **Settings → Billing → Change plan**. Upgrades are immediate with prorated billing; downgrades take effect at the end of the current cycle. If your usage exceeds the lower plan's limits, you are asked to reduce usage before downgrading.\n\n### Can I get a refund?\n\nYes, a 30-day money-back guarantee for first-time subscribers and a 14-day withdrawal window for returning subscribers; yearly downgrades refund the unused portion on a pro-rated basis. Add-on refunds are reviewed case by case. For plan and refund details, see [Subscription Plans](/docs/subscription-plans).\n\n### How does the yearly discount work?\n\nYearly billing is roughly 17 to 20 percent cheaper than 12 monthly charges. You pay once for the year; cancelling mid-year refunds the unused portion on a pro-rated basis.\n\n### Do you bill in TRY?\n\nPlans and add-ons are priced in USD, but charges are always settled in Turkish Lira (TRY), converted at checkout using the current market exchange rate. You can view your payment history under **Settings → Billing**.\n\n## Capacity and limits\n\n### How many monitors can I run?\n\nIt depends on your plan: Free starts at 20 monitors, and higher plans offer larger ceilings (unlimited on Enterprise). See the [pricing page](https://uptimewarden.online/pricing) for current values. You can buy more via [Add-on packs](/docs/addon-purchase).\n\n### How many regions does each plan run from?\n\nMulti-region consensus re-checks a monitor from other regions when it goes down. The verification (witness) region cap scales with your plan: Free = 2 (threshold fixed at 2 of 2; a split is still sent, labelled unverified), Hobby and Starter = up to 3, Professional = up to 5, Enterprise = up to 6. Adjustable consensus is unlocked at Starter and above. Choosing the region a monitor runs from is a separate limit: Professional can use up to 5 regions, Enterprise all regions, and on Free, Hobby and Starter monitors run from the default region.\n\n### How long is data retained?\n\nRetention is plan-dependent: Free starts at 30 days, and higher plans offer longer retention (unlimited on Enterprise). See the [pricing page](https://uptimewarden.online/pricing) for current values. To extend it, upgrade to a higher plan (there is no separate retention pack).\n\n### Can I export my data?\n\nYes, you can download monitor performance data as CSV, JSON, or Excel from the export dialog on the **Monitors** page; this is available on every plan with API access (including Free). For a full GDPR export of your personal data, use **Settings → Data & Privacy**.\n\n## Monitoring questions\n\n### Server monitoring or website monitoring?\n\nUptimeWarden is **uptime monitoring**, we check the availability and response of an endpoint from the outside (HTTP, TCP, UDP, SSL, WebSocket, gRPC, MCP, ping). For server-internal metrics (CPU, memory, disk), use the **self-hosted agent** running on your hosts. The agent reports back to UptimeWarden but it complements an APM rather than replacing one.\n\n### What's the difference between server-side checks and the self-hosted agent?\n\nServer-side checks run from our edge in 5 regions, anything publicly reachable can be checked. The **self-hosted agent** is a lightweight binary you install on your own host; it runs the same checks from inside your network (useful for private endpoints, VPN-only services, internal APIs).\n\n### How fast can I check?\n\nIt depends on your plan: Free checks every 3 minutes, and higher plans check more often (down to every 30 seconds on Enterprise). See the [pricing page](https://uptimewarden.online/pricing) for current values. The lower bound is enforced server-side.\n\n## Compliance\n\n### Are you KVKK / GDPR compliant?\n\nUptimeWarden is built for KVKK (Law 6698) and GDPR alignment: granular consent records, Article 11 data-subject rights as self-service flows, a 30-day soft-delete grace before permanent deletion runs, and personal-data redaction before any AI prompt leaves the platform. For the controller / processor split and what is implemented vs. configurable, see [KVKK & Privacy](/docs/kvkk-compliance) and [GDPR Export & Account Deletion](/docs/gdpr-export-delete). Export and deletion are self-serve under **Settings → Privacy** and **Settings → Account**.\n\n### Do you sign DPAs?\n\nA bilingual (Turkish and English) Data Processing Agreement is offered as part of the **Enterprise tier**. Request the legally reviewed version from `sales@uptimewarden.online`. For other plans, the master Terms of Service plus the KVKK and Privacy page describe the same processor stance.\n\n### Where is my data stored?\n\nIn Microsoft Azure data centres in the European Union: the primary database and the application platform are in **Sweden**, and backups stay in the EU. Monitor checks run from five locations (Sweden Central, Sydney, East Asia, Phoenix, São Paulo); the locations outside the EU run checks and send results to the EU, and do not store customer data. AI requests go only to Microsoft Azure, which does not store prompts or outputs and does not use them for training. For customers who need \"all data must stay in Türkiye,\" the right answer is usually a dedicated or on-premise deployment, talk to `sales@uptimewarden.online`.\n\n## Status pages and branding\n\n### How many status pages can I create?\n\nFree 1, Hobby 2, Starter 3, Professional 10, Enterprise unlimited. If your account already has more pages than your plan allows, for example after a downgrade, those pages keep working and stay published; only creating a new page is refused.\n\n### Can I host my status page on my own domain?\n\nYes, you can map a subdomain like `status.acme.com`. Domain ownership is verified with a DNS TXT record. Custom domains are served over HTTP; there is no automatic SSL/Let's Encrypt certificate provisioning yet. See [Custom Domain Setup](/docs/custom-domain-setup). Available on Professional and above.\n\n### Can I white-label the dashboard and emails?\n\nWhite-label is **Enterprise only**. It rebrands the dashboard, email templates, and status pages, and removes \"Powered by UptimeWarden\" badges. See [White-Label Branding](/docs/white-label-branding).\n\n### Can I embed a status badge on my site?\n\nA drop-in embed snippet (script/iframe/badge) is not available yet, it is on the roadmap. For now, you can pull the data into your own site using the status page's public JSON API (`GET /api/public/status/:slug`). See [Embed the Status Widget](/docs/embed-status-widget).\n\n## API and integrations\n\n### Do you have an API?\n\nYes. Public API v1. See [Getting Started](/docs/getting-started) and the [Endpoints reference](/docs/endpoints). API access depends on your plan; the dashboard's **Settings → Billing → Plan details** is authoritative for whether your current plan includes it.\n\n### Are there Terraform modules?\n\nYes, the official UptimeWarden Terraform provider lets you manage monitors, webhooks, and status pages as HCL. See [Terraform Provider](/docs/developers-terraform-provider). The OpenAPI document at `/api/docs/v1-openapi.json` also powers code generators.\n\n### Webhooks for incidents?\n\nYes, configure outgoing webhooks in **Settings → Notifications → Webhooks**. The payload follows a stable schema; delivery is at-least-once with retries. Available on all plans. The number of webhook configs you can create varies by plan (3 on Free). Every send counts against the monthly webhook quota (1,000 per month on Free), including Slack, Microsoft Teams, Telegram and Discord sends.\n\n## Mobile and push\n\n### Is there a mobile app?\n\nYes, iOS and Android. Biometric sign-in, an in-app incident feed, and push notifications are included. Sign in with your account email and password; your team role on the dashboard carries over.\n\n### Do push notifications cost extra?\n\nPush counts against your monthly push quota (Free is limited; paid plans include higher caps). To get a higher quota, upgrade to a higher plan, there is no separate push add-on pack. See [Add-on Purchase](/docs/addon-purchase) for the packs that do exist.\n\n## Account and team\n\n### How many seats do I get?\n\nSeat counts scale with plan tier. Roles are Admin, Editor, and Reader. See [Roles & Permissions](/docs/roles-permissions) and [Team Management](/docs/team-management).\n\n### Can I transfer ownership?\n\nYes, open **Settings → Account → Transfer ownership**. The flow has two-step confirmation; the new owner must accept.\n\n### How do I cancel my account?\n\nOpen **Settings → Privacy → Delete account**. The account is marked for deletion and a 30-day grace period begins. You can reverse it any time inside the window via **Settings → Account → Cancel deletion**; once it expires, the permanent deletion runs and related audit-log entries are anonymised. Full flow: [GDPR Export & Account Deletion](/docs/gdpr-export-delete).\n\n## Still stuck?\n\nOpen a support ticket from the dashboard, email **support@uptimewarden.online**, or check the operational issues page in [Troubleshooting](/docs/troubleshooting).","category":"faq","tags":["faq","pricing","plans","refunds","kvkk","gdpr","regions","agents"],"order":10,"parentSlug":null,"published":true,"version":1,"metaTitle":"Frequently Asked Questions. UptimeWarden Documentation","metaDescription":"Top customer questions about UptimeWarden, pricing, free plan, plan changes, KVKK / GDPR, mobile app, regions, agents, API access, and more.","icon":"HelpCircle","createdAt":"2026-10-12T22:06:41.860Z","updatedAt":"2026-10-12T22:06:41.860Z","publishedAt":"2026-10-12T22:06:41.860Z"},{"publicId":"01M4S2EP6CZEACHRKK8K6DW7SW","locale":"en","translationGroup":"troubleshooting","slug":"troubleshooting","title":"Troubleshooting","description":"Common operational issues, false-down alerts, slow response times, certificate warnings, webhook delivery failures, push not arriving, OAuth sign-in problems.","body":"# Troubleshooting\n\nOperational issues, ordered by how often we see them in support tickets. Each scenario lists the symptom, the most likely cause, and the steps to fix it.\n\n> Looking for product or pricing questions instead? See [Frequently Asked Questions](/docs/frequently-asked-questions).\n\n## Monitor shows DOWN but my service is UP\n\n**Symptom**: The dashboard reports the monitor as down and you have received an alert, but your browser confirms the service responds.\n\n**Likely causes**:\n\n- **Geographic block**: your service is firewalled away from the region UptimeWarden checks from.\n- **Cloudflare or WAF**: bot-protection challenges return 403 or 503; UptimeWarden's user agent (`UptimeWarden/1.0.0`) is being blocked.\n- **Single-region transient**: one region failed but consensus held, so you should not have been paged. If you were paged, the confirmation threshold may have been lowered.\n\n**Fix**:\n\n1. Open **Monitors → [monitor] → Recent results**. Each row shows the region, status code, latency, and a response snippet. The pattern usually reveals one of the causes above.\n2. Allowlist our user agent (`UptimeWarden/1.0.0`) in your WAF. For region egress IP ranges, contact `support@uptimewarden.online`.\n3. Reset the confirmation threshold to its default of 2 (the consensus threshold is configurable on Starter and above) under **Monitor → Settings → Multi-region**.\n\n## Response time alarm fires constantly\n\n**Symptom**: Frequent response-time threshold alerts even though uptime stays at 100%.\n\n**Likely cause**: The threshold is tighter than your service's natural variance. On the Free plan the lowest threshold you can set is 5000 ms; higher plans allow lower thresholds, but most services do not need that.\n\n**Fix**:\n\n1. Open **Monitors → [monitor] → Stats → Response time histogram**.\n2. Pick the p95 of your last 7 days; set the threshold to p95 multiplied by 1.5.\n3. A single slow check never alerts: the alert waits for **N slow checks in a row** (default 3, the same N that confirms a recovery). If alerts still come often, the service is slow for several checks at a time; the threshold from step 2 is the fix.\n\n## SSL \"expires soon\" but I just renewed\n\n**Symptom**: An SSL alert fires within hours of a successful renewal.\n\n**Likely cause**: SSL data is recomputed on a daily schedule; the cache has not refreshed yet.\n\n**Fix**:\n\n1. Open **Monitors → [monitor] → SSL → Refresh now**. The next SSL check runs immediately.\n2. If still wrong, the certificate chain may have been deployed to only one of your origins (load-balancer mismatch). Verify with `openssl s_client -connect <host>:443 -servername <host>`.\n\n## Webhook delivery failing\n\n**Symptom**: Email notifications arrive but your webhook receiver never sees them. **Settings → Notifications → Webhooks → [webhook] → Recent deliveries** shows failed.\n\n**Likely causes**:\n\n- The receiver returns a non-2xx response (anything outside 200-299 is treated as a failure).\n- The receiver rejects the user agent or HMAC signature.\n- The receiver is slow: the dispatch timeout defaults to 30 seconds (configurable per webhook).\n\n**Fix**:\n\n1. Inspect the **Recent deliveries** row, it shows the request body, response code, and response body.\n2. Verify your HMAC secret matches what you saved in UptimeWarden. When a secret is set, the signature is sent over the raw body in two headers: `X-Webhook-Signature` (raw HMAC-SHA256, hex) and `X-Webhook-Signature-256: sha256=<hex>`.\n3. Make sure your receiver replies before the timeout (default 30 seconds), return 200 quickly and queue the work asynchronously.\n4. Click **Replay** on a failed delivery to retry without waiting for the next event.\n\n## Push notifications not arriving on mobile\n\n**Symptom**: The mobile app shows the alert in the in-app feed but no system push appears.\n\n**Likely causes**:\n\n- Notification permissions revoked at the OS level.\n- Push registration expired (after iOS or Android updates, or app reinstall).\n- Do Not Disturb or Focus mode active.\n\n**Fix**:\n\n1. **iOS**: Settings → Notifications → UptimeWarden → ensure *Allow Notifications* is on; *Banners*, *Sounds*, and *Badges* enabled.\n2. **Android**: App info → Notifications → all categories on.\n3. In the app: **Settings → Notifications → Re-register device**, generates a fresh push registration.\n4. Verify on the dashboard side: **Settings → Notifications → Push devices** lists registered devices and their last-seen timestamp.\n\n## Forgot my password / cannot sign in\n\n**Symptom**: You cannot remember your password or otherwise cannot sign in.\n\n**Fix**:\n\n1. Use the **Forgot password** link on the sign-in screen. A 6-digit verification code is emailed to your address; enter it and set a new password.\n2. If the email with the code does not arrive, check your spam folder and confirm you typed your email address correctly.\n3. After 5 failed attempts your account is temporarily locked; if that happens, wait 30 minutes or email `support@uptimewarden.online`.\n\n## OAuth sign-in (Google / GitHub) loops back to the sign-in page\n\n**Symptom**: You click *Continue with Google*, complete the consent, and get redirected back to the sign-in page with no error.\n\n**Likely causes**:\n\n- The browser blocks third-party cookies (Safari Intelligent Tracking Prevention).\n- The OAuth identity does not match an UptimeWarden account email.\n\n**Fix**:\n\n1. In Safari: Settings → Privacy → uncheck *Prevent cross-site tracking* for app.uptimewarden.online (or use the password fallback once).\n2. Make sure your Google or GitHub email is the same as your UptimeWarden email. An OAuth account is auto-linked to an existing password account only when the email is verified on both sides; otherwise you will need to register a separate account with that email, or sign in with a password.\n3. If the problem persists, email `support@uptimewarden.online`.\n\n## Payment missing or billing details wrong\n\n**Symptom**: A renewal fired but the transaction does not appear in your payment history under **Settings → Billing**, or the details in your billing profile are wrong.\n\n**Fix**:\n\n1. Refresh the page; payment transactions are listed under **Settings → Billing → Payment history**.\n2. If the transaction still does not appear, the payment may have failed; failed payments get a 7-day grace period. Check your card details.\n3. For wrong billing-profile data, edit **Settings → Billing → Profile**. For refunds, email `support@uptimewarden.online`, first-time purchasers get a 30-day money-back guarantee, returning customers a 14-day withdrawal right.\n\n> **Coming soon**: A full billing system with PDF invoices, e-Fatura/e-Arşiv, and VAT (KDV) breakdown is planned. For now, if you need a formal document, request one at `support@uptimewarden.online`.\n\n## Agent stuck on \"Pending heartbeat\"\n\n**Symptom**: A self-hosted agent shows up in **Settings → Agents** but its status is \"pending\" and no checks are running.\n\n**Likely causes**:\n\n- The agent cannot reach `app.uptimewarden.online` (firewall or proxy).\n- The agent token was revoked or expired.\n- Time skew on the host (TLS handshake fails when the clock drifts beyond 5 minutes).\n\n**Fix**:\n\n1. From the agent host: `curl -v https://app.uptimewarden.online/api/health`, must return 200.\n2. Check the agent's logs (via your service manager or container logs), look for HTTP 401 or TLS errors.\n3. Sync time: `sudo timedatectl set-ntp true`.\n4. Recreate the agent with a fresh token from **Settings → Agents → New agent**.\n\n## Monitor \"consumed\" the daily limit but I'm under quota\n\n**Symptom**: Monitor creation returns a \"limit exceeded\" message, but the **Usage** page shows you have headroom.\n\n**Likely cause**: Your current limits have not refreshed yet. Plan and add-on limits are cached for about 15 minutes; an add-on you just bought may not be live yet.\n\n**Fix**: Wait 15 minutes, or open **Settings → Billing → Refresh limits** to force a refresh.\n\n## Status page custom domain stuck on \"Pending\"\n\n**Symptom**: You configured the CNAME 30+ minutes ago, but the status page still shows \"Pending\" verification.\n\n**Fix**: See the troubleshooting section of [Custom Domain Setup](/docs/custom-domain-setup), most cases are DNS typos, conflicting A records, or strict CAA records.\n\n## Still stuck?\n\n- Open a support ticket from **Help → Contact support** in the dashboard.\n- Email **support@uptimewarden.online**.\n- For incidents impacting many customers, check our public [status page](https://status.uptimewarden.online).","category":"faq","tags":["troubleshooting","false-positive","ssl","webhook","push","oauth"],"order":20,"parentSlug":null,"published":true,"version":1,"metaTitle":"Troubleshooting. UptimeWarden Documentation","metaDescription":"Diagnose and fix common UptimeWarden issues, flapping monitors, false-down alerts, SSL warnings, webhook delivery, push notifications, OAuth sign-in.","icon":"HelpCircle","createdAt":"2026-10-12T22:06:41.868Z","updatedAt":"2026-10-12T22:06:41.868Z","publishedAt":"2026-10-12T22:06:41.868Z"}],"total":109}