---
title: "Uptime Kuma Phone Call Alerts: Make Your Phone Ring"
description: "Uptime Kuma ships 90+ notification providers but none that rings your phone. Here is how to add phone call alerts for downtime using one webhook."
date: 2026-08-28
author: Nooc
authorAvatarLink: /images/avatars/nooc.webp
authorLink: https://nooc.me
tags:
  - Uptime Kuma
  - self-hosted monitoring
  - phone call alerts
  - webhook notifications
  - uptime monitoring
  - on-call
---

# Uptime Kuma Phone Call Alerts: Make Your Phone Ring

Uptime Kuma supports more than 90 notification providers, but none of them makes your phone ring. To get a phone call when a monitor goes down, send Uptime Kuma's **Webhook** notification to an Echobell channel set to **Calling**. This guide covers the exact custom body to use, how to separate down alerts from recovery alerts, and the two mistakes that silently break the setup.

[Uptime Kuma](https://github.com/louislam/uptime-kuma) is the most popular self-hosted uptime monitor there is — roughly 90,000 GitHub stars, with 2.5.0 landing in August 2026. It checks HTTP endpoints, TCP ports, DNS records, Docker containers, and more, and it is genuinely excellent at detecting downtime.

Where it leaves you exposed is the last mile: getting the alert to a human who is asleep.

## Why Uptime Kuma cannot ring your phone on its own

Uptime Kuma's notification list is long — Telegram, Discord, Slack, email, Gotify, ntfy, and dozens more — but every one of them delivers a *message*. Messages are subject to your phone's ringer switch, Do Not Disturb, and iOS Focus Modes. At 03:00 that means the alert arrives and nothing happens.

There is no first-party "call my phone" provider. The options people usually land on are:

- **Twilio** — you can build voice calls on top of it, but Uptime Kuma's Twilio provider sends SMS. Voice means writing a bridge service, buying a number, and paying per call.
- **PagerDuty, Zenduty, Spike.sh, Splunk On-Call** — these do place calls, and they are full incident-management platforms with per-seat pricing to match. Right answer if you need rotations and escalation policies; heavy if you need a phone to ring.
- **SMS gateways** — an SMS still lands as a message, and on iOS a text does not break Focus Mode unless the sender is on your allow list.

A [feature request for VoIP call notifications](https://github.com/louislam/uptime-kuma/issues/3812) has been open on the Uptime Kuma repo for a while. In the meantime, the generic **Webhook** provider is the escape hatch — it can post anything to any URL, which is all you need.

## What you need

- A running Uptime Kuma instance (this guide is written against 2.x; the webhook custom body also works on 1.23+)
- Echobell installed ([App Store](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-uptime-kuma-phone-call-alerts-en&mt=8) / [Google Play](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid))
- Five minutes

Your Uptime Kuma instance needs outbound HTTPS to `hook.echobell.one`. It does **not** need to be reachable from the internet — this is an outbound webhook, so a monitor running on a home server or inside a private network works fine.

## Step 1 — Create a channel that calls you

In Echobell, create a channel named something like `Production Down`. Set its subscription notification type to **Calling**. This is the setting that matters: Calling alerts arrive as an incoming call screen and ring through iOS Focus Mode and Do Not Disturb, which a push notification does not.

Set the templates to:

```
Title: 🔴 {{monitor}} is down
Body: {{message}}
Target: {{target}}
```

Then copy the channel's **Webhook URL**. It looks like:

```
https://hook.echobell.one/t/<channel-token>
```

Treat that URL as a secret — anyone holding it can make your phone ring.

## Step 2 — Add Echobell as a webhook notification

In Uptime Kuma, go to **Settings → Notifications → Setup Notification** and fill in:

| Field | Value |
| --- | --- |
| Notification Type | `Webhook` |
| Friendly Name | `Echobell — Down` |
| Post URL | your Echobell webhook URL |
| Request Body | `Custom Body` |

Leave **Additional Headers** empty.

## Step 3 — Send a payload you can filter on

This is the step most guides skip, and it is the one that makes the difference between an alert system and a noise machine.

Paste this into **Custom Body**:

```json
{
  "monitor": "{{name}}",
  "target": "{{hostnameOrURL}}",
  "message": "{{ msg | strip_newlines }}",
  "up": "{{ heartbeatJSON['status'] }}"
}
```

Uptime Kuma renders custom bodies with Liquid and exposes these variables:

| Variable | What it holds |
| --- | --- |
| `{{name}}` | The monitor's friendly name |
| `{{hostnameOrURL}}` | The hostname or URL being checked |
| `{{status}}` | `🔴 Down`, `✅ Up`, or `⚠️ Test` |
| `{{msg}}` | The human-readable reason, e.g. `connect ECONNREFUSED 10.0.0.4:443` |
| `{{ monitorJSON['...'] }}` | The full monitor object |
| `{{ heartbeatJSON['...'] }}` | The full heartbeat object |

Two details in that payload are deliberate:

**`strip_newlines` on `msg`.** Uptime Kuma's message often contains line breaks, and a raw newline inside a JSON string is invalid JSON. Without the filter your webhook intermittently fails — only for the errors whose text happens to wrap. If your Uptime Kuma is new enough to have Liquid's `json` filter, `"message": {{ msg | json }}` (note: no surrounding quotes) is even safer, because it escapes quotes too.

**`heartbeatJSON['status']` instead of `{{status}}`.** The `status` variable renders as emoji text, which is awkward to compare against. The heartbeat status is a plain number:

- `0` — down
- `1` — up
- `2` — pending
- `3` — maintenance

Quoting it (`"up": "{{ ... }}"`) matters too, and Step 5 explains why.

## Step 4 — Stop recovery alerts from calling you

A single Uptime Kuma notification fires on both down *and* recovery. Left alone, this setup calls you when the service breaks and then calls you again when it fixes itself. The second call is the one that teaches people to ignore the first.

Split them using Echobell **conditions**, which are evaluated before anything is delivered:

**On the `Production Down` channel** (notification type **Calling**), set the condition to:

```
up == "0"
```

**Create a second channel** named `Production Recovered`, set its notification type to **Normal**, and give it the condition:

```
up == "1"
```

With templates:

```
Title: ✅ {{monitor}} is back up
Body: {{message}}
```

Then add a second webhook notification in Uptime Kuma — same custom body, same monitors, but pointing at the recovery channel's URL. Both notifications receive every event; each channel drops the half it does not care about.

The result: downtime rings, recovery arrives as a quiet push you read in the morning.

## Step 5 — Tune the monitor so it does not cry wolf

A call that turns out to be a two-second network blip is worse than no call, because the next one gets dismissed too. Three Uptime Kuma settings do most of the work here, all on the monitor itself:

- **Retries** — set to `2` or `3`. Uptime Kuma only marks the monitor down after this many consecutive failures, which filters out single dropped packets.
- **Heartbeat Retry Interval** — how fast it re-checks while failing. 20–30 seconds is a reasonable balance; combined with 3 retries you detect a real outage in about a minute.
- **Resend Notification if Down X times consecutively** — set this to something like `10` and Uptime Kuma will call again if the service is still down after ten more checks. It is a crude escalation policy, and it works.

If you want an unacknowledged call to keep trying immediately rather than waiting for the resend, turn on **Retry Failed Call** in Echobell's app settings.

## Only ring outside working hours

During the workday you are probably already looking at a dashboard, and a ringing phone is an interruption you did not need. Echobell's system time variables (all UTC) let one channel behave differently by hour:

```
up == "0" && (hour >= 17 || hour < 9)
```

That condition calls you only outside 09:00–17:00 UTC. Point a second, Normal-type channel at the inverse for daytime pushes:

```
up == "0" && hour >= 9 && hour < 17
```

Remember to offset for your own timezone — these variables are always computed in UTC. There is a fuller treatment in [time window notifications using UTC conditions](/en/blog/time-window-notifications-using-utc-conditions).

## Sharing the alert with your team

An Echobell channel can be shared with teammates via a subscription link, and every subscriber picks their own notification type. So the same monitor can ring the on-call engineer's phone while landing as a normal push for everyone else — no per-seat pricing, no separate routing rules in Uptime Kuma.

This also pairs well with the privacy posture of self-hosting in the first place: your monitors stay on your infrastructure, and Echobell keeps notification content and history on the device rather than on its servers.

## What this setup does not give you

Being honest about the boundary saves you a bad migration later. Echobell is a delivery layer, not an incident-management platform. It has no:

- On-call rotation schedules or follow-the-sun handoffs
- Escalation trees that page a second person automatically
- Incident timelines, acknowledgement tracking, or postmortem tooling

If your team needs those, you need PagerDuty, Grafana Cloud IRM, or similar. What this setup covers is the specific gap Uptime Kuma leaves open: converting a detected outage into a phone that actually rings. For solo operators, small teams, and homelabs, that is usually the entire requirement.

## Troubleshooting

**The Test button does nothing.** This is expected with the payload above, and it confuses everyone the first time. When you click Test, Uptime Kuma has no heartbeat to render, so `{{ heartbeatJSON['status'] }}` resolves to an empty string and neither condition matches. To test properly, create a throwaway TCP monitor pointing at a port nothing is listening on (`127.0.0.1:9`) and let it fail.

**The webhook fails intermittently.** Almost always the newline problem — check that `msg` goes through `strip_newlines`. It only breaks for error messages that happen to contain a line break, which is why it looks random.

**Echobell returns `success: false` with HTTP 200.** The channel token is wrong or the channel was deleted. Echobell answers `200` for an unknown-but-valid-length token, so check the JSON body, not the status code.

**HTTP 405.** The channel has **POST Only** enabled and something sent a GET. Uptime Kuma posts, so this usually means you tested the URL in a browser.

**Nothing rings, but the notification arrives.** The subscription's notification type is Normal or Time Sensitive, not Calling. Notification type is chosen per subscriber, so check it on the device that is not ringing.

## Frequently asked questions

### Can Uptime Kuma make a phone call natively?

No. Uptime Kuma has over 90 notification providers, but all of them deliver messages. Phone calls require routing a webhook to a service that can place one, such as Echobell, or using a paid incident-management platform.

### Does this work with a self-hosted Uptime Kuma behind a firewall?

Yes. The webhook is an outbound HTTPS request from your Uptime Kuma instance, so it only needs to reach `hook.echobell.one`. Your instance does not need a public address.

### Will the phone call bypass Do Not Disturb?

Yes. Echobell's Calling notification type presents as an incoming call, which rings through iOS Focus Mode and Do Not Disturb. See [bypassing iOS Focus Mode for critical alerts](/en/blog/how-to-bypass-ios-focus-mode-for-critical-alerts) for the details and the settings involved.

### How do I stop getting called when the service recovers?

Use two channels with conditions — `up == "0"` for the calling channel and `up == "1"` for a normal-priority recovery channel — and point a webhook notification at each. Step 4 above walks through it.

### Can several people be called for the same monitor?

Yes. Share the channel with your teammates and each subscriber chooses their own notification type. Everyone subscribed to the calling channel gets rung.

## Wrap-up

The setup is one webhook, one custom body, and two conditions. It leaves your Uptime Kuma monitors, retry logic, and status pages exactly as they are, and it closes the gap between "the monitor noticed" and "a human noticed."

[Download Echobell for iPhone](https://apps.apple.com/app/apple-store/id6743597198?pt=128151925&ct=blog-uptime-kuma-phone-call-alerts-en&mt=8) or [get it on Google Play](https://play.google.com/store/apps/details?id=one.echobell.echobellandroid), then wire up one non-critical monitor first and let it fail on purpose. Trust the path before you rely on it.

---

## Related

- [Uptime Kuma integration docs](/en/docs/developer/uptime-kuma)
- [Channel conditions reference](/en/docs/conditions)
- [Upptime alerts with Echobell](/en/blog/upptime-alerts-with-echobell)
- [Phone call alerts when your API goes down](/en/blog/phone-call-alerts-api-downtime)
- [A developer's guide to fixing alert fatigue](/en/blog/fix-alert-fatigue-developer-guide)
