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.
Message Formats
Section titled “Message Formats”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:
| State | Description |
|---|---|
| (implicit) none | No source format declared. Automatic format conversion is skipped. |
| text | Plain text input. Apprise may simplify content for text-only services. |
| markdown | Markdown input. Apprise may convert or simplify as needed. |
| html | HTML 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.
Declaring Input vs Transforming Output
Section titled “Declaring Input vs Transforming Output”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:
| Interface | Default input format |
|---|---|
| CLI | text |
| Python API | none - no automatic format conversion unless body_format is provided in notify() or preset in AppriseAsset() |
| Apprise-API | none - 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.”
Pass-Through and Overflow
Section titled “Pass-Through and Overflow”The URL’s overflow setting still applies when no input format is declared:
upstreamsends one message without splitting or truncating it for the service’s documented limit.truncatekeeps the portion that fits and discards the rest.splitprefers 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.
CLI Examples
Section titled “CLI Examples”Use --input-format to tell Apprise how to interpret your body content.
# Markdown bodyapprise -t "Release" -b "**v1.2.3** is now live" \ --input-format=markdown \ "discord://..."
# HTML bodyapprise -t "Build Report" -b "<b>Success</b>: artifacts uploaded" \ --input-format=html \ "mailto://user:pass@example.com"Python Library Examples
Section titled “Python Library Examples”Use body_format to specify the message format you are providing.
from apprise import Apprisefrom apprise import NotifyFormat
apobj = Apprise()apobj.add("discord://...")
# Markdown inputapobj.notify( title="Status", body="**All checks passed**", body_format=NotifyFormat.MARKDOWN,)
# HTML inputapobj.notify( title="Build Report", body="<b>Success</b>: artifacts uploaded", body_format=NotifyFormat.HTML,)Apprise-API Examples
Section titled “Apprise-API Examples”For JSON payloads, use the format field:
# Stateless Examplecurl -X POST http://localhost:8000/notify/ \ -d 'urls=["discord://..."]' \ -d 'title=Status' \ -d 'body=**All checks passed**' \ -d 'format=markdown'
# Stateful Examplecurl -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:
# --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, APIformat)
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.
Examples
Section titled “Examples”Email supports multiple delivery formats.
# Default behaviour (HTML email)mailto://user:pass@example.com
# Force plain-text email deliverymailto://user:pass@example.com?format=textIn this case:
format=htmlis unnecessary because HTML is the defaultformat=textexplicitly selects the plain-text delivery routeformat=markdownis ignored because email does not support Markdown delivery
Services with Multiple Endpoints
Section titled “Services with Multiple Endpoints”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.
Use Cases
Section titled “Use Cases”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?
Technical Issues
Having trouble with the code? Open an issue on GitHub: