---
title: "Auto-Categorize and Route Inbound Emails with n8n + AI"
description: "Build an n8n workflow that auto-classifies inbound emails (sales, support, billing, spam) and routes each one with zero manual triage. AI credits included — no API key needed."
canonical: https://agentroost.app/en/blog/email-triage-routing-n8n-ai
date: 2026-06-03T20:00:00Z
---

[Canonical URL](https://agentroost.app/en/blog/email-triage-routing-n8n-ai)

Every busy inbox has the same problem: a sales lead arrives, sits unread in the general support queue, and goes cold before anyone notices. Meanwhile your support team answers billing questions meant for finance, and spam clogs the view. Manual triage is slow, inconsistent, and impossible to scale past a handful of daily emails.

An AI-powered n8n workflow solves this cleanly. You classify each incoming message once — automatically — then route it to exactly the right destination. Here is how to build it, node by node.

---

## What the finished workflow does

1. **Trigger** on every new inbound email.
2. **Extract** the sender, subject line, and body text.
3. **Classify** the email with an AI/LLM node: one of `sales`, `support`, `billing`, `spam`, or `other`.
4. **Branch** on that label with an IF or Switch node.
5. **Route** each category to a different destination — a CRM, a helpdesk ticket queue, a Slack channel, a label in Gmail, a row in a Google Sheet, or simply a forward to the right team alias.

The result is a hands-free triage layer that runs 24/7. Nothing falls through the cracks, and no human has to read an email twice just to decide *where* it belongs.

---

## Build it step by step

### 1. Trigger: IMAP Email node (or Gmail Trigger)

Add an **IMAP Email** node (or **Gmail Trigger** if you use Google Workspace) to poll a shared inbox — something like `inbox@yourcompany.com`.

Key settings:
- **Poll Times**: every 1–5 minutes is enough for most teams.
- **Download Attachments**: off for triage purposes (keeps payloads small).
- **Only Unseen**: on, so you never re-process an email.

If you prefer webhooks over polling, point a mail routing rule (Mailgun, Postmark Inbound, or SendGrid Inbound Parse) at n8n's **Webhook** node and receive emails as JSON in real time.

### 2. Prepare the text: Set node

Raw email JSON is noisy. Use a **Set** node immediately after the trigger to pull out only what the AI needs:

```json
{
  "sender":  "{{ $json.from.value[0].address }}",
  "subject": "{{ $json.subject }}",
  "body":    "{{ $json.text }}"
}
```

Truncate the body if it can be long. An LLM only needs the first 400–600 characters of body text to classify reliably — trimming saves tokens and speeds up the call:

```
{{ $json.text.slice(0, 600) }}
```

### 3. Classify: AI / LLM node

This is where the intelligence lives. Add an **AI** node (the **Basic LLM Chain** or **Information Extractor** node in n8n's AI section) and write a system prompt like:

> You are an email triage assistant. Read the email below and return exactly one of these labels — and nothing else: `sales`, `support`, `billing`, `spam`, `other`.
>
> Sender: {{sender}}
> Subject: {{subject}}
> Body: {{body}}

Set the output format to **text** (not JSON) to get back a single word you can branch on cleanly.

**Model choice**: For classification tasks you do not need a top-tier model. A fast, inexpensive model works well and keeps per-email cost negligible. With AI credits included in your subscription, you can let this workflow run at high volume without watching a spending dashboard.

### 4. Normalize the label: Set node

The LLM might occasionally return `"Sales"` instead of `"sales"`, or add trailing whitespace. A quick normalization step prevents routing failures:

```
{{ $json.text.trim().toLowerCase() }}
```

Store the result in a field called `category`.

### 5. Branch: Switch node

Add a **Switch** node with these output rules:

| Rule | Condition | Output index |
|------|-----------|-------------|
| 1 | `category` equals `sales` | 0 |
| 2 | `category` equals `support` | 1 |
| 3 | `category` equals `billing` | 2 |
| 4 | `category` equals `spam` | 3 |
| (else) | — | 4 (fallback) |

Each output index connects to a different downstream branch.

### 6. Route to the right destination

Here is where you wire up your actual tools. Common patterns:

**Sales branch** — Create a lead in your CRM. Use the **HubSpot**, **Salesforce**, or **Pipedrive** node. At minimum: set contact email, source = `email`, and a note with the original subject. Optionally ping `#sales-leads` in Slack via the Slack node.

**Support branch** — Open a ticket. Use the **Zendesk**, **Freshdesk**, or **Linear** node. Map `sender` to the requester email and `subject` to the ticket title.

**Billing branch** — Forward to your finance alias using an **SMTP** node or apply a Gmail label (`billing/incoming`) via the Gmail node's **Add Label** operation.

**Spam branch** — Archive or delete without forwarding. In Gmail, apply the `SPAM` system label. No need to notify anyone.

**Fallback branch** — Send a brief Slack message to a catch-all channel (`#email-fallback`) so a human reviews edge cases. This matters during the first week while you tune the prompt.

### 7. Log every decision: Google Sheets node (optional but recommended)

Append a row for every classified email:

| Timestamp | Sender | Subject | Category | Destination |
|-----------|--------|---------|----------|-------------|
| 2026-06-13 09:14 | alice@acme.com | Re: Quote #1024 | sales | HubSpot |

This log makes it easy to spot misclassifications in the first days and refine your prompt — without digging through n8n execution history.

---

## Tips and common pitfalls

**Prompt drift**: "other" is your safety net. Do not try to enumerate every possible category upfront — you will miss cases. Start with five labels, watch the fallback rate, and add new buckets once you see a real pattern.

**Rate limits on polled inboxes**: If you receive bursts of emails (e.g., a marketing campaign reply-storm), polling every minute will hit the IMAP connection limit. Use a Webhook inbound approach instead, or add a **Wait** node between batches.

**HTML bodies**: Many business emails arrive as HTML only. Use the `text` field from the Email node rather than `html`. If `text` is empty, strip HTML with n8n's **HTML Extract** node before sending to the LLM.

**Confidence note**: LLM classification is not perfect. A `billing` email with the subject "Quick question" might land in `support`. The fallback Slack channel plus the log sheet give you visibility to catch these and update the prompt.

---

## Run this workflow on AgentRoost

You get your own n8n instance — your login, your workflows, your data — hosted at `https://<your-id>.agentroost.app`. No Docker, no SSL certificates, no VPS to manage.

The critical part for this workflow: **AI credits are already included**. You do not need an OpenAI API key, an Anthropic account, or any external billing relationship. The AI/LLM node in your n8n editor is already wired to your included credit balance. Classification calls run immediately, out of the box.

How to get started:

1. Sign up at [agentroost.app](https://agentroost.app) — email, Google, Microsoft, or Discord.
2. Pick the **n8n** framework, name your instance, and it opens in under two minutes.
3. Import or build the workflow above. The AI node already has credits — no configuration needed beyond writing your prompt.
4. Point your shared inbox at the workflow and let it run.

Pricing starts at **$19.99/mo all-in** — server, AI credits, and setup bundled into one price. 14-day money-back guarantee, cancel anytime.

[Compare plans](/en/pricing) or [see the n8n workspace](/en/agents/n8n) to understand what each tier includes in compute and credits.

---

## One workflow, permanent leverage

Manual email triage compounds in cost: one person spending 30 minutes a day on inbox sorting is 130+ hours a year, every year. A workflow you build once runs indefinitely. The first time it catches a sales inquiry that would have sat in the support queue over a weekend, it has already paid for itself.
