Configuration
Configuration keeps your notification services, tags, and groups in one file. It also keeps credentials out of your shell history.
Apprise configuration is portable. The same configuration file can be used by the CLI, the API server, and the Python library without modification.
Consider using configuration files when:
- You want to reuse the same notification setup across scripts or systems
- You want to keep credentials out of your shell history
- You want to group services or simplify references to your Apprise URLs with tags
- You want the same configuration to work with the CLI, API, and Python library
If you only need a one-off notification, inline URLs are sufficient. For anything beyond that, configuration files are recommended.
Supported Configuration Formats
Section titled “Supported Configuration Formats”Apprise supports two configuration formats. Both describe the same information, but YAML can express more structure.
- TEXT: Simple, line-based, and easy to read. Best for small or manual setups.
- YAML: Structured and standardised. Better suited for larger configurations and automation tools.
TEXT Configuration
Section titled “TEXT Configuration”TEXT configuration is line-based.
- Blank lines are ignored
- Comments start with
#or; - Each URL can optionally be prefixed with one or more tags
- You can define tag groups
- You can include other configuration sources
TEXT configuration is ideal when:
- You want the simplest possible setup
- You are managing only a few services
- You prefer minimal syntax
Basic TEXT Syntax
Section titled “Basic TEXT Syntax”# Email notificationsmailto://user:password@gmail.com
# Discord notificationsdiscord://webhook_id/webhook_tokenParameter Priority in TEXT Configuration
Section titled “Parameter Priority in TEXT Configuration”For TEXT URLs and URLs passed directly to the CLI or Python library, values follow this order:
- Query-string parameters (
?key=value) — override URL-path values, including aliases (e.g.?pass=is treated as?password=). - URL-path values (lowest) — credentials and host parsed directly from the URL string (e.g.
user:pass@host:port).
In YAML, settings written under a URL take priority over both.
TEXT Tagging and Grouping
Section titled “TEXT Tagging and Grouping”Tags let you organize notification services into logical groups such as personal, ops, or critical. You can then target groups without changing your destination URLs.
TEXT Tagging Examples
Section titled “TEXT Tagging Examples”You can categorize services by placing tags before the URL, separated by an equals sign (=).
# Syntax: tag=url# Associates the 'desktop' tag with this notificationdesktop=gnome://
# You can assign multiple tags using commas or spaces# This URL is part of 'tv' AND 'kitchen'tv,kitchen=kodi://user:pass@kitchen.hostGrouping Tags with TEXT Configuration
Section titled “Grouping Tags with TEXT Configuration”You can include other configuration files to keep your setup clean. This is excellent for separating secrets from general logic.
# 1. Define your base servicesuser1=mailto://credentialsuser2=mailto://credentials
# 2. Define a group# Notifying 'friends' will notify 'user1' and 'user2'friends = user1, user2TEXT Includes
Section titled “TEXT Includes”You can import other configuration files (local or remote) using the include keyword.
# Read from another Apprise configuration file on the local serverinclude /etc/apprise/secrets.conf
# Read from an Apprise API serverinclude https://my-config-server.com/get/my-key/YAML Configuration
Section titled “YAML Configuration”YAML configuration is structured and is best for larger setups. But it also provides optional asset configuration (branding and defaults) which isn’t available with TEXT configuration.
Basic YAML Syntax
Section titled “Basic YAML Syntax”List notification services under urls.
urls: - json://localhost - slack://tokenA/tokenB/tokenCYAML vs TEXT for Complex Parameters
Section titled “YAML vs TEXT for Complex Parameters”With YAML, you can write settings below the URL. Passwords and other values containing spaces or characters such as @ and # can then be written as ordinary text. In a plain URL, those characters need URL encoding.
Consider an SMTP email URL with a complex password, a display-name sender address, and a private PGP key path:
As a single URL (TEXT format or inline CLI argument):
mailtos://joe:myP%40ss%23w0rd%21@example.com?smtp=smtp.example.com&from=Joe+User%3Cjoe%40example.com%3E&pgp=sign&pgpprv=%2Fhome%2Fjoe%2FMy+Keys%2Fprivate.ascAs YAML, with no encoding and immediately readable:
urls: - mailtos://example.com: password: "myP@ss#w0rd!" smtp: smtp.example.com from: "Joe User <joe@example.com>" pgp: sign pgpprv: "/home/joe/My Keys/private.asc"YAML sub-keys follow a strict three-level priority. The highest level wins when the same field is set by more than one source:
- YAML token sub-keys (highest): always override everything else.
- URL query-string parameters (e.g.
?smtp=...,?user=abc): override URL-path values. - URL-path values (lowest): the
user,password,host, andportparsed from the URL itself (e.g.user:pass@host:port).
Common URL components such as user, password, host, port, and verify can be supplied as sub-keys. The same applies to service-specific parameters from the plugin’s ## Parameter Breakdown table, including named URL parts such as Discord’s botname:.
The email service above is one example. The XMPP example below places credentials and options under the URL too. Its host: setting replaces the host in the URL:
urls: - xmpp://chat.example.com: user: alerts@example.com password: "correct horse battery staple" host: xmpp.example.com verify: yes to: ops-room@example.comYAML URL Entry Forms
Section titled “YAML URL Entry Forms”A urls: entry can take four distinct forms. Each form controls how many service instances are created and how parameter values are applied.
One URL entry creates one service instance. Token keys map directly to plugin parameters and override any value already in the URL.
Tokens may be written either indented one level under the URL key (child form, standard YAML nesting) or at the same indentation level as the URL key (sibling form). Both produce identical results.
Child form:
urls: - mailtos://smtp.example.com: user: sender@example.com password: "myP@ss#w0rd!" to: recipient@example.comSibling form (equivalent):
urls: - mailtos://smtp.example.com: user: sender@example.com password: "myP@ss#w0rd!" to: recipient@example.comWhen all credentials are supplied as YAML tokens, omit them from the URL entirely — a bare schema:// is all that is needed:
urls: - mailtos://: user: sender@example.com password: "myP@ss#w0rd!" smtp: smtp.example.com from: sender@example.com to: recipient@example.comWhen a plugin parameter accepts multiple values (such as to: for multiple recipients), supply them as a comma-separated string or as a YAML list under that key. Either way, one service instance is created with all values in its target list — this is not the same as creating multiple instances.
Comma-separated (equivalent to ?to=user1,user2 in the URL):
urls: - mailtos://smtp.example.com: user: sender@example.com password: secret to: user1@example.com, user2@example.comYAML list (same result, easier to read for long lists):
urls: - mailtos://smtp.example.com: user: sender@example.com password: secret to: - user1@example.com - user2@example.comThe same syntax applies to tag: and any other list-type parameter.
When the child value of a URL key is a YAML list, Apprise creates one service instance per list entry. Each entry’s tokens override values from the URL independently — entries do not inherit tokens from each other.
urls: - mailto://user:pass@gmail.com: - to: manager@example.com tag: boss - to: coworker@example.com tag: new-hireThis loads two mailto:// services. Both inherit user:pass@gmail.com from the URL. Each instance gets its own to and tag; neither sees the other entry’s values.
Combine a child-indented list (one instance per entry) with sibling tokens (at the same indentation level as the URL key) to share settings across every generated instance.
Per-entry tokens take priority over sibling tokens for any key that both define.
urls: - mailtos://smtp.example.com: - to: manager@example.com tag: boss - to: coworker@example.com tag: new-hire user: sender@example.com password: shared_secretThis creates two mailtos:// instances. The sibling tokens user: and password: are applied to both. Each entry’s own to: and tag: are per-instance and override any sibling value for the same key.
YAML Tagging and Grouping
Section titled “YAML Tagging and Grouping”Tags let you organize notification services into logical groups such as personal, ops, or critical. You can then target groups without changing your destination URLs.
YAML Tagging Examples
Section titled “YAML Tagging Examples”Assign one tag:
version: 1urls: - discord://webhook_id/webhook_token: tag: opsAssign multiple tags:
version: 1urls: - mailto://user:password@gmail.com: tag: - personal - after-hoursReusing One URL with Multiple YAML Entries
Section titled “Reusing One URL with Multiple YAML Entries”A child-indented YAML list under a URL key creates one service instance per list entry. This is covered in detail in the Multiple Instances and Multiple Instances + Shared Tokens tabs above.
Grouping Tags with YAML Configuration
Section titled “Grouping Tags with YAML Configuration”You can apply tags to every URL in a file using tag (or tags) at the root:
version: 1tag: org-default
urls: - discord://webhook_id/webhook_token - mailto://user:password@gmail.comYou can also tag your individual Apprise URLs with the same identifier
version: 1
urls: - discord://webhook_id/webhook_token: tag: ops - slack://token_a/token_b/token_c: tag: ops - mailto://user:password@gmail.com: tag: opsYou can also leverage the groups directive to create new tag identifiers and identify which existing tags will be encompased in them.
version: 1
groups: critical: ops, after-hours
urls: - discord://webhook_id/webhook_token: tag: ops
- mailto://user:password@gmail.com: tag: after-hoursAsset Configuration
Section titled “Asset Configuration”Asset configuration lets you tune defaults and branding. Effectively you can override the default Apprise branding (Icons, App ID) sent to the upstream service.
Asset keys have a few rules:
- Keys that start with
_or end with_are ignored - Only asset keys that already exist and are string or boolean values can be set
- Values must be strings or booleans, with strings converted to booleans when the underlying default is boolean
A practical subset of commonly used keys is shown below; simply not over-riding an entry uses its default value.
version: 1
asset: # # Branding #
# A shortened identify to describe the application app_id: Apprise # A default description of the notification (used in some upstream services) app_desc: Apprise Notifications # Where can people go to get more information on your application? app_url: https://github.com/caronc/apprise
# # Behaviour defaults #
# notifications are issued sequentially if this is set to false (default = true) async_mode: true
# Convert \r or \n into their actual <CR> and <LF> characters when processing body string # (default = false) interpret_escapes: false
# credentials are protected when written to logging (default = true) secure_logging: true
# Encoding used when reading configuration from disk encoding: utf-8
# # Themes #
# The default theme used when resolving icons theme: default
# Optionaly override icon URL paths (advanced) # Defaults are pullled from: # http://github.com/caronc/apprise/tree/master/apprise/assets/themes/default image_url_mask: https://example.local/assets/themes/{THEME}/apprise-{TYPE}-{XY}{EXTENSION} image_url_logo: https://example.local/assets/themes/{THEME}/apprise-logo.png image_path_mask: /apprise/installation/assets/themes/{THEME}/apprise-{TYPE}-{XY}{EXTENSION}
# Let Apprise know in advance what you will be feeding it; # Values are: # - null: (default) pass content along as is # - "text": content being passed in is in a "text" format (default for CLI tool) # - "html": content being passed in is HTML # - "markdown": content being provided is in Markdown format. body_format: null
urls: - discord://webhook_id/webhook_token: tag: ops
- mailto://user:password@gmail.com: tag: after-hoursTimezone can also be set under asset using timezone (or tz) to control the default timezone used by Apprise.
The language Apprise uses for its own text can be set under asset using language (or lang), such as language: fr. Leave it out to follow the language of the computer Apprise runs on.
Grouping
Section titled “Grouping”YAML allows for recursive group definitions (Groups containing Groups).
groups: - finance: user1, user2 - devteam: user3, user4 # Recursive group - company: finance, devteam, boss
urls: - mailto://credentials: - tag: user1YAML Includes
Section titled “YAML Includes”You can import other configurations by leveraging the optional include: section
include: # Read from another Apprise configuration file on the local server - /etc/apprise/secrets.yml # Read from an Apprise API server - https://my-config-server.com/get/my-key/Template Variables
Section titled “Template Variables”YAML configurations can declare ${NAME} values that are supplied later:
template: recipient:
urls: - mailtos://user:password@example.com/: - to: ${RECIPIENT}Only names declared under template: are replaced. Templates cannot set
tag:, tags:, or the service name before ://. See
Template Variables for rules and CLI, API, and environment
examples.
Targeting Tags when Sending
Section titled “Targeting Tags when Sending”Tag filtering is consistent across tools. For example, with the CLI you can target a group by tag:
General filter expressions follow:
| Filter | Selected services |
|---|---|
--tag TagA | Has TagA |
--tag TagA,TagB | Has TagA AND TagB |
--tag 'TagA' --tag 'TagB | Has TagA OR TagB |
--tag 'TagA,TagC --tag TagB | Has ( TagA AND TagC) OR TagB |
Example:
apprise --tag="ops,critical" \ --body="Notify services that have the tag ops AND critical associated with it"
apprise --tag="ops" --tag "critical" \ --body="Notify all services that have either 'ops' AND/OR 'critical' associated with it"Loading Configuration
Section titled “Loading Configuration”Whether you use TEXT or YAML, you load your configuration into the CLI or Library the same way.
CLI Usage
Section titled “CLI Usage”You can load a file using the --config (or -c) flag. You can specify this flag multiple times to load multiple files.
# Load a local fileapprise --config=/etc/apprise/config.yml --body="test"
# Load from a URLapprise --config=https://myserver.com/cfg/apprise --body="test"Default Configuration Locations
Section titled “Default Configuration Locations”If you do not specify a configuration file via the CLI (--config), Apprise automatically loads a default configuration file for you.
The following configuration files are scanned in the order identified below; the first match is loaded and nothing further is processed thereafter.
~/.apprise~/.apprise.conf~/.apprise.yml~/.apprise.yaml~/.config/apprise~/.config/apprise.conf~/.config/apprise.yml~/.config/apprise.yaml~/.apprise/apprise~/.apprise/apprise.conf~/.apprise/apprise.yml~/.apprise/apprise.yaml~/.config/apprise/apprise~/.config/apprise/apprise.conf~/.config/apprise/apprise.yml~/.config/apprise/apprise.yaml
The following global paths are also searched if nothing is found above:
/etc/apprise/etc/apprise.yml/etc/apprise.yaml/etc/apprise/apprise/etc/apprise/apprise.conf/etc/apprise/apprise.yml/etc/apprise/apprise.yaml
The following configuration files are scanned in the order identified below; the first match is loaded and nothing further is processed thereafter.
%APPDATA%\Apprise\apprise%APPDATA%\Apprise\apprise.conf%APPDATA%\Apprise\apprise.yml%APPDATA%\Apprise\apprise.yaml%LOCALAPPDATA%\Apprise\apprise%LOCALAPPDATA%\Apprise\apprise.conf%LOCALAPPDATA%\Apprise\apprise.yml%LOCALAPPDATA%\Apprise\apprise.yaml
The following global paths are also searched if nothing is found above:
%ALLUSERSPROFILE%\Apprise\apprise%ALLUSERSPROFILE%\Apprise\apprise.conf%ALLUSERSPROFILE%\Apprise\apprise.yml%ALLUSERSPROFILE%\Apprise\apprise.yaml%PROGRAMFILES%\Apprise\apprise%PROGRAMFILES%\Apprise\apprise.conf%PROGRAMFILES%\Apprise\apprise.yml%PROGRAMFILES%\Apprise\apprise.yaml%COMMONPROGRAMFILES%\Apprise\apprise%COMMONPROGRAMFILES%\Apprise\apprise.conf%COMMONPROGRAMFILES%\Apprise\apprise.yml%COMMONPROGRAMFILES%\Apprise\apprise.yaml
For a user named foobar with Microsoft Windows installed on C:\, these paths become:
| Environment Variable | Example Translation |
|---|---|
%APPDATA% | C:\Users\foobar\AppData\Roaming |
%LOCALAPPDATA% | C:\Users\foobar\AppData\Local |
%ALLUSERSPROFILE% | C:\ProgramData |
%PROGRAMFILES% | C:\Program Files |
%COMMONPROGRAMFILES | C:\Program Files\Common Files |
Reserved Tags
Section titled “Reserved Tags”There are two special tags you can use to control notification behavior.
| Tag | Description |
|---|---|
always | If you assign the tag always to a URL in your config, it will ALWAYS trigger, even if you are filtering for a different tag via the CLI. |
all | Used when sending a notification (e.g. apprise --tag=all). This tells Apprise to ignore all filters and notify every service defined in your configuration. |
For advanced tagging features — priority-based escalation chains, exclusive priority filtering, per-service retry and wait, and per-call retry overrides — see Tag Routing & Retry.
Private Web Hosted Configuration
Section titled “Private Web Hosted Configuration”If you are hosting your configuration on a private web server, Apprise detects the format based on the Content-Type header returned by the server, or by an explicit URL parameter.
| Format | HTTP Content-Type | URL Force Override |
|---|---|---|
| YAML | text/yaml, application/x-yaml | http://...?format=yaml |
| TEXT | text/plain | http://...?format=text |
Questions or Feedback?
Technical Issues
Having trouble with the code? Open an issue on GitHub: