Message
The message is the body a notification carries. You write it once on the action, formatting it with Markdown and enriching it with dynamic variables (tokens) that are replaced with real values when the Flow runs.
Formatting the Message
The Message field is a rich text editor that stores what you write as Markdown. You can format as you go:
| To | Do This |
|---|---|
| Apply styles such as bold and italic | Select the text and pick the style on the formatting toolbar that appears. |
| Write the formatting yourself | Type the Markdown and the editor converts it as you type, for example **bold**, *italic*, or - for a list item. |
| Insert a block, such as a heading or a list | Type / to open the block menu. |
| Insert a variable | Type {{, or press Ctrl+Space, to open the variable menu. It has two groups: Variables, the tokens the Flow's trigger provides, and Optional section, one entry per token that can arrive empty, reading Only if |
| Spot a variable the trigger does not provide | A name outside the menu turns red, with a dotted underline, as soon as you type it. The editor does not stop you, since you may still be typing, but publishing the Flow or testing the action refuses it (see Validation). |
How the formatting arrives depends on the channel:
| Channel | How the Message Renders |
|---|---|
| In App | The Markdown is rendered in the notification panel, so bold, italic, lists, and links arrive formatted. |
| The Markdown is rendered into the Qualytics email layout, so the message arrives formatted rather than as characters. A plain-text copy travels with it for clients that do not render HTML. | |
| Slack and Microsoft Teams | The channel composes its own per-event layout (an interactive message or an Adaptive Card), shown in the panel's Preview. |
| PagerDuty | The message becomes the incident's plain-text summary, which is also the alert title, so Markdown arrives as characters. PagerDuty caps it at 1024 characters and refuses a longer one. |
| Webhook, HTTP Action, and n8n | The message travels as text inside the JSON payload for the receiving system to use. |
Where You Write It
The message is written on the action's settings panel, and the field you get depends on the channel:
| Channel | Message Field |
|---|---|
| In App and Email | A rich text editor with a formatting toolbar. Its placeholder reads Write the message recipients will see..., and the hint under it says Type {{ for variables and optional sections. Email adds an Email Subject field that takes the same tokens. |
| PagerDuty, Webhook, and HTTP Action | A plain text field with the same {{ menu, and the same red mark on a name the trigger does not provide, but no formatting toolbar, since these channels carry the message as text. |
| Slack and Microsoft Teams | No message field. The channel composes its own layout from the event, and the panel shows it in a Preview field. |
| n8n | No message field. The workflow receives the event's data and composes its own text. |
Default Message
A new notification does not start empty. Every trigger has a default message, so the field opens on text that already reads well, and an edit is a departure from that default rather than from a blank page. The full default has four parts:
- A heading naming the event, such as Record anomaly in orders.
- A body written with optional sections, so it adapts to what the event carries. The Operation Completed default, for example, reads This operation finished with the result Success. when the operation recorded no message, and This operation finished with the result Failure and left logs. followed by a Logs heading and the logs when it did.
- A link back to the resource, such as Review this anomaly.
- A footer naming the Flow, as a quote: Sent by the Quality Monitor flow.
What a channel starts on depends on what it can show. Email gets all four parts. In App gets the body and the footer, since the notifications panel draws the title and the row itself is the link. Webhook and HTTP Action get the same text with the Markdown marks removed. PagerDuty starts on its own one-line summary instead, written to fit an alert title (see Add a PagerDuty Notification). A Schedule or Manual trigger has no resource to point at, so its default is the heading and a one-line body, with no link and no footer.
The default is also what Reset to defaults returns you to, on every channel that has a message field. It restores the message, and on Email the subject. A field that itself has a default returns to it as well, such as the PagerDuty Severity or the HTTP Action Http Verb and Auth Type; recipients, URLs, keys, and any field without a default are left as you set them.
Message Variables
The available tokens depend on the Flow's trigger type, and the same set applies to every notification channel. Pick the tab below for your trigger type.
Info
The message editor's autocomplete only offers the tokens valid for the Flow's trigger type. A token that does not appear in the list is not provided by that trigger: the editor marks it in red, and publishing the Flow or testing the action refuses it (see Validation).
A scheduled run has no target object, so the Flow's name is the only token available.
{{operation_message}} can be empty when the operation recorded no message; see Optional Sections.
{{anomaly_message}} and {{check_description}} can be empty, for example on a shape anomaly with no failed check details; see Optional Sections.
{{anomaly_message}}, {{check_description}}, and {{old_status}} can be empty, for example on a newly detected anomaly with no earlier status; see Optional Sections.
{{anomaly_message}}, {{check_description}}, and {{old_status}} can be empty; see Optional Sections.
A manual run has no target object, so the Flow's name is the only token available.
Tokens after an anomaly action
A notification chained after an Archive or Delete action offers {{flow_name}}, {{anomaly_count}} (how many anomalies the action touched), {{inactivity_timeframe}} (the inactivity period in days), and {{target_link}}. {{anomaly_count}} and {{inactivity_timeframe}} can arrive empty, so wrap them as Optional Sections when the message has to read well either way; {{flow_name}} and {{target_link}} are always filled.
Tokens after a ticketing action
A notification chained after a Create Ticket action also offers {{ticket_number}}, {{ticket_url}}, {{ticket_status}}, and {{anomaly_id}}. One chained after an Update Ticket Status action offers {{tickets_updated_count}}, {{ticket_status}}, and {{anomaly_id}}. Every token specific to these two actions can arrive empty, so each is offered as an optional section. Slack and Microsoft Teams render these messages with a dedicated ticket layout.
Optional Sections
A token that can arrive empty is worth wrapping in a conditional section, so the message stays clean when there is nothing to show. The editor's autocomplete offers these as Optional section entries:
The text between {{#if token}} and {{/if}} is only included when the token has a value; the {{else}} part is optional and is used when it does not.
Only a token that can arrive empty is offered as an Optional section. A token the trigger always fills has no entry, because its condition could never be false. Presence is the only test a condition makes: {{#if token}} asks whether the token has a value, and nothing else. A comparison inside the condition, a condition opened inside another, an {{else}} with a condition after it or a second one in the same block, and any block tag other than the conditional are refused when you publish or test, with a message saying what is not supported. To act on a value, filter on it in the Flow's trigger instead.
Validation
Publishing the Flow and Test Notification run the same check on the message, and on the Email subject. Saving the action on its panel does not run it: the check happens when the Flow is published, so a refused message is caught before the Flow goes live rather than on every edit. A template is refused when it names a variable the trigger does not provide, or when a conditional is malformed. The refusal names the field and the variable:
- The message uses {{old_status}}, which this notification does not provide. A variable that is not provided is not filled in and reaches the recipient exactly as written.
- The subject has a condition on {{ticket_number}}, which this notification does not provide. A condition can only check a variable this notification provides; otherwise its section would never be shown.
A malformed conditional is refused with a message saying what is wrong: an opening marker without its closing one, a condition opened inside another, a comparison inside the condition, an {{else}} with a condition after it or a second one in the same block, or a block tag other than the conditional.
Where the refusal shows up depends on what you clicked. See Publish Validation for the publish dialog and the action card, and Testing Notifications for the test verdict.
See Also
-
Workflow
Hand the event to an external system through a Webhook, an HTTP action, or n8n.
-
Ticketing
Create or update tickets in your issue tracker from anomaly events.
-
Examples
Real scenarios showing what each action category does inside a working Flow.
-
Best Practices
Guidelines per category for actions that do their work quietly and fail loudly.
-
How It Works
The action node, the five categories in detail, how actions run, and the chaining rules and limits.
-
Operation
Run datastore operations (Sync, Profile, Scan, Export, Materialize) when the trigger activates.
-
Anomaly
Archive or delete inactive anomalies automatically.
-
Notifications
The dispatch pipeline and the five channels: In App, Email, Slack, Microsoft Teams, and PagerDuty.