This workflow corresponds to n8n.io template #13940 — we link there as the canonical source.
This workflow follows the Agent → HTTP Request recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"nodes": [
{
"id": "b30ebe2e-6f4e-4faa-be37-e93475a2a03f",
"name": "Email Trigger (IMAP)",
"type": "n8n-nodes-base.emailReadImap",
"position": [
-1872,
64
],
"parameters": {
"options": {}
},
"typeVersion": 2.1
},
{
"id": "7a80d209-2c3f-4011-bfa9-f5f81d6a9f98",
"name": "Webhook Trigger",
"type": "n8n-nodes-base.webhook",
"position": [
-1872,
256
],
"parameters": {
"path": "support-ticket",
"options": {},
"httpMethod": "POST",
"responseMode": "lastNode"
},
"typeVersion": 2.1
},
{
"id": "e9fa3657-3950-4360-9fb3-1429ab8c864a",
"name": "Workflow Configuration",
"type": "n8n-nodes-base.set",
"position": [
-1648,
160
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "crmApiUrl",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__CRM/Helpdesk API URL__>"
},
{
"id": "id-2",
"name": "escalationWebhookUrl",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Escalation Webhook URL__>"
},
{
"id": "id-3",
"name": "observabilityEndpoint",
"type": "string",
"value": "<__PLACEHOLDER_VALUE__Observability Logging Endpoint__>"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "6e16757c-fc12-405e-b4c4-7dd885e31e34",
"name": "Clean HTML",
"type": "n8n-nodes-base.html",
"position": [
-1424,
160
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"dataPropertyName": "={{ $json.html || $json.body || $json.text }}",
"extractionValues": {
"values": [
{}
]
}
},
"typeVersion": 1.2
},
{
"id": "2ac5a9ea-512b-469e-bb11-628bc0920454",
"name": "Normalize Ticket Data",
"type": "n8n-nodes-base.set",
"position": [
-1200,
160
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "id-1",
"name": "ticket_id",
"type": "string",
"value": "={{ $json.id || $json.messageId || $now }}"
},
{
"id": "id-2",
"name": "user_email",
"type": "string",
"value": "={{ $json.from || $json.email }}"
},
{
"id": "id-3",
"name": "original_message",
"type": "string",
"value": "={{ $json.text }}"
},
{
"id": "id-4",
"name": "timestamp",
"type": "string",
"value": "={{ $now }}"
},
{
"id": "id-5",
"name": "source_channel",
"type": "string",
"value": "={{ $json.source || \"email\" }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "f510b588-4469-4386-b8cd-207a0d172467",
"name": "Language Detection & Translation Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-976,
160
],
"parameters": {
"text": "={{ $json.original_message }}",
"options": {
"systemMessage": "You are a language detection and translation specialist.\n\nYour task is to:\n1. Detect the language of the provided message\n2. If the language is NOT English, translate it to English while preserving meaning and tone\n3. If the language is already English, return the original text\n4. Provide a confidence score (0-1) for your language detection\n\nReturn your response in the exact JSON format specified by the output parser."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "7f6d8b42-08b8-4e6a-a13c-c933a02373c5",
"name": "Anthropic Model - Translation",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
-1008,
352
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"typeVersion": 1.3
},
{
"id": "9f5a852f-af4a-4148-97ed-a2647f00e4b0",
"name": "Translation Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-832,
352
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"original_language\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"description\": \"ISO language code detected\"\n\t\t},\n\t\t\"translated_text\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"description\": \"English translation or original if already English\"\n\t\t},\n\t\t\"confidence\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"description\": \"Confidence score 0-1 for language detection\"\n\t\t}\n\t}\n}"
},
"typeVersion": 1.3
},
{
"id": "174cabb0-d024-4b9c-a6dd-fd171b013f91",
"name": "Support Intelligence Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
-592,
160
],
"parameters": {
"text": "={{ $json.translated_text }}",
"options": {
"systemMessage": "You are a senior support analyst specializing in ticket classification and triage.\n\nAnalyze the provided support message and classify it according to these criteria:\n\n1. **Sentiment**: positive, neutral, or negative\n2. **Urgency**: low, medium, high, or critical\n3. **Category**: billing, bug, feature_request, account, technical, or other\n4. **Summary**: A concise 1-2 line summary of the issue\n5. **Churn Risk**: Score from 0 to 1 indicating likelihood of customer churn\n6. **Recommended Path**: auto_reply, escalate, or engineering\n\nBe thorough and accurate. Return your analysis in the exact JSON format specified."
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3
},
{
"id": "88f489e1-f3c9-4f44-a917-2308375c0bc3",
"name": "Anthropic Model - Intelligence",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
-608,
352
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"typeVersion": 1.3
},
{
"id": "56878b3b-1410-4212-8df6-5a7e0b99adb2",
"name": "Intelligence Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
-448,
368
],
"parameters": {
"schemaType": "manual",
"inputSchema": "{\n\t\"type\": \"object\",\n\t\"properties\": {\n\t\t\"sentiment\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"enum\": [\"positive\", \"neutral\", \"negative\"],\n\t\t\t\"description\": \"Sentiment of the support ticket\"\n\t\t},\n\t\t\"urgency\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"enum\": [\"low\", \"medium\", \"high\", \"critical\"],\n\t\t\t\"description\": \"Urgency level of the ticket\"\n\t\t},\n\t\t\"category\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"enum\": [\"billing\", \"bug\", \"feature_request\", \"account\", \"technical\", \"other\"],\n\t\t\t\"description\": \"Category of the support ticket\"\n\t\t},\n\t\t\"summary\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"description\": \"Brief 1-2 line summary\"\n\t\t},\n\t\t\"churn_risk\": {\n\t\t\t\"type\": \"number\",\n\t\t\t\"description\": \"Score 0-1\",\n\t\t\t\"minimum\": 0,\n\t\t\t\"maximum\": 1\n\t\t},\n\t\t\"recommended_path\": {\n\t\t\t\"type\": \"string\",\n\t\t\t\"enum\": [\"auto_reply\", \"escalate\", \"engineering\"],\n\t\t\t\"description\": \"Recommended action path for the ticket\"\n\t\t}\n\t},\n\t\"required\": [\"sentiment\", \"urgency\", \"category\", \"summary\", \"churn_risk\", \"recommended_path\"]\n}"
},
"typeVersion": 1.3
},
{
"id": "01a089f7-b439-4f8c-9801-2c5a4bc86d29",
"name": "Decision Router",
"type": "n8n-nodes-base.switch",
"position": [
-176,
144
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Auto Reply",
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.recommended_path }}",
"rightValue": "auto_reply"
}
]
},
"renameOutput": true
},
{
"outputKey": "Escalate",
"conditions": {
"options": {
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "or",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.urgency }}",
"rightValue": "critical"
},
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.recommended_path }}",
"rightValue": "escalate"
}
]
},
"renameOutput": true
}
]
},
"options": {
"ignoreCase": true,
"fallbackOutput": "extra",
"renameFallbackOutput": "Escalate"
}
},
"typeVersion": 3.4
},
{
"id": "fe58d0c7-3f2a-4ec9-92ca-bf73997abeae",
"name": "Draft Reply Generator",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
96,
48
],
"parameters": {
"text": "=Original message: {{ $json.original_message }}\n\nCategory: {{ $json.category }}\nSentiment: {{ $json.sentiment }}\nUrgency: {{ $json.urgency }}",
"options": {
"systemMessage": "You are a professional customer support representative.\n\nDraft a reply to the customer based on the provided ticket information:\n- Use an empathetic and professional tone\n- Provide clear and actionable solutions when possible\n- Keep the response under 200 words\n- Do NOT make promises about features or timelines unless explicitly stated\n- Do NOT hallucinate information\n- If you cannot provide a solution, acknowledge the issue and indicate it will be reviewed\n\nReturn ONLY the draft reply text, nothing else."
},
"promptType": "define"
},
"typeVersion": 3
},
{
"id": "68a7c723-07e8-48af-b8e6-0decb0cdcc9a",
"name": "Anthropic Model - Reply",
"type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
"position": [
96,
240
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "claude-sonnet-4-5-20250929",
"cachedResultName": "Claude Sonnet 4.5"
},
"options": {}
},
"typeVersion": 1.3
},
{
"id": "f2da4eb7-b757-4b58-bc9f-ea62c9c18df7",
"name": "Update CRM/Helpdesk",
"type": "n8n-nodes-base.httpRequest",
"position": [
512,
48
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.crmApiUrl }}",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "ticket_id",
"value": "={{ $('Normalize Ticket Data').item.json.ticket_id }}"
},
{
"name": "priority",
"value": "={{ $('Support Intelligence Agent').item.json.urgency }}"
},
{
"name": "tags",
"value": "={{ $('Support Intelligence Agent').item.json.category }}"
},
{
"name": "summary",
"value": "={{ $('Support Intelligence Agent').item.json.summary }}"
},
{
"name": "sentiment",
"value": "={{ $('Support Intelligence Agent').item.json.sentiment }}"
},
{
"name": "churn_risk",
"value": "={{ $('Support Intelligence Agent').item.json.churn_risk }}"
},
{
"name": "draft_reply",
"value": "={{ $('Draft Reply Generator').item.json.output }}"
},
{
"name": "original_language",
"value": "={{ $('Language Detection & Translation Agent').item.json.original_language }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "2abd6fe3-63d4-4f8b-8645-7b7ab82ca5a5",
"name": "Escalate to Team",
"type": "n8n-nodes-base.httpRequest",
"position": [
496,
288
],
"parameters": {
"url": "={{ $('Workflow Configuration').first().json.escalationWebhookUrl }}",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "ticket_id",
"value": "={{ $json.ticket_id }}"
},
{
"name": "urgency",
"value": "={{ $json.urgency }}"
},
{
"name": "category",
"value": "={{ $json.category }}"
},
{
"name": "sentiment",
"value": "={{ $json.sentiment }}"
},
{
"name": "summary",
"value": "={{ $json.summary }}"
},
{
"name": "churn_risk",
"value": "={{ $json.churn_risk }}"
},
{
"name": "user_email",
"value": "={{ $json.user_email }}"
},
{
"name": "original_message",
"value": "={{ $json.original_message }}"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "15a0215a-8c9e-4c14-9592-6665d338c61a",
"name": "Log Observability Metrics",
"type": "n8n-nodes-base.code",
"position": [
800,
144
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Log observability metrics\nconst startTime = $('Workflow Configuration').item.json.timestamp || new Date().toISOString();\nconst currentTime = new Date().toISOString();\n\n// Calculate response time in milliseconds\nconst responseTime = new Date(currentTime) - new Date(startTime);\n\n// Determine escalation status based on which path was taken\nconst escalationStatus = $input.item.json.escalated || false;\n\n// Get intelligence data from Support Intelligence Agent\nconst intelligenceData = $('Support Intelligence Agent').item.json;\n\nconst metrics = {\n response_time: responseTime,\n escalation_status: escalationStatus,\n model_used: 'anthropic',\n category: intelligenceData.category || 'unknown',\n urgency: intelligenceData.urgency || 'unknown',\n sentiment: intelligenceData.sentiment || 'unknown',\n churn_risk: intelligenceData.churn_risk || 'unknown',\n timestamp: currentTime\n};\n\n// Get observability endpoint from Workflow Configuration\nconst observabilityEndpoint = $('Workflow Configuration').item.json.observability_endpoint;\n\nif (observabilityEndpoint) {\n try {\n // Send metrics to observability endpoint\n await $http.post(observabilityEndpoint, {\n body: metrics,\n headers: {\n 'Content-Type': 'application/json'\n }\n });\n \n return {\n json: {\n success: true,\n metrics: metrics,\n message: 'Metrics logged successfully'\n }\n };\n } catch (error) {\n return {\n json: {\n success: false,\n metrics: metrics,\n error: error.message,\n message: 'Failed to send metrics to observability endpoint'\n }\n };\n }\n} else {\n // If no endpoint configured, just return the metrics\n return {\n json: {\n success: true,\n metrics: metrics,\n message: 'No observability endpoint configured, metrics collected only'\n }\n };\n}"
},
"typeVersion": 2
},
{
"id": "67d5f769-0697-4d49-b601-aaa9f2ca165d",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
752,
64
],
"parameters": {
"color": 7,
"height": 272,
"content": "## ILog Observability Metrics"
},
"typeVersion": 1
},
{
"id": "6eb6169d-1e57-46ab-96bd-f5359fda5aa5",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
432,
240
],
"parameters": {
"color": 7,
"width": 256,
"height": 192,
"content": "## Escalate to Team"
},
"typeVersion": 1
},
{
"id": "3bf1cb06-cc8c-4a8e-bfdf-d8fc97e5de75",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
64,
-80
],
"parameters": {
"color": 7,
"width": 320,
"height": 320,
"content": "## generate reply with context\nCategory, Sentiment:, Urgency."
},
"typeVersion": 1
},
{
"id": "ba350b07-565b-422f-ad51-9d7e49d7a243",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
448,
-80
],
"parameters": {
"color": 7,
"height": 304,
"content": "Updates the CRM/helpdesk system with ticket insights and logs workflow metrics such as response time, sentiment, and urgency."
},
"typeVersion": 1
},
{
"id": "f6bd1799-9bef-4f18-97f6-675106184d17",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-240,
16
],
"parameters": {
"color": 7,
"width": 208,
"height": 384,
"content": "Decision router sends tickets either to:\n\u2022 Auto reply generation\n\u2022 Escalation webhook for urgent issues"
},
"typeVersion": 1
},
{
"id": "c9bcb733-612f-4b37-8b64-581d7db7a9e3",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-656,
-32
],
"parameters": {
"color": 7,
"width": 368,
"height": 544,
"content": "## AI AGENT analyzes tickets\nAI analyzes sentiment, urgency, category, churn risk, and generates a short summary to guide ticket routing decisions."
},
"typeVersion": 1
},
{
"id": "ea4555c3-f039-4d63-8cb1-640aafac983d",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1056,
-32
],
"parameters": {
"color": 7,
"width": 384,
"height": 528,
"content": "## AI AGENT for multi Language support\nDetects the language of the support message and translates it to English when required so downstream AI analysis works consistently."
},
"typeVersion": 1
},
{
"id": "81e5b36e-b976-4af3-aa46-f7f258593033",
"name": "Sticky Note7",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1488,
-16
],
"parameters": {
"color": 7,
"width": 256,
"height": 400,
"content": "Cleans HTML content and normalizes ticket fields such as:\nticket ID, email, message body, timestamp, and source channel."
},
"typeVersion": 1
},
{
"id": "d4a7e562-9f75-4343-935b-fa10a6a9575f",
"name": "Sticky Note8",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2016,
-48
],
"parameters": {
"color": 7,
"width": 336,
"height": 448,
"content": "Receives support tickets from two sources:\n\u2022 Email inbox (IMAP trigger)\n\u2022 Webhook endpoint\n\nBoth sources feed messages into the same processing pipeline."
},
"typeVersion": 1
},
{
"id": "4dd478a5-41b9-4f44-844f-37130e1f633e",
"name": "Sticky Note9",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2544,
-32
],
"parameters": {
"width": 416,
"height": 464,
"content": "## How it works\nThis workflow processes incoming support tickets from email or webhooks. Messages are cleaned, normalized, and translated to English if needed. AI agents analyze the ticket to determine sentiment, urgency, category, and churn risk. Based on the analysis, tickets are either auto-replied with a drafted response or escalated to a support team. Ticket data and AI insights are then sent to a CRM/helpdesk system. Finally, observability metrics are logged.\n\n## Setup steps\n1. Add Anthropic API credentials for the AI agents.\n2. Configure IMAP credentials if using email ingestion.\n3. Set your CRM/Helpdesk API URL in the Workflow Configuration node.\n4. Add an escalation webhook URL for urgent tickets.\n5. Optionally configure an observability endpoint for metrics logging."
},
"typeVersion": 1
}
],
"connections": {
"Clean HTML": {
"main": [
[
{
"node": "Normalize Ticket Data",
"type": "main",
"index": 0
}
]
]
},
"Decision Router": {
"main": [
[
{
"node": "Draft Reply Generator",
"type": "main",
"index": 0
}
],
[
{
"node": "Escalate to Team",
"type": "main",
"index": 0
}
]
]
},
"Webhook Trigger": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"Escalate to Team": {
"main": [
[
{
"node": "Log Observability Metrics",
"type": "main",
"index": 0
}
]
]
},
"Update CRM/Helpdesk": {
"main": [
[
{
"node": "Log Observability Metrics",
"type": "main",
"index": 0
}
]
]
},
"Email Trigger (IMAP)": {
"main": [
[
{
"node": "Workflow Configuration",
"type": "main",
"index": 0
}
]
]
},
"Draft Reply Generator": {
"main": [
[
{
"node": "Update CRM/Helpdesk",
"type": "main",
"index": 0
}
]
]
},
"Normalize Ticket Data": {
"main": [
[
{
"node": "Language Detection & Translation Agent",
"type": "main",
"index": 0
}
]
]
},
"Workflow Configuration": {
"main": [
[
{
"node": "Clean HTML",
"type": "main",
"index": 0
}
]
]
},
"Anthropic Model - Reply": {
"ai_languageModel": [
[
{
"node": "Draft Reply Generator",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Translation Output Parser": {
"ai_outputParser": [
[
{
"node": "Language Detection & Translation Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Intelligence Output Parser": {
"ai_outputParser": [
[
{
"node": "Support Intelligence Agent",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Support Intelligence Agent": {
"main": [
[
{
"node": "Decision Router",
"type": "main",
"index": 0
}
]
]
},
"Anthropic Model - Translation": {
"ai_languageModel": [
[
{
"node": "Language Detection & Translation Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Anthropic Model - Intelligence": {
"ai_languageModel": [
[
{
"node": "Support Intelligence Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Language Detection & Translation Agent": {
"main": [
[
{
"node": "Support Intelligence Agent",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates customer support ticket processing using AI-powered analysis.
Source: https://n8n.io/workflows/13940/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow automates customer support ticket processing using AI-powered analysis, classification, and intelligent routing.
⏺ 🚀 How it works
Fully automates your service order pipeline from incoming booking to supplier confirmation — with built-in SLA enforcement and automatic escalation if a supplier goes silent. 📥 Receives orders via web
Tired of grinding out YouTube content? This n8n workflow turns AI into your personal video factory—creating engaging, faceless shorts on autopilot. Perfect for creators, marketers, or side-hustlers lo
Faceless YouTube Generator. Uses httpRequest, limit, googleDrive, googleSheets. Webhook trigger; 49 nodes.