Smart Alert Consolidation
Smart Alert Consolidation is a ticket lifecycle manager for ConnectWise PSA. It takes alert data from any monitoring tool — RMM, network monitor, uptime checker, or anything else — and automatically creates, updates, closes, and reopens service tickets based on alert state.
Key benefits:
- Reduces ticket spam — repeated failure alerts update the existing ticket instead of creating new ones
- Auto-closes on recovery — success alerts automatically resolve the matching ticket
- Reopens on recurrence — if a resolved issue comes back, the original ticket reopens with full history instead of creating a duplicate
- Consolidates notes — multiple alerts merge into a single timestamped note, keeping tickets clean and readable even under high-frequency alerting
- Attaches configuration items — automatically links the affected device by MAC, IP, or hostname
How it works in one sentence: the node matches alerts to tickets using a composite key of the Alert Name and Alert ID, then decides whether to create, update, close, or reopen the ticket based on the alert’s success or failure state.
Quick Start
To get a basic create-on-failure, close-on-recovery integration, you only need these fields:
| Field | What to set | Example |
|---|---|---|
| Company | The ConnectWise company for this alert | Select from dropdown, use expression {{ $json.companyId }}, or use MSP Copilot Link to look up the ID from a name or other identifier |
| Alert Name | A short code to group related alerts (max 40 chars) | ping, disk, backup |
| Alert ID | Unique ID for the monitored entity, any length | srv-01 or {{ $json.deviceId }} |
| Alert Status | false = failure, true = recovery | {{ $json.status === 'ok' }} |
| Board | The service board for tickets | Select from dropdown |
| Failure Status | Status to set when alert fails | New or select from dropdown |
| Success Status | Status to set when alert recovers | Closed or select from dropdown |
| Summary | Ticket title (trimmed to 100 chars) | {{ $json.deviceName }} is not responding |
Simplest scenario
- Your monitoring tool detects a failure and sends data to n8n
- The node creates a ticket: “SERVER01 is not responding” with status New
- A second failure alert arrives — no new ticket is created; the existing one already matches
- Your monitoring tool detects recovery and sends a success alert
- The node finds the open ticket and sets its status to Closed
You now have a working integration. Read on to add messages, note consolidation, and reopening rules.
Recommended Setup
Most real-world integrations benefit from a few additional settings beyond the Quick Start. This section walks through what we recommend for a typical monitoring integration.
Use both detailed and short messages
The node uses two message types for each state — a detailed one and a short one — and picks the right one depending on context:
- Detailed messages are used when creating a ticket or adding the first resolution note. They contain full diagnostic context — links to your RMM, affected services, troubleshooting steps.
- Short messages are used when appending to existing notes, reopening, or updating. They’re one-liners that record what happened without repeating the full context.
| Field | Example |
|---|---|
| Failure Message (Detailed) | SERVER01 (10.0.0.21) is down:\n- Not responding to pings\nCheck [device history](https://rmm.example.com/123). |
| Failure Message (Short) | DOWN: Not responding to pings |
| Success Message (Short) | UP: Ping restored |
This combination gives you rich context on the initial ticket while keeping subsequent notes compact. On a noisy alert, the short messages keep the ticket readable instead of dumping the same wall of text over and over.
Tip: You don’t need both detailed and short for every state. If you only provide a short message, it will be used everywhere — including the initial ticket description. This works well for success messages where a one-liner like
UP: Ping restoredis often all you need.
Enable note consolidation
Without note consolidation, every alert creates a separate note. If your monitoring tool sends an alert every 5 minutes, that’s 288 notes per day on a single ticket. Enable Append to Previous Note to merge repeated alerts into a single timestamped entry:
`2025-01-15 Wed 02:45:00 PM` DOWN: Not responding to pings
`2025-01-15 Wed 02:40:00 PM` DOWN: Not responding to pings
`2025-01-15 Wed 02:35:00 PM` DOWN: Not responding to pings
All three alerts live in one note, newest at the top. This is especially important for flip-flopping alerts — if a service goes down and back up repeatedly, each state change is logged in the same note instead of creating a flood of separate entries.
Set the Append Timeframe (e.g., 4 hours) to start a new note periodically. This gives technicians natural breakpoints to follow the timeline.
The Max Comments setting (default: 20) is a safety cap. When reached, the node updates the last note in-place instead of creating new ones, preventing PSA performance issues on noisy tickets.
Enable reopening
Without reopening, a failure alert for an already-resolved issue creates a brand-new ticket with no connection to the original. Enable Reopen Closed Tickets so the original ticket reopens with its full history intact. Set age limits (e.g., Max Creation Age of 30 days) to avoid reopening ancient tickets — if the ticket is too old, a new one is created instead.
Use Preview Mode during setup
Preview Mode runs the full decision logic without making any changes to ConnectWise. It returns exactly what would happen — which action, what the note would say, which configuration was matched. Use it to verify your configuration before going live, and again whenever you change settings.
How It Works
Every time the node runs, it looks up the ticket by the composite key (Alert Name + Alert ID), then follows this decision tree:
graph TD
A["Alert received"] --> B["Look up ticket by Alert Name + Alert ID"]
B --> C{"Existing ticket#quest;"}
C -- No --> D{"Alert status#quest;"}
D -- SUCCESS --> E["Nothing to close, skip"]
D -- FAIL --> F["Create new ticket"]
C -- Yes --> G{"Alert status#quest;"}
G -- SUCCESS --> H["Close ticket and add note"]
G -- FAIL --> I{"Ticket already closed#quest;"}
I -- No --> J["Update ticket status and add note"]
I -- Yes --> K["Reopen ticket and add note"]
classDef start fill:#6366f1,stroke:#4f46e5,color:#fff
classDef create fill:#22c55e,stroke:#16a34a,color:#fff
classDef close fill:#3b82f6,stroke:#2563eb,color:#fff
classDef reopen fill:#f97316,stroke:#ea580c,color:#fff
classDef update fill:#a855f7,stroke:#9333ea,color:#fff
classDef skip fill:#94a3b8,stroke:#64748b,color:#fff
class A,B start
class E skip
class F create
class H close
class J update
class K reopen
A few things to note:
- New tickets get the failure message as their initial description. Notes are only added to existing tickets.
- Closed tickets only appear in the search when Reopen Closed Tickets is enabled. Otherwise, only open tickets are matched.
- Open tickets are always matched regardless of age. Age restrictions only apply to closed tickets — this prevents duplicate tickets when an alert fires repeatedly for an already-open issue.
The deduplication key
The node combines Alert Name and Alert ID into a composite key for matching. For example, if Alert Name is ping and Alert ID is srv-01, the key is ping|srv-01.
- Alert Name is a short code that groups related alerts (e.g.,
ping,disk,backup). Max 40 characters. - Alert ID identifies the specific entity being monitored (e.g., a device ID, hostname, or service name). Any length.
- The search is always scoped to the specified Company.
Configuration Reference
Alert Identifiers
| Field | Type | Required | Description |
|---|---|---|---|
| Company | Dropdown | Yes | ConnectWise company to associate with the ticket. Use MSP Copilot Link to look up the ID from a name or other identifier. |
| Alert Name | String | Yes | Short code for grouping related alerts (e.g., ping, disk-space, backup). Max 40 characters. Part of the deduplication key. |
| Alert ID | String | Yes | Unique identifier for the monitored entity (e.g., device ID, hostname). Any length. Part of the deduplication key. |
| Alert Status | Boolean | Yes | false = failure (open/update ticket). true = recovery (close ticket). Use an expression to set this dynamically from your alert data. |
Ticketing
| Field | Type | Required | Description |
|---|---|---|---|
| Board | Dropdown | Yes | Service board where tickets are created. |
| Failure Status | Dropdown or text | No | Status to set on failure. Select from the board’s statuses, or type a status name as text (see Using text for statuses and priorities). |
| Success Status | Dropdown or text | No | Status to set on recovery. Typically a closed/resolved status. |
| Priority | Dropdown or text | No | Priority for new tickets. Select from dropdown, or type a priority name for automatic case-insensitive lookup. |
| Summary | String | Yes | Ticket title. Automatically trimmed to 100 characters if needed. |
Messages
| Field | Type | Description |
|---|---|---|
| Failure Message (Detailed) | String (multiline) | Full failure context. Used for initial ticket descriptions and first failure notes. Supports markdown and links. |
| Success Message (Detailed) | String (multiline) | Full recovery context. Used for the first resolution note. |
| Failure Message (Short) | String | One-liner for failures (e.g., DOWN: Service offline). Used when appending to notes or reopening tickets. |
| Success Message (Short) | String | One-liner for recovery (e.g., UP: Service restored). Used when appending recovery events. |
| Internal Note | Boolean | When enabled, all automated notes are internal-only (not visible to the customer). Default: off. |
Note Consolidation
| Field | Type | Default | Description |
|---|---|---|---|
| Max Comments | Number | 20 | Safety cap. When reached, the last note is updated in-place instead of creating new ones. Prevents PSA slowdown on noisy alerts. |
| Append to Previous Note | Boolean | Off | Merge new alerts into the most recent automated note instead of creating separate notes. |
| Append Timeframe | Duration | (empty) | How old a note can be before the node starts a new one instead of appending. Example: 4 hours, 2 days. |
| Append Only If Last Note | Boolean | On | Only merge if the automated note is still the most recent. If a technician added a note since, a new one is created to preserve context. |
| Prepend to Note | Boolean | On | Add new content at the top (newest first). Recommended for readability. |
Reopen Rules
| Field | Type | Default | Description |
|---|---|---|---|
| Reopen Closed Tickets | Boolean | Off | Reopen a closed ticket when a new failure arrives for the same alert, instead of creating a duplicate. |
| Reopen on Same Board Only | Boolean | On | Only match closed tickets on the same board. If off, tickets on any board may be reopened — but you must use status names instead of IDs (see Using text for statuses and priorities). |
| Reopen Status | Dropdown or text | (empty) | Status to set when reopening. Falls back to the Failure Status if not set. Useful for using a distinct status like Reopened. |
| Max Creation Age | Duration | (empty) | Only reopen closed tickets created within this window (e.g., 15 days, 2w). |
| Max Last Updated Time | Duration | (empty) | Only reopen closed tickets updated within this window (e.g., 7 days). |
Important: Age restrictions only apply to closed tickets. Open tickets are always found and updated regardless of age.
Configuration Item Attachment
These fields are inside the Configuration Attachment collection. They let you automatically find and link a ConnectWise configuration (managed device) to the ticket.
| Field | Type | Description |
|---|---|---|
| Configuration Types | Multi-select | Filter by one or more configuration types. Leave empty to search all types. |
| MAC Address | String | MAC address to match. Accepts any format (00:11:22:33:44:55, 001122334455, etc.). Supports * wildcards. |
| IP Address | String | IP address for exact match. 127.0.0.1 is automatically ignored. |
| Hostname Full Match | String | Full hostname for exact match. Supports * wildcards (e.g., server*.example.com). Case-insensitive. |
| Hostname Smart Match | String | Flexible hostname match — tries exact first, then prefix. server01 matches server01, server01.example.com, and SERVER01.internal. |
| Skip If No Configuration | Boolean | Skip ticket creation entirely if no matching configuration is found. Default: off. |
| Append Configuration Details | Boolean | Append hardware details (serial, model, tag, notes) to the initial ticket description. Default: off. |
Processing Options
| Field | Type | Default | Description |
|---|---|---|---|
| Preview Mode | Boolean | Off | Dry-run mode. Returns exactly what would happen without making any changes. Strongly recommended during initial setup and whenever you change settings. |
Using Text for Statuses and Priorities
By default, you select statuses and priorities from dropdowns, which pass numeric IDs to ConnectWise. But you can also type a text name using an expression, and the node will look it up automatically.
Why this matters:
-
Statuses are board-specific. Each service board has its own set of statuses with its own numeric IDs. A status ID that means “New” on one board may not exist on another. If you enable Reopen on Same Board Only = Off (to match tickets across boards), you must use text names like
"New"or"Closed"— they work on any board. -
Priority names from external tools. If your RMM sends priority as text like
"High"or"Critical", you can pass it directly. The node does a case-insensitive lookup and resolves it to the matching ConnectWise priority.
To use text instead of a dropdown value, switch the field to Expression mode and enter a string like {{ "New" }} or pass a value from your input data like {{ $json.priority }}.
Note Consolidation
When multiple alerts arrive for the same ticket, you have control over how notes are organized. The key question is: does each alert get its own note, or do they get merged together?
graph TD
A["New alert for existing ticket"] --> B{"Append to Previous Note enabled#quest;"}
B -- No --> C{"At Max Comments limit#quest;"}
C -- No --> D["Create new note"]
C -- Yes --> E["Update last note in-place"]
B -- Yes --> F{"Previous automated note exists#quest;"}
F -- No --> G["Create new note"]
F -- Yes --> H{"Within Append Timeframe#quest;"}
H -- No --> I["Create new note"]
H -- Yes --> J{"Still the last note on ticket#quest;"}
J -- No --> K["Create new note"]
J -- Yes --> L["Append to existing note"]
classDef start fill:#6366f1,stroke:#4f46e5,color:#fff
classDef create fill:#22c55e,stroke:#16a34a,color:#fff
classDef append fill:#f97316,stroke:#ea580c,color:#fff
classDef inplace fill:#a855f7,stroke:#9333ea,color:#fff
class A start
class D,G,I,K create
class L append
class E inplace
Which message is used where
The node picks detailed or short messages based on where you are in the ticket’s lifecycle. The rule is simple: detailed messages get one shot per state, then everything after uses short messages.
- Detailed Failure Message — used once, as the initial ticket description when the ticket is created
- Detailed Success Message — used once, as a standalone note for the first recovery on a ticket
- Short Failure Message — used for all subsequent failure notes (repeated alerts, reopening, consolidation)
- Short Success Message — used for all subsequent recovery notes after the first
You don’t need to provide all four messages. Every context has a fallback chain: if the preferred message isn’t provided, the node tries the other type, and if neither exists, it falls back to a generic string ("Alert failure" or "Alert success"). The fallback always crosses over — so if you only provide a detailed message, it will also be used in short contexts like consolidation lines. If you only provide a short message, it will be used for the initial ticket description too.
| Context | 1st choice | Fallback | Last resort |
|---|---|---|---|
| New ticket description | Detailed | Short | "Alert failure" |
| First recovery note | Detailed | Short | "Alert success" |
| All other notes | Short | Detailed | "Alert failure" / "Alert success" |
In practice, short-only works well for success messages where a one-liner like UP: Ping restored is all you need. Detailed-only works if you want the same rich message everywhere. Both together gives you the best of both worlds — rich context on first appearance, compact lines for everything after.
graph TD
A["Alert for existing ticket"] --> B{"Alert state#quest;"}
B -- Failure --> C{"Creating a new ticket#quest;"}
C -- Yes --> D["Detailed Failure Message<br/><em>used as ticket description</em>"]
C -- No --> E["Short Failure Message<br/><em>timestamped note</em>"]
B -- Success --> F{"First recovery on this ticket#quest;"}
F -- Yes --> G["Detailed Success Message<br/><em>standalone note</em>"]
F -- No --> H["Short Success Message<br/><em>timestamped note</em>"]
D -. "falls back to" .-> E
G -. "falls back to" .-> H
classDef start fill:#6366f1,stroke:#4f46e5,color:#fff
classDef detailed fill:#3b82f6,stroke:#2563eb,color:#fff
classDef short fill:#22c55e,stroke:#16a34a,color:#fff
class A start
class D,G detailed
class E,H short
| Scenario | Failure state | Success state |
|---|---|---|
| New ticket created | Detailed (ticket description) | — |
| First recovery | — | Detailed (standalone note) |
| Repeated failure before any recovery | Short (timestamped, appendable) | — |
| Failure after recovery | Short (starts a fresh note) | — |
| Ongoing alerts (consolidation) | Short (timestamped, appendable) | Short (timestamped, appendable) |
Example
With Append to Previous Note enabled and Prepend to Note on (newest first), here is what a ticket’s notes look like after three failures, a recovery, and then another failure:
Note 3 (new failure after recovery — starts a fresh note):
`2025-01-15 Wed 03:25:00 PM` DOWN: Not responding to pings
Note 2 (first recovery — uses Detailed Message):
SERVER01 (10.0.0.21) is back online. Ping restored.
Note 1 (consolidated failures — uses Short Message):
`2025-01-15 Wed 02:45:00 PM` DOWN: Not responding to pings
`2025-01-15 Wed 02:40:00 PM` DOWN: Not responding to pings
`2025-01-15 Wed 02:35:00 PM` DOWN: Not responding to pings
The initial ticket description (not shown as a note) used the Detailed Failure Message with the full diagnostic context. Subsequent failure alerts used the Short Message and were consolidated into a single timestamped note. The first recovery used the Detailed Success Message as a standalone note. When the alert failed again after recovery, a fresh note was started.
Flip-flopping alerts: When an alert alternates between failure and success rapidly, each state change is recorded in the same note rather than creating separate notes, as long as Append to Previous Note is enabled and the events fall within the Append Timeframe.
Max Comments is a safety net. Regardless of other settings, once a ticket reaches this limit, new content updates the last note in-place instead of creating more. This prevents ConnectWise from slowing down on tickets with hundreds of notes.
Configuration Item Matching
When you provide device identifiers (MAC address, IP, hostname), the node searches ConnectWise configurations to find and attach the best match. This is useful for RMM integrations where you want each ticket to link to the affected device automatically.
If multiple identifiers are provided, they are checked in priority order:
- MAC Address (highest priority) — pattern match with wildcard support
- IP Address — exact match (localhost is skipped)
- Hostname Full Match — exact or wildcard pattern, case-insensitive
- Hostname Smart Match — exact first, then prefix (e.g.,
server01matchesserver01.example.com)
The first match at the highest priority level wins. The search is scoped to the specified company and only returns active configurations. If you specify Configuration Types, only those types are searched.
When Append Configuration Details is enabled, the initial ticket description is extended with available hardware info:
*Serial Number:* ABC123XYZ
*Model Number:* PowerEdge R740
*Tag:* ASSET-001
Notes: Located in Server Room B, Rack 3
Only fields that have values on the configuration are included.
Common Scenarios
Basic monitoring
Use only the Quick Start fields. One ticket per incident, auto-closed on recovery.
Best for: simple uptime monitors, infrequent alerts, or when you want a clean ticket per incident.
RMM integration with note consolidation
A typical RMM setup with device attachment and consolidated notes:
| Setting | Value | Why |
|---|---|---|
| Append to Previous Note | On | Merge repeated alerts into one note |
| Append Timeframe | 4 hours | Start a new note every 4 hours |
| Prepend to Note | On | Newest events at the top |
| Max Comments | 20 | Safety cap |
| Failure Message (Short) | DOWN: {{ $json.message }} | Brief per-event line |
| Failure Message (Detailed) | (full RMM diagnostic output) | Used only for the initial ticket |
| Hostname Smart Match | {{ $json.hostname }} | Match the device in ConnectWise |
| Append Configuration Details | On | Add serial/model to ticket |
Controlled reopening
Reopen tickets for recurring issues, but only if they’re recent:
| Setting | Value | Why |
|---|---|---|
| Reopen Closed Tickets | On | Enable reopening |
| Max Creation Age | 30 days | Don’t reopen tickets older than a month |
| Max Last Updated Time | 14 days | Don’t reopen stale tickets |
| Reopen Status | "Reopened" | Distinct from new tickets |
Cross-board tracking
When tickets may be moved between boards and you still want to match them:
| Setting | Value | Why |
|---|---|---|
| Reopen on Same Board Only | Off | Search across all boards |
| Failure Status | {{ "New" }} | Text name works on any board |
| Success Status | {{ "Closed" }} | Text name works on any board |
| Reopen Status | {{ "Reopened" }} | Text name works on any board |
Actions and Preview Mode
The node returns an action value that tells you exactly what happened (or what would happen in Preview Mode). You can use this in downstream nodes — for example, a Switch node on {{ $json.action }} to send notifications only when a new ticket is created.
Enable Preview Mode during setup. It runs the full logic without writing to ConnectWise, so you can verify every decision before going live.
Action values
| Action | What happened |
|---|---|
CREATE_TICKET | A new ticket was created for a failure alert |
CLOSE_TICKET | An open ticket was closed by a success alert |
REOPEN_TICKET | A closed ticket was reopened by a new failure |
UPDATE_TICKET_STATUS | An existing open ticket’s status was refreshed |
NO_STATUS_UPDATE | A ticket was found but no status change was needed |
NO_TICKET_TO_RESOLVE | A success alert arrived but there was no open ticket to close |
SKIP_NO_CONFIGURATION | No configuration item was found and Skip If No Configuration is enabled |
CLOSE_TICKET_STATUS_ERRORREOPEN_TICKET_STATUS_ERRORUPDATE_TICKET_STATUS_ERROR | A ticket was found but the status couldn’t be updated — usually a cross-board status mismatch. Use text status names to fix this. |
Note action values
| Note Action | What happened |
|---|---|
CREATE_NOTE | A new note was added to the ticket |
APPEND_TO_PREVIOUS_NOTE | Content was merged into the most recent automated note |
UPDATE_LAST_NOTE | The last note was updated in-place (at Max Comments limit) |
Using output in downstream nodes
- Switch node on
{{ $json.action }}to handle different outcomes differently - IF node on
{{ $json.action === 'CREATE_TICKET' }}to trigger notifications only for new tickets - Access the ticket ID with
{{ $json.ticketId }}for further logic to modify the ticket or push to other systems