Skip to content

Formatting

Apprise can deliver plain text, Markdown, and HTML, then adapt what you send to what each service can actually accept. For example, a service that only supports text will still receive your notification, but any rich formatting will be reduced appropriately.

Apprise does not automatically guess your content type. Instead, you tell Apprise what kind of content you are providing, and Apprise uses that knowledge to make intelligent, per-service delivery decisions.

Apprise recognises four input format states:

StateDescription
(implicit) noneNo source format declared. Automatic format conversion is skipped.
textPlain text input. Apprise may simplify content for text-only services.
markdownMarkdown input. Apprise may convert or simplify as needed.
htmlHTML input. Apprise may strip or convert markup as required.

In short: Apprise preserves your content whenever possible, and only adapts it when a destination cannot support what you provided.

When you specify a format (such as text, markdown, or html), you are describing your input, not forcing a specific output format.

Apprise uses this information to determine whether any transformation is necessary for a given destination.

  • If the destination service natively supports the declared format, content is passed through unchanged
  • If the destination cannot support the declared format, Apprise performs the minimal conversion required
  • If no conversion is required, no transformation occurs

In other words, Apprise only intervenes when there is a mismatch between the declared input format and what the upstream provider can support. It can only do this when you have provided an input format to work with.

For example:

  • An HTML message sent to Email may be delivered as rich HTML
  • The same HTML message sent to SMS will be converted to readable plain text
  • A Markdown message sent to a chat service may retain formatting
  • That same Markdown message sent to a text-only service will be simplified automatically

This makes destinations more compatible without requiring you to manually tailor content per service.

What Happens if you do not Specify a Format?

Section titled “What Happens if you do not Specify a Format?”

If you do not specify a format, Apprise assumes slightly different states depending on which component you’re using:

InterfaceDefault input format
CLItext
Python APInone - no automatic format conversion unless body_format is provided in notify() or preset in AppriseAsset()
Apprise-APInone - no automatic format conversion unless the request supplies format, or the server operator sets APPRISE_DEFAULT_FORMAT

Formatting on the Apprise-API is entirely opt-in per request. If you run your own Apprise-API server and want every request that leaves out format to assume one automatically, set the APPRISE_DEFAULT_FORMAT environment variable (e.g. APPRISE_DEFAULT_FORMAT=text) — see the Environment Variables reference for details. Callers can still override this on a per-request basis: sending a real format value always wins, and so does deliberately sending it blank or null — that’s treated as the caller explicitly asking for no formatting, even if you’ve set a server-wide default.

With the exception of the CLI, if no input format is specified, Apprise skips automatic format conversion and markup repair. The destination still decides how to display the content. For example, ?format=html tells an HTML-capable service to treat the body as ready-to-use HTML.

Message limits, overflow handling, character encoding, escaping, JSON packaging, and encryption may still affect the final payload. Pass-through therefore means “do not interpret my source format,” not “send these exact bytes.”

The URL’s overflow setting still applies when no input format is declared:

  • upstream sends one message without splitting or truncating it for the service’s documented limit.
  • truncate keeps the portion that fits and discards the rest.
  • split prefers readable breaks such as newlines or spaces, then uses a hard boundary when needed and sends every part in order.

With an unknown source format, splitting is best effort. Apprise cannot reliably repair HTML, Markdown, JSON, ciphertext, signatures, or other structured content it was not asked to interpret. Use overflow=upstream when a message must remain one intact document, or declare the input format when you want format-aware handling.

Declaring the correct input format is optional, but doing so allows Apprise to assist more effectively across mixed destinations.

Use --input-format to tell Apprise how to interpret your body content.

Terminal window
# Markdown body
apprise -t "Release" -b "**v1.2.3** is now live" \
--input-format=markdown \
"discord://..."
# HTML body
apprise -t "Build Report" -b "<b>Success</b>: artifacts uploaded" \
--input-format=html \
"mailto://user:pass@example.com"

Use body_format to specify the message format you are providing.

from apprise import Apprise
from apprise import NotifyFormat
apobj = Apprise()
apobj.add("discord://...")
# Markdown input
apobj.notify(
title="Status",
body="**All checks passed**",
body_format=NotifyFormat.MARKDOWN,
)
# HTML input
apobj.notify(
title="Build Report",
body="<b>Success</b>: artifacts uploaded",
body_format=NotifyFormat.HTML,
)

For JSON payloads, use the format field:

Terminal window
# Stateless Example
curl -X POST http://localhost:8000/notify/ \
-d 'urls=["discord://..."]' \
-d 'title=Status' \
-d 'body=**All checks passed**' \
-d 'format=markdown'
# Stateful Example
curl -X POST http://localhost:8000/notify/team-alerts/\
-d 'tags=outage' \
-d 'type=failure' \
-d 'title=Outage Report' \
-d 'body=<strong>File Server is no longer responding</strong>' \
-d 'format=html'

If you’re using Apprise already, consider just using the Apprise API Service to simplify Stateful queries:

Terminal window
# --config= allows you to source an upstream Apprise API for your
# configuration.
apprise --config=http://localhost:8000/cfg/team-alerts/ \
--tag=outage \
--input-format=html \
--notification-type=failure \
--title "Outage Report" \
--body "<strong>File Server is no longer responding</strong>"

Selecting an Output Format (Upstream Delivery)

Section titled “Selecting an Output Format (Upstream Delivery)”

In addition to declaring the input format, some services allow you to select how content is delivered upstream by specifying a format= parameter directly in the service URL.

This does not describe the input you are providing. Instead, it instructs the service plugin which delivery route or representation to use, if supported.

How Input and Output Formats Work Together

Section titled “How Input and Output Formats Work Together”
  • Input format (body_format, --input-format, API format)
    Tells Apprise what kind of content you are providing

  • Output format (?format= on a service URL)
    Tells the service plugin how to deliver that content upstream

When both are specified, Apprise will correctly adapt the content as needed before handing it off to the selected upstream delivery route.

If the upstream service does not support the requested output format, the request is ignored (a warning is logged) and the service’s default behaviour is used instead.

Email supports multiple delivery formats.

# Default behaviour (HTML email)
mailto://user:pass@example.com
# Force plain-text email delivery
mailto://user:pass@example.com?format=text

In this case:

  • format=html is unnecessary because HTML is the default
  • format=text explicitly selects the plain-text delivery route
  • format=markdown is ignored because email does not support Markdown delivery

Some services expose different API endpoints depending on format support.

In these cases, setting format= may:

  • Select a different upstream endpoint
  • Change how content is rendered by the service
  • Bypass formatting transformations entirely

This behaviour is plugin-specific and only applies when the service explicitly supports multiple output formats.

Specifying an output format is useful when:

  • You want to force a specific delivery type (for example, text-only email)
  • The service supports multiple content representations
  • You are sending content as-is and need to route it through a specific upstream path

If a service does not support the requested output format, Apprise safely falls back to the default behaviour.

Questions or Feedback?

Documentation

Notice a typo or an error?

Technical Issues

Having trouble with the code? Open an issue on GitHub:

Made with love from Canada