CrawlForge
HomePlaygroundUse CasesIntegrationsPricingDocumentationBlog
Build a Lead Enrichment Engine with CrawlForge
Use Cases
Back to Blog
Use Cases

Build a Lead Enrichment Engine with CrawlForge

C
CrawlForge Team
Engineering Team
April 14, 2026
10 min read

On this page

Your sales team gets 200 new leads per week. Each lead arrives as a name, email, and maybe a company name. Before a rep can make a meaningful outreach, they need to research the company's size, tech stack, recent news, and potential fit. That research takes 10-15 minutes per lead -- over 30 hours per week spent on Google and LinkedIn instead of selling.

Lead enrichment automates this research. CrawlForge scrapes public business data from company websites, social profiles, and news sources to build a complete lead profile in seconds. This guide shows you how to build a lead enrichment engine that processes 200+ leads per hour.

Table of Contents

  • What Is Lead Enrichment
  • Architecture Overview
  • Step 1: Company Website Analysis
  • Step 2: Technology Stack Detection
  • Step 3: Company Intelligence Gathering
  • Step 4: Build the Enrichment Pipeline
  • Credit Cost Analysis
  • Results and Benefits
  • Frequently Asked Questions

What Is Lead Enrichment

Lead enrichment is the process of supplementing basic lead data (name, email, company) with additional information that helps sales teams qualify and prioritize prospects. Enriched data typically includes:

Data PointSourceSales Value
Company sizeAbout/team pageQualification
IndustryWebsite contentSegmentation
Tech stackPage source analysisProduct fit
Recent newsSearch resultsConversation starters
Funding statusPress releasesBudget signals
Content topicsBlog analysisPain point mapping

What is lead enrichment? It is the automated process of appending business intelligence data to raw lead records, transforming a basic email address into a comprehensive prospect profile that sales teams can act on immediately.

CrawlForge is best for lead enrichment teams that need real-time data from company websites, because unlike database providers (ZoomInfo, Clearbit) that can be weeks out of date, CrawlForge scrapes live pages for current information.

Architecture Overview

The enrichment engine uses five CrawlForge tools:

ComponentToolCreditsPurpose
Website contentextract_content2Company description and positioning
Metadataextract_metadata1Title, description, social profiles
Page sourcefetch_url1Detect technologies from HTML
Company researchsearch_web5Recent news, funding, social
Analysisanalyze_content3Industry classification and topics

Step 1: Company Website Analysis

Start by extracting core company information from their website.

Typescript
import { Client } from '@modelcontextprotocol/sdk/client/index.js';

const client = new Client({
  name: 'lead-enrichment',
  version: '1.0.0',
});

interface CompanyProfile {
  domain: string;
  name: string;
  description: string;
  industry: string;
  topics: string[];
  socialLinks: {
    twitter?: string;
    linkedin?: string;
    github?: string;
  };
  estimatedSize: string;
}

async function analyzeCompanyWebsite(
  domain: string
): Promise<CompanyProfile> {
  // Extract main page content
  const contentResult = await client.callTool({
    name: 'extract_content',
    arguments: { url: `https://${domain}` },
  });

  const content = JSON.parse(contentResult.content[0].text);

  // Get metadata including social links
  const metaResult = await client.callTool({
    name: 'extract_metadata',
    arguments: { url: `https://${domain}` },
  });

  const meta = JSON.parse(metaResult.content[0].text);

  // Analyze content for industry and topics
  const analysis = await client.callTool({
    name: 'analyze_content',
    arguments: { text: content.content },
  });

  const analyzed = JSON.parse(analysis.content[0].text);

  // Try to get team page for company size estimation
  let estimatedSize = 'Unknown';
  try {
    const teamPage = await client.callTool({
      name: 'extract_content',
      arguments: { url: `https://${domain}/about` },
    });
    const teamContent = JSON.parse(teamPage.content[0].text);
    // Simple heuristic: count mentions of team-related terms
    const teamMentions = (teamContent.content.match(/team|employee|people|staff/gi) || []).length;
    if (teamMentions > 20) estimatedSize = '100+';
    else if (teamMentions > 10) estimatedSize = '50-100';
    else if (teamMentions > 5) estimatedSize = '10-50';
    else estimatedSize = '1-10';
  } catch {
    // About page might not exist; that is fine
  }

  return {
    domain,
    name: meta.title?.split(/[|\-]/)[0]?.trim() || domain,
    description: meta.description || analyzed.summary || '',
    industry: analyzed.topics?.[0] || 'Unknown',
    topics: analyzed.topics || [],
    socialLinks: {
      twitter: meta.twitterHandle,
      linkedin: meta.linkedinUrl,
      github: meta.githubUrl,
    },
    estimatedSize,
  };
}

Step 2: Technology Stack Detection

Detect the technologies a company uses by analyzing their website's HTML source and headers.

Typescript
interface TechStack {
  frontend: string[];
  analytics: string[];
  marketing: string[];
  infrastructure: string[];
  cms: string[];
}

async function detectTechStack(domain: string): Promise<TechStack> {
  const result = await client.callTool({
    name: 'fetch_url',
    arguments: {
      url: `https://${domain}`,
      timeout: 10000,
    },
  });

  const page = JSON.parse(result.content[0].text);
  const html = page.body || '';
  const headers = page.headers || {};

  const stack: TechStack = {
    frontend: [],
    analytics: [],
    marketing: [],
    infrastructure: [],
    cms: [],
  };

  // Frontend framework detection
  if (html.includes('__next') || html.includes('_next/static')) {
    stack.frontend.push('Next.js');
  }
  if (html.includes('__nuxt')) stack.frontend.push('Nuxt.js');
  if (html.includes('react')) stack.frontend.push('React');
  if (html.includes('vue')) stack.frontend.push('Vue.js');
  if (html.includes('tailwindcss') || html.includes('tailwind')) {
    stack.frontend.push('Tailwind CSS');
  }

  // Analytics detection
  if (html.includes('gtag') || html.includes('google-analytics')) {
    stack.analytics.push('Google Analytics');
  }
  if (html.includes('segment.com') || html.includes('analytics.js')) {
    stack.analytics.push('Segment');
  }
  if (html.includes('mixpanel')) stack.analytics.push('Mixpanel');
  if (html.includes('hotjar')) stack.analytics.push('Hotjar');

  // Marketing tools
  if (html.includes('hubspot')) stack.marketing.push('HubSpot');
  if (html.includes('intercom')) stack.marketing.push('Intercom');
  if (html.includes('drift')) stack.marketing.push('Drift');
  if (html.includes('mailchimp')) stack.marketing.push('Mailchimp');

  // Infrastructure
  const server = headers['server'] || headers['x-powered-by'] || '';
  if (server.includes('Vercel') || html.includes('vercel')) {
    stack.infrastructure.push('Vercel');
  }
  if (server.includes('cloudflare') || headers['cf-ray']) {
    stack.infrastructure.push('Cloudflare');
  }
  if (html.includes('amazonaws')) stack.infrastructure.push('AWS');

  // CMS
  if (html.includes('wp-content')) stack.cms.push('WordPress');
  if (html.includes('shopify')) stack.cms.push('Shopify');
  if (html.includes('webflow')) stack.cms.push('Webflow');

  return stack;
}

This detection runs on a single fetch_url call (1 credit) -- making it extremely cost-efficient for bulk lead enrichment.

Step 3: Company Intelligence Gathering

Use search_web to find recent news, funding announcements, and market context.

Typescript
interface CompanyIntel {
  recentNews: Array<{ title: string; url: string; snippet: string }>;
  fundingInfo: string;
  competitorMentions: string[];
}

async function gatherIntelligence(
  companyName: string,
  domain: string
): Promise<CompanyIntel> {
  // Search for recent company news
  const newsResult = await client.callTool({
    name: 'search_web',
    arguments: {
      query: `"${companyName}" OR "${domain}" news funding`,
      limit: 10,
      time_range: 'month',
    },
  });

  const news = JSON.parse(newsResult.content[0].text);

  return {
    recentNews: (news.results || []).slice(0, 5).map(
      (r: { title: string; url: string; snippet: string }) => ({
        title: r.title,
        url: r.url,
        snippet: r.snippet,
      })
    ),
    fundingInfo: news.results?.find(
      (r: { title: string }) =>
        r.title.toLowerCase().includes('funding') ||
        r.title.toLowerCase().includes('raises') ||
        r.title.toLowerCase().includes('series')
    )?.snippet || 'No recent funding news found',
    competitorMentions: news.results
      ?.filter((r: { title: string }) =>
        r.title.toLowerCase().includes('vs') ||
        r.title.toLowerCase().includes('alternative')
      )
      .map((r: { title: string }) => r.title) || [],
  };
}

Step 4: Build the Enrichment Pipeline

Combine all enrichment steps into a single pipeline that processes leads in bulk.

Typescript
interface Lead {
  email: string;
  name: string;
  company?: string;
}

interface EnrichedLead extends Lead {
  companyProfile: CompanyProfile;
  techStack: TechStack;
  intelligence: CompanyIntel;
  enrichedAt: string;
  qualityScore: number;
}

function extractDomain(email: string): string {
  return email.split('@')[1];
}

function calculateLeadScore(enriched: Omit<EnrichedLead, 'qualityScore'>): number {
  let score = 0;

  // Company has a real website with content
  if (enriched.companyProfile.description.length > 50) score += 20;

  // Company uses modern tech stack (potential product fit)
  if (enriched.techStack.frontend.length > 0) score += 15;

  // Company uses analytics/marketing tools (signals budget)
  if (enriched.techStack.analytics.length > 0) score += 10;
  if (enriched.techStack.marketing.length > 0) score += 15;

  // Recent news/activity
  if (enriched.intelligence.recentNews.length > 0) score += 10;

  // Funding signals
  if (!enriched.intelligence.fundingInfo.includes('No recent')) score += 20;

  // Company size signals
  const size = enriched.companyProfile.estimatedSize;
  if (size === '50-100' || size === '100+') score += 10;

  return Math.min(score, 100);
}

async function enrichLeads(leads: Lead[]): Promise<EnrichedLead[]> {
  const enriched: EnrichedLead[] = [];

  for (const lead of leads) {
    const domain = lead.company
      ? lead.company.toLowerCase().replace(/\s+/g, '') + '.com'
      : extractDomain(lead.email);

    // Skip free email providers
    if (['gmail.com', 'yahoo.com', 'hotmail.com', 'outlook.com'].includes(domain)) {
      continue;
    }

    try {
      console.log(`Enriching ${lead.email} (${domain})...`);

      const companyProfile = await analyzeCompanyWebsite(domain);
      const techStack = await detectTechStack(domain);
      const intelligence = await gatherIntelligence(
        companyProfile.name,
        domain
      );

      const partial = {
        ...lead,
        companyProfile,
        techStack,
        intelligence,
        enrichedAt: new Date().toISOString(),
      };

      enriched.push({
        ...partial,
        qualityScore: calculateLeadScore(partial),
      });
    } catch (error) {
      console.error(`Failed to enrich ${lead.email}:`, error);
    }
  }

  // Sort by quality score (highest first)
  return enriched.sort((a, b) => b.qualityScore - a.qualityScore);
}

Credit Cost Analysis

Per-lead enrichment cost:

OperationToolCredits
Website contentextract_content2
About pageextract_content2
Metadataextract_metadata1
Tech detectionfetch_url1
Content analysisanalyze_content3
News searchsearch_web5
Per lead14 credits

Monthly cost at scale:

VolumeCredits/MonthRecommended Plan
50 leads/month700Free tier (1,000 credits)
200 leads/month2,800Hobby ($19/mo, 5,000 credits)
1,000 leads/month14,000Professional ($99/mo, 50,000 credits)
5,000+ leads/month70,000Business ($399/mo, custom credits)

Results and Benefits

A lead enrichment engine with CrawlForge delivers:

  • Speed: Enrich a lead in 15-30 seconds instead of 10-15 minutes
  • Consistency: Every lead gets the same depth of research
  • Prioritization: Quality scores let reps focus on the highest-value leads first
  • Cost efficiency: $0.07-0.13 per lead vs. $0.50-2.00 for database providers

Compared to enrichment database providers like Clearbit ($99/mo for 1,000 lookups) or ZoomInfo ($15,000+/year), CrawlForge delivers current data at a fraction of the cost. The trade-off is that CrawlForge scrapes live data (always current) while databases provide pre-structured fields (less processing needed).

Frequently Asked Questions

How accurate is tech stack detection from HTML?

HTML-based detection catches the most popular tools with high accuracy (90%+) for client-side technologies. Server-side technologies are harder to detect. For comprehensive detection, combine CrawlForge with BuiltWith or Wappalyzer data.

Can I enrich leads from personal email domains?

Leads from gmail.com or outlook.com do not have company domains to analyze. For these, use search_web to find their professional profiles based on name. This costs 5 credits per lookup instead of the full 14-credit pipeline.

How do I handle rate limiting when enriching in bulk?

CrawlForge's batch_scrape tool handles rate limiting automatically. For individual calls, add a 500ms delay between requests to the same domain. Process different domains in parallel for maximum throughput.


Enrich your first 50 leads free. Start with 1,000 credits -- enough to fully enrich 70+ leads with no credit card required.

Related resources:

  • CrawlForge Documentation
  • Competitive Intelligence with AI Agents
  • E-commerce Data Extraction
  • Pricing Plans

Try this yourself — no signup needed

Run any of CrawlForge's 27 scraping and extraction tools in the playground, then start free with 1,000 credits.

1,000 free credits • Refills monthly • No credit card required

Tags

lead-enrichmentsalesweb-scrapingautomationcrmb2bmcp

About the Author

C

CrawlForge Team

Engineering Team

Building the most comprehensive web scraping MCP server. We create tools that help developers extract, analyze, and transform web data for AI applications.

Stay updated with the latest insights

Get tutorials, product updates, and web scraping tips delivered to your inbox.

No spam. Unsubscribe anytime.

Put this into practice

Test CrawlForge's tools on any URL — free, no signup.

On this page

Related Articles

Build a Research Agent with CrawlForge Deep Research
Use Cases

Build a Research Agent with CrawlForge Deep Research

Create an AI research agent that gathers, verifies, and synthesizes information from dozens of sources in minutes using CrawlForge deep_research.

C
CrawlForge Team
|
Apr 16
|
10m
Content Migration Automation with CrawlForge
Use Cases

Content Migration Automation with CrawlForge

Migrate website content between CMS platforms automatically. Extract pages, preserve structure, and rebuild content in your new system without rewrites.

C
CrawlForge Team
|
Apr 12
|
9m
Real-Time Competitive Intelligence with AI Agents
Use Cases

Real-Time Competitive Intelligence with AI Agents

Build an AI-powered competitive intelligence system using CrawlForge and Claude. Monitor competitors, track changes, and generate strategic insights weekly.

C
CrawlForge Team
|
Apr 8
|
9m

Footer

CrawlForge

Enterprise web scraping for AI Agents. 27 specialized MCP tools designed for modern developers building intelligent systems.

Product

  • Features
  • Playground
  • Pricing
  • Use Cases
  • Integrations
  • Alternatives
  • Changelog

Resources

  • Getting Started
  • API Reference
  • Templates
  • Guides
  • Blog
  • Glossary
  • FAQ
  • Sitemap

Developers

  • MCP Protocol
  • Claude Desktop
  • Cursor IDE
  • LangChain
  • LlamaIndex

Company

  • About
  • Contact
  • Privacy
  • Terms
  • Acceptable Use
  • Cookies

Stay updated

Get the latest updates on new tools and features.

Built with Next.js and MCP protocol

© 2025-2026 CrawlForge. All rights reserved.