How to Automate Customer Support with n8n (Ticket Routing, SLA Alerts, and Auto-Replies)
Build a customer support automation system with n8n — auto-route tickets, send instant replies, monitor SLAs, escalate urgent issues, and follow up on satisfaction. Step-by-step.
Your Support Queue Is Running on Manual. It Doesn't Have To.
Every ticket that arrives without an instant acknowledgment, sits in the queue past its SLA, or gets routed to the wrong agent is a degraded customer experience. Most of it is preventable with a pipeline.
Teams that automate their support workflows don't just respond faster — they prioritize better. Urgent issues from paying customers get flagged immediately. Common questions get auto-resolved. Agents spend time on conversations that need human judgment, not inbox sorting.
n8n lets you build this pipeline without a dedicated help desk tool. Whether your tickets come in via email, a web form, or a Slack channel, n8n can triage, route, acknowledge, and monitor every one — automatically.
What You Can Automate
Every stage of the support lifecycle has an automation opportunity:
- Instant acknowledgment — send a ticket confirmation with a ticket ID and estimated response time the moment a request arrives
- Ticket classification — detect topic, urgency, and customer tier from the content and metadata
- Smart routing — assign tickets to the right team or agent based on topic, language, or account type
- SLA monitoring — check open tickets every hour and fire alerts when any ticket is close to or past its SLA window
- Escalation paths — route unresponded tickets to a team lead and mark them urgent in your tracking sheet
- Workload distribution — assign new tickets to whoever has the fewest open cases
- CSAT follow-up — send a satisfaction survey 24 hours after a ticket is closed
The Support Automation Pipeline
A complete n8n support system runs three coordinated tracks:
Track 1 — Ticket Ingestion:
Webhook / Gmail Trigger → Code (parse + classify) → Google Sheets (log ticket)
→ Switch (by topic + urgency)
→ Slack (alert agent channel)
→ Gmail (send acknowledgment to customer)
Track 2 — SLA Monitoring:
Schedule Trigger (hourly) → Google Sheets (open tickets) → Code (compute age hours)
→ IF (approaching SLA) → Slack (warn agent)
→ IF (past SLA) → Slack (escalation alert) + Sheets (flag status: breached)
Track 3 — Resolution and Follow-Up:
Webhook (ticket closed event) → Sheets (mark resolved + timestamp)
→ Wait (24 hours) → Gmail (send CSAT survey) → Sheets (log survey sent)
All three tracks read and write to the same ticket log — one source of truth for your support operation.
1. Collect — Ingest Tickets from Any Source
Use a Webhook node as your universal intake point. Configure your web form, support email forwarder, or Slack /support command to POST to this endpoint.
A Code node parses the incoming payload and extracts the fields you need:
const raw = items[0].json;
return [{
json: {
ticket_id: `TKT-${Date.now()}`,
customer_email: raw.email || raw.from,
customer_name: raw.name || raw.from_name || 'Unknown',
subject: raw.subject || raw.title || '',
body: raw.message || raw.body || '',
source: raw.source || 'web',
created_at: new Date().toISOString(),
status: 'open',
urgency: 'normal',
}
}];
A Google Sheets node writes this row to your ticket log immediately. Every downstream step reads from this same row.
Add a source field to every incoming payload — email, web form, Slack, API. The Code node normalizes them into a single schema. Your routing and logging logic never needs to know where the ticket originated.
2. Process — Classify Each Ticket
A Code node scans the ticket subject and body for signals to set urgency and topic:
const body = (items[0].json.body + ' ' + items[0].json.subject).toLowerCase();
let urgency = 'normal';
let topic = 'general';
if (body.includes('outage') || body.includes('down') || body.includes('critical')) {
urgency = 'critical';
} else if (body.includes('billing') || body.includes('payment') || body.includes('charge')) {
urgency = 'high';
}
if (body.includes('billing') || body.includes('invoice') || body.includes('refund')) {
topic = 'billing';
} else if (body.includes('bug') || body.includes('error') || body.includes('broken')) {
topic = 'technical';
} else if (body.includes('cancel') || body.includes('downgrade')) {
topic = 'retention';
}
return [{ json: { ...items[0].json, urgency, topic } }];
This classification drives routing, SLA targets, and agent assignment.
Replace the keyword classifier with an OpenAI node. Pass the ticket subject and body and ask it to return a JSON object with topic, urgency, and sentiment. You get multilingual support and handling of phrasing variations that keyword matching misses. Route the JSON response directly into your Switch node.
3. Route — Get Each Ticket to the Right Place
A Switch node branches on topic and urgency:
Switch on topic:
billing → Slack #billing-support + Gmail (billing acknowledgment)
technical → Slack #tech-support + Gmail (technical acknowledgment)
retention → Slack #retention-team + Gmail (priority acknowledgment)
general → Slack #support + Gmail (standard acknowledgment)
IF urgency = critical:
→ Slack @here in the relevant channel
→ Twilio SMS to on-call agent
The Gmail node sends the acknowledgment email to the customer immediately — before any agent has read the ticket. Include the ticket ID, the team name, and a realistic response window.
4. Act — Monitor SLAs and Escalate Overdue Tickets
The monitoring workflow runs on an hourly Schedule Trigger. A Google Sheets node reads all rows where status = open. A Code node computes ticket age and SLA status:
const now = new Date();
return items.map(item => {
const created = new Date(item.json.created_at);
const ageHours = (now - created) / 3600000;
const slaTarget = item.json.urgency === 'critical' ? 1
: item.json.urgency === 'high' ? 4
: 8; // normal: 8-hour SLA
return {
json: {
...item.json,
age_hours: Math.round(ageHours),
sla_target: slaTarget,
sla_status: ageHours >= slaTarget ? 'breached'
: ageHours >= slaTarget * 0.75 ? 'warning'
: 'ok',
}
};
}).filter(i => i.json.sla_status !== 'ok');
IF nodes split breached tickets from warning tickets. Each branch fires a Slack alert with the ticket ID, age, customer name, and a direct link to the ticket row.
For any ticket with sla_status: breached, add a second Slack node that messages your support lead by name. This removes the chance of an alert being missed in a busy team channel.
5. Follow Up — Close the Loop with CSAT
When a ticket is resolved, a webhook fires to close the loop. The workflow:
- Updates the Google Sheets row — sets
status: resolved, recordsresolved_at - Passes through a Wait node set to 24 hours
- Sends a Gmail survey: "How did we do? Reply with a rating from 1–5."
- Logs
survey_sent_atin the ticket row
A separate Gmail Trigger workflow reads survey replies and writes the score back to the ticket log so you have resolution quality tracked alongside ticket metadata.
Get the Decision Support System template for routing logic →Implementation Patterns
Pattern 1: Email-to-Ticket with Auto-Acknowledge
For teams where support arrives as email:
Gmail Trigger (support@yourcompany.com)
→ Code (extract metadata + body → ticket schema)
→ Google Sheets (log new ticket)
→ Gmail (acknowledgment with ticket ID)
→ Slack (post to #support)
Set the Gmail Trigger to check every minute. The customer gets a receipt within 60 seconds of sending their email.
Pattern 2: Workload-Based Agent Assignment
Distribute tickets evenly across your team rather than by topic alone:
Webhook (new ticket) → Google Sheets (read agents + open ticket counts)
→ Code (find agent with fewest open tickets)
→ Google Sheets (assign ticket to that agent)
→ Slack (DM assigned agent with ticket details)
The Code node sorts agents by open ticket count and returns the first:
const agents = items.map(i => i.json);
agents.sort((a, b) => parseInt(a.open_tickets) - parseInt(b.open_tickets));
return [{ json: { assigned_to: agents[0].name, agent_email: agents[0].email } }];
No ticket pile-up on your busiest agents while others sit idle.
Pattern 3: Morning Support Digest
Every morning, a digest gives the team a snapshot of the queue:
Schedule Trigger (daily, 8am) → Google Sheets (all open tickets)
→ Code (aggregate by urgency, status, and age)
→ Slack (post morning digest to #support)
The Code node builds a summary: total open tickets, how many are breached or at risk, the oldest open ticket, and which topics are trending. No one needs to open a spreadsheet to know where the queue stands. Pair this with the App Analytics Dashboard template to track support volume and resolution trends over time.
n8n Nodes You'll Use Most
| Node | Purpose |
|---|---|
| Webhook | Ingest tickets from web forms, email forwarders, and third-party tools |
| Gmail Trigger | Watch a support inbox for new inbound emails |
| Code | Parse payloads, classify tickets, compute SLA age, aggregate stats |
| Switch / IF | Route tickets by topic, urgency, or SLA status |
| Google Sheets | Log all tickets, track open/closed status, store agent assignments |
| Gmail | Send acknowledgment emails, CSAT surveys, and escalation notices |
| Slack | Alert agents in topic-specific channels, DM assignees, post digests |
| Wait | Hold CSAT follow-up until 24 hours after ticket resolution |
| Schedule Trigger | Drive hourly SLA checks and daily digest workflows |
| HTTP Request | Query your help desk API or push data to external tools |
Getting Started
Start with ticket ingestion and acknowledgment — that delivers immediate value and takes under an hour to build.
- Create your ticket log in Google Sheets with columns:
ticket_id,customer_email,customer_name,subject,topic,urgency,status,created_at,assigned_to,resolved_at - Set up a Webhook node and copy the URL — configure your web form or email forwarder to POST to it
- Add a Code node to normalize the incoming payload into your ticket schema and set default values
- Connect a Google Sheets node to append each new ticket as a row
- Add a Switch node to branch by topic and wire a Gmail node on each branch to send the right acknowledgment template
- Add a Slack node on each branch to notify the relevant agent channel with ticket details
- Build the SLA monitor as a separate workflow — Schedule Trigger, read open tickets, compute age, wire Slack alert branches one tier at a time
Once the ingestion pipeline is solid, layer in workload-based assignment and the CSAT follow-up track. Use the Data Entry Hub template to manage the Google Sheets logging step if you want a ready-made structure for multi-source data intake.
For collecting structured customer satisfaction data and running NPS analysis, see the full guide to n8n customer feedback automation. For e-commerce teams where support tickets often relate to orders or refunds, the n8n e-commerce automation guide covers the order-status lookup and refund workflow patterns that pair directly with this pipeline.
Browse automation templates for customer operations →Common questions
Can n8n automatically route support tickets by topic or urgency?
How does n8n monitor SLAs for open support tickets?
Can n8n send automatic first replies to customers who open a support ticket?
Get the workflow templates this guide is built on
Import-ready n8n JSON, step-by-step setup, and tested end-to-end. One-time payment, own it forever.
More automation guides

How to Automate Airtable with n8n (Sync, Update, and Trigger Workflows from Your Database)
Airtable Is Your Database. n8n Makes It Behave Like a Full Automation Platform. Airtable is where teams store structured data — project trackers, CRM records, content calendars, inventory, hiring pipe…

How to Automate Your Email Inbox with n8n (Triage, Route, and Auto-Reply)
Your Inbox Is a Queue. n8n Can Run It for You. Most knowledge workers spend 2–4 hours a day on email. Sorting, reading, deciding who to forward to, writing the same replies again and again. That is op…

How to Automate Notion Workflows with n8n (Databases, Pages, and Syncs)
Notion Is Your Team's Source of Truth. n8n Keeps It Accurate Without the Manual Work. Notion is where teams track projects, log decisions, manage content pipelines, and maintain wikis. The problem is…