# Apprise: One Notification Library for Telegram, Discord, Slack and Most Everything Else

> Apprise is a BSD-2-Clause Python library and CLI that turns a single URL syntax into notifications for Telegram, Discord, Slack, Gotify and many other services. It suits developers and sysadmins who are tired of writing a new integration per platform.

**caronc/apprise** — Apprise - Push Notifications that work with just about every platform!

- Repository: https://github.com/caronc/apprise
- Website: https://hub.docker.com/r/caronc/apprise
- Stars: 17,391 · Forks: 668
- Language: Python
- License: BSD-2-Clause
- Published: 2026-08-08 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/caronc-apprise

## The problem Apprise solves, and who ends up using it

Every notification service has its own authentication scheme, payload shape and endpoint. A team that wants alerts in Telegram, Discord and Slack writes three integrations and maintains three sets of credentials. Apprise's premise is that you write none of them. The README states that developers "no longer need to research each and every one out there" and that system administrators and DevOps staff get the same coverage through the apprise command line tool that ships with the package. The audience is therefore narrow and specific: Python developers embedding notifications in an application, and operators who want a shell command for alerting. It is not aimed at end users who want a phone app, despite the word appearing in search queries. The pyproject.toml classifiers list Intended Audience as Developers and System Administrators, which matches the README's framing.

## How a service URL becomes a delivered message

The mechanism is URL-driven. Each supported service has a Service ID and an example syntax, so a Discord webhook is discord://webhook_id/webhook_token and a Gotify server is gotify://hostname/token. You hand one or more of these URLs to the library or the CLI, and the scheme selects the plugin that knows how to talk to that service. The README describes messages as sent asynchronously and the library as lightweight, which is the stated reason for its response times. Attachments and images are supported, with the README adding the qualifier that this applies "to the notification services that will accept them". That qualifier matters: the URL syntax is uniform, but the capabilities behind it are not. A service that cannot render an image will not suddenly gain that ability because Apprise handed it one. The repository layout reinforces the plugin model. There is an apprise/ package directory, a tests/ directory, and an all-plugin-requirements.txt at the top level, which implies that some service support depends on optional dependencies beyond the core list in pyproject.toml. The core dependencies are requests, requests-oauthlib, click, markdown, PyYAML, certifi, plus tzdata on Windows.

## Installing Apprise and sending a first notification

The README points to the Official Documentation site for more information and lists Installation as a section, but the installation commands themselves are not in the portion of the README available here. The project is published on PyPI, so pip is the expected route. The CLI entry point is named apprise, as shown in the docker-compose.yml comment block where a test container runs bin/apprise. After installing, the simplest real use is to pass a service URL and a message body. The example below follows the syntax the README gives for Discord, with the two values replaced by your own webhook ID and token.

## Where the uniform URL syntax breaks down

The abstraction is only as good as the plugin behind each scheme, and the README's own tables show how uneven that is. The Default Port column mixes TCP 443, TCP 80, TCP 8096 for Emby, USB for Blink(1), and UDP 23053 for Growl. Those are not interchangeable transports, and a firewall policy that permits HTTPS outbound will not help you reach a Growl listener. The example syntaxes also carry service-specific quirks that the uniform scheme hides: FCM uses a project@apikey form with #topic fragments, Flock encodes user and channel targets as u:userid and g:channel_id, and the Dot. entry notes that device_id is a hardware serial. The README also shows a typo in the Chanify row, where the Service ID is listed as chantify:// while the service name is Chanify, which is a reminder that this table is maintained by hand across a very long plugin list. None of this makes Apprise wrong, but it means the plugin list is a starting point, not a guarantee. If your chosen service is obscure or recently changed its API, you are depending on a volunteer-maintained plugin, and the README does not promise a support timeline for any individual one.

## Apprise compared with wiring webhooks by hand

The direct alternative is calling each provider's webhook yourself. For a single Slack channel, an HTTP POST with a JSON body is a few lines and adds no dependency beyond an HTTP client you already have. Apprise trades that simplicity for breadth: one call site covers Discord, Slack, Telegram, Amazon SNS, Gotify and the rest of the table, and switching providers becomes a URL change rather than a code change. The difference in approach is real rather than cosmetic. Hand-rolled webhooks give you exact control over retries, payload fields and error handling per provider, and you see precisely what is sent. Apprise gives you one interface and one set of error semantics across all of them, and you accept that the plugin decides the payload. If your requirement is one service and a stable payload, the hand-rolled version is the smaller system. If your requirement is five services and the ability to add a sixth without a release, Apprise is the one that scales.

## Maintenance, releases and what the licence permits

The last push to the repository was on 2026-08-20, the same day as the v1.13.0 release. v1.12.0 came on 2026-07-04 and v1.11.0 on 2026-05-29, so the cadence across those three releases is roughly six to eight weeks. The repository is not archived. That is a healthy release rhythm for a library of this size, and it also means the upgrade cost is recurring rather than one-off. Because each release can touch plugin behaviour, a version range in your dependency file will let a new plugin change reach production without a code review. Pinning the version and reading the release notes before bumping is the cheaper habit. The licence is BSD-2-Clause, declared in pyproject.toml as a text field with a note that it is not yet supported for all distributions, and the full text appears at the top of setup.py. BSD-2-Clause is permissive: it permits use and redistribution provided the copyright notice and conditions are retained. That is a summary of the licence text, not legal advice; if you redistribute Apprise inside a product, have your own counsel read the terms. Note also that setup.py carries a comment describing itself as a temporary shim for RHEL9 package building, to be removed when RHEL9 support is dropped, so the packaging story has a known expiry.

## Testing a change without touching your real channels

The repository ships a docker-compose.yml whose services are test environments for Python 3.9 through 3.12 plus RPM build targets for el9, el10, f44 and rawhide. The comment block at the bottom documents the intended workflow, including running a single test selection by keyword, which is how you would check whether a specific plugin behaves as you expect before trusting it in production. The same comment block shows the CLI being invoked as bin/apprise from inside the container, which is useful if you want to confirm a URL parses without installing anything on your host.

## Conclusion

Adopt Apprise if you need one code path or one CLI command to reach many notification services and you are willing to pin the version and test each URL you rely on. Do not adopt it if you only ever talk to one service, since a direct webhook call is smaller and has no dependency chain. Before rollout, verify that every service you plan to use appears in the supported-notifications table, that the extras or plugin requirements for those services are installed, and that your Python is 3.9 or newer.

## FAQ

### How do I install Apprise?

The README lists an Installation section and points to the official documentation site, and the project is published on PyPI, so pip install apprise is the expected route. The CLI entry point is named apprise, as shown in the docker-compose.yml comment block where a container runs bin/apprise.

### How do I set up Apprise for a notification service?

You construct a service URL using the Service ID and example syntax from the supported-notifications table, then pass it to the library or the apprise command line tool. The README suggests the Apprise URL Builder if you have trouble constructing a URL.

### How do I use Apprise?

Pass one or more service URLs plus a message to the library or the CLI. The README shows the CLI shipping with the product for system administrators and DevOps, and notes that messages are sent asynchronously and that images and attachments are supported for services that accept them.

### Is Apprise the same word as appraise?

No. The README opens with the definition of apprise as a verb meaning to inform or tell someone, and the project name is taken from that word. Appraise is a different verb with a different meaning, and the two are unrelated despite the similar spelling.

### What does apprise mean?

The README defines apprise as a verb meaning to inform or tell someone, or to make one aware of something. The notification library takes its name from that word.

## Sources

- [Official documentation](https://hub.docker.com/r/caronc/apprise)
- [Official README](https://github.com/caronc/apprise#readme)
- [Project repository](https://github.com/caronc/apprise)
- [Release notes](https://github.com/caronc/apprise/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/caronc-apprise
