Notification channels
For a step-by-step phone connection, see Connect the App.
Configure in the console
- Open Notifications and choose Bark, Pushover, Webhook or Mailwake App.
- Fill the selected channel's fields below. For Mailwake App, first pair the phone, then choose the receiving phone.
- Choose the preview, notification language and retry count. A retry count of 0 makes one attempt.
- Save, then explicitly send a test notification. Check the phone or webhook receiver and the delivery result.
The settings apply to all mailboxes. Changing settings preserves queued work according to its existing delivery plan; verify future behavior with a new message.
Channel configuration
Configure the global channel through
/api/v1/settings/delivery, sending its current
revision. Channel, preview, retry count and
notification language apply to all mailboxes. All credentials are
encrypted and write-only; omitted credential fields keep their saved
values when the target is unchanged. Changing a saved Bark endpoint
requires re-entering its device key.
| Channel | Parameters | Credentials |
|---|---|---|
bark |
bark.endpoint, default
https://api.day.app
|
bark.key |
pushover |
none |
pushover.token, pushover.user
|
webhook |
HTTPS, query allowed |
webhook.url and webhook.secret (at
least 32 non-whitespace characters)
|
native |
Official production push delivery service by default;
override with MAILWAKE_RELAY_URL; pair phones
in App authorization
|
Locally generated, encrypted outpost identity |
Webhook URLs are write-only because paths and queries may contain
routing credentials. preview accepts
off or subject;
retry_count accepts 0–9 and defaults to 0;
language accepts the
nine catalog codes and their regional aliases
and defaults to en. Bark and Pushover show only the
subject with subject; Webhook retains structured sender
and subject, while its message also contains only the
subject. off (and an empty subject) uses the localized
“New mail” message. Titles stay
{display name} · {folder}; Bark groups by that same
truncated title. Test notification text is unchanged. API input
sender_subject returns 400
config_preview_invalid. For third-party channels,
switching from subject to off atomically
removes sender and subject from all pending and failed records;
later enqueues also follow the saved privacy policy. Native push
always records sender and subject while preserving the third-party
preview preference.
Bark history retention follows the Bark app's save-history setting for both mail and test notifications.
Webhook payload
The outpost sends a POST with a JSON body and never
follows redirects:
{
"version": 1,
"id": "3f9c…",
"test": false,
"mailbox_id": "mbx_example",
"account": "Work mailbox",
"folder": "Clients",
"sender": "anna@example.org",
"subject": "Re: Q4 proposal",
"received_at": "2026-09-28T10:32:00Z",
"title": "Work mailbox · Clients",
"message": "Re: Q4 proposal"
}
mailbox_id is the stable mailbox ID;
account is its display name at enqueue time. Bark,
Pushover and Webhook ordinary notifications use the title
{display name} · {folder} in all supported languages.
Renaming or deleting a mailbox preserves the identity metadata of
already queued tasks. Test notifications use separate text and omit
mailbox fields.
sender and subject appear only with the
subject preview. title and
message are localized and ready to forward to ntfy,
Gotify and similar services. The display name and folder are sent
even with preview off; choose a label suitable for sharing with your
notification provider.
| Header | Meaning |
|---|---|
X-Mailwake-Event |
Event ID, equal to id; unchanged across
retries, use it to deduplicate
|
X-Mailwake-Timestamp |
Send time in Unix seconds |
X-Mailwake-Signature |
sha256= followed by the hex
HMAC-SHA256(secret, "<timestamp>.<raw
body>")
|
Verify the signature with the same secret using a constant-time comparison, and reject timestamps more than five minutes away:
import hashlib, hmac, time
def verify(secret: bytes, timestamp: str, body: bytes, signature: str) -> bool:
expected = "sha256=" + hmac.new(secret, timestamp.encode() + b"." + body, hashlib.sha256).hexdigest()
return abs(time.time() - int(timestamp)) <= 300 and hmac.compare_digest(expected, signature)
Any 2xx response counts as accepted. 429 and 5xx follow the retry setting; other statuses end the attempt and record a failure.
Saving notification settings validates fields, addresses, pairing state and revision without sending a test. Use the explicit test button after saving. Native tests use the push delivery service’s fixed free test endpoint and share the App test quota; ordinary email notifications require Native Push entitlement.
Markdown · AGPL-3.0-only · Mailwake contributors