---
title: "AI-Powered Lead Routing: Score and Assign Leads in n8n"
description: "Build an n8n lead-scoring workflow that rates inbound leads 1-10 with AI and routes hot ones to your CRM or Slack instantly. AI credits included, no API key needed."
canonical: https://agentroost.app/en/blog/ai-lead-scoring-routing-n8n
date: 2026-06-06T20:00:00Z
---

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

Most sales teams sort leads the same way: whoever sees the notification first takes a stab at it, or everything piles into a spreadsheet and gets triaged manually at the end of the day. Both approaches mean your best-fit leads sit waiting while the team chases contacts who submitted a demo form out of idle curiosity.

n8n can fix this. With an AI node in the middle of your intake pipeline, every lead gets scored on intent before a human ever looks at it — and the hot ones land in Slack or your CRM within seconds of the form submit.

Here is exactly how to build it.

## What the Workflow Does

1. A lead submits a form (or your CRM fires a webhook).
2. n8n receives the payload and optionally enriches it with company data.
3. An AI/LLM node reads the lead's message, job title, and company size, then returns a structured JSON score from 1 to 10 with a short rationale.
4. An IF node branches on that score: **hot (7–10)** goes right to your Slack channel and creates a CRM deal; **warm (4–6)** gets tagged for nurture; **cold (1–3)** is logged and dropped into a low-priority queue.

Eight nodes total. No custom code required for the happy path.

## Node-by-Node Build

### 1. Webhook — receive the lead

Add a **Webhook** node, set the method to `POST`, and copy the generated URL into your form tool (Tally, Typeform, a plain HTML form — all work). Give the path something readable like `/lead-intake`.

The webhook URL on your AgentRoost instance is public HTTPS by default, so you do not need to set up SSL or a reverse proxy.

### 2. Set — normalize the fields

Incoming payloads differ by form tool. A **Set** node gives you consistent field names for the rest of the workflow:

```json
{
  "name":        "{{ $json.submitter_name }}",
  "email":       "{{ $json.email }}",
  "company":     "{{ $json.company_name }}",
  "employees":   "{{ $json.employee_count }}",
  "title":       "{{ $json.job_title }}",
  "message":     "{{ $json.how_can_we_help }}"
}
```

Adjust keys to match whatever your form actually sends.

### 3. HTTP Request — optional enrichment

If you have a Clearbit, Hunter, or Apollo key, insert an **HTTP Request** node here to pull company domain, industry, and headcount. Feed the response back into a second **Set** node to merge the enriched fields.

If you do not have an enrichment API, skip this and rely on what the form captures. The AI node still does useful scoring on message intent alone.

### 4. AI / LLM Node — the scoring step

This is the core. Add an **AI Agent** or **Basic LLM Chain** node (both are under the AI section in n8n's node panel). Set the model — on AgentRoost you pick from the built-in credential that is already connected to your included credits.

Set the **System Prompt** to something like:

```
You are a B2B sales qualification assistant.
Given a lead's details, return a JSON object with two keys:
  "score" (integer 1-10, where 10 = strongest buyer intent),
  "reason" (one sentence explaining the score).
Score higher for: clear pain described, decision-maker title,
company size >50, urgency language, specific use-case mentioned.
Score lower for: vague curiosity, student/freelancer signals,
competitor research language.
Return ONLY valid JSON. No preamble.
```

Set the **User Message** to:

```
Name: {{ $json.name }}
Title: {{ $json.title }}
Company: {{ $json.company }} ({{ $json.employees }} employees)
Message: {{ $json.message }}
```

The node returns something like:

```json
{ "score": 8, "reason": "Decision-maker at a 200-person company describing a specific integration pain, with urgency language." }
```

### 5. Code (mini) — parse the score

Add a small **Code** node to pull the score out reliably:

```javascript
const raw = $input.first().json.text ?? $input.first().json.output;
const parsed = JSON.parse(raw);
return [{ json: { ...($input.first().json), score: parsed.score, reason: parsed.reason } }];
```

This handles slight variations in which key the LLM node returns the text on.

### 6. IF — branch by score

Add an **IF** node with the condition:

```
{{ $json.score }} >= 7
```

- **True branch** → hot lead path
- **False branch** → warm/cold path

For a three-way split (hot / warm / cold), chain a second IF on the false branch checking `>= 4`.

### 7a. Hot lead path — Slack + CRM

On the true branch, add two parallel nodes:

**Slack** node → Send Message to `#sales-hot-leads`:

```
*New hot lead — score {{ $json.score }}/10*
{{ $json.name }} · {{ $json.title }} @ {{ $json.company }}
_{{ $json.reason }}_
Reply to: {{ $json.email }}
```

**HubSpot / Pipedrive / HTTP Request** node → Create deal or contact. Most CRMs have a native n8n node; use **HTTP Request** with your CRM's REST API if yours does not.

### 7b. Warm/cold path — nurture or log

Add a **HubSpot** (or similar) node to tag the contact with a nurture list, or simply write a row to a **Google Sheets** node for manual review later.

### 8. Respond to Webhook

If your form tool expects a `200` response, end both branches with a **Respond to Webhook** node returning `{"status":"ok"}`. Some tools will retry on timeout otherwise.

## Realistic Configuration Tips

- **Temperature**: Set the LLM temperature to `0.2`. You want consistent, predictable JSON — not creative variation.
- **Max tokens**: 150 is enough. The response is always a small JSON object.
- **Error handling**: Enable **Continue on Error** on the AI node and the Code node, then add a fallback Set node that assigns `score: 5` (neutral) when parsing fails. This prevents the whole workflow from stopping on a malformed LLM response.
- **Test with real messages**: Open the n8n editor, pin a few actual form submissions as test data, and run the AI node in isolation first. Tweak the prompt until score distributions feel right before wiring up the Slack/CRM nodes.

## How to Run This on AgentRoost

You get your own n8n instance — your login, your data, your workflows, on a public subdomain at `https://<your-id>.agentroost.app`. Self-hosting without the DevOps.

1. [Sign up and pick the n8n framework](/en/pricing).
2. Name your instance — it becomes your subdomain.
3. Your n8n editor opens. The AI credential is already wired to included credits. No OpenAI account, no API key, no billing setup to configure.
4. Build the workflow node by node (or paste a JSON export if you have one from a test environment).
5. Copy the webhook URL and drop it into your form tool.
6. Activate the workflow.

The AI scoring calls run against your included credits. If you want to switch models, change one dropdown — the rest of the workflow is untouched. Start at $19.99/mo all-in, 14-day money-back guarantee, cancel anytime.

[Compare plans and get started](/en/pricing) · [See the n8n framework details](/en/agents/n8n)

## What to Watch After Launch

Once live, check the execution log in your n8n editor after the first 20–30 leads. Look for:

- **Score clustering**: if everything lands 4–6, your prompt may be under-differentiating. Add sharper scoring criteria.
- **Parse failures**: if the Code node errors, the LLM returned non-JSON. Add a regex fallback or tighten the prompt with `"Return ONLY valid JSON, no markdown fences."`.
- **False positives in hot leads**: review Slack alerts manually for the first week to calibrate the `>= 7` threshold. Moving it to `>= 8` tightens the hot bucket.

A well-tuned version of this workflow typically takes one person less than an hour to build and another day of calibration. After that it runs unattended, and your sales team stops triaging — they follow up on leads that are actually worth their time.
