Notion Alert Sync with n8n, SIGNL4 & Slack
This reference guide describes a complete Notion – n8n – SIGNL4 – Slack integration for incident alerting and synchronization. The workflow ingests alerts via webhook, classifies their status, updates a Notion database, pushes notifications into SIGNL4 and Slack, and keeps incident resolution states in sync across tools.
1. Solution overview
The workflow turns Notion into a central incident repository, uses SIGNL4 for mobile on-call escalation, and leverages Slack for team visibility. n8n acts as the orchestration layer that:
- Accepts incoming alert webhooks from external monitoring systems
- Normalizes and interprets alert status codes and event types
- Reads and updates incident records in a Notion database
- Creates and resolves alerts in SIGNL4 using a consistent external identifier
- Posts human-readable status messages into Slack channels
- Runs interval-based checks to discover new Notion incidents and finalize resolved ones
The template is designed for operators who want a low-code automation pattern that keeps multiple incident tools consistent without manual copy-paste or ad hoc integrations.
2. Workflow architecture
The n8n workflow is logically split into three main functional areas:
2.1 Incoming webhook and real-time parsing
- Accepts HTTP POST requests from your monitoring or alerting system
- Runs a Function node that interprets
statusCodeandeventTypeinto human-readable states - Updates the related Notion page with the latest status description
- Posts a concise summary to Slack for immediate team awareness
2.2 Interval-based Notion queries and synchronization
- Uses a timer (Interval) node to run on a fixed schedule
- Queries Notion for:
- New incidents that have not yet been sent to SIGNL4
- Open incidents that should be resolved in SIGNL4 based on Notion state
- Creates new SIGNL4 incidents for fresh Notion pages
- Resolves SIGNL4 incidents when Notion indicates that an incident is closed
- Updates Notion flags (for example
Read,Up) to prevent duplicates
2.3 Optional Notion page trigger
- Uses a Notion trigger node (optional) that fires when a page is added to the incident database
- Immediately sends the new incident into SIGNL4 without waiting for the next scheduled interval
You can enable or disable the optional trigger depending on whether you prefer real-time or scheduled synchronization from Notion to SIGNL4.
3. Node-by-node breakdown
3.1 Webhook node (incoming alerts)
Role: Entry point for third-party alerts.
- Trigger type: Webhook (HTTP POST)
- Endpoint: Configured via the node’s path/ID in n8n
- Payload: JSON body from your monitoring system, including:
body.alert.statusCodebody.eventTypebody.annotation(optional)body.user(optional)
The webhook node forwards the raw payload to the parsing Function node. No transformation should occur here, so downstream nodes can rely on consistent field names.
3.2 Function node: ParseStatus
Role: Normalize SIGNL4-style status codes and event types into readable incident status strings, and determine whether an incident should be considered “Up” (resolved) in Notion.
The node iterates over each input item and enriches its JSON with two new fields:
s4Status– human-readable summary, used in Notion and Slacks4Up– boolean flag indicating resolution state
Function code used in the workflow:
// Loop over inputs and add a new field called 's4Status' to the JSON of each one
for (item of items) { var type = "Status"; if ((item.json.body.alert.statusCode == 2) && (item.json.body.eventType == 201)) { type = "Acknowledged"; } if ((item.json.body.alert.statusCode == 4) & (item.json.body.eventType == 201)) { type = "Closed"; } if ((item.json.body.alert.statusCode == 1) & (item.json.body.eventType == 200)) { type = "New Alert"; } if ((item.json.body.alert.statusCode == 16) & (item.json.body.eventType == 201)) { type = "No one on duty"; } var annotation = ""; if ((item.json.body.eventType == 203) & (item.json.body.annotation != undefined) ) { type = "Annotated"; annotation = item.json.body.annotation.message; } if (annotation != "") { annotation = ": " + annotation; } var username = "System"; if (item.json.body.user != undefined) { username = item.json.body.user.username; } var data = type + " by " + username + annotation; item.json.s4Status = data; item.json.s4Up = false; if (type == "Closed") { item.json.s4Up = true; }
}
return items;
Behavior details:
statusCodeandeventTypecombinations are mapped as follows:statusCode = 2andeventType = 201→AcknowledgedstatusCode = 4andeventType = 201→ClosedstatusCode = 1andeventType = 200→New AlertstatusCode = 16andeventType = 201→No one on dutyeventType = 203withannotationpresent →Annotated
- If an annotation is present, it is appended to the type string with a leading colon.
- Usernames are taken from
body.user.usernameif available, otherwise default toSystem. s4Statusis constructed as:<Type> by <Username>[: <Annotation>].s4Upistrueonly when the derived type isClosed. For all other types it isfalse.
Configuration notes:
- If your alerting provider uses different numeric codes, adjust the conditional checks accordingly.
- Use
console.log(item.json)inside this node if you need to debug payloads or mapping logic. - Be careful with single ampersand operators in the code; they are used here as bitwise operators but effectively act as logical checks with these numeric values. You can convert them to
&&if you prefer explicit logical operations.
3.3 Notion nodes
The workflow uses multiple Notion nodes to read and update incident pages. These nodes rely on a shared Notion credential configured in n8n.
3.3.1 NotionPageUpdater
Role: Update the Notion incident page that corresponds to the incoming alert.
- Operation: Update page
- Key fields:
- Page ID – typically mapped from the alert payload or a stored external reference
- Description (or equivalent text property) – set to the
s4Statusstring - Optional link back to the monitoring system via an
externalEventIdor similar field
This node ensures that the Notion record always reflects the latest state parsed from SIGNL4 or the monitoring system.
3.3.2 NotionNewAlertsQuery
Role: Find Notion incidents that have not yet been forwarded to SIGNL4.
- Operation: Search or List database pages
- Filter criteria (example):
Read = falseUp = false
The output of this node is a set of incident pages that are treated as new alerts to be created in SIGNL4. Each resulting page is processed by the SIGNL4 IncidentAlertForNew node.
3.3.3 NotionOpenAlertsQuery
Role: Identify Notion incidents that are currently considered “Up” and need to be reconciled with SIGNL4.
- Operation: Search or List database pages
- Filter criteria (example):
Up = trueRead = true
This node is used in the resolve flow to find incidents that should be resolved in SIGNL4, based on Notion’s state.
3.3.4 NotionMarkRead / NotionFinalizeUpdate
NotionMarkRead
- Role: After a new Notion incident is sent to SIGNL4, mark it as processed.
- Typical updates:
- Set
Read = trueto avoid re-sending the same incident - Optionally store the SIGNL4 incident identifier or timestamp
- Set
NotionFinalizeUpdate
- Role: Clean up or finalize Notion state after a SIGNL4 incident is resolved.
- Typical updates:
- Adjust flags to reflect that the incident is fully closed
- Update status fields or resolution notes
Exact property names depend on your Notion database schema; the template expects at least boolean properties equivalent to Read and Up.
3.4 SIGNL4 nodes
SIGNL4 nodes handle creation and resolution of on-call incidents. All SIGNL4 nodes share a configured SIGNL4 credential in n8n.
3.4.1 IncidentAlert & IncidentAlertForNew
Role: Send incidents into SIGNL4 for on-call notification and escalation.
- Operation: Create alert
- Key parameter:
externalIdset to the Notion page ID
Using the Notion page ID as externalId lets you correlate subsequent status updates and resolve operations back to the same SIGNL4 incident. The template includes two variants:
- IncidentAlert: Used in the webhook-driven path for alerts that originate from external systems.
- IncidentAlertForNew: Used in the scheduled Notion scan to create alerts for newly discovered incident pages.
3.4.2 IncidentResolve
Role: Resolve a SIGNL4 incident when Notion indicates that the incident should be closed.
- Operation: Resolve alert
- Key parameter:
externalIdset to the Notion page ID of the incident
This node is called in the resolve flow after NotionOpenAlertsQuery identifies incidents that are ready for closure. It ensures that SIGNL4’s state matches Notion’s resolution state.
3.5 Slack node: NotifySlack
Role: Post concise incident updates into a Slack channel.
- Operation: Send message
- Content: Typically uses the
s4Statusfield computed by ParseStatus - Destination: Preconfigured Slack channel for incident updates
This node keeps the wider team informed about acknowledgements, closures, annotations, and on-call availability without requiring them to log into Notion or SIGNL4.
4. Execution flows by scenario
4.1 Real-time alert flow (incoming webhook)
Used when an external monitoring system pushes alerts directly to n8n.
- Webhook receives the POST request and passes the full JSON payload to the next node.
- ParseStatus inspects
statusCode,eventType, optional annotations, and user information. It sets:s4Statusto a human-readable descriptions4Uptotrueif the event represents a closure, otherwisefalse
- NotionPageUpdater updates the relevant Notion page:
- Writes
s4Statusinto the Description or similar field - Optionally includes a link back to the original monitoring event via an
externalEventIdproperty
- Writes
- NotifySlack posts the
s4Statussummary into the configured Slack channel so the team sees the change immediately.
In this flow, SIGNL4 may already be managing the incident, and the webhook updates are primarily used to keep Notion and Slack synchronized with the alert lifecycle.
4.2 Scheduled discovery of new Notion incidents
Used when Notion is the system of record for incident creation and you want SIGNL4 to be notified of new records.
- IntervalTimer triggers on a schedule (for example every few minutes) and starts the scan.
- NotionNewAlertsQuery retrieves pages with:
Read = falseUp = false
These represent new incidents that have not yet been sent to SIGNL4.
- For each returned page, IncidentAlertForNew sends an alert to SIGNL4, using the Notion page ID as
externalId. - NotionMarkRead then updates each processed page, typically setting
Read = trueso that the same incident is not re-sent on the next interval.
This pattern ensures idempotent behavior, since already processed incidents are excluded from subsequent queries.
4.3 Scheduled resolve flow
Used to reconcile open incidents between Notion and SIGNL4 and close them when appropriate.
- IntervalTimer (which can be the same or a separate timer) triggers the resolve sequence.
- NotionOpenAlertsQuery returns pages that match:
Up = trueRead = true
These represent incidents that have been processed and are currently considered “Up” or open in Notion.
