Skip to content

notifications

Alexander Herling edited this page Oct 14, 2026 · 19 revisions

Notifications

rDownloader delivers notifications server-side, with a persistent history — so a finished download reaches you with the browser closed. Configure it under Settings → Notifications, which has three parts: targets and rules on the tab Targets & rules, and the history on the tab History.

This is separate from the browser notifications the web interface raises for itself (links arrived, queue finished, download failed); those need only a permission under Settings → Interface → This browser. With several tabs open, one of them speaks for the browser, so each of these appears once. What Push to this device already sends to this browser is not raised a second time by a tab, and links handed over while the capture agent is connected are announced by the agent alone. What the browser extension hands over — from its context menu, its popup, Click'n'Load or a file — is announced by the extension alone: neither a tab nor the agent repeats it. Failed downloads arrive once per package with the number of failed files, and queue finished only when nothing waits any more — a pause is no end — and at most once in ten minutes. To get rDownloader's server-side notifications as push messages on a phone or desktop with no tab open, see Push to this device.

Targets

Settings → Notifications & webhooks on its Targets & rules tab, beside History: the Edit target form for the plugin destination Phone push (demo) with its ntfy address, and the list of demo targets, among them the Plex server Plex (demo), each with Test, Duplicate, edit and delete

A target is a destination. The New target form asks for:

Field What it is
Name Your label, 1 to 100 characters. Rules name their target by it
Kind Webhook, E-mail (SMTP), Apprise, Plugin destination or Browser push
The address field Its label follows the kind: URL, SMTP host, Service or Destination. Always required
The secret field Its label follows the kind: Signing secret, Password, Apprise target URL or Token
Plugin Only for Plugin destination: which installed notifier delivers
Enabled A switched-off target keeps its queued deliveries until it is switched on again

Plugin destination is offered only while at least one notifier plugin is installed. Six are bundled — Discord, Telegram, ntfy, and Plex, Jellyfin and Emby for media libraries — but a fresh installation lists them as available, not installed: choose them in the setup assistant's Your services step or install them under Settings → Plugins → Catalogue. A notifier installed while the service runs may need a restart of the service before a target can use it. Browser push needs no address and no secret; the first browser that turns push on creates it by itself.

The secret goes straight into the encrypted vault. When you edit a target the secret field starts empty; leave it empty to keep the stored one.

Duplicate copies a target under a free name and opens the copy in the form — without its secret, which you enter again. Rules can be duplicated the same way.

The setup guides below go through each kind:

Then add a rule — a target without a rule receives nothing but tests.

Discord

The Discord plugin posts to a channel through a Discord webhook. Tried against a real Discord server.

  1. In Discord, open the channel's settings (Edit Channel) → Integrations → Webhooks → New Webhook. Give it a name if you like, then press Copy Webhook URL. Creating a webhook needs the Manage Webhooks permission on that server.
  2. The copied URL looks like https://discord.com/api/webhooks/123456789012345678/AbCdEf…. You need only the part after /api/webhooks/: 123456789012345678/AbCdEf… — the webhook id, a slash, the webhook token.
  3. In rDownloader, Settings → Notifications → Targets & rules → New target:
    • Kind: Plugin destination
    • Plugin: Discord
    • Token: the <id>/<token> part from step 2 — not the full URL. The plugin puts it behind https://discord.com/api/webhooks/ itself; a full URL there produces an address Discord rejects.
    • Destination: anything, for example #downloads. The field is required, but the Discord plugin does not use it — the webhook alone decides which channel receives the message.
  4. Create target, then send a test.

The message arrives as an embed: the title, the text below it, the event name in the footer, and a coloured stripe — red for errors, amber for warnings, blue for everything else. Discord markdown in a package name is neutralised, so a release called @everyone mentions nobody. Long text is cut to what Discord accepts.

If Discord answers 401 or 404, the webhook was deleted or the token is wrong: create a new one and paste its tail into Token.

Telegram

The Telegram plugin sends through a bot you create, to a chat you name. It needs two values: the bot token (secret) and the chat id (not secret).

  1. Create the bot. In Telegram, open a chat with @BotFather, send /newbot, and answer its two questions — a display name and a username ending in bot. BotFather replies with the bot token, which looks like 123456789:AAH….
  2. Find the chat id. A bot cannot write to anyone first, so:
    • To yourself: open a chat with your new bot and send it any message. Then open https://api.telegram.org/bot<token>/getUpdates in a browser, with your token in place of <token>. In the answer, "chat":{"id":123456789,…} is your chat id.
    • To a group: add the bot to the group and write a message there — mentioning the bot (@yourbot hello) makes sure it sees it. The group's id in getUpdates is negative; a supergroup's starts with -100.
    • To a public channel: make the bot an administrator of the channel and use the channel's @username.
  3. In rDownloader, Settings → Notifications → Targets & rules → New target:
    • Kind: Plugin destination
    • Plugin: Telegram
    • Destination: the chat id — 123456789, -1001234567890 or @channelname
    • Token: the bot token from step 1
  4. Create target, then send a test.

The Destination must be one of those three shapes. Anything else — a space, a slash, a name without @ — is not sent at all; the reason reads This destination has no usable chat id. A target without a token fails with This destination has no bot token stored.

The message uses Telegram's HTML parse mode: the title in bold, the text on the next line, ⛔ in front of an error and ⚠ in front of a warning. <, > and & in a file name are escaped, so a name cannot turn into markup. Text beyond 3,800 characters is cut off; Telegram refuses anything over 4,096.

ntfy

The ntfy plugin publishes to a topic on ntfy.sh or on an ntfy server of your own.

  1. Install the ntfy app on your phone (or open ntfy.sh or your own server in a browser) and subscribe to a topic. On ntfy.sh anyone who knows a topic's name can read it, so pick a name nobody would guess.
  2. In rDownloader, Settings → Notifications → Targets & rules → New target:
    • Kind: Plugin destination
    • Plugin: ntfy
    • Destination: a bare topic name, my-downloads-x7q2, which means ntfy.sh; or the full address of the topic, https://ntfy.sh/my-downloads-x7q2 or, on your own server, https://ntfy.example.org/downloads
    • Token: leave empty for a public topic. For a reserved or protected topic, an ntfy access token (tk_…); it is sent as Authorization: Bearer <token>.
    • Priority for info messages / warnings / errors: the ntfy priority each kind of message is sent with, from 1 – min (silent) to 5 – max (overrides do-not-disturb on the phone). Left alone, they are 2, 3 and 4.
    • Fixed priority: one priority for every message of this target, whatever its severity. Leave it at Not set to use the three above.
  3. Create target, then send a test.

Each delivery reaches exactly the one host its destination names, and the token goes nowhere else: a redirect from that server to another host is not followed.

https is required — except inside your own network, where http:// is accepted: a private address, localhost, a name ending in .lan or .local, or a single-label service name such as http://ntfy:2586 from a Docker network. A server on this machine works (http://localhost:2586), but not on one of rDownloader's own ports — its web interface and API, or Click'n'Load — and a link-local address never does; both are refused when the target is saved. Anywhere else the token would cross the internet readable, so such a destination is refused — already when the target is saved, with A notification destination outside your own network needs https.

The message title becomes ntfy's title and the event name, package_completed for example, its tag. A 429 or a 5xx answer is retried; any other refusal fails at once.

Webhook

Signed JSON over HTTP, for your own receiver or an automation tool.

  1. Settings → Notifications → Targets & rules → New target, Kind: Webhook.
  2. URL: the http:// or https:// address to post to. Anything else is refused on save.
  3. Signing secret: a random string you also give the receiver. Optional — without one the request carries no signature header.
  4. Create target, then send a test.

The address keeps to the rule for an address you entered yourself: a receiver on your own network or on this machine is fine, a link-local address and rDownloader's own ports are refused, and the name is resolved through the same guard. A webhook follows no redirect, and of a failed answer only the first 8 KiB are read. A refused address is not retried.

Each delivery is a POST with Content-Type: application/json and this body:

{
  "event": "package_completed",
  "title": "Package finished: Holiday 2026",
  "body": "Holiday 2026 (completed)",
  "idempotency_key": "<rule id>:<event id>"
}

The events are package_completed, package_failed, storage_blocked, budget_exhausted, captcha_waiting, power_pending, usenet_job_hopeless and stop_mark_reached, the activity events download_started, links_added, stream_recorded and subscription_matched, the queue events queue_paused, queue_resumed and queue_finished, and the operational events backup_failed, backup_verify_failed, update_available, update_installed, update_failed, service_restarting, plugin_update_available, plugin_update_failed, account_expiring, account_invalid and usenet_quota_reached. A test sends "event": "test" with the title rDownloader test.

Two headers come with it:

  • X-RDownloader-Signature: sha256=<hex> — HMAC-SHA256 over the exact bytes of the body, keyed with the signing secret. The secret itself never travels.
  • X-RDownloader-Idempotency-Key — the same for every attempt of one delivery, so a receiver can drop a repeat.

Verify the signature over the raw body, before parsing it — re-serialised JSON will not match. In Python:

import hashlib, hmac

def is_genuine(raw_body: bytes, header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, header)

Any 2xx answer counts as delivered. 5xx, 408, 429 and a connection that fails are retried; any other 4xx means the request itself is wrong and fails at once.

E-mail (SMTP)

Mail through a server you have an account on.

  1. Settings → Notifications → Targets & rules → New target, Kind: E-mail (SMTP).
  2. SMTP host: the mail server's host name, smtp.example.org — no smtp://, no port.
  3. Password: the account's password (or the app password your provider issues for this).
  4. Sender: the address the mail comes from. Most servers accept only the account's own.
  5. Recipients: one or more addresses, comma-separated.
  6. Username: the account name. Credentials are sent only when both a username and a password are stored.
  7. Encryption: STARTTLS (the default), Implicit TLS or None.
  8. Port: empty picks 587 for STARTTLS, 465 for implicit TLS and 25 for none.
  9. Create target, then send a test.

The subject is the message title and the mail body its text, as plain text. None sends everything, password included, unencrypted — only for a relay on your own network. A permanent refusal from the server (a 5xx reply) fails at once; anything else is retried.

Apprise

Apprise is a separate command line program that speaks to a long list of services — Telegram, Discord, Slack, Matrix, ntfy (including self-hosted servers), Gotify, Pushover, Home Assistant and more. rDownloader hands it one message at a time.

  1. Have Apprise installed. The Docker image ships it, at a pinned version, so there is nothing to do. The Windows and Linux packages leave it to you: it is a Python program, and pip install apprise is the usual way. rDownloader looks for apprise like every other helper — see Where a tool is looked up — and a changed vendor folder applies without a restart. Settings → Tools → Status and rdownloader doctor show whether it was found, with its path and version.
  2. Write the Apprise URL for your service, following Apprise's own documentation — for Telegram, for example, tgram://<bot token>/<chat id>. Try it once by hand with the apprise command if you are unsure.
  3. Settings → Notifications → Targets & rules → New target, Kind: Apprise:
    • Apprise target URL: the URL from step 2. It carries the service's token, so it goes into the vault.
    • Service: a label for the list, Telegram for example. It is shown and not used.
  4. Create target, then send a test.

The target URL is handed to apprise in its environment, as APPRISE_URLS, never as a command line argument, where any user on the machine could read it in the process list. An apprise run that has not finished after 60 seconds is stopped and counts as a failed delivery, and a running one is stopped with the service.

A target can name its own apprise program instead (config.executable, over the API and MCP only). Setting or changing that path needs the administration area (api:admin), and a path only ever runs once an administrator saved the target with it; a delivery to a target whose path no administrator saved fails with that reason instead of starting the program.

If Apprise is missing, the reason reads apprise is not installed or not configured. When it runs but fails, the reason is what Apprise printed — on its error output and on its normal output, where it reports most errors — with the target URL masked. Every Apprise failure is retried — a wrong token and an outage look the same — so a wrong URL reaches Failed only after the sixth attempt.

Plex, Jellyfin and Emby

These three plugins do not send a message: they ask your media server to scan its libraries when a package finishes, so a new film or episode shows up without waiting for the server's own schedule. Every other event is answered as delivered and sends nothing.

For the scan to find anything, the download folder must lie inside a library folder of the media server; a film saved outside every library folder stays invisible. With a Path mapping on the target, rDownloader tells the server where the finished package lies, and the server scans that folder instead of every library — see Scan only the new folder. Without one, the whole library is scanned. See Media server in Docker for the usual setup.

Install the plugin

The three plugins ship with rDownloader but are not installed until you choose them — in the setup assistant's Your services step, or under Settings → Plugins → Catalogue (Plex notifications, Jellyfin notifications, Emby notifications). Plugin destination appears under Kind once one is installed; a notifier installed while the service runs may need a restart of the service before a target can use it.

Get the credential

Jellyfin — an API key, required:

  1. Sign in to Jellyfin's web interface as an administrator.
  2. Dashboard → Advanced → API Keys → New API Key (in older versions the + button).
  3. Enter an app name such as rDownloader and press Create. The key appears in the list; copy it.

Jellyfin's dashboard, page API Keys: a New API Key button above the table of keys, the key issued to the app rDownloader with its date and a delete button

Emby — an API key, required: in Emby's web interface open the server's settings (the gear icon), then Advanced → Api Keys → New Api Key, enter rDownloader as the app name and copy the key from the list.

Plex — an X-Plex-Token, or nothing:

  • With a token — the way Plex itself documents: sign in to Plex Web, open any item of a library, choose ⋯ → Get Info, then View XML at the bottom of the dialog. The page that opens has X-Plex-Token=… at the end of its address; copy the value after the =. Treat it like a password — it is your Plex account's sign-in for that server.
  • Without a token — a Plex server that admits a network without sign-in needs none from inside it. In Plex Web: Settings → Network → Show Advanced → List of IP addresses and networks that are allowed without auth, for example 192.168.1.0/24 or, for a Docker network, 172.16.0.0/12 (the plexinc/pms-docker image takes it as ALLOWED_NETWORKS). Then the destination must be the server's IP address, http://192.168.1.20:32400 — Plex treats a request addressed by a name it does not know, http://plex:32400, as coming from outside and answers 401.

Create the target and the rule

  1. Settings → Notifications → Targets & rules → New target:

    • Kind: Plugin destination
    • Name: your label, Jellyfin for example
    • Destination: the server's address, such as http://192.168.1.20:32400 (Plex) or http://jellyfin:8096. Like ntfy, it must be https outside your own network; a base path behind a reverse proxy (https://media.example.org/jellyfin) is kept. A destination that is not an address is refused when the target is saved.
    • Token: the API key or token from Get the credential (empty for a Plex server that admits rDownloader's network).
    • Plugin: Plex, Jellyfin or Emby

    Settings → Notifications, New target: kind Plugin destination, name Jellyfin, the Jellyfin server's address, the token field filled and masked, plugin Jellyfin; beside it the targets Emby, Jellyfin and Plex

  2. Create target, then press Test on its row. For these three plugins the test is a real library scan, so it checks the address and the key: Test notification delivered to "Jellyfin". means the server accepted it.

  3. Add a rule for Package finished (package_completed) with this target — the only event these plugins act on. One rule per target; three servers need three rules.

The next finished package then shows up in the library within seconds. Named like the film, Big Buck Bunny (2008), a package is matched by the media server's own metadata lookup, with poster, description and cast:

Jellyfin's home page: the Movies library with Big Buck Bunny as its picture, and under Recently Added in Movies the film Big Buck Bunny, downloaded by rDownloader as a torrent a moment before

Jellyfin's page for Big Buck Bunny: the Big Buck Bunny logo over a still of the film, its year and length, the plot summary, the English subtitles that came with the torrent, director Sacha Goedegebure and the studio Blender Foundation

The delivery reaches only the server the destination names.

Scan only the new folder

A large library takes a while to scan whole. The target's own fields, below the plugin, let the server look at the finished package alone:

  • Path mapping (all three) — one line per folder, rDownloader's path, =, and the path the media server sees for the same folder: /downloads=/data/movies. Several lines are allowed; the longest path that holds the package decides. A package that no line holds refreshes the whole library, as without a mapping.
  • Library section (Plex only) — the number of the Plex library the downloads go to. Plex Web shows it as source=<number> in the library's address. Plex scans a single folder only within one section, so a mapping without a section still refreshes every library.

Jellyfin and Emby are told the folder as newly created and scan the folder that holds it, not every library; Plex refreshes the section for that folder alone. The section is one line of up to 256 characters, the mapping up to 4096 over several lines; a longer text or a control character is refused when the target is saved.

The Edit target form for the Plex destination Plex (demo): the plugin Plex, the library section, and Path mapping with a line per folder, the download folder on the left and Plex's folder on the right of the equals sign, above Enabled and Save

When it does not work

What the test reports, and what History shows for a finished package:

You see Meaning What to do
Delivered, but the film is not in the library The scan ran, but the folder is not part of a library Put the download folder inside a library folder (Docker)
Delivered, but the server scans every library No line of the Path mapping holds the package's folder, or a Plex target has no Library section Add the line for the download folder, and for Plex the section (Scan only the new folder)
Failed — Jellyfin answered 401 (or Emby, Plex) Wrong or deleted key; for Plex, also a name instead of an IP address without a token Create a new key and enter it in the target. Failed at once, not retried
Retrying — … error sending request … No route to host, Connection refused or a timeout The server cannot be reached at that address Check the address and that the server runs. Retried for about half an hour, then Failed
Failed — This destination has no API key stored A Jellyfin or Emby target without a key Edit the target and enter the key

A Plex server that admits rDownloader's network without sign-in ignores the token, so there a wrong token is not noticed — the scan runs anyway.

Settings → Notifications → History: the deliveries for a test package — most of them Delivered, one Failed with Jellyfin answering that it was unauthorized, one Retrying with a No route to host error

Media server in Docker

When rDownloader and the media server run as containers, mount the same host folder into both. The path inside each container may differ; a Path mapping translates one into the other:

services:
  rdownloader:
    image: ghcr.io/degoya/rdownloader:latest
    volumes:
      - ./config:/config
      - /srv/media/movies:/downloads
  jellyfin:
    image: jellyfin/jellyfin:latest
    volumes:
      - ./jellyfin-config:/config
      - /srv/media/movies:/data/movies

In Jellyfin, the Movies library then points at /data/movies, and the target's destination is http://jellyfin:8096 — containers of one compose project reach each other by service name, and the path mapping /downloads=/data/movies lets Jellyfin scan just the new film's folder. Emby works the same way. If you download into a storage root instead of /downloads, mount that folder into both containers. rDownloader puts each package in a folder of its own, Film Name (2026)/, which is the layout Jellyfin, Emby and Plex expect for films.

For Plex without a token, use the Plex container's IP address rather than http://plex:32400 (see Get the credential), or give the target a token.

Push to this device

rDownloader can send its notifications as Web Push messages to a browser — best the installed app on a phone or desktop. They arrive while the browser runs, with no rDownloader tab open, and a click opens the view of the event (a finished package the downloads, a failed backup the backups).

  1. Open rDownloader over https (or as localhost on the same machine). Push needs a secure context; on plain http the switch stays off and says so — see Reverse proxy for https.
  2. Settings → Interface → This browser, card This browser only: switch on Push on this device and allow notifications when the browser asks. It holds for this browser only; turn it on in every browser or device that should receive pushes.
  3. Under Events below the switch, choose which events reach this device; none chosen means every event.

The first browser that turns push on creates the target Browser push and a rule for every event; every further browser joins that same target. A message is encrypted for the one browser and signed with a key of this installation, made on first use and kept in the vault — no third-party push account is involved; the browser's own push service only carries it. A browser whose subscription its push service dropped is removed by itself; a lost device is removed over MCP (delete_web_push_subscription) or the REST API.

Testing

Every target row has a Send a test button (the paper-plane icon). It sends rDownloader test — This is a test notification from rDownloader. — straight away and shows what came back:

  • Test notification delivered to "Name"., or
  • "Name" did not accept the test: … with the reason — the service's answer, the HTTP status or the error, such as Discord answered 404 or Resolver HTTP header is not allowed.

A test needs no rule, ignores quiet hours, also works on a switched-off target, and is not written to the delivery history.

Braces in notification text

Every { in a notification's text is shown as ❴ (and so is %7B, its percent-encoded form), in the title and the body alike. A package called Holiday {2026} arrives as Holiday ❴2026}.

The reason is the token: a plugin destination's token is filled into a placeholder such as {{secret}} on the way out (see Secrets). Package names, file names and feed titles are chosen by somebody else, so without this a release named Release {{secret}} would publish your bot, access or webhook token in the chat, topic or channel. The destination itself is used exactly as you entered it.

Rules

A rule routes events to a target, filtered by:

  • event,
  • category,
  • minimum severity.

One event produces at most one delivery per rule, even across a restart.

One notification per moment. An event is raised once, when the state changes, never again for the same moment:

  • Package finished comes once, when the package finishes — not again when it is written again, moves on to a later step or is reordered. A package whose files all failed ends failed and raises package_failed with the number of failed files.
  • A storage root that is released again does not report out of space. The out of space notification names the root and its folder.
  • A captcha is waiting comes when the first captcha starts waiting, not for every answer or expiry; Captcha not answered in time when the last one runs out.
  • A standby or shutdown countdown is one event when it starts and one when it is cancelled.

Under Events, nothing selected means every event except Download started, Links added and the three queue events: a rule gets those only when you select them.

Own wording

A rule can send its notifications in your own words: Own title and Own text in the rule's form, with placeholders in braces that rDownloader fills, for example

{package} finished at {time}

arrives in ntfy or Telegram as Holiday photos finished at 14:32. Leave a field empty and the built-in title or text is sent, as before.

  • Placeholders the chosen events fill are listed under the fields; a click puts one at the cursor of the field you used last, replacing the text selected there. The preview below shows the result with sample data.
  • A placeholder an event does not fill comes out empty, {error} on a finished package for instance. A part that comes out empty altogether is sent in the built-in wording.
  • A name that is no placeholder is refused when you save ({pakage} is a typo the form points out right away). To write a brace itself, double it: {{ and }}. A plugin destination then shows it as ❴, like every brace.
  • No conditions, no loops, and no placeholder carries a secret: an account is named by its label and provider, never by its user name.
  • Time and date are the service's: HH:MM and YYYY-MM-DD in the time zone rDownloader runs in, when the event happened.
  • The traffic budget of the active bandwidth profile fills {budget_used}, {budget_left}, {budget_limit} and {budget_period} in every event: of a daily and a monthly budget, the one with less left. Without an active budget they come out empty.
  • Filled once, when the notification is queued, so a retry sends the same words. Line breaks in a package or file name become spaces, and the result is cut to what every destination takes: 250 characters of title, 2000 characters (and 4000 bytes) of text.
  • The webhook JSON keeps its fields: your wording fills title and body, nothing else.
  • A burst of Download started or Links added is worded once, when it closes: {count}, {items} and {names} describe the whole burst, and a burst of exactly one start also fills {file}, {package} and {category}. The summary at the end of quiet hours keeps its own text, which lists the titles it held.

The title holds at most 200 characters, the text 2000. API and MCP: title_template and body_template on the rule, the table under GET /api/v1/notifications/placeholders and the tool list_notification_placeholders.

Which placeholder holds what (generated from rDownloader's own table):

Placeholder Holds Example
{event} The event's code, such as package_completed package_completed
{severity} info, warning or error info
{time} When it happened, HH:MM in the service's time zone 14:32
{date} The day it happened, YYYY-MM-DD in the service's time zone 2026-10-13
{title} The built-in title Package finished: Holiday photos
{message} The built-in text Holiday photos (completed)
{budget_used} Traffic of the active budget used so far, empty without one 12.5 GiB
{budget_left} Traffic of the active budget left 37.5 GiB
{budget_limit} The active budget's limit 50.0 GiB
{budget_period} The active budget's period, daily or monthly monthly
{package} The package's name Holiday photos
{file} The file's name IMG_2048.jpg
{category} The category's name Pictures
{state} The package's state, such as completed or failed completed
{size} The size, such as 1.4 GiB 1.4 GiB
{path} The folder on disk /downloads/Pictures/Holiday photos
{error} What went wrong The server refused the request (403)
{storage_target} The storage root or backup destination Downloads
{version} The version 1.28.0
{plugin} The plugin's name Example Hoster
{account} The account's label and provider, never its user name Main (example.com)
{reason} Why the queue paused: manual, automation, schedule, stop_mark or game_mode schedule
{count} How many times the event happened in the burst: imports or starts 3
{items} Links or downloads in the burst altogether 12
{names} The burst's first names: the files started, the rest as and N more, or the links' sources clipboard, browser extension

Every event fills {event}, {severity}, {time}, {date}, {title}, {message}, {budget_used}, {budget_left}, {budget_limit}, {budget_period}.

Event Also fills
package_completed {package}, {category}, {state}, {size}, {path}
package_failed {package}, {category}, {state}, {size}, {error}
storage_blocked {storage_target}, {path}
budget_exhausted (nothing more)
captcha_waiting (nothing more)
power_pending (nothing more)
backup_failed {error}
backup_verify_failed {storage_target}, {error}
update_available {version}
plugin_update_available {plugin}, {version}
plugin_update_failed {plugin}, {version}, {error}
update_installed {version}
update_failed {version}, {error}
service_restarting (nothing more)
account_expiring {account}
account_invalid {account}, {error}
usenet_job_hopeless {package}, {category}
usenet_quota_reached (nothing more)
stop_mark_reached {package}, {file}, {category}
download_started {count}, {items}, {names}, {file}, {package}, {category}
links_added {count}, {items}, {names}
stream_recorded {file}, {package}, {category}, {size}
subscription_matched {category}
queue_paused {reason}
queue_resumed (nothing more)
queue_finished (nothing more)

download_started and links_added arrive in bursts, one notification each, worded when the burst closes. A burst of one start also fills {file}, {package} and {category}; a burst of several leaves them empty.

The budget_exhausted event

Raised when the active bandwidth profile uses up its daily or monthly traffic budget — once per profile and period. Another profile using up its own budget raises it again, and so does the next day or month. After a restart inside a used-up period it is raised once more. The budget counts from the first moment, also when a bandwidth profile has been active since the service started.

The usenet_job_hopeless event

Raised, with severity error, when a Usenet download is stopped because more PAR2 blocks are missing than its recovery volumes can repair (Usenet). It belongs to the package's category, and its text names the missing and the available blocks. The package also ends failed, so a rule that asks for package_failed hears about it too.

The stop_mark_reached event

Raised, with severity info, when the queue pauses at its stop mark: the marked file is done, or no file of the marked package waits or runs any more. It belongs to the marked package's category, and its text names the file or package. Once per mark.

Activity events

Four events report ordinary activity rather than an outcome. All of them have severity info.

Event Shown as Raised when Category
download_started Download started a download leaves the queue for the transfer — resuming after a pause or a retry wait is not a start the package's
links_added Links added links arrive in the LinkGrabber; the text names how many and where they came from none
stream_recorded Stream recorded a livestream recording finishes the package's
subscription_matched Subscription found new items a subscription check accepted new items the subscription's

Download starts and added links are opt-in. They can come in large numbers, so a rule without a selected event does not receive them; select them under Events to hear about them.

A burst arrives as one notification. Starts and added links are gathered per event and category until ten seconds pass without another, or a minute after the first: a hundred pasted links or a fifty-file package starting arrive as one message with the total and the first names, in the rule's own wording when it has one.

Plugin destinations receive these events like every other one.

Queue events

Three events report the whole queue, with severity info and no category:

Event Shown as Raised when
queue_paused Queue paused the queue pauses — {reason} says why: manual, automation, schedule, stop_mark or game_mode
queue_resumed Queue resumed that pause ends, whatever ended it
queue_finished Queue finished nothing waits, downloads or is post-processed any more

They are opt-in: a rule without a selected event does not receive them. Each comes once per change — a second pause on top of the first, or a queue that stays empty, raises nothing more. A used-up traffic budget raises budget_exhausted instead.

Operational events

Eleven events come from what rDownloader does in the background rather than from the queue. They belong to no category, so a rule restricted to one never receives them.

Event Severity Raised when Sent once per
backup_failed error a scheduled full backup fails, or reaches only some of its destinations backup run
backup_verify_failed error a scheduled verification finds an archive changed, unreadable or gone verification
update_available info the update check finds a newer rDownloader, and when an automatic install of it begins version
update_installed info rDownloader runs a newer version after an update — automatic or by hand version
update_failed error an update did not go ahead, or was taken back version
service_restarting info rDownloader restarts to apply a plugin change — on Restart now, from the tray, or by itself; queued before the stop, so it is delivered at the latest once rDownloader is back restart
plugin_update_available info the plugin repository refresh finds an update that waits for you — set to manual, or asking for new permissions plugin and version
plugin_update_failed error a plugin set to update automatically could not fetch or install its update; the installed version keeps running plugin and version
account_expiring warning an account check reports the premium ending within seven days, or already ended account and end date
account_invalid error an account check refuses the account, or renewing its sign-in token fails for good account and day
usenet_quota_reached warning a Usenet server used up its quota; it then serves as a backup only or pauses, as set crossing of the limit

The checks behind them repeat — the update check and the plugin repository refresh run on their own intervals — but each notice reaches a rule once, even after a restart or after you cleared the history. A backup or verification you start by hand does not notify: you see its outcome yourself. An update a plugin installs automatically does not notify either — only one that fails.

Account expiry is only known when an account is checked: Test under Settings → Accounts reads the premium end the hoster reports. rDownloader does not sign in to your hosters on its own to find out, because a hoster's sign-in may ask for a captcha. Accounts that sign in with a token (debrid services) report a failed renewal by themselves.

Delivery and retries

  • A failed attempt that can succeed later is retried after about 1, 2, 4, 8 and 16 minutes (each ±10 %). After the sixth failed attempt the delivery is Failed — roughly half an hour after the first.
  • A non-retryable answer from a webhook or a mail server fails at once.
  • A plugin destination's permanent failure — a rejected Telegram token, a wrong chat id, a deleted Discord webhook — is Failed with that reason on the first attempt. A temporary one — 429, a 5xx answer, no network — or one the plugin could not classify is retried as above. A target whose plugin is no longer installed fails at once.
  • A hanging endpoint delays neither the other targets nor any transfer.
  • Quiet hours hold deliveries instead of dropping them. When they end, each target receives one summary — While it was quiet: N notifications, naming the first five and how many more — carrying the most serious of the held events, so a rule or browser that would have let the worst of them through lets the summary through. A single held notification arrives as itself. Quiet hours hold the browser tab's and the capture agent's notifications too.

History

Settings → Notifications → History. Delivery history lists the latest 50 deliveries, newest first. Each row shows:

  • the state — Queued, Delivered, Retrying or Failed,
  • the title, the time of the last change and the number of attempts,
  • the HTTP status, where there was one,
  • the reason: what the target answered, or the error, below the title.

A delivery stuck on Retrying with the same reason each time is a configuration problem, not an outage — fix the target and the next attempt uses the new settings. What a target answers is truncated to 500 characters and redacted before it is stored, so no secret ends up here.

Clear beside the list heading empties the history. Its dialog, Clear the notification history?, first says how many finished deliveries will go; Clear for good removes them. Deliveries still Queued or Retrying stay, and so do the targets, the rules, the logs and the statistics.

Discard pending appears beside it while deliveries are still Queued or Retrying — for example after a target was unreachable for a while. Its dialog, Discard the pending notifications?, says how many will never be sent; Discard for good deletes exactly those. A delivery being sent at that very moment still goes out, but its result is not recorded.

Both need the administration area and are recorded in the audit log with the number removed.

Secrets

Every target secret lives in the encrypted vault as a reference. It is never returned by the API, never written to a log, and never placed in a backup exported without secrets. See Backup and restore.

A plugin never sees its token either: the stored value is filled in on the way out, only for the hosts the plugin's manifest allows or the one host its destination names. See also Braces in notification text.

Related pages

Clone this wiki locally