Assets & Branding
AppriseAsset defines the global execution context for an Apprise session.
It is not limited to branding or theming. An asset instance influences behaviour across:
- All notification plugins
- All delivery threads
- Persistent storage and key material
- Global safety boundaries (log redaction and recursion protection)
Under usual conditions, an asset is created once and then passed into Apprise(...) during its instantiation.
from apprise import Apprise, AppriseAsset
asset = AppriseAsset(app_id="My Application", theme="default")apobj = Apprise(asset=asset)If no asset is provided, Apprise creates a default one.
Lifecycle and Scope
Section titled “Lifecycle and Scope”- Created once, typically at application startup
- Shared across all loaded plugins and configuration processing
- Intended to be treated as immutable for the lifetime of an
Appriseinstance
Mutating an asset after it has been bound to Apprise can produce inconsistent results across plugins.
Object Initialization
Section titled “Object Initialization”AppriseAsset.__init__() provides named arguments for storage, timeouts,
payload limits, and other shared settings. Always use the documented
constructor name, such as timezone=, service_timeout=, or
payload_max_size=. These arguments validate values before applying them.
Python constructor arguments and YAML asset: keys are separate interfaces.
Some settings are available to applications through AppriseAsset(...) but
are intentionally unavailable to YAML configuration.
Defaults and Field Reference
Section titled “Defaults and Field Reference”This table documents the actual defaults from the implementation, plus where each field is used.
Identity and Presentation
Section titled “Identity and Presentation”| Field | Type | Default | Used by | Notes |
|---|---|---|---|---|
app_id | str | Apprise | Plugin headers, key generation names | Used as a human-facing application identifier and as a default name in PGP key generation. |
app_desc | str | Apprise Notifications | Metadata / Presentation | Used by tooling and services that display an application description. |
app_url | str | https://github.com/caronc/apprise | Metadata / Presentation | Provider URL exposed in docs and some plugin metadata. |
theme | str | default | Icon URL/path resolution | Drives {THEME} substitution for icon lookup. |
language | str | system language | Translated text | Sets the language Apprise uses for its own text, such as the field names returned by details(). Accepts en, en-CA, or en_CA. A region falls back to its plain language, then to English, when no translation is installed. YAML accepts language or its lang alias. |
default_extension | str | .png | Icon URL/path resolution | Used when extension is not provided to image_url() or image_path(). |
default_image_size | NotifyImageSize | XY_256 | Icon URL resolution | Used when size is omitted. |
image_url_mask | str | GitHub raw URL | image_url() | Produces a themed image URL for NotifyType + size. |
image_url_logo | str | GitHub raw URL | image_url(logo=True) | Used for the application logo. |
image_path_mask | str | local assets/themes/... | image_path() / image_raw() | Used for local icon resolution and raw bytes loading. |
Type Mapping Helpers
Section titled “Type Mapping Helpers”| Field | Type | Default | Used by | Notes |
|---|---|---|---|---|
html_notify_map | dict[NotifyType,str] | type-to-hex map | color() | Default colour mapping for HTML-capable services. |
default_html_color | str | #888888 | color() | Used when a mapping is missing. |
ascii_notify_map | dict[NotifyType,str] | type-to-token map | ascii() | Default ASCII tokens for text-only contexts. |
default_ascii_chars | str | [?] | ascii() | Used when a mapping is missing. |
Content Interpretation
Section titled “Content Interpretation”| Field | Type | Default | Used by | Notes |
|---|---|---|---|---|
body_format | NotifyFormat | None | Message pre-processing | Selects the default input format. If None, no pre-formatting is applied. |
interpret_emojis | bool | None | Message pre-processing | Controls emoji conversion. If None, it defers to each service (for example, emojis=yes at the URL level). |
interpret_escapes | bool | False | Message pre-processing | Enables \n, \t, etc. prior to sending. |
encoding | str | utf-8 | Encoding | Used when encoding strings for processing and by some services when sending content. Keep the default unless a service requires another encoding. |
Concurrency and Delivery
Section titled “Concurrency and Delivery”| Field | Type | Default | Used by | Notes |
|---|---|---|---|---|
async_mode | bool | True | Delivery orchestration | Controls concurrent vs sequential dispatch. |
default_service_retry | int | 0 | Per-service retry | Fallback retry count for any service that does not set ?retry= in its URL. Clamped to [0, 10]. |
default_service_wait | float | 0.5 | Per-service retry | Fallback inter-retry pause (seconds) for services without ?wait=. Clamped to [0.0, 20.0]. |
service_timeout | int / float | 60.0 | Per-service timeout | Maximum seconds a single service (including all of its retries) may take before Apprise gives up on it and reports a TIMEOUT. 0 disables the limit. See Notification Results. |
result_log_memory_size | int | 0 | Result logs | Bytes kept in memory before result logs spill to temporary disk storage. Used only when result_log_disk_size is greater than 0. |
result_log_disk_size | int | 0 | Result logs | Maximum temporary disk space for one notification result. 0 keeps all result logs in memory. |
Plugin Discovery
Section titled “Plugin Discovery”| Field | Type | Default | Used by | Notes |
|---|---|---|---|---|
plugin_paths | list[str] | [] | Custom plugin loading | Triggers module detection at asset initialisation time. |
Persistent Storage
Section titled “Persistent Storage”| Field | Type | Default | Used by | Notes |
|---|---|---|---|---|
storage_path | str | None | PersistentStore | PersistentStore root. If unset, Apprise operates memory-only for storage-backed features. |
storage_mode | PersistentStoreMode | auto | PersistentStore behaviour | auto, flush, memory. |
storage_idlen | int | 8 | Namespace generation | Controls how long generated namespace directories are. |
storage_salt | bytes | b"" | Namespace generation | Provides optional salting for namespace generation, string values are encoded using encoding. |
Key Material Management
Section titled “Key Material Management”| Field | Type | Default | Used by | Notes |
|---|---|---|---|---|
pgp_autogen | bool | True | PGP controller | When True, a pgp=encrypt self-send may generate the sender’s RSA-2048 key pair in persistent storage. Recipient keys and pgp=sign keys are never generated. |
pem_autogen | bool | True | PEM controller | Enables auto-generation of PEM keys when storage allows it and no key is provided. |
PGP Auto-Generation Details
Section titled “PGP Auto-Generation Details”When pgp_autogen = True, a pgp=encrypt self-send may generate both sender key files when no key is found:
{localpart}-pub.asc: RSA-2048 public key used for the self-send{localpart}-prv.asc: RSA-2048 private key used for replies and later signing
{localpart} is derived from the sender’s From address (everything before @, lowercased).
The private key can later be discovered by pgp=sign from the same storage. Import it into the client that reads encrypted replies. External recipients always require an existing key; Apprise never generates one for them.
To disable auto-generation globally:
from apprise import AppriseAsset
asset = AppriseAsset( storage_path="/var/lib/apprise", pgp_autogen=False,)With pgp_autogen = False, no key pair is created automatically. A key must come from local storage, WKD, or an explicit pgppub= path.
Safety Boundaries
Section titled “Safety Boundaries”| Field | Type | Default | Used by | Notes |
|---|---|---|---|---|
http_redirects | bool | True | All HTTP plugins | When True (the default), plugins follow 3xx redirects, matching the behaviour of the underlying requests library. Set to False to disable redirect following globally without touching individual URLs. |
secure_logging | bool | True | Logging pipeline | Adds overhead to redact secrets from logs, recommended to keep enabled. |
allow_templates | bool | True | YAML configuration | Lets a YAML configuration declare a template: section and fill in ${NAME} markers. Set to False and the section is ignored, ${NAME} stays ordinary text, and nothing is read from the environment. See Template Variables. |
payload_max_size | int | 0 | Message formatting/splitting | Optional input ceiling for the combined title and body. 0 disables it. Applies to every overflow= mode. |
payload_buffer_threshold | int | 10 | Message formatting/splitting | A title or body at or below this length may remain whole; see Payload Size Cap. |
payload_min_buffer | int | 25 | Message formatting/splitting | Characters reserved for the other side before keeping a short side whole; see Payload Size Cap. |
timezone | str / tzinfo | system tz | Time-based behaviour | Sets the timezone used by plugins that generate timestamps. Accepts an IANA name such as "America/Toronto" or a tzinfo object. YAML accepts timezone or its tz alias. |
Common Usage Patterns
Section titled “Common Usage Patterns”Configures the Apprise instance to use an altered branding.
from apprise import AppriseAsset
asset = AppriseAsset( app_id="StatsBot", app_desc="Metrics Aggregation Service", app_url="https://example.com",)Disables concurrent delivery and forces sequential notification dispatch.
from apprise import AppriseAsset
# Force sequential sending (no concurrency)asset = AppriseAsset(async_mode=False)Give every service in the session the same time budget, instead of the default 60 seconds. See Notification Results for how a service that runs out of time is reported back to you.
from apprise import Apprise, AppriseAsset
# Give each service 10 seconds (including all of its own retries)# before Apprise gives up on it and reports a TIMEOUTasset = AppriseAsset(service_timeout=10)
apobj = Apprise(asset=asset)apobj.add("slack://tokenA/tokenB/tokenC")
# This one call also gets its own 30-second ceiling, on top of the# asset's own 10-second-per-service budget -- whichever is sooner winsapobj.notify(body="Time-sensitive alert", timeout=30)Keep a small result-log buffer in memory and place later entries in an automatically removed temporary file:
from apprise import Apprise, AppriseAsset
asset = AppriseAsset( result_log_memory_size=2 * 1024 * 1024, result_log_disk_size=256 * 1024 * 1024,)apobj = Apprise(asset=asset)The limits are shared by all services and retries in one notification. If the disk allowance is exhausted or unavailable, delivery continues and the result contains a warning that later log entries could not be retained.
When plugin_paths is set, module detection occurs during asset initialization.
from apprise import AppriseAsset
asset = AppriseAsset( plugin_paths=[ "/opt/apprise/plugins", "/srv/myapp/apprise_plugins", ])Controls disk-backed caching and plugin state.
from apprise import AppriseAssetfrom apprise.common import PersistentStoreMode
asset = AppriseAsset( storage_path="/var/lib/apprise", storage_mode=PersistentStoreMode.AUTO, storage_idlen=12, storage_salt="my-namespace-salt",)storage_salt may be bytes or str. String values are encoded using the asset encoding.
Plugins that generate timestamps (for example email Date headers) use the configured timezone.
from apprise import AppriseAsset
asset = AppriseAsset(timezone="America/Toronto")Apprise translates its own human-readable text, such as the field names
details() returns. Leave language unset and the language of the system
Apprise runs on is used.
from apprise import AppriseAsset
# Two-letter codes and regional tags are both accepted; case does not matterasset = AppriseAsset(language="fr")asset = AppriseAsset(language="en-CA")A regional tag looks for that exact translation first (en_CA), then for
its plain language (en), and finally falls back to English. Apprise ships
translations for ar, de, en, es, fr, hi, id, it, ja, ko,
ms, nl, pl, pt, ru, th, tl, tr, vi, and zh.
Only text a person reads is translated. Anything a program reads, such as a status code or a key in a response, stays in English.
Icon and Image Resolution
Section titled “Icon and Image Resolution”Apprise resolves icons using configurable masks.
asset = AppriseAsset( image_path_mask="/icons/{THEME}/{TYPE}-{XY}{EXTENSION}", image_url_mask="https://cdn.example.com/{TYPE}-{XY}{EXTENSION}",)| Token | Description |
|---|---|
{THEME} | Active theme |
{TYPE} | info, success, warning, failure |
{XY} | Image size |
{EXTENSION} | File extension |
Security and Safety Controls
Section titled “Security and Safety Controls”HTTP Redirects
Section titled “HTTP Redirects”By default, Apprise follows HTTP 3xx redirects, matching the behaviour of the underlying requests library. If you want to prevent custom headers and credentials from being forwarded to destinations that differ from the original URL, you can disable redirect following globally:
asset = AppriseAsset(http_redirects=False)Individual URLs can still override the asset default using the redirect=
URL parameter:
# Override per-URL regardless of the asset settingschema://token/?redirect=yesschema://token/?redirect=noSecure Logging
Section titled “Secure Logging”When enabled, secrets are redacted from all logging output.
asset = AppriseAsset(secure_logging=True)Disabling this is strongly discouraged outside isolated environments.
Payload Size Cap
Section titled “Payload Size Cap”payload_max_size is the payload limit, or total character budget (N), for
the title and body before formatting or splitting begins. A value of 0
disables the limit. If the title and body already fit within N, Apprise
leaves both unchanged.
asset = AppriseAsset(payload_max_size=100000)Three settings work together when the content is larger than N:
| Setting | Default | Purpose |
|---|---|---|
payload_max_size | 0 | Sets N, the total budget. 0 disables the limit. |
payload_buffer_threshold | 10 | A title or body of this length or shorter may be kept whole. |
payload_min_buffer | 25 | Space the other side must retain before the short side can be kept whole. |
With the default values, an oversized payload is resolved in this order:
- One side is empty: The other side receives the full budget.
- One side is short: A title of 10 characters or fewer stays whole if the body can keep 25 characters, or its full length when shorter. The same rule then checks for a short body. If both qualify, the title is checked first.
- Otherwise: The title and body share
Nin proportion to their original lengths. WhenNhas room for both, each keeps at least one character.
For example, a 20-character title and an 18-character body with N=20
split approximately 10/10. A smaller cap may still leave a short fragment,
but it does not favor one side when both can be represented.
Library users can change both settings when constructing the asset:
asset = AppriseAsset( payload_max_size=100000, payload_buffer_threshold=10, payload_min_buffer=25,)Setting payload_min_buffer=0 removes the reservation, so a qualifying
short side may use the entire cap.
Formatting and escaping can add a few characters afterward. The limit
applies to every overflow= mode, including upstream.
Configuration File Boundaries
Section titled “Configuration File Boundaries”YAML deliberately supports a smaller set of asset settings than the Python
constructor. Numeric controls such as service_timeout, payload_max_size,
payload_buffer_threshold, and payload_min_buffer must be supplied
through their named AppriseAsset(...) arguments. Plugin paths and storage
settings are also application-controlled so configuration files cannot load
code or redirect persistent storage.
timezone is supported in YAML and may also use the tz alias:
asset: timezone: America/Toronto # or: tz: America/Torontolanguage is supported in YAML and may also use the lang alias:
asset: language: fr # or: lang: frSee Also
Section titled “See Also”- Tag Routing & Retry — how to configure priority tags, per-service retry/wait, per-service timeouts, and per-call overrides in configuration files.
- Notification Results — how a timed-out or failed service is reported back to you from
notify().
Questions or Feedback?
Technical Issues
Having trouble with the code? Open an issue on GitHub: