Skip to content

Notifications

Get notified about print events via WhatsApp, Telegram, Discord, Email, Home Assistant, and more.

Notifications Settings


Supported Providers

Provider Setup Features
ntfy Easy Free, no account needed
WhatsApp Easy Via CallMeBot
Discord Easy Channel webhooks
Pushover Easy Professional push service
Bark Easy iOS push, no account, self-hostable
Notify! Easy Device and group notifications, optional iOS Live Activities and Lock Screen widgets
Gotify Easy Push from your own Gotify server, per-event priority
Telegram Medium Via Telegram Bot
Email Medium SMTP email
Home Assistant Easy HA dashboard or mobile push via any notify service, with custom data fields and automatic photo attachment
Webhook Flexible Custom HTTP POST

Adding a Provider

  1. Go to Settings > Notifications
  2. Click Add Provider
  3. Select provider type
  4. Enter configuration
  5. Click Test Configuration to verify
  6. Configure event triggers
  7. Click Add

Saved tokens, passwords and webhook URLs

Once saved, a provider's secrets (tokens, keys, passwords, webhook URLs) are never shown again: the edit dialog shows ******** instead. Leave it as is to keep the saved value, clear it to remove it, or enter a new one. If you change where a provider sends to (the SMTP server, port or security, or the ntfy, Gotify or Bark server, or the webhook URL), enter its secret again.


Provider Setup Guides

ntfy (Easiest)

Simple topic-based notifications - no account needed!

  1. Choose a unique topic name (e.g., my-printer-xyz123)

  2. Subscribe on your phone:

  3. Install ntfy app (Android / iOS)
  4. Subscribe to your topic

  5. In Bambuddy, enter:

Field Value
Topic Your topic name
Server https://ntfy.sh (or self-hosted)

Keep Topic Secret

Anyone who knows your topic can send you messages. Use a random string.

Per-event priority

ntfy supports a Priority header that controls how the receiving device escalates an alert (sound, vibration, do-not-disturb override, banner persistence). Bambuddy lets you map each enabled event to one of five levels:

Priority ntfy value Typical use
Min 1 Diagnostics-style pings — no sound, no badge
Low 2 Informational, non-urgent (e.g. "first layer complete")
Default 3 Standard notification (the ntfy default if nothing is set)
High 4 Audible / urgent (e.g. "filament low", "AMS humidity high")
Urgent 5 Wakes the device, ignores DND (e.g. "print failed", "printer offline")

After enabling the events you want, scroll to the ntfy Priority section in the Add / Edit Notification dialog. Each enabled event gets its own dropdown — events left at Default fall through to whatever the ntfy server is configured to send. Disabled events don't appear in the section.

Switching the provider type away from ntfy hides the section; the priorities are still saved if you switch back.

The daily digest is not covered by these priorities: it is one message summarising several events, so it goes out at the ntfy server's default.


WhatsApp (CallMeBot)

Free WhatsApp notifications:

  1. Add CallMeBot to contacts: +34 644 51 95 23

  2. Send via WhatsApp: I allow callmebot to send me messages

  3. You'll receive an API key

  4. In Bambuddy, enter:

Field Value
Phone Number Your number with country code (e.g., +1234567890)
API Key Key from CallMeBot

Discord

Via channel webhooks:

  1. In Discord, go to channel settings
  2. Navigate to Integrations > Webhooks
  3. Click New Webhook
  4. Customize name/avatar
  5. Click Copy Webhook URL
  6. In Bambuddy, paste the URL

Pushover

Professional push notification service:

  1. Create account at pushover.net
  2. Install Pushover app on your device
  3. Create an Application in dashboard
  4. In Bambuddy, enter:
Field Value
User Key From Pushover account
API Token From your Application
Priority Message priority, -2 (lowest) to 2 (Emergency). Defaults to 0 (normal).

Emergency priority (2)

Priority 2 is Pushover's Emergency level: the notification keeps re-alerting on your device until you acknowledge it. Pushover requires two extra parameters for this, and Bambuddy exposes them only when you set Priority to 2:

Field Meaning Range Default
Emergency Retry (s) How often Pushover re-alerts until acknowledged 30–10800 s 60 s
Emergency Expire (s) When Pushover stops re-alerting if never acknowledged 30–10800 s (max 3 h) 3600 s

Values outside the allowed range are clamped automatically. These fields have no effect at any other priority.


Bark (iOS)

Open-source push notifications for iPhone/iPad via the Bark app — no account needed, self-hostable:

  1. Install the Bark app from the App Store
  2. Copy your device key from the app (shown on the main screen)
  3. In Bambuddy, add a provider and select Bark:
Field Value
Device Key From the Bark app
Server URL Optional — defaults to the official https://api.day.app relay; enter your own bark-server URL if self-hosting
Group Optional — groups notifications in the iOS notification center
Sound Optional — a Bark sound name (e.g. minuet)
Interruption Level Optional — Time Sensitive breaks through scheduled summaries; Critical also bypasses Silent mode and Focus (great for print failures); Passive delivers without waking the screen

Photo attachment

When a camera snapshot is available, it's sent as Bark's icon — the closest thing Bark's push schema has to a photo attachment, shown as a round icon on iOS. See Finish Photos below for requirements.


Notify!

Send print alerts through Notify! and optionally follow running prints or keep printer status on an iPhone or iPad Lock Screen.

  1. Open Notify! and copy your Device ID and Token from Settings > Device. For group notifications, use the group's ID and token instead.
  2. In Bambuddy, go to Settings > Notifications, add a provider and select Notify!.
  3. Enter the matching ID and token, then use Test Configuration to check delivery.
  4. Choose the printers and notification events you want, then save the provider.
Field Value
Device or group ID Your Notify! device ID or a group ID beginning with GRP
Notify! token The token belonging to that device or group
Icon URL (optional) HTTPS image URL for the notification's sender icon
Notification thread (optional) Thread name for grouping notifications on the receiving device. Leave empty to group by printer.
Live Activities (iOS) Optional live print progress on an iPhone or iPad; requires an individual device
Lock Screen Widgets (iOS) Optional persistent printer status widgets; requires an individual iOS device

Ordinary notifications work with iOS, browser and Mac devices, and groups. Device IDs can be eight characters or the newer longer IDs; copy the whole ID from Notify!. A group uses its own token, not a member's device token. Group (GRP), browser (WB) and Mac (MC) targets use ordinary notifications, and both iOS options are turned off for them.

Finish photos

With Attach Photo enabled, Notify! can show a camera snapshot inside the expanded notification. Set Bambuddy's External URL to an HTTPS address reachable from the receiving device. If no HTTPS photo URL is available, Bambuddy still sends the text. Browser (WB) and group (GRP) recipients receive text without camera photos, including problem alerts; Attach Photo is unavailable for those targets. See Finish Photos.

Live print progress

Enable Live Activities (iOS) for an individual iPhone or iPad device. Open Notify! on that device at least once and allow Live Activities in iOS settings. Browser, Mac and group targets receive ordinary notifications only.

Bambuddy starts a Live Activity for each printing machine, updates its progress and countdown, reflects pauses, and ends it when the print finishes, fails or stops. Updates continue independently of the Print Progress notification milestones. The provider's printer selection applies to both notifications and Live Activities.

When the printer reports a problem that needs attention, the activity displays the fault and stops its countdown, even if the printer still reports that it is running. The error text temporarily replaces any metric chips so the reason is visible. A manual pause also stops the countdown. Progress and the countdown resume when the problem clears and the printer resumes; informational HMS advisories do not turn a healthy print into an error.

  • Event triggers and Daily Digest control ordinary notifications. The Live Activities switch controls live progress separately.
  • Quiet Hours prevent new Live Activities from starting. An activity that already exists continues updating and ends normally, so it cannot be left showing an old print overnight.
  • Swiping away an activity dismisses it for that print. A later print can create a new one.
  • Restarting Bambuddy retains saved activity IDs and waits up to two minutes for the printer's first real status. If none arrives, the activity shows Printer offline and stops its countdown. Normal updates resume when the printer reconnects.
  • Long prints get a replacement activity at Apple's eight-hour limit.

Notify! supports up to five simultaneous Live Activities per device. If your farm has more active printers, use the provider's printer selection to choose which machines appear on your Lock Screen.

Customize the activity

The default activity shows the printer and job name, a progress bar and a live countdown, with no extra metrics selected. Expand Live Activity appearance in the provider settings to customize it:

Option What it changes
Hide file name on tile Keeps the filename off the Live Activity. Ordinary notification templates are unchanged.
Progress style Choose a continuous bar, segmented progress, or no bar. The countdown remains when an estimate is available.
Show print stage Show the printer's current stage, such as heating or calibration, in the activity's status.
Metrics Optionally show progress, time remaining, layer count, nozzle temperature, bed temperature or chamber temperature as small values. All are off by default; select only the ones you need. Metrics take the place of the job-name line.
Dashboard URL (optional) Add a button that opens your Bambuddy dashboard. Use an HTTPS URL your phone can reach.
Symbol (optional) Choose an SF Symbol for the activity's icon.
Tint (optional) Change its accent color using a hex color such as #00A76F.

Missing metric readings are omitted rather than displayed as zero. Hiding the job name affects the Live Activity only; to keep filenames out of ordinary alerts too, remove {filename} from the relevant notification templates.

The separate Time Sensitive problem alerts option applies to problem notifications. It requests delivery through iOS Focus and Do Not Disturb, subject to the receiving device's settings. Successful print notifications keep their normal priority.

Persistent Lock Screen widgets

Enable Lock Screen Widgets (iOS) to keep status widgets for up to ten selected active printers, including between prints. Printers in maintenance mode do not receive widgets. This option works independently of Live Activities. A widget shows progress while printing, the printer's status while idle or offline, and a useful description when a problem needs attention.

Bambuddy keeps the same widget for later prints. Its updates do not send push notifications and run independently of event toggles, Daily Digest and Quiet Hours. Notify! allows up to ten widgets per device in total, including widgets created outside Bambuddy. The provider settings show this limit. With All Printers, Bambuddy keeps existing widgets and adds eligible printers up to that limit. Choose a specific printer to control which machine appears when your device does not have enough available widget slots. If Notify! reports that all slots are occupied, Bambuddy stops trying to create more widgets; free a slot in Notify! and save the provider to retry.

After saving the provider:

  1. Open Notify! on the receiving iOS device.
  2. Touch and hold the Lock Screen, choose Customize, then tap the widget area below the clock.
  3. Choose Notify! and add a rectangular or circular widget.
  4. While still customizing, tap that widget and select the printer to display. Enable Show Last Updated in the same sheet to see how fresh its value is.

iOS refreshes these widgets on its own schedule, roughly every fifteen minutes and sometimes longer. They display the most recently fetched status and do not have a live countdown. Use Live Activities for the timer and push notifications for timely problem alerts.

Disabling widgets or removing a printer from this provider's selection schedules removal of the widget Bambuddy manages. Cleanup runs in the background after saving or deleting a provider, so its old tiles may remain visible briefly. Widgets have no automatic expiry: if cleanup fails while deleting the provider or changing its device ID, an old widget can remain in Notify!. Remove that obsolete widget before setting it up again. The Notify! widget API also supports deleting an individual widget by its WG ID; removing its placement from the Lock Screen alone does not delete the stored widget.

If Bambuddy reports that widget creation could not be confirmed, it stops trying to create another copy. Check Notify! for a widget that may already have been created and remove it before retrying. Then turn Lock Screen Widgets (iOS) off, save the provider, and turn it back on to start again.

Avoid duplicate alerts

After configuring the native provider, stop the separate notify-bambuddy companion before enabling Bambuddy's Live Activities. Leaving both running creates duplicate activities; setting the companion's ALERTS=off only disables its ordinary notifications. Dismiss its existing activities on your device, because Bambuddy does not take over activities created by the companion. Disable any generic webhook provider that sends the same events to Notify! to avoid duplicate push notifications.

An alert test does not test a Live Activity

Test Configuration and Send Test Notification send an ordinary push notification. To check live progress, enable Live Activities, save the provider, then start a print. If Notify! reports that starts are temporarily limited, respect the retry time it gives; repeatedly starting more activities does not clear that limit.

For Notify!'s device setup and delivery troubleshooting, see its help and API reference.


Gotify

Push notifications from your own Gotify server, received by the Gotify Android app or any other Gotify client:

  1. In the Gotify web UI, open Apps and create an application (e.g. "Bambuddy")
  2. Copy the application's token
  3. In Bambuddy, add a provider and select Gotify:
Field Value
Server URL Your Gotify server, e.g. https://gotify.example.com (a LAN address works too)
App Token The application token from step 2

The token is sent in the X-Gotify-Key header, never in the URL.

Per-event priority

Like ntfy, each enabled event gets a dropdown in the Gotify Priority section of the dialog. Gotify priorities run from 0 to 10, and Bambuddy sends the five levels as:

Level Gotify priority Gotify Android app
Min 0 Silent, minimised
Low 2 Silent
Default 5 Sound
High 8 Sound and pop-up
Urgent 10 Sound and pop-up

Events left at Default, the test notification and the daily digest go out at 5.

Photo and tap action

When a camera snapshot is available, it's sent as Gotify's bigImageUrl, which the Android app shows as a large picture. The outcome confirmation opens the outcome dialog in Bambuddy when you tap the notification. Both need External URL set; see Finish Photos.


Telegram

Via Telegram Bot:

  1. Message @BotFather
  2. Send /newbot and follow prompts
  3. Save the Bot Token
  4. Message @userinfobot to get your Chat ID
  5. In Bambuddy, enter:
Field Value
Bot Token From BotFather
Chat ID Your user/group ID
Forum Topic ID Optional — see below
Outcome verdict via How the post-print outcome prompt is answered — buttons, a 👍 / 👎 reaction, or both. See Verdict mode

Group Notifications

Add the bot to a group and use the group's chat ID for team notifications.

Forum Topics

If the target group has Topics enabled, Bambuddy posts to the General topic unless you tell it otherwise. Set Forum Topic ID to route the notifications into one specific topic instead — useful for giving each printer its own topic inside a single group rather than running a separate chat per printer.

To find the ID, open the topic in Telegram and copy its link. The last number is the topic ID:

https://t.me/c/1234567890/25
                         ^^ Forum Topic ID

The field takes a plain number and may be left empty. Two things to watch for:

  • The bot needs permission to post in the group, and Topics must actually be enabled on it. Bambuddy passes the ID through unchanged and reports back whatever Telegram answers, so a wrong ID surfaces as a Telegram error.
  • Deleting and recreating a topic gives it a new ID, so the notifications will need repointing.

Use Test in the provider dialog to confirm the message lands where you expect before saving.

Verdict mode

When a print that opted in to outcome confirmation completes, the Outcome Confirmation event asks for a Good / Reject verdict. Outcome verdict via in the provider dialog decides how you answer that prompt on Telegram:

Option How you answer
Inline buttons (link) 👍 Good / 👎 Reject buttons under the message, each opening a one-tap verdict link. The default. Needs the External URL setting, and your phone has to be able to reach that address.
Reaction (👍 / 👎) No buttons — the prompt ends with React with 👍 or 👎 to record the outcome. and you answer by reacting to the message.
Buttons and reaction Both at once; use whichever is handier. The buttons still need the External URL: without it they point at APP_URL, which defaults to localhost, so only the reaction works from the phone.

Reactions work away from the LAN

A reaction needs no inbound connectivity to Bambuddy: your phone only talks to Telegram, and Bambuddy fetches the reaction from Telegram. No External URL, port forwarding or VPN required — answer the prompt from wherever the Telegram app works.

How it works. For every bot with a provider in Reaction or Both mode, Bambuddy long-polls the Telegram Bot API (getUpdates) for reactions on the outcome prompts it sent, so a reaction is picked up within seconds. 👍 records Good, 👎 records Reject; any other emoji is ignored. Once the verdict is stored, the bot edits the prompt to confirm — ✅ marked as good or ❌ marked as reject is appended to the message, and in Both mode the buttons disappear. The first verdict wins: a later reaction, or a tap on an old link, does not overturn a decision that was already made. A reaction counts exactly as long as the prompt's links would: once the print was answered some other way, or the archive was printed again, a reaction on the old message changes nothing, and the new run asks its own question. A reject recorded by reaction carries no reason; the verdict and reason stay editable in the Edit Archive modal.

Requirements and limits

  • Private chat recommended. In a group, Telegram only delivers reactions to a bot that is an administrator of that group — as a plain member the bot sees nothing and the prompt goes unanswered.
  • Use a bot only Bambuddy uses. Create a separate bot with @BotFather for Bambuddy instead of sharing one with Home Assistant, Node-RED or another script. Telegram allows one getUpdates consumer per bot, so a webhook or a second application polling the same bot conflicts with Bambuddy's poll. Sharing also breaks the other application quietly: Bambuddy asks Telegram for reaction updates only, and Telegram keeps that choice for the bot, so an application that polls the same bot without naming the updates it wants (Home Assistant's telegram_bot integration, for example) then receives nothing but reactions, and that stays so even after you switch back to Inline buttons. Bambuddy's poll also marks the other application's updates as read.
  • Conflicts show on the provider. A conflict appears as a provider error — the red Error label on the provider card, with Telegram's message in its tooltip — and Bambuddy retries every five minutes. A wrong or deleted bot token is reported the same way. The label goes away with the next notification the provider delivers.
  • One poll per bot. Several providers sharing a bot token — one per printer, say — share a single poll; each reaction is matched to the provider that sent the prompt.
  • Only prompts sent in Reaction or Both mode can be answered by reacting. Prompts sent before you switched mode carry no mapping, and a prompt nobody reacts to within a week is forgotten.
  • The poll starts when you save the provider and stops when you switch back to Inline buttons, disable or delete it. Nothing to restart.

Outcome Confirmation must stay enabled

The verdict mode only matters for the Outcome Confirmation event. With that event switched off for the provider, no prompt is sent and there is nothing to react to. The provider card shows a Reactions or Buttons + reactions badge while the event is on and a reaction mode is selected.


Email (SMTP)

Send via email:

Field Example
SMTP Server smtp.gmail.com
Port 587 (STARTTLS) or 465 (SSL)
Security STARTTLS or SSL
Username Your email
Password App password (not regular password)
From Address Sender email
To Address Recipient email

Gmail Setup

  1. Enable 2-Factor Authentication
  2. Generate an App Password
  3. Use: smtp.gmail.com, Port 587, STARTTLS

Home Assistant

Zero-config notifications if Home Assistant is already connected:

  1. Ensure HA is configured in Settings > Network > Home Assistant
  2. Add a notification provider and select Home Assistant
  3. No additional fields needed — click Send Test to verify

Notifications appear as persistent notifications in your HA dashboard.

Push straight to your phone

Set the Home Assistant Service field to a notify service like notify.mobile_app_myphone to push directly to the HA Companion app instead of the dashboard.

Custom data fields. When targeting a notify service, the optional Data (JSON) field is forwarded as the service call's nested data object — the same place HA automations put mobile push options:

{"priority": "high", "ttl": 0, "channel": "3D Printing", "group": "printers"}

ttl: 0 + priority: high make Android pushes arrive immediately; channel creates a dedicated Android notification channel so you can give printer alerts their own sound. See the HA Companion notification docs for all supported keys. Leave the field empty when using the default persistent notification — it doesn't accept custom data.

The field is passed to Home Assistant exactly as you write it, so anything the notify service accepts works here — including nested objects and lists, not just the flat values above. Action buttons are the common case:

{
  "ttl": 0,
  "priority": "high",
  "group": "3D Printer",
  "actions": [
    {"action": "SNOOZE_PRINT_FINISHED", "title": "Snooze 20 min"},
    {"action": "BED_COOL_NOTIFY_ON", "title": "Notify on Bed Cool"}
  ]
}

Two things decide whether those buttons appear and do anything, and neither is set here:

  • Pressing a button does nothing until Home Assistant listens for it. The Companion app fires a mobile_app_notification_action event carrying your action string; you need an HA automation triggered on that event to act on it.
  • On iOS, a bare actions list is ignored. iOS renders buttons only for a notification category you have registered in the Companion app, so send "category": "your_category" instead. Android renders the list directly.

Write it as JSON, not YAML

The examples in the HA docs are YAML. This field is JSON: keys and string values need double quotes, lists use [ ], and there are no trailing commas. Bambuddy refuses to save malformed JSON rather than sending a half-built payload, so if Save reports invalid JSON, the field content is the thing to check — nothing was dropped silently.

Photo attachment

When a camera snapshot is available, Bambuddy merges an image key into the service call's data object automatically — HA's notify.mobile_app_* services fetch that URL and attach it to the push notification. This only happens when you've set a custom Home Assistant Service above; the default persistent-notification dashboard has a strict schema that rejects fields it doesn't recognize, so nothing is attached there (you'd need {finish_photo_url} in the template body instead — see Finish Photos). A data.image you set yourself in the Data field always wins over the auto-attached one. Also requires External URL to be set in Settings > Network, since HA fetches the image itself rather than the browser loading it.


Webhook (Custom)

For custom integrations:

Field Value
URL Your webhook endpoint
Headers Optional (e.g., Authorization)

All webhook payloads use a standardized format with title, message, timestamp, source, an event field identifying the event type, and all event-specific variables as structured fields. This makes it easy for automation tools (n8n, Node-RED, Home Assistant, etc.) to parse event data without extracting information from the message text.

Print complete example:

{
  "title": "Print Completed",
  "message": "Workshop X1C: benchy\nTime: 2h 15m\nFilament: 15.2g",
  "timestamp": "2026-04-02T14:30:00.123456",
  "source": "Bambuddy",
  "event": "print_complete",
  "app_name": "Bambuddy",
  "printer": "Workshop X1C",
  "filename": "benchy",
  "duration": "2h 15m",
  "filament_grams": "15.2",
  "filament_details": "AMS-A T1 PLA: 15.2g"
}

Failed/stopped prints include additional fields:

{
  "title": "Print Failed",
  "message": "Workshop X1C: benchy\nTime: 0h 45m\nReason: Filament runout",
  "timestamp": "2026-04-02T15:15:00.123456",
  "source": "Bambuddy",
  "event": "print_failed",
  "app_name": "Bambuddy",
  "printer": "Workshop X1C",
  "filename": "benchy",
  "duration": "0h 45m",
  "filament_grams": "7.6",
  "filament_details": "PLA: 7.6g",
  "progress": "50",
  "reason": "Filament runout"
}

Simpler events include fewer fields — only what's relevant:

{
  "title": "Printer Offline",
  "message": "Workshop X1C has disconnected",
  "timestamp": "2026-04-02T14:30:00.123456",
  "source": "Bambuddy",
  "event": "printer_offline",
  "app_name": "Bambuddy",
  "printer": "Workshop X1C"
}

When a camera snapshot is available (e.g. First Layer Complete, Print Started, Print Completed), the payload includes a base64-encoded JPEG image in the image field:

{
  "title": "First Layer Complete",
  "message": "Workshop X1C: benchy.3mf — Layer 1/200 done",
  "timestamp": "2026-04-02T14:30:00.123456",
  "source": "Bambuddy",
  "event": "first_layer_complete",
  "printer": "Workshop X1C",
  "filename": "benchy.3mf",
  "total_layers": "200",
  "image": "/9j/4AAQSkZJRg..."
}

Decoding the image

The image field contains a standard base64-encoded JPEG. In Home Assistant automations, you can decode it with a template sensor or pass it to notify.mobile_app_* as image data. In Node-RED, use a Buffer.from(msg.payload.image, 'base64') node. The field is only present when a snapshot was captured — not all events include images.

Slack/Mattermost Format

When using the Slack payload format, only {"text": "..."} is sent — structured event fields are not included. Use the generic format for automation integrations that need structured data.

A camera snapshot is the one exception: when one is available, Bambuddy adds a legacy attachments: [{"image_url": "..."}] block so Slack/Mattermost can render it, since incoming webhooks can't take a byte upload — only a URL they fetch themselves. Requires External URL to be set in Settings > Network.


Event Triggers

Event Description
Print Started Print job begins
Plate Not Empty Objects detected on build plate before print (bypasses quiet hours, includes a camera snapshot of the plate)
Print Completed Print finishes successfully (includes filament usage)
Print Failed Print fails or errors (includes scaled filament usage and progress)
Print Stopped Manual cancellation (includes scaled filament usage and progress)
Plate Clear Required A print reached a terminal state and the queue is gated until the build plate is confirmed clear. Off by default — it fires after every print, at the same moment as Print Completed. Also published over MQTT.
Outcome Confirmation A completed print that opted in to outcome confirmation asks for its good/reject verdict. On ntfy and Telegram the notification carries Good/Reject buttons that answer it directly; every other channel, Pushover, Bark and Gotify included, gets a link that opens the outcome dialog in Bambuddy. Set External URL so these links work from a phone — without it they point at APP_URL, which defaults to localhost. Telegram can take a 👍 / 👎 reaction on the message instead, which needs no External URL — see Verdict mode. The one-tap verdict links are also available as {good_url} / {reject_url} for your own templates, but the default body leaves them out, because anything that opens links in a message (a preview card, a mail scanner) would reach them. On by default — it only ever fires for prints where you enabled Ask for Outcome, so this toggle just mutes a channel.
Missing Spool Assignment Print started with required AMS trays that have no assigned spool (off by default)
First Layer Complete First layer finished — check adhesion remotely (includes camera snapshot)
Pause Coming Up A pause added in the slicer is a few minutes away, so you can be at the printer for it (inserts, magnets, a colour swap). Sent once per pause, 5 minutes before by default, while the printer runs at Standard speed; set the minutes under Settings > Notifications > Pause Heads-Up (1-120). Off by default.
Bed Cooled Bed temperature dropped below threshold after print (configurable in Settings)
Progress Milestones At 25%, 50%, 75%, counted from the first printed layer. Some printers report a meaningless percentage while they heat and calibrate, so nothing fires before layer 1. A printer that reaches layer 1 already past a milestone sends that one milestone then.

Printer Events

Event Description
Printer Offline Connection lost
Printer Error A new HMS fault, with the description Bambu publishes for it on your printer model. Faults Bambu publishes no text for, and notices that don't need you (such as "The top cover is open"), are not sent; see HMS Error Monitoring. Also used for smart plug power alerts.
AI Failure Detection The selected Failure Detection provider detected a possible print failure. Obico uses the configured sensitivity threshold; OctoEverywhere uses warning/pause suggestions at the configured confidence level. Both include the camera frame that triggered the alert when Attach Photo is enabled and the notification channel supports it. Enable this event on each notification provider that should receive AI alerts and check its printer filters. Off by default.
Printer Sensor Alert A Home Assistant sensor bound to a printer entered its alert state — an enclosure door opened, a chamber ran hot. Fires on the transition in, not repeatedly. Off by default. Storage-location sensors have their own event, below.
Low Filament A spool assigned to an AMS slot or external holder dropped below its low-stock threshold: the same global percentage (default 20 %) and per-spool override that drive the inventory's Low Stock count, so the alert and the card agree. Remaining filament comes from the spool's weight, never the AMS remain percentage. Sent once per spool and slot; it can fire again after the spool goes back above the threshold. Slots with no assigned spool never alert. Off by default.
Maintenance Due Scheduled maintenance is due

AMS Events

Event Description
AMS Humidity High AMS humidity exceeds threshold
AMS Temperature High AMS temperature exceeds the alarm threshold — a separate value from the Fair display band, falling back to it when unset. Silent while the unit is drying — see below.
AMS-HT Humidity High AMS-HT humidity exceeds threshold
AMS-HT Temperature High AMS-HT temperature exceeds the alarm threshold. Silent while the unit is drying — see below.
Auto-Drying Suspended Bambuddy stopped automatically drying an AMS unit because repeated cycles brought the humidity no lower. On by default — it reports that Bambuddy has stopped acting, so silence would read as "still drying". Fires once per unit; the suspension lifts on its own when the reading falls. See the threshold floor. It also fires when two cycles in a row never ran, using the Auto-Drying Not Heating template.

Inventory Events

Event Description
Reorder Alert An inventory SKU has reached its reorder point in the Forecast view. A SKU is one material, subtype, brand and colour, the same grouping the Forecast uses, with the same arithmetic. A SKU that is already in stock break has also reached its reorder point, so it counts here too. Checked every hour whether or not the Forecast page is open. Off by default. See How the stock alerts fire.
Stock Break Alert An inventory SKU is forecast to run out before a replenishment could arrive: its days of stock are no more than its effective lead time. Needs a lead time above zero, global or per SKU, since with none there is nothing to run out before. Off by default. See How the stock alerts fire.
Storage Location Sensor Alert A Home Assistant sensor bound to a storage location entered its alert state — a drybox got too humid, a battery ran low. Fires on the transition in, not repeatedly. Off by default. This is a separate switch from Printer Sensor Alert: a provider narrowed to one printer would otherwise receive every drybox alert as well, with no way to have one without the other.

Temperature alerts stay quiet while an AMS is drying

Drying deliberately runs hotter than the alert threshold — 45°C for PLA, 65°C for PETG, up to 85°C on an AMS-HT, against a default threshold of 35°C. Left alone, a twelve-hour dry would send twelve notifications about a temperature you asked for.

Bambuddy holds the temperature alert back for the length of a cycle and through the cool-down that follows, using the drying state the printer reports. It starts alerting again as soon as the unit reads back at or below your threshold, so the quiet period matches how long the unit actually takes to cool rather than a fixed delay. Nothing to configure, and the suppression survives a restart.

Two deliberate exceptions. The humidity alert is unaffected — during drying that reading falling is the whole point. And a unit reporting a loss of thermal control still alerts, because that is exactly when you want to hear about it.

How the stock alerts fire

  • Every hour, in the background. The scheduler runs the same forecast the Forecast view does, in both inventory modes (Bambuddy's own inventory and Spoolman). No spools are read unless an enabled provider has one of the two events on.
  • On the way in. An alert is sent when a SKU moves into the condition, and again after the condition has cleared (for example after a restock). A SKU that gets worse, from reorder to break, alerts again as a break. One that eases, from break back to reorder, is not announced again.
  • A break is also a reorder. A provider with only Reorder Alert on is told when a SKU breaks, as a reorder. A provider with Stock Break Alert on is told it as a break, and not a second time as a reorder.
  • Snoozed SKUs are skipped. Use the snooze icon on the SKU's row in the Forecast view. Un-snoozing a SKU that is still in the condition sends the alert again.
  • Switching an event on tells you what is already low. SKUs that were in the condition while it was off are reported the next time the check runs.
  • A SKU with no measurable usage has no forecast, so it never alerts. In Spoolman mode the daily rate is the SKU's consumption divided by the days since its oldest spool was registered, because Bambuddy holds no per-print usage history for Spoolman spools.
  • Quiet hours and restarts. An alert that falls in a provider's quiet hours is skipped, as for every event, and is not repeated when they end. What has been sent is stored, so a restart or an update does not repeat the alerts for SKUs that are still in the condition. A SKU that has no spools left is dropped from what is stored.
Event Default Description
Job Added Off Job added to queue, from any source (print dialog, File Manager, webhook, virtual printer, pipeline run, order dispatch). Several jobs added at once are one message per printer
Job Assigned Off Model-based job assigned to a printer
Job Started Off Queue job started printing
Job Waiting On Job waiting for filament (actionable)
Job Skipped On Job skipped due to previous print failure
Job Failed On Job failed to start (upload error, etc.)
Queue Complete Off All queued jobs finished

Actionable Queue Notifications

The most important queue notifications (Waiting, Skipped, Failed) are enabled by default because they require user action - load the right filament, check why a print failed, etc.

Messages from Connected Apps

Event Default Description
Messages from connected apps Off Messages another application sends through Bambuddy, e.g. Bambuddy Orders' "3 orders need you"

An app sends its message to POST /api/v1/notifications/app-message; Bambuddy hands it to every enabled provider with this switch on. A sender limited to certain printers (Printer Access) reaches only the providers bound to one of those printers, not the ones set to all printers. It goes through the same path as Bambuddy's own events: quiet hours, the daily digest and the notification log (listed with the event type app:<API key name>).

curl -X POST http://localhost:8000/api/v1/notifications/app-message \
  -H "X-API-Key: bb_your_key" \
  -H "Content-Type: application/json" \
  -d '{"title": "3 orders need you", "message": "#1004: print failed", "url": "http://orders.lan:8090/todo"}'
# => {"channels": 2}
  • Who may send: an API key with the Send Notifications permission (API Keys), whose owner has notifications:update; or a signed-in user with notifications:update.
  • What is accepted: plain text; a title up to 120 characters, a message up to 2,000. The optional url must be an http or https address and is added as the message's last line.
  • Limit: 20 messages a minute per key. More are refused with 429.
  • Where it arrives: GET /api/v1/notifications/app-message/channels lists the providers that take app messages for this sender (names and types only), so an app can tell its user where its messages go.

Enable/disable each event per provider.


Quiet Hours

Suppress notifications during sleep:

  1. Enable Quiet Hours toggle
  2. Set Start Time (e.g., 22:00)
  3. Set End Time (e.g., 07:00)

Notifications during quiet hours are silently skipped. The daily digest is the exception: it goes out at the time you set for it.

Notify! Live Activities that have already started keep updating and end normally during quiet hours. New activities wait until quiet hours have ended.


Per-Printer Filtering

Limit notifications to specific printers:

  1. Open provider settings
  2. Find Printers section
  3. Select specific printers or "All"

Only events from selected printers trigger notifications. A job waiting on a printer (for filament, a plate confirmation, the printer itself) reaches that printer's providers. An event that has no printer yet, such as a job added for Any or one waiting for any printer of a model, goes to providers set to "All" only; a provider limited to one printer hears of the job once it is assigned to or started on that printer. Events about the whole setup (the queue finishing, stock alerts, messages from connected apps) reach every provider that has them on.

Deleting a printer deletes the providers limited to it.


Daily Digest

Batch notifications into a summary:

  1. Enable Daily Digest toggle
  2. Set Digest Time (e.g., 08:00)

How It Works

  • Events are collected (not sent immediately)
  • At digest time, one summary is sent
  • Includes counts and details
  • It goes out at digest time even when that falls inside the provider's quiet hours: you chose that time for it
  • If sending fails, the events are kept and go out with the next day's digest; events more than two days old are dropped, so a provider that keeps failing doesn't pile them up

Notify! Live Activities continue showing live progress independently of digest summaries.

Example Digest

Daily Print Summary (Dec 14)

✅ 3 prints completed
❌ 1 print failed
⏱️ Total time: 8h 45m
🧵 Filament used: 245g

Details:
- Benchy (2h 15m) ✅
- Phone Stand (45m) ✅
- Cable Clip (15m) ✅
- Prototype v3 (3h 30m) ❌

Message Templates

Customize notification messages:

Accessing Templates

  1. Go to Settings > Notifications
  2. Click Templates tab
  3. Select event type to edit

Variables

Insert dynamic content with {variable}:

Print Events:

  • {printer} - Printer name
  • {filename} - Print filename
  • {duration} - Print time
  • {filament_grams} - Total filament used in grams (scaled by progress for failed/stopped prints)
  • {filament_details} - Per-filament breakdown (e.g., "PLA: 15.2g" or "PLA: 10.0g | PETG: 5.0g")
  • {estimated_time} - Estimated duration (e.g., "1h 23m")
  • {eta} - Wall-clock completion time (e.g., "15:53" or "3:53 PM"), respects your time format setting
  • {progress} - Completion percentage (available for failed/stopped prints)
  • {reason} - Failure reason
  • {archive_id} / {run_id} - The archive (the file) and the run (this print of it), for links and webhooks (print_complete, print_failed, print_stopped)
  • {finish_photo_url} - Camera snapshot URL (print_complete, print_failed, print_stopped). Email special-case (#1792): if your Email template references {finish_photo_url} in the body, the rendered URL also triggers an inline embed — the HTML part replaces the URL with the snapshot rendered inline at exactly that position, while the plain-text part keeps the URL as a clickable link. Place the variable WHERE you want the image to appear. If the template doesn't reference it, the email stays text-only — no surprise attachment.

Printer Events:

  • {printer} - Printer name
  • {error_type} - HMS error type
  • {error_detail} - Error description

AI Failure Detection:

  • {printer} - Printer name
  • {task_name} - Print task name
  • {provider} - Obico or OctoEverywhere
  • {print_quality} - OctoEverywhere print quality, such as 2/10; N/A for Obico
  • {confidence} - Obico detection confidence; N/A for OctoEverywhere
  • {action} - Action taken: notify, pause, or pause_and_off

Both detection providers use the same default template, which shows the provider, print quality, confidence, and action. The previous default message body is updated automatically; customized bodies and titles are preserved.

First Layer Complete:

  • {printer} - Printer name
  • {filename} - Print filename
  • {total_layers} - Total layer count

Pause Coming Up:

  • {printer} - Printer name
  • {filename} - Print filename
  • {time_to_pause} - Time until the pause, e.g. 5m
  • {eta} - Clock time of the pause
  • {layer} - Layer the printer pauses at
  • {total_layers} - Total layer count

Bed Cooled:

  • {printer} - Printer name
  • {bed_temp} - Current bed temperature
  • {threshold} - Configured threshold
  • {filename} - Print filename

Printer Sensor Alert:

  • {printer} - Printer name
  • {sensor} - Sensor display name
  • {state} - State that triggered the alert (open, 41.2 °C)

Storage Location Sensor Alert:

  • {location} - Storage location name (there is no {printer} here — the alert belongs to a location, not a machine)
  • {sensor} - Sensor display name
  • {state} - State that triggered the alert (24.7 °C, 43.6 %) — trimmed of trailing zeros, unlike the two-decimal form shown on the inventory page

Missing Spool Assignment:

  • {printer} - Printer name
  • {missing_slots} - Comma-separated slot labels (e.g., "A1, A3")
  • {missing_slot_details} - Per-slot breakdown with expected profile (e.g., "- A1: PLA Basic")

Reorder Alert / Stock Break Alert:

  • {material} - Material (e.g. "PLA")
  • {subtype} - Subtype (e.g. "Matte"); empty when the spool has none
  • {brand} - Brand; empty when the spool has none
  • {color} - Colour name; empty when the spool has none. Two colours of one product are separate SKUs, so this is what tells their messages apart
  • {stock_g} - Grams left across the SKU's spools
  • {rate_g_day} - Forecast daily use in grams
  • {days_left} - Days of stock left at that rate
  • {lead_time_days} - The effective lead time (Stock Break Alert only)

The default message bodies include {subtype} and {color} (the titles still show only the material). An existing template is updated to match only if it is still the default; one you have edited keeps your wording.

AMS Events:

  • {printer} - Printer name
  • {slot} - AMS slot (e.g. "A1", "HT-A", "Ext-L")
  • {remaining_percent} - Filament left
  • {color} - Colour name of the spool (Low Filament only)
  • {humidity} - Humidity level
  • {ams_label} - Which unit (e.g. "AMS-A")
  • {threshold} - The configured threshold the reading is measured against
  • {cycles} - Drying cycles that ended above the threshold (Auto-Drying Suspended), or whose timer stood still (Auto-Drying Not Heating)

Outcome Confirmation:

  • {printer} - Printer name
  • {filename} - Print filename
  • {confirm_url} - Link that opens the outcome dialog for this print in Bambuddy (used by the default template)
  • {good_url} / {reject_url} - Single-use links that record Good or Reject after a confirmation click. Keep them out of channels that build link previews or scan links; see What a One-Tap Link Does
  • {finish_photo_url} - Finish photo, when one was taken

Common:

  • {timestamp} - Event time
  • {app_name} - "Bambuddy"

Reset to Default

Click reset to restore original template.

Finish Photos

A camera snapshot can reach your notification three ways: uploaded directly as a real attachment, attached after the receiving service fetches it from a URL, or as a plain link you click. Which one you get depends on the channel — see the tables below.

Taking snapshots is gated on Settings > General > Archive Settings > Capture finish photo. With that off, no snapshot is taken and nothing is attached or linked, for any channel. There is one exception: AI Failure Detection attaches the frame Failure Detection has already captured for its check, so that notification carries a photo either way.

Each provider also has its own Attach Photo toggle in the Add/Edit Notification dialog (on by default) if you want a specific provider to get the text only, without the image. While it is on, Test sends a sample image along with the test message, so you can see how photos arrive on that channel.

Uploaded attachment

ntfy, Pushover, Telegram, Discord and the generic Webhook format receive the photo bytes directly with the message — no External URL needed, and you don't need {finish_photo_url} in the template for this.

Channel Snapshot delivery
ntfy Attached. If your ntfy server has attachments disabled, Bambuddy retries automatically and sends the text alone.
Pushover Attached.
Telegram Attached — sent as a photo with the message as its caption.
Discord Attached and shown inline in the embed.
Webhook (generic format) Base64-encoded JPEG in the payload's image field.

Fetched-URL attachment

Home Assistant, Bark, Notify!, Gotify and Slack/Mattermost-format webhooks can't take a byte upload — they fetch the photo from a URL themselves and attach it on their end. This needs External URL set in Settings > Network, or there's nothing for them to fetch, and (same as above) doesn't need {finish_photo_url} in the template.

Channel Snapshot delivery
Home Assistant Attached automatically via data.image — but only when you've set a custom Home Assistant Service. The default persistent-notification dashboard has a strict schema that rejects the extra field, so it falls back to link-only (see below) unless you set a service.
Bark Attached automatically as the notification icon.
Notify! Attached as imageUrl in the expanded notification. Requires an HTTPS External URL reachable from the receiving device; otherwise the notification is sent without the photo. Browser (WB) and group (GRP) targets receive text only.
Gotify Attached automatically as bigImageUrl, shown as a large picture in the Android app.
Webhook (Slack format) Attached via a legacy attachments[].image_url block.

How the photo link is protected

These services fetch the photo without logging in to Bambuddy, so the link itself is the key: each one points at a single saved snapshot under a long random name, opens that one photo and nothing else (no camera stream, no other photos), and stops working after 3 days. Anyone who can see the notification, for example everyone in a Slack channel, can open the photo until then.

Inline embed (Email)

Email is template-driven rather than automatic: it inlines the photo only when your template's body literally contains {finish_photo_url} (#1792), so nobody who never asked for a photo gets a surprise attachment. The HTML part replaces the URL with the image at exactly that position; the plain-text part keeps the URL as a clickable link. Unlike the fetched-URL channels above, this works even without External URL set — the image bytes travel with the email itself — though the fallback link text will be a relative, unclickable path in that case.

CallMeBot has no attachment mechanism in its API at all — a {finish_photo_url} link in the text is the only way to get the photo there. Home Assistant also falls back to this when you're using the default persistent-notification service instead of a custom one.

With authentication off, {finish_photo_url} is the archive's own photo link, which needs no login and keeps working. With authentication on, that page needs a login a tapped link can't carry, so the link points at a copy of the photo instead, protected the same way as the fetched-URL photos above: one photo, a long random name, and it stops working after 3 days.

Uploaded and fetched-URL attachments are capped at 2.5 MB. A larger snapshot is skipped and the message is sent as text — the reason is written to the log.

Snapshots aren't limited to completed prints — Print Started, Print Progress, First Layer Complete, Plate Not Empty, AI Failure Detection and printer-error notifications all capture a live frame at the moment they fire, and get attached wherever the channel supports it. {finish_photo_url} itself is only exposed as an insertable template variable on print_complete, print_failed and print_stopped (and the per-user print emails, below) — the other events attach automatically to channels that support it, but have no variable for a manual link or Email's inline embed.

  1. Go to Settings > Network
  2. Set External URL to your Bambuddy server's address (e.g., http://192.168.1.100:8000)
  3. Edit your print_complete / print_failed / print_stopped template to include {finish_photo_url}

External URL Required

External URL is required for the link to resolve to something clickable, and for Home Assistant/Bark/Notify!/Gotify/Slack's automatic attachment to have anything to fetch. Notify! requires HTTPS. It's auto-detected from your browser when you first visit the Network settings page.

Example template:

Print completed!
Printer: {printer}
File: {filename}
Filament: {filament_details}
Photo: {finish_photo_url}

For Email, that same variable also switches the message to an inline embed — see Inline embed (Email) above.


Testing

Always test before relying on notifications:

  1. Configure provider
  2. Click Send Test
  3. Verify you receive the message
  4. Check message formatting

Quick Disable

Quickly disable all notifications:

  1. Find the Quick Disable button
  2. Click to toggle all notifications off
  3. Click again to re-enable

Useful during maintenance or troubleshooting.


Tips

Start with ntfy

ntfy is the simplest setup - no account needed, just pick a topic.

Use Quiet Hours

Avoid middle-of-night alerts with quiet hours.

Multiple Providers

Set up multiple providers for redundancy.

Progress for Long Prints

Enable progress milestones for prints over a few hours.

Customize Templates

Personalize messages to include only info you need.

Test Regularly

Periodically test notifications to ensure they still work.

Bed Cooled Threshold

Configure the bed cooled temperature threshold in Settings > Notifications. Default is 35°C. The notification fires as soon as the printer reports the bed at or below the threshold — no timeout.

Pause Heads-Up

Set how many minutes before a slicer pause Pause Coming Up is sent in Settings > Notifications > Pause Heads-Up. Default is 5 minutes. A print that starts with its pause already that close sends it straight away.

Plate Not Empty Bypasses Quiet Hours

Plate detection notifications are always sent immediately, even during quiet hours or when digest mode is enabled. This ensures you're alerted to potential issues before a print starts.


:material-account-bell: Per-User Email Notifications

When Advanced Authentication is enabled, individual users can receive email notifications for their own print jobs. This is separate from the provider-based notification system above — it sends emails directly to the user who submitted the print.

Requirements

  • Advanced Authentication must be enabled
  • SMTP must be configured
  • "User Notifications" must be enabled in Settings → Notifications
  • User must have an email address on their account
  • User must have the notifications:user_email permission (Administrators and Operators by default)

Supported Events

Event Description
Print Started Your print job has begun
Print Completed Your print job finished successfully
Print Failed Your print job encountered an error
Print Stopped Your print job was cancelled

Setup

  1. Enable User Notifications in Settings → Notifications
  2. Click Notifications in the sidebar
  3. Toggle each event type on or off
  4. Click Save

Photos

Print Completed, Print Failed and Print Stopped emails support the same inline-photo opt-in as the provider-based Email path: add {finish_photo_url} to the template body (Settings → Notifications → Templates) and the photo is embedded at that position when one was captured — see Inline embed (Email) above for how the opt-in works. Print Started has no photo support, since there's no finished-print snapshot yet at that point.

See Authentication → Per-User Email Notifications for full details.