Tutorial

How to Build n8n Lead Scoring with Search API Data

Build an n8n workflow that scores incoming leads using web search signals. Automated qualification based on company data, funding, and tech stack.

Lead scoring based on web search signals identifies which leads deserve immediate attention. Instead of scoring solely on form data (job title, company size), you can enrich each lead with live search data about their company -- funding status, tech stack, hiring activity, and growth signals -- then score based on that context. This tutorial builds an n8n workflow that receives leads via webhook, enriches them with search API data, calculates a qualification score, and routes high-scoring leads to your sales team. Each enrichment costs $0.005-0.015 via Scavio.

Prerequisites

  • n8n instance running (self-hosted or cloud)
  • A Scavio API key from scavio.dev
  • A webhook URL to receive leads (or manual trigger for testing)
  • Slack or email for lead notifications

Walkthrough

Step 1: Set up the lead intake webhook

Create an n8n webhook that receives new leads. This can connect to your form tool, CRM, or any system that generates leads.

JavaScript
// n8n Webhook node configuration:
// HTTP Method: POST
// Path: /score-lead
// Response Mode: Last Node
//
// Expected payload:
// {
//   "company": "Acme Corp",
//   "domain": "acme.com",
//   "contact_name": "John Doe",
//   "email": "john@acme.com",
//   "job_title": "VP Engineering"
// }

// Test with curl:
// curl -X POST http://your-n8n:5678/webhook/score-lead \
//   -H 'Content-Type: application/json' \
//   -d '{"company": "Acme Corp", "domain": "acme.com"}'

Step 2: Enrich with company search data

Search for the company to find recent news, funding, and general information. Use two targeted searches for maximum signal extraction.

JSON
// HTTP Request node 1 - Company overview:
// POST https://api.scavio.dev/api/v1/search
// Headers: x-api-key: {{ $env.SCAVIO_API_KEY }}
// Body:
{
  "query": "{{ $json.company }} company overview funding",
  "country_code": "us"
}

// HTTP Request node 2 - Hiring signals:
// Body:
{
  "query": "{{ $json.company }} hiring OR jobs OR careers 2026",
  "country_code": "us"
}

// HTTP Request node 3 - Tech stack (optional, +1 credit):
// Body:
{
  "query": "site:{{ $json.domain }} technology OR stack OR platform",
  "country_code": "us"
}

Step 3: Extract scoring signals from search results

Parse the search results to identify growth signals, funding status, company size, and technology usage. Each signal contributes to the lead score.

JavaScript
// n8n Code node - Extract and score signals:
const overview = $('HTTP Request - Overview').first().json;
const hiring = $('HTTP Request - Hiring').first().json;

const overviewText = (overview.organic_results || [])
  .map(r => `${r.title} ${r.snippet || ''}`).join(' ').toLowerCase();
const hiringText = (hiring.organic_results || [])
  .map(r => `${r.title} ${r.snippet || ''}`).join(' ').toLowerCase();

const signals = {
  hasFunding: /series [a-d]|raised|funding|venture/.test(overviewText),
  isHiring: (hiring.organic_results || []).length > 3,
  isSaaS: /saas|software|platform|cloud/.test(overviewText),
  hasGrowth: /growing|growth|expanding|scaling/.test(overviewText),
  seniorTitle: /vp|director|head|chief|cto|ceo/.test(
    ($input.first().json.job_title || '').toLowerCase()),
  hasWebsite: Boolean($input.first().json.domain),
};

return [{ json: { ...$input.first().json, signals } }];

Step 4: Calculate the composite lead score

Assign point values to each signal and compute a total score. Route leads based on score thresholds.

JavaScript
// n8n Code node - Calculate score:
const signals = $json.signals;
const weights = {
  hasFunding: 25,
  isHiring: 20,
  isSaaS: 15,
  hasGrowth: 15,
  seniorTitle: 15,
  hasWebsite: 10,
};

let score = 0;
const matchedSignals = [];
for (const [signal, points] of Object.entries(weights)) {
  if (signals[signal]) {
    score += points;
    matchedSignals.push(`${signal}: +${points}`);
  }
}

const tier = score >= 70 ? 'HOT' : score >= 40 ? 'WARM' : 'COLD';

return [{
  json: {
    ...$json,
    score,
    tier,
    matchedSignals,
    enrichmentCost: '$0.010'  // 2 search queries
  }
}];

Step 5: Route and notify based on score

Use an n8n Switch node to route leads by tier. Hot leads go to Slack immediately, warm leads to a review queue, cold leads to nurture.

JavaScript
// Switch node on $json.tier:
// HOT -> Slack notification + CRM "Hot Lead" pipeline
// WARM -> CRM "Review" pipeline
// COLD -> CRM "Nurture" sequence

// Slack node for HOT leads:
// Channel: #sales-alerts
// Message:
// *HOT LEAD* (Score: {{ $json.score }}/100)
// Company: {{ $json.company }}
// Contact: {{ $json.contact_name }} ({{ $json.job_title }})
// Signals: {{ $json.matchedSignals.join(', ') }}
// Enrichment cost: {{ $json.enrichmentCost }}

// Cost summary:
// 2-3 search queries per lead = $0.010-0.015
// 100 leads/day = $1.00-1.50/day
// 3000 leads/month = $30-45/month ($30 plan covers it)

Python Example

Python
import os, requests, re

API_KEY = os.environ['SCAVIO_API_KEY']

def search(query):
    resp = requests.post('https://api.scavio.dev/api/v1/search',
        headers={'x-api-key': API_KEY, 'Content-Type': 'application/json'},
        json={'query': query, 'country_code': 'us'})
    return resp.json()

def score_lead(company, domain='', title=''):
    overview = search(f'{company} company funding')
    text = ' '.join(r.get('snippet', '') for r in overview.get('organic_results', [])).lower()
    score = 0
    if re.search(r'series [a-d]|raised|funding', text): score += 25
    if re.search(r'saas|software|platform', text): score += 15
    if re.search(r'growing|scaling', text): score += 15
    if re.search(r'vp|director|head|chief', title.lower()): score += 15
    if domain: score += 10
    tier = 'HOT' if score >= 70 else 'WARM' if score >= 40 else 'COLD'
    return {'company': company, 'score': score, 'tier': tier}

for company in ['Stripe', 'Local Bakery LLC']:
    result = score_lead(company)
    print(f'{result["company"]}: {result["score"]}/100 ({result["tier"]})')

JavaScript Example

JavaScript
const API_KEY = process.env.SCAVIO_API_KEY;

async function search(query) {
  const resp = await fetch('https://api.scavio.dev/api/v1/search', {
    method: 'POST',
    headers: { 'x-api-key': API_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ query, country_code: 'us' })
  });
  return resp.json();
}

async function scoreLead(company) {
  const data = await search(`${company} company funding`);
  const text = (data.organic_results || []).map(r => r.snippet || '').join(' ').toLowerCase();
  let score = 0;
  if (/series [a-d]|raised|funding/.test(text)) score += 25;
  if (/saas|software|platform/.test(text)) score += 15;
  if (/growing|scaling/.test(text)) score += 15;
  const tier = score >= 70 ? 'HOT' : score >= 40 ? 'WARM' : 'COLD';
  console.log(`${company}: ${score}/100 (${tier})`);
}

Promise.all(['Stripe', 'Local Bakery'].map(scoreLead));

Expected Output

JSON
Stripe: 55/100 (WARM)
  hasFunding: +25
  isSaaS: +15
  hasGrowth: +15

Local Bakery LLC: 0/100 (COLD)
  (no signals matched)

Cost: $0.010 per lead (2 searches)
100 leads/day = $1.00/day, $30/month

Related Tutorials

Frequently Asked Questions

Most developers complete this tutorial in 15 to 30 minutes. You will need a Scavio API key (free tier works) and a working Python or JavaScript environment.

n8n instance running (self-hosted or cloud). A Scavio API key from scavio.dev. A webhook URL to receive leads (or manual trigger for testing). Slack or email for lead notifications. A Scavio API key gives you 250 free credits per month.

Yes. The free tier includes 250 credits per month, which is more than enough to complete this tutorial and prototype a working solution.

Scavio has a native LangChain package (langchain-scavio), an MCP server, and a plain REST API that works with any HTTP client. This tutorial uses the raw REST API, but you can adapt to your framework of choice.

Start Building

Build an n8n workflow that scores incoming leads using web search signals. Automated qualification based on company data, funding, and tech stack.