Notifications
Mobius emits platform events and a routing layer decides where each goes. An event is an incident opened, an IR action pending approval, ingest paused, a connector gone unhealthy, or a billing threshold reached.
Routing rules
In the notifications settings, your organization's admins configure a matrix of event types × channels: for each event type, choose who receives it and whether it notifies in-app on the bell, on a connected channel, or both.
Under Platform rules, toggle which platform events reach you: a workflow started, succeeded or failed, a new environment added, a user invited, billing events such as an invoice paid, an invoice failed or a trial ending, and budget thresholds at 85%, 90% and 100%. Each workflow's own output is routed separately, from that workflow's page.
The Ingestion family covers the ingestion policy and the ingest pipeline for each environment:
| Event | Meaning |
|---|---|
| Ingestion policy changed | An admin saved or restored a policy version, with a summary of what changed. |
| Ingestion policy rejected by Wazuh | The indexer refused the saved policy, for example after a mapping change. |
| Ingestion running a fallback policy | Mobius is ingesting on the last known-good version, or on Critical-only, until a save works. |
| Ingestion policy recovered | The saved policy runs again. |
| Ingestion backlog building | Alerts are arriving faster than the rate limit; they are deferred, not dropped. |
| Ingestion backlog cleared | The backlog has drained. |
| Ingestion paused / stopped | Ingest was paused by an admin, or stopped by the free credit or the budget cap. |
Every event type carries a severity, which drives the color in the bell and the chip in the history: bad news never reads as routine.
Delivery channels
Under Channels, connect where notifications land beyond the in-app bell:
-
Slack. Paste the incoming-webhook URL for the channel where notifications should land.
-
JIRA. Your JIRA URL, project, email, and API token. Matching events open tickets in that project.
-
Email. Notifications and report sharing by email. During the beta, each recipient address is confirmed with us before delivery to it starts.
-
Webhook. Any HTTPS endpoint. Pick a format:
- Generic JSON (signed) for n8n, Zapier, Make, Tines, a SOAR or your own service. See Receiving webhooks below.
- Microsoft Teams. In Teams, create a Workflow from the Post to a channel when a webhook request is received template and paste its URL.
- Discord. Channel settings > Integrations > Webhooks, then copy the URL.
- Google Chat. Space > Apps & integrations > Webhooks, then copy the URL.
You can also add request headers, for example an
Authorizationheader your endpoint expects. The URL and headers are stored encrypted and never shown again.
Pasting a Discord, Google Chat or Teams Workflows URL picks the matching format for you. Discord and Google Chat only accept their own format, so Mobius refuses to save one of their URLs under another format. A Slack URL belongs in a Slack channel, not a Webhook.
Every channel URL must be https:// on a public internet address. Mobius
does not follow redirects, so save the final URL. Test connection sends a
real test message before you save.
Only users with the admin role can change integrations and notification settings.
Receiving webhooks
A Generic JSON channel sends one POST per event with this body:
{
"version": "1",
"delivery_id": "0f6c9a52-6b1f-4c5e-9d3a-3c1f7d2e8a41",
"event_type": "case_auto_opened",
"severity": "danger",
"title": "Outbreak on 3 hosts",
"body": "Indicator 203.0.113.9 seen on web-1, web-2, db-1",
"link": "https://mobius.wazuh.com/cases/7/",
"occurred_at": "2026-10-06T12:00:00Z",
"data": { "case_pk": 7, "env_id": 3 }
}
severity is one of info, success, warning or danger. data depends
on the event type. A workflow's output uses event_type wf:<workflow id>,
and the Test connection button sends mobius.test. Any 2xx answer counts
as delivered. Mobius waits up to 8 seconds and does not retry.
Every request, in every format, carries these headers:
| Header | Value |
|---|---|
X-Mobius-Event | The event type. |
X-Mobius-Delivery | A unique id for this delivery. Use it to drop duplicates. |
X-Mobius-Signature | t=<unix seconds>,v1=<signature> |
When you create the channel, Mobius shows a signing secret once
(whsec_...). Copy it into your receiver. To check that a request really came
from Mobius, compute an HMAC-SHA256 of <t>. followed by the raw request
body, keyed with the signing secret, and compare it with v1. Reject requests
whose t is more than 5 minutes old.
import hashlib, hmac, time
def is_from_mobius(secret: str, header: str, raw_body: bytes) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
if abs(time.time() - int(parts["t"])) > 300:
return False
expected = hmac.new(secret.encode(), f"{parts['t']}.".encode() + raw_body,
hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, parts["v1"])
const crypto = require("crypto");
function isFromMobius(secret, header, rawBody) {
const parts = Object.fromEntries(header.split(",").map((p) => p.split("=")));
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > 300) return false;
const expected = Buffer.from(crypto.createHmac("sha256", secret)
.update(`${parts.t}.`).update(rawBody).digest("hex"));
const given = Buffer.from(parts.v1 || "");
return given.length === expected.length && crypto.timingSafeEqual(expected, given);
}
Verify against the bytes you received, before parsing the JSON. Re-encoding the parsed body changes the bytes and the signature will not match.
If the secret leaks, open the channel's details and select Rotate signing secret. The new secret is shown once and the old one stops working on the next delivery.
The bell and the history
- The bell shows recent notifications with severity chips. Each one deep-links to the object it is about, whether that is the incident, the environment or the approval. It only carries the latest few.
- The history is the queryable archive: every notification your organization has received, newest first, with the page each one opens. Filter it by family, which is Ingestion, Workflows, Response, Organization, Billing or Budget, search by title or message, and page back through older ones. It is where the bell's View all notifications link takes you.
Recommended baseline
| Event | Route |
|---|---|
| Incident opened at high risk | in-app + email to the on-call |
| IR action pending approval | in-app + email, since approvals are time-sensitive |
| Connector unhealthy or ingest paused | in-app + email to the environment owner |
| Billing thresholds | email to the org admin |
Everything else can stay in-app only. The history keeps it auditable.