Automated Lead Scoring with n8n and HubSpot

Build automated lead scoring workflows with n8n and HubSpot. Score leads based on behavior demographics and engagement.

What is lead scoring

Lead scoring is a simple system for ranking leads so your sales team knows who to contact first. Instead of treating every inbound lead the same, you assign points based on signals like:

  • Behavior: visited pricing page, booked a demo, replied to an email
  • Fit: job title, company size, industry, location
  • Engagement: email opens/clicks, webinar attendance, chat conversations

In HubSpot, lead scoring usually ends up as a numeric property on the contact (or company) that gets updated as new activity happens. The moment you have that number, you can build consistent handoff rules to sales (MQL/SQL), route to the right rep, or trigger follow-ups.

This post shows how to build automated lead scoring with n8n + HubSpot, including practical scoring rubrics and a workflow structure you can adapt.

For a broader view of how capture and enrichment fit together, see the complete guide to n8n lead capture automation.


Why automate lead scoring

Manual scoring (or “gut feel”) breaks down quickly as lead volume increases. Automation helps you:

  • Respond faster to high-intent leads (the ones most likely to convert)
  • Score consistently across channels and reps
  • Keep scores current as behavior changes (e.g., a lead comes back months later)
  • Reduce admin work updating CRM properties

Lead scoring is often worth automating because it can directly impact pipeline efficiency. For example, one source reports that lead scoring increases conversion rates by 30% (https://www.salesmate.io/blog/best-lead-scoring-software/). You’re not guaranteed that number, but it’s a strong indicator that structured scoring is more than a “nice to have.”

Automation also benefits the wider sales process. One source reports CRM automation boosts sales performance by 29% (https://utmost.agency/blogs/sales-automation-statistics/). And another notes that 63% of top-performing sales teams use CRM automation (https://www.realgeeks.com/blog/crm-real-estate-stats-workflows-automations). The theme is consistent: sales teams that systematize follow-up and prioritization tend to outperform.

What we’re not doing here: complex statistical modeling or enterprise-only tooling. The goal is a practical, explainable scoring system your team can maintain.


Setting up HubSpot API in n8n

You’ll connect n8n to HubSpot so n8n can read contact activity (or event inputs) and update contact properties.

API authentication

Recommended approach: use HubSpot Private App credentials (token-based). In HubSpot:

  1. Go to Settings → Integrations → Private Apps
  2. Create a private app (name it something like “n8n Lead Scoring”)
  3. Assign scopes you actually need, commonly:
    • crm.objects.contacts.read
    • crm.objects.contacts.write
    • (optional) crm.objects.companies.read, crm.objects.companies.write if you score at company level
  4. Copy the token and store it in your secrets manager (or n8n credentials)

In n8n:

  • Create new HubSpot credentials
  • Paste the private app token
  • Test the connection with a simple “Get Contact” node

Tip: keep “write” access narrow. Lead scoring only needs a small set of updates, usually one score property + a few helper fields (like last scored date).

If you haven't set up the HubSpot connection yet, a full walkthrough of the HubSpot connection and lead workflow setup covers Private App creation, credential configuration, and contact creation from start to finish.

If you specifically want to connect n8n to HubSpot Free and automate deal stage progression without a paid plan, the guide on automating deal stages in HubSpot for free with n8n walks through exactly that setup.


Building scoring criteria

A scoring model only works if it’s:

  • Clear (sales trusts it)
  • Observable (data actually exists)
  • Actionable (triggers a next step)

Contact properties

Before building n8n logic, decide where the score lives. In HubSpot, create:

  • lead_score (Number)
  • lead_score_band (Single-select: Cold, Warm, Hot)
  • lead_score_last_updated (Date)
  • (optional) lead_scoring_notes (Text) to store a short explanation like “+10 pricing page, +15 demo booked”

Custom scoring fields

A practical approach is to score across three buckets:

  1. Fit score (0–40): how well the lead matches your ideal customer profile
  2. Intent score (0–40): what they did that suggests buying intent
  3. Engagement score (0–20): responsiveness / recency

Total = 0–100.

Here’s an example rubric you can implement today (edit it to match your business):

Fit (max 40)

  • Job title contains “VP”, “Head”, “Director”: +10
  • Company size 50–200: +10
  • Company size 201–1000: +8
  • Industry is one of your target industries: +10
  • Non-target region: -5

Intent (max 40)

  • Visited pricing page (last 14 days): +15
  • Requested demo / booked call: +25
  • Viewed case study page: +10
  • Downloaded product sheet: +10

Engagement (max 20)

  • Opened marketing email: +2 (cap at 6)
  • Clicked email link: +5 (cap at 10)
  • Replied to outreach email: +10
  • No activity in 30+ days: -10

Bands

  • 0–39 = Cold
  • 40–69 = Warm
  • 70–100 = Hot

This stays explainable and avoids fragile, overfit scoring.


Behavioral scoring vs demographic scoring

Behavioral and demographic scoring solve different problems, so treat them differently.

Behavioral scoring (intent) answers: “Are they actively evaluating?”
Typical signals:

  • Pricing page views
  • Demo requests
  • Webinar attendance
  • High-intent form submissions

Demographic scoring (fit) answers: “Are they the right kind of buyer?”
Typical signals:

  • Job title / seniority
  • Department (Sales, RevOps, IT)
  • Company size
  • Industry

Best practice for sales teams: don’t let one dominate. A “perfect fit” lead with no intent isn’t ready. A high-intent lead with poor fit might still be worth routing, but maybe to a different segment or nurture path.

If you’re enriching leads (like firmographics), tools like Clearbit can fill in missing company size/industry fields so your fit score is based on real data rather than blanks.


Implementing the workflow

Below is a realistic n8n workflow pattern that works well for sales teams using HubSpot. It’s designed to be modular: you can swap triggers and scoring rules without rebuilding everything.

Workflow triggers

Common trigger options:

  1. New lead created (e.g., webhook from form, chat, or landing page)
  2. HubSpot contact updated (polling or webhook-like integrations depending on your setup)
  3. Behavior event received (pricing page view sent to n8n via webhook)
  4. Scheduled re-score (nightly cron to adjust for recency decay)

If you’re starting from scratch with webhooks, see how to set up webhook lead capture in n8n step-by-step.

Score calculation logic

A practical scoring workflow has these stages:

  1. Ingest event
    • Webhook, form submission, or scheduled trigger
  2. Find/Upsert contact in HubSpot
    • Search by email; create if missing
  3. Enrich (optional)
  4. Compute score
    • Apply your rubric and caps
  5. Update HubSpot properties
    • lead_score, lead_score_band, lead_score_last_updated, optional notes
  6. Route/Notify
    • If Hot: send Slack alert + assign owner + create task

Example workflow (realistic)

Scenario: A lead fills out your “Request a demo” form.

  • n8n receives the form webhook containing: email, name, company, job title, page URL, form type = “demo”
  • n8n finds the HubSpot contact by email
  • If missing, create the contact
  • Enrich via Clearbit if company size/industry aren’t present
  • Score:
    • Demo request = +25
    • Title contains “Director” = +10
    • Company size 50–200 = +10
    • Total so far = 45 → Warm
  • If the lead also visited pricing in last 7 days (if you track that event): +15 → 60 (still Warm)
  • Update HubSpot fields
  • If score ≥ 70 (Hot), notify sales in Slack with a direct contact link

If you prefer to start from pre-built patterns instead of building from scratch, see 10 ready-made n8n lead capture templates you can adapt for scoring and routing.



This is a starter template you can import and then map to your exact HubSpot properties and triggers. It focuses on: webhook → find contact → compute score → update contact → Slack alert.

Notes:

  • You must replace credential names, HubSpot property names, and webhook URL.
  • This is intentionally simple and explainable—no complex models.

{
"name": "HubSpot Lead Scoring (Webhook → Score → Update → Slack)",
"nodes": [
{
"parameters": {
"path": "lead-scoring-ingest",
"httpMethod": "POST",
"responseMode": "onReceived"
},
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [240, 260]
},
{
"parameters": {
"operation": "search",
"resource": "contact",
"filtersUi": {
"filterGroups": [
{
"filters": [
{
"propertyName": "email",
"operator": "EQ",
"value": "={{$json.body.email}}"
}
]
}
]
}
},
"name": "HubSpot - Find Contact",
"type": "n8n-nodes-base.hubspot",
"typeVersion": 2,
"position": [500, 260],
"credentials": {
"hubspotPrivateAppTokenApi": {
"name": "HubSpot Private App"
}
}
},
{
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "const body = $json.body || {};\nconst title = (body.job_title || '').toLowerCase();\nconst companySize = body.company_size || null;\nconst formType = (body.form_type || '').toLowerCase();\n\nlet score = 0;\nlet notes = [];\n\n// Intent\nif (formType.includes('demo')) { score += 25; notes.push('+25 demo request'); }\n\n// Fit (examples)\nif (title.includes('vp') || title.includes('head') || title.includes('director')) { score += 10; notes.push('+10 senior title'); }\nif (companySize === '50-200') { score += 10; notes.push('+10 company size 50-200'); }\nelse if (companySize === '201-1000') { score += 8; notes.push('+8 company size 201-1000'); }\n\n// Engagement (placeholder)\n// Add email click/open logic if you pass those events into this workflow.\n\n// Band\nlet band = 'Cold';\nif (score >= 70) band = 'Hot';\nelse if (score >= 40) band = 'Warm';\n\nreturn [{ json: { score, band, notes: notes.join('; ') } }];"
},
"name": "Compute Score",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [760, 260]
},
{
"parameters": {
"operation": "update",
"resource": "contact",
"contactId": "={{$node["HubSpot - Find Contact"].json.results[0].id}}",
"updateFields": {
"properties": {
"lead_score": "={{$json.score}}",
"lead_score_band": "={{$json.band}}",
"lead_scoring_notes": "={{$json.notes}}",
"lead_score_last_updated": "={{new Date().toISOString()}}"
}
}
},
"name": "HubSpot - Update Contact Score",
"type": "n8n-nodes-base.hubspot",
"typeVersion": 2,
"position": [1020, 260],
"credentials": {
"hubspotPrivateAppTokenApi": {
"name": "HubSpot Private App"
}
}
},
{
"parameters": {
"conditions": {
"number": [
{
"value1": "={{$node["Compute Score"].json.score}}",
"operation": "greaterThanOrEqual",
"value2": 70
}
]
}
},
"name": "IF Hot Lead",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [1260, 260]
},
{
"parameters": {
"resource": "message",
"operation": "post",
"channel": "sales-alerts",
"text": "Hot lead scored {{$node["Compute Score"].json.score}} ({{$node["Compute Score"].json.band}}). Notes: {{$node["Compute Score"].json.notes}}"
},
"name": "Slack Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [1500, 200],
"credentials": {
"slackApi": {
"name": "Slack"
}
}
}
],
"connections": {
"Webhook": {
"main": [[{ "node": "HubSpot - Find Contact", "type": "main", "index": 0 }]]
},
"HubSpot - Find Contact": {
"main": [[{ "node": "Compute Score", "type": "main", "index": 0 }]]
},
"Compute Score": {
"main": [[{ "node": "HubSpot - Update Contact Score", "type": "main", "index": 0 }]]
},
"HubSpot - Update Contact Score": {
"main": [[{ "node": "IF Hot Lead", "type": "main", "index": 0 }]]
},
"IF Hot Lead": {
"main": [
[{ "node": "Slack Alert", "type": "main", "index": 0 }],
[]
]
}
}
}

If you’d rather start from an existing public example and adapt it, n8n has a relevant workflow 

If you want a full walkthrough of the Clearbit enrichment step specifically, including API setup, fallback handling, and field mapping, see automating lead enrichment with Clearbit and n8n.


Updating scores automatically

Lead scoring fails when it becomes stale. You want scores to update when:

  • A lead performs a new high-intent action
  • New enrichment arrives (company size, industry, etc.)
  • Time passes without engagement (decay)

A reliable setup uses two update paths:

  1. Event-driven updates (real-time)

    • Webhook events: demo request, pricing page view, email click
    • Update score immediately, notify Slack if Hot
  2. Scheduled recalculation (batch)

    • Nightly Cron node in n8n
    • Pull contacts updated in the last X days (or in certain lifecycle stages)
    • Recompute score and apply decay rules

Practical decay rule examples (keep it simple):

  • If no tracked activity in 14 days: subtract 5
  • If no tracked activity in 30 days: subtract 10 and set band down one level (if applicable)

This keeps your sales team from calling “Hot” leads that went cold months ago.

For multi-channel capture (Google Forms, landing pages, ads), you can standardize all inbound sources into the same scoring webhook. If one of your sources is Google Forms, see how to connect Google Forms to your CRM with n8n.


Reporting and optimization

Once scores are flowing into HubSpot, the fastest way to improve them is to make the model measurable.

What to track (simple and useful):

  • Score distribution: how many Cold/Warm/Hot leads per week
  • Conversion by band: % of Cold/Warm/Hot that become meetings, opportunities, customers

For details on how to route high-scoring leads to the right rep—by territory, capacity, and schedule—see automated lead routing rules and best practices.

  • False positives: Hot leads that sales rejects repeatedly (tighten fit criteria)
  • False negatives: Cold/Warm leads that convert anyway (increase weight on that behavior)

Optimization cadence:

  • Review weekly for the first month
  • Then bi-weekly or monthly once stable

Small improvements that matter:

  • Add caps (e.g., email opens can’t inflate the score)
  • Add negative scoring (students, competitors, too-small companies)
  • Store scoring notes so reps understand why a lead is Hot

If you want a broader blueprint for CRM workflows beyond scoring, reference CRM automation complete guide for patterns you can reuse (routing, task creation, lifecycle updates).


Frequently Asked Questions

What is a good lead score?

A “good” score is one that reliably predicts the next step you care about (usually: booked meeting or qualified opportunity). Practically, set your bands so that:

  • Hot leads are a manageable number for sales to contact quickly (same day)
  • Warm leads get sequences + light SDR outreach
  • Cold leads stay in nurture until behavior changes

Start with simple thresholds like 70+ = Hot, 40–69 = Warm, then adjust based on conversion outcomes.

How often should lead scores update?

Use both:

  • Immediately for key actions (demo requests, pricing views, high-intent forms)
  • Daily for decay and cleanup (stale leads dropping a band)

This keeps the score accurate without overloading your system or creating noisy changes.

Can I score leads from multiple sources?

Yes. The cleanest pattern is to normalize all sources into a single intake format (webhook payload), then run one scoring workflow. Whether the lead comes from a landing page, Google Forms, a chat tool, or imports, you map the fields (email, title, company, event type) and apply the same rubric.

What data points should I use for scoring?

Use data points you can consistently capture and explain:

  • Fit: job title, company size, industry, region
  • Intent: demo request, pricing page views, case study views, product sheet downloads
  • Engagement: email clicks, replies, recency of activity

Avoid scoring on “nice but unreliable” signals if you can’t capture them cleanly or if they introduce bias.

How do I connect n8n to HubSpot?

Create a HubSpot Private App token, then add HubSpot credentials in n8n and use HubSpot nodes to search/create/update contacts. You typically need read/write scopes for contacts. After that, build a workflow that computes a score and updates HubSpot contact properties.

Does this work with HubSpot free tier?

It can work on the free tier for basic contact properties and updates, but availability of certain automation features and reporting varies by HubSpot plan. The safe approach is: store the score in a contact property and do the automation logic in n8n, then keep HubSpot workflows optional depending on your tier.


If you want help tailoring a scoring rubric to your sales process (and turning it into a maintainable n8n workflow with clean inputs, caps, decay rules, and Slack routing), you can Book a free automation consult.