AutomationFlowsAI & RAG › Automate Customer Support with Mintlify Documentation & Zendesk AI Agent

Automate Customer Support with Mintlify Documentation & Zendesk AI Agent

ByAlex Gurinovich @alexg on n8n.io

This n8n workflow automates support ticket handling with AI-driven classification, response generation, and safety checks. Responses are based solely on your Mintlify documentation, ensuring accuracy, consistency, and reduced manual effort in customer support.

Webhook trigger★★★★★ complexityAI-powered32 nodesAgentOpenRouter ChatHTTP Request
AI & RAG Trigger: Webhook Nodes: 32 Complexity: ★★★★★ AI nodes: yes Added:

This workflow corresponds to n8n.io template #5046 — 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 →

Download .json
{
  "id": "YEArXtErE6aQQmka",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI customer support agent",
  "tags": [],
  "nodes": [
    {
      "id": "79ff2d59-8fac-42cd-a61b-0f87723af80a",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3256,
        420
      ],
      "parameters": {
        "text": "={{ $json.aiResponse }}",
        "options": {
          "systemMessage": "You are a helpful AI support assistant for <YOUR-DOMAIN>. A customer has asked a question, and relevant information has already been fetched from the documentation.  \nYour task is to:\n\n- Summarize and rephrase the fetched content into a clear and friendly response.  \n- Keep the response within 120 words.  \n- Start the reply with \u201cHi,\\n\u201d.  \n- End the reply with \u201cBest regards,\\n AI support agent\u201d.  \n- Don't mention any billing, compliance, or sales teams.  \n- Don't offer the customer to contact <YOUR-DOMAIN>.  \n- Keep the tone professional, polite, and supportive. Avoid technical jargon unless necessary.  \n- If the information is partial or the question is unclear, mention it briefly and offer a helpful direction.  \n- If the customer says their proxy is not working, politely ask for more details such as:\n  - Which software or tool they are using  \n  - Whether they can recheck their configuration  \n  - If possible, to share a screenshot of the issue  \n\nOutput your answer as a properly formatted JSON object:\n\n{\n  \"ticket\": {\n    \"comment\": {\n      \"body\": \"Hi,\\n\\n{Response to customer}\\n\\nBest regards,\\nAI support agent\",\n      \"public\": true\n    },\n    \"status\": \"pending\"\n  }\n}\n\nKeep the tone professional, polite, and supportive. Avoid technical jargon unless necessary. If the information is partial or the question is unclear, mention it briefly and offer a helpful direction and escalate to a human support agent."
        },
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "1322e147-e25f-476e-9823-1898c5ec0e82",
      "name": "OpenRouter Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        3344,
        640
      ],
      "parameters": {
        "model": "deepseek/deepseek-r1-distill-llama-70b:free",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9769ad77-a395-4251-b45e-aa817482d821",
      "name": "Message router",
      "type": "n8n-nodes-base.switch",
      "position": [
        1496,
        99
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "billing",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "83dbaa68-8ece-4cd9-b553-e05157c03afd",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "\"category\": \"billing\""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "advertisement",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "c4409784-1d61-43c6-8f00-038888fb8853",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "\"category\": \"advertisement\""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "fraud",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "cf2b9652-c9a1-4101-b525-46a947de5b3c",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "\"category\": \"fraud\""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "other",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fc49d233-30eb-403e-934f-9f0b59b0836e",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "\"category\": \"other\""
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "ccc9a63b-d5ed-460f-be44-0bb62a8439d0",
      "name": "New ticket?",
      "type": "n8n-nodes-base.switch",
      "position": [
        1936,
        420
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "new",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "45668a4b-48c9-48d1-869e-0769701c415d",
                    "operator": {
                      "type": "string",
                      "operation": "empty",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.topicId }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "existing",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "acc77f71-06a9-444b-a780-9319490ab014",
                    "operator": {
                      "type": "string",
                      "operation": "exists",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.topicId }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "1a448d28-8c30-4aaf-b6c2-6c15ac7a1544",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -640,
        120
      ],
      "parameters": {
        "path": "d5df4915-3245-468d-970f-54e7bf8f4084",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "2db01f51-b260-4dbb-ab88-9745612f774b",
      "name": "Parse conversation",
      "type": "n8n-nodes-base.code",
      "position": [
        240,
        220
      ],
      "parameters": {
        "jsCode": "// Define the agent's author_id (update this to match your system)\nconst supportStaffId = 19780258553884;\n\n// Get the input data (from previous node)\nconst comments = items[0].json.comments;\nconst subject = items[0].json.subject;\nconst ticketId = $('Fetch Zendesk ticket').first().json.ticket.id\n\n// Filter only public comments\nconst publicComments = comments.filter(comment => comment.public === true && comment.type === 'Comment');\n\n// Build the conversation array\nconst conversation = publicComments.map(comment => {\n    return {\n        role: comment.author_id === supportStaffId ? 'support_agent' : 'customer',\n        message: comment.body\n    };\n});\n\n// Return the final structured output\nreturn [\n    {\n        json: {\n            subject: subject,\n            conversation: conversation,\n            ticketId: ticketId\n        }\n    }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "4d7ab1c4-73fc-4894-ab8c-3b27a4e3ec28",
      "name": "Look for Mintlify topicId",
      "type": "n8n-nodes-base.code",
      "position": [
        1716,
        420
      ],
      "parameters": {
        "jsCode": "const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\n// Get tags from the Zendesk ticket\nconst tags = $('Fetch Zendesk ticket').first().json.ticket.tags || [];\n\n// Find the first tag that matches the UUID format\nconst topicId = tags.find(tag => uuidRegex.test(tag)) || null;\n\n// Return with new field\nreturn [\n  {\n    json: {\n      ...items[0].json,\n      topicId: topicId\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "70fd61ed-65a2-4d80-b419-c8dac980649c",
      "name": "Add Mintlify topicID to ticket",
      "type": "n8n-nodes-base.code",
      "position": [
        2596,
        320
      ],
      "parameters": {
        "jsCode": "// Get topicId from tags[0] in the other node\nconst topicId = $('Add Mintlify topicId to ticket tags').first().json.tags?.[0] || null;\n\n// Get the current item (from \"Parse conversation\")\nconst item = $('Parse conversation').first().json.conversation\n\n// Extract and simplify the conversation to only include message fields\nconst conversation = (item || []).map(entry => ({\n  message: entry.message\n}));\n\n// Build and return the final output\nreturn [\n  {\n    json: {\n      conversation,\n      topicId\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "059f2573-2a5c-464e-8114-cb08cd7b11b3",
      "name": "Create Mintlify Chat Topic",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2156,
        320
      ],
      "parameters": {
        "url": "https://api-dsc.mintlify.com/v1/chat/topic",
        "method": "POST",
        "options": {},
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer <YOUR-API-KEY>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "7b561eb4-add1-43d2-8957-8fe684e257e2",
      "name": "Add Mintlify topicId to ticket tags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2376,
        320
      ],
      "parameters": {
        "url": "=https://<YOUR-DOMAIN>.zendesk.com/api/v2/tickets/{{ $('Fetch Zendesk ticket').item.json.ticket.id }}/tags",
        "method": "PUT",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "tags",
              "value": "={{ $json.topicId }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "zendeskApi"
      },
      "credentials": {
        "zendeskApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "d499662f-be7a-4319-bbae-5a5e5477cc54",
      "name": "Delete ticket",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1716,
        20
      ],
      "parameters": {
        "url": "=https://<YOUR-DOMAIN>.zendesk.com/api/v2/tickets/{{ $('Parse conversation').item.json.ticketId }}",
        "method": "DELETE",
        "options": {},
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "zendeskApi"
      },
      "credentials": {
        "zendeskApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f0d52e9e-034a-452d-81a9-7904d62f6114",
      "name": "Check if human agent is assigned",
      "type": "n8n-nodes-base.switch",
      "position": [
        -200,
        120
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Don't involve",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "3a2d99f6-2c18-4515-9b6b-ea346067b9fe",
                    "operator": {
                      "type": "number",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.ticket.assignee_id }}",
                    "rightValue": 19780258553884
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Involve",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "3dd54bce-0b01-43a8-85a8-539937d22670",
                    "operator": {
                      "type": "string",
                      "operation": "empty",
                      "singleValue": true
                    },
                    "leftValue": "={{ $json.ticket.assignee_id }}",
                    "rightValue": ""
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "d2ebc6e6-f164-40ee-8910-6a1c3bc85f70",
      "name": "If human assigned, don't reply",
      "type": "n8n-nodes-base.noOp",
      "position": [
        20,
        20
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "439d7ac6-5335-4660-a94f-b4f5f616f335",
      "name": "OpenRouter Chat Model1",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        3940,
        640
      ],
      "parameters": {
        "model": "deepseek/deepseek-r1-distill-llama-70b:free",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d8a6bb45-beaf-41dc-b615-34e58d22f447",
      "name": "Check uncertainty",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        3852,
        420
      ],
      "parameters": {
        "text": "={{ $json.ticket.comment.body }}",
        "options": {
          "systemMessage": "You are a classification assistant. Your task is to analyze the support agent's reply and determine whether it expresses uncertainty or lack of confidence.\n\nUncertainty may be indicated by phrases such as:\n- \"I'm not sure\"\n- \"I don't know\"\n- \"Unfortunately, I cannot help\"\n- \"I don't have enough information\"\n- \"You may want to check with someone else\"\n- \"This might not be accurate\"\n- \"Possibly\"\n- \"It could be\"\n- \"The documentation does not provide specific pricing information\"\n\nIf the reply contains any of these or similar expressions, return:\n\n{\n  \"isUncertain\": true\n}\n\nIf the reply is confident, helpful, and provides a clear answer, return:\n\n{\n  \"isUncertain\": false\n}\n\nOnly return the JSON object. Do not include any explanation or additional text."
        },
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "78d023f3-71b4-49a4-885a-197862b29c9b",
      "name": "If more that x replies, don't reply",
      "type": "n8n-nodes-base.noOp",
      "position": [
        900,
        320
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "aad3ff45-fc88-4400-90f2-6a46972da86d",
      "name": "If uncertain, don't reply",
      "type": "n8n-nodes-base.noOp",
      "position": [
        4448,
        320
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "ee1525fc-e2b3-4a0f-a5eb-3347e48c0f08",
      "name": "OpenRouter Chat Model2",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenRouter",
      "position": [
        1208,
        340
      ],
      "parameters": {
        "model": "deepseek/deepseek-r1-distill-llama-70b:free",
        "options": {}
      },
      "credentials": {
        "openRouterApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "65e03e7e-e86f-495e-9b2e-04ac4e33a40a",
      "name": "Message classifier",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1120,
        120
      ],
      "parameters": {
        "text": "={{ $json.conversation[0].message }}",
        "options": {
          "systemMessage": "You are a classification assistant. Your task is to analyze a customer's message and classify it into one of the following categories:\n\n- billing: The customer is asking about charges, refunds, invoices, payments, crypto transactions, or requesting a custom plan that is not listed on the website. Do not include messages related to plan auto-renewal, switching to a monthly plan, removing a payment method, or how to view receipts.\n- advertisement: The customer is proposing a partnership, collaboration, promotion, review, or business opportunity.\n- fraud: The customer is reporting or discussing issues related to hacking, DDoS attacks, griefing, illegal use, abuse, stealing, spam, bots, reselling, surveys or any suspicious or malicious activity.\n- other: The message does not clearly fit into any of the above categories.\n\nOutput your answer as a properly formatted JSON object:\n\n{\n  \"category\": \"billing\"\n}\n\nOnly return the JSON object. Do not include any explanation or additional text."
        },
        "promptType": "define"
      },
      "typeVersion": 2
    },
    {
      "id": "02612319-2fdf-4c2e-801b-8e374baa9ccf",
      "name": "Uncertainty router",
      "type": "n8n-nodes-base.switch",
      "position": [
        4228,
        420
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "uncertain",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "bc93432b-5015-4dac-beda-68ab221ed4f2",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "true"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "certain",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "7d4dc081-6d62-4b9c-9344-15713b21bb30",
                    "operator": {
                      "type": "string",
                      "operation": "contains"
                    },
                    "leftValue": "={{ $json.output }}",
                    "rightValue": "false"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "9b04c360-cb9c-4614-b0ab-15bd936d9243",
      "name": "Billing suspected - escalate",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1716,
        -180
      ],
      "parameters": {
        "url": "=https://<YOUR-DOMAIN>.zendesk.com/api/v2/tickets/{{ $('Fetch Zendesk ticket').item.json.ticket.id }}",
        "method": "PUT",
        "options": {},
        "jsonBody": "{\n  \"ticket\": {\n    \"comment\": {\n      \"body\": \"Hi,\\n\\nThis request is related to billing and was forwarded to a human agent. We will return to you as soon as possible.\\n\\nBest regards,\\nAI support agent\",\n      \"public\": true\n    },\n    \"status\": \"open\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "zendeskApi"
      },
      "credentials": {
        "zendeskApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "8c3bb2e4-76d6-4be9-b1d7-4d1f9738f682",
      "name": "Fraud suspected - escalate",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1716,
        220
      ],
      "parameters": {
        "url": "=https://<YOUR-DOMAIN>.zendesk.com/api/v2/tickets/{{ $('Fetch Zendesk ticket').item.json.ticket.id }}",
        "method": "PUT",
        "options": {},
        "jsonBody": "{\n  \"ticket\": {\n    \"comment\": {\n      \"body\": \"Hi,\\n\\nYour message appears to involve activity that may violate our Acceptable Use Policy. Please review our guidelines here: https://<YOUR-DOMAIN>.com/legal/acceptable-use-policy.\\n\\nIf you believe this is a mistake or need further clarification, feel free to provide more context.\\n\\nBest regards,\\nAI support agent\",\n      \"public\": true\n    },\n    \"status\": \"pending\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "zendeskApi"
      },
      "credentials": {
        "zendeskApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b5292f27-97a5-4e57-a082-6a74f2b31ec0",
      "name": "Mintlify generated response (new)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2816,
        320
      ],
      "parameters": {
        "url": "https://api-dsc.mintlify.com/v1/chat/message",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "topicId",
              "value": "={{ $('Add Mintlify topicID to ticket').item.json.topicId }}"
            },
            {
              "name": "message",
              "value": "={{ $json.conversation[0].message }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer <YOUR-API-KEY>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "X-Mintlify-Base-Url",
              "value": "https://docs.<YOUR-DOMAIN>.com"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c7f53efc-7513-48ba-9ad5-e5a977a181bd",
      "name": "Mintlify generated response (existing)",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2816,
        520
      ],
      "parameters": {
        "url": "https://api-dsc.mintlify.com/v1/chat/message",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "topicId",
              "value": "={{ $json.topicId }}"
            },
            {
              "name": "message",
              "value": "={{ $('Flip conversation to get the last message').item.json.conversation[0].message }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer <YOUR-API-KEY>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "X-Mintlify-Base-Url",
              "value": "https://docs.<YOUR-DOMAIN>.com"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "e1aa2510-f473-4e23-8d9e-f36d889c97ff",
      "name": "Check how many times the AI replied",
      "type": "n8n-nodes-base.switch",
      "position": [
        680,
        220
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Keep AI",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fb02a796-2f4d-45a7-8c3a-d2bae8bb9964",
                    "operator": {
                      "type": "number",
                      "operation": "lte"
                    },
                    "leftValue": "={{ $json.aiReplyCount }}",
                    "rightValue": 3
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Involve a human agent",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "774acb34-caeb-4596-9404-9d97844708de",
                    "operator": {
                      "type": "number",
                      "operation": "gt"
                    },
                    "leftValue": "={{ $json.aiReplyCount }}",
                    "rightValue": 3
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "9e5a90c0-4a7e-4745-bef2-6f6b8dad3c50",
      "name": "Fetch Zendesk ticket",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -420,
        120
      ],
      "parameters": {
        "url": "=https://<YOUR-DOMAIN>.zendesk.com/api/v2/tickets/{{ $json.body.ticket.id }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "zendeskApi"
      },
      "credentials": {
        "zendeskApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "1188f26f-3a37-40aa-b6b8-01dede339b39",
      "name": "Fetch ticket conversation",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        20,
        220
      ],
      "parameters": {
        "url": "=https://<YOUR-DOMAIN>.zendesk.com/api/v2/tickets/{{ $json.ticket.id }}/comments",
        "options": {},
        "sendHeaders": true,
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "zendeskApi"
      },
      "credentials": {
        "zendeskApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "63f16b5d-6ca2-40ca-b4c8-4b5a33b2ef1c",
      "name": "Count AI replies",
      "type": "n8n-nodes-base.code",
      "position": [
        460,
        220
      ],
      "parameters": {
        "jsCode": "// Get the conversation array from the first input item\nconst conversation = $input.first().json.conversation || [];\n\n// Count how many messages are from support_agent\nconst supportAgentReplyCount = conversation.filter(msg => msg.role === 'support_agent').length;\n\n// Return the count\nreturn [\n  {\n    json: {\n      aiReplyCount: supportAgentReplyCount\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "ced12732-e0ba-4787-a8ea-0b5673567f80",
      "name": "Flip conversation to get the last message",
      "type": "n8n-nodes-base.code",
      "position": [
        900,
        120
      ],
      "parameters": {
        "jsCode": "// Get the first item from input\nconst item = $input.first();\n\n// Reverse the conversation array\nconst reversedConversation = $('Parse conversation').first().json.conversation.reverse();\n\n// Return the modified object\nreturn [\n  {\n    json: {\n      conversation: reversedConversation,\n      ticketId: item.json.ticketId\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "c7994f00-1ef5-4c40-abff-c277d4fa0047",
      "name": "Parse mintlify response",
      "type": "n8n-nodes-base.code",
      "position": [
        3036,
        420
      ],
      "parameters": {
        "jsCode": "const response = $input.first().json.data\nconst [answer, citationsRaw] = response.split('||');\nconst citations = citationsRaw ? JSON.parse(citationsRaw) : [];\n\nlet final = answer;\nif (citations.length > 0) {\n  final += '\\n\\n\ud83d\udcda Related Docs:\\n';\n  citations.forEach((c, i) => {\n    final += `${i + 1}. [${c.metadata.title}](https://docs.<YOUR-DOMAIN>.com${c.link})\\n`;\n  });\n}\n\nreturn {\n  aiResponse: answer,\n  citations,\n  finalResponse: final\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "bd74c61c-eea7-480e-ab1d-a84fa564fbaa",
      "name": "Parse AI response",
      "type": "n8n-nodes-base.code",
      "position": [
        3632,
        420
      ],
      "parameters": {
        "jsCode": "// Get the raw output string\nconst rawOutput = $input.first().json.output;\n\n// Try to extract only the JSON part using a regex\nconst jsonMatch = rawOutput.match(/\\{[\\s\\S]*\\}/);\n\n// If no match found, throw an error\nif (!jsonMatch) {\n  throw new Error('No valid JSON object found in the string.');\n}\n\n// Parse the matched JSON string\nconst parsed = JSON.parse(jsonMatch[0]);\n\n// Ensure it's a plain object\nif (typeof parsed !== 'object' || Array.isArray(parsed)) {\n  throw new Error('Parsed JSON must be a plain object');\n}\n\n// Return parsed object\nreturn [\n  {\n    json: parsed\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "ad38d9c9-d7c4-4ef1-bcc4-3547dc0eef21",
      "name": "Reply ticket and put on pending",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        4448,
        520
      ],
      "parameters": {
        "url": "=https://<YOUR-DOMAIN>.zendesk.com/api/v2/tickets/{{ $('Fetch Zendesk ticket').item.json.ticket.id }}",
        "method": "PUT",
        "options": {
          "allowUnauthorizedCerts": true
        },
        "jsonBody": "={{ JSON.stringify($('Parse AI response').item.json) }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "zendeskApi"
      },
      "credentials": {
        "zendeskApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "08338dd4-507c-4c74-b594-91d11c418a51",
  "connections": {
    "Webhook": {
      "main": [
        [
          {
            "node": "Fetch Zendesk ticket",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Parse AI response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "New ticket?": {
      "main": [
        [
          {
            "node": "Create Mintlify Chat Topic",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mintlify generated response (existing)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete ticket": {
      "main": [
        []
      ]
    },
    "Message router": {
      "main": [
        [
          {
            "node": "Billing suspected - escalate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Delete ticket",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fraud suspected - escalate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Look for Mintlify topicId",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Count AI replies": {
      "main": [
        [
          {
            "node": "Check how many times the AI replied",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check uncertainty": {
      "main": [
        [
          {
            "node": "Uncertainty router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI response": {
      "main": [
        [
          {
            "node": "Check uncertainty",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Message classifier": {
      "main": [
        [
          {
            "node": "Message router",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse conversation": {
      "main": [
        [
          {
            "node": "Count AI replies",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Uncertainty router": {
      "main": [
        [
          {
            "node": "If uncertain, don't reply",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Reply ticket and put on pending",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Zendesk ticket": {
      "main": [
        [
          {
            "node": "Check if human agent is assigned",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model1": {
      "ai_languageModel": [
        [
          {
            "node": "Check uncertainty",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "OpenRouter Chat Model2": {
      "ai_languageModel": [
        [
          {
            "node": "Message classifier",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse mintlify response": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch ticket conversation": {
      "main": [
        [
          {
            "node": "Parse conversation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Look for Mintlify topicId": {
      "main": [
        [
          {
            "node": "New ticket?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Mintlify Chat Topic": {
      "main": [
        [
          {
            "node": "Add Mintlify topicId to ticket tags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Mintlify topicID to ticket": {
      "main": [
        [
          {
            "node": "Mintlify generated response (new)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if human agent is assigned": {
      "main": [
        [
          {
            "node": "If human assigned, don't reply",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Fetch ticket conversation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mintlify generated response (new)": {
      "main": [
        [
          {
            "node": "Parse mintlify response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add Mintlify topicId to ticket tags": {
      "main": [
        [
          {
            "node": "Add Mintlify topicID to ticket",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check how many times the AI replied": {
      "main": [
        [
          {
            "node": "Flip conversation to get the last message",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "If more that x replies, don't reply",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mintlify generated response (existing)": {
      "main": [
        [
          {
            "node": "Parse mintlify response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Flip conversation to get the last message": {
      "main": [
        [
          {
            "node": "Message classifier",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This n8n workflow automates support ticket handling with AI-driven classification, response generation, and safety checks. Responses are based solely on your Mintlify documentation, ensuring accuracy, consistency, and reduced manual effort in customer support.

Source: https://n8n.io/workflows/5046/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

🧪 LABR - nuevo asistente (REPARADO). Uses httpRequest, postgres, postgresTool, toolCalculator. Webhook trigger; 63 nodes.

HTTP Request, Postgres, Postgres Tool +9
AI & RAG

leads. Uses supabase, gmail, formTrigger, httpRequest. Webhook trigger; 62 nodes.

Supabase, Gmail, Form Trigger +13
AI & RAG

Brokeria-v20. Uses n8n-nodes-waha, httpRequest, redis, googleGemini. Webhook trigger; 56 nodes.

N8N Nodes Waha, HTTP Request, Redis +7
AI & RAG

Brokeria-v15. Uses n8n-nodes-waha, httpRequest, postgres, redis. Webhook trigger; 55 nodes.

N8N Nodes Waha, HTTP Request, Postgres +7
AI & RAG

Transform your WhatsApp group conversations into actionable business intelligence through automated AI analysis and daily reporting. This workflow eliminates manual conversation monitoring by capturin

OpenRouter Chat, Output Parser Autofixing, Agent +6