Apprise

Send notifications to dozens of services from one library

Automation & Workflows ★ 17.4k stars Easy setup BSD-2-Clause

Apprise is a notification library and CLI that can push messages to dozens of services such as email, Telegram, Discord, and webhooks through a single unified interface. It is commonly embedded in automation scripts and other self-hosted apps.

Key features

  • Dozens of notification targets
  • Unified URL syntax
  • CLI and library
  • Attachment support

Pros & cons

Strengths

  • Massive service coverage
  • Easy to embed

Trade-offs

  • Not a standalone app
  • Configuration sprawl possible

Apprise replaces

Last reviewed Aug 26, 2026 · 805 words

You do not run Apprise. Things you already run call it. It is a Python library and CLI, about 17,200 stars and BSD-2-Clause, that turns one URL string into a delivered message on any of roughly 100 services: Telegram, Discord, Matrix, Slack, email, ntfy, Gotify, Pushover, SMS gateways, plain webhooks. The point is that every app which embeds Apprise inherits that whole list without writing an integration per service, and every self-hoster who learns the URL syntax once can wire notifications into anything with a shell.

One URL per destination is the entire idea

An Apprise URL encodes the service and its credentials in a scheme. A Telegram bot is tgram://123456789:AAExampleBotToken/-100987654321, a Discord webhook is discord://WebhookID/WebhookToken, an ntfy topic is ntfy://ntfy.example.com/homelab, and a Gotify server is gotify://gotify.example.com/AppToken. Email is mailto://user:[email protected]. Because the format is uniform, you can store a list of these URLs in a file, tag them, and send to a subset by tag:

# ~/.apprise
backups,critical=tgram://123456789:AAExampleBotToken/-100987654321
backups=ntfy://ntfy.example.com/homelab
critical=mailto://alerts:[email protected]

Then apprise -g critical -t "Disk 91% full" -b "/dev/sda1 on nas" reaches Telegram and email but not ntfy. Tags are the feature that keeps a growing setup sane, and they are the first thing to adopt.

The CLI is how it earns a place in cron

Install with pip install apprise (or your distro package), and a backup script gains a real notification in one line:

restic backup /srv --tag nightly && \
  apprise -g backups -t "restic ok" -b "$(hostname) nightly backup finished" || \
  apprise -g critical -t "restic FAILED" -b "$(hostname) exit code $?"

Add --attach /var/log/restic.log and the log rides along as an attachment on services that support it. This is the pattern for anything that finishes: certificate renewals, ZFS scrubs, docker compose pull runs. It needs 64 MB or less and nothing persistent, which is why it belongs in a cron job and not in a dashboard.

The API container is what other apps talk to

The library has a sibling project, Apprise API, shipped as the caronc/apprise Docker image on port 8000. It exposes the same URL scheme over HTTP so tools that cannot import Python can still use it. You either post URLs with each request or store a named configuration on the server and hit POST /notify/{key} with a JSON body containing title and body. Mount /config so stored configurations survive restarts, and keep it off the public internet; the stateless endpoint will happily relay to any URL it is handed.

services:
  apprise:
    image: caronc/apprise
    ports:
      - "8000:8000"
    volumes:
      - ./apprise-config:/config
    restart: unless-stopped

Where it already lives in your stack

You are probably using Apprise without knowing it. Uptime Kuma offers "Apprise" as a notification type and bundles the CLI in its official image, which is how it claims support for so many services. Sonarr, Radarr and the rest of the *arr family have an Apprise connection that points at the API container. Healthchecks has an Apprise integration when the library is installed alongside it. Home Assistant has an apprise notify platform. So the practical question is rarely "should I deploy Apprise" and more often "should every one of these apps hold its own copy of my Telegram token, or should they all point at one Apprise API with one stored config". The second answer is the correct one once you pass 3 apps.

Sprawl is the one real failure mode

The catalogue's warning about configuration sprawl is earned. Apprise makes it so cheap to add a destination that people end up with 6 apps each carrying slightly different URL lists, and rotating a single webhook token becomes an afternoon. Two rules prevent it: credentials live in one place (the API container's stored config, or one ~/.apprise on the host that runs cron), and apps reference tags, not URLs. If you also run ntfy or Gotify as your own push server, point Apprise at it and let that be the only thing your phone knows about; the automation category has the rest of the plumbing.

What I'd do

Run the Apprise API container with a single stored configuration keyed by tag, and point Uptime Kuma, the *arr apps and any n8n or script traffic at it. Keep the CLI installed on whichever host runs cron and use the same tags in a ~/.apprise file. Route everything to a self-hosted ntfy topic plus one email address for the critical tag. That is about 20 minutes of setup, after which adding a new notifying app is a URL, not a project.

Similar automation & workflows apps