Lead Quality Score

Quantitative assessment of lead conversion potential based on demographics, behavior, and engagement

Overview

Lead Quality Score is a quantitative assessment that predicts the likelihood of a lead converting to a customer. This composite metric combines demographic information, behavioral data, engagement patterns, and firmographic details to prioritize sales efforts and improve conversion rates.

By scoring leads systematically, sales teams can focus their time on the most promising prospects, marketing can optimize targeting strategies, and businesses can improve overall conversion efficiency and revenue predictability.

Formula:
Lead Score = Weighted Sum of (Demographic Score + Behavioral Score + Engagement Score + Firmographic Score)

80-100

Hot Lead

Immediate Contact

60-79

Warm Lead

Priority Follow-up

40-59

Qualified Lead

Standard Process

0-39

Cold Lead

Nurture Campaign

Demographics

Job title, seniority, company

Behavior

Website activity, content engagement

Engagement

Email opens, clicks, responses

Firmographics

Company size, industry, revenue

Model Calibration

Regularly validate and recalibrate scoring models using historical conversion data to maintain accuracy and relevance as market conditions change.

Why It Matters

  • Sales Efficiency: Prioritizes high-potential leads for maximum conversion
  • Resource Optimization: Allocates sales efforts to most promising opportunities
  • Marketing Alignment: Improves marketing-sales handoff and collaboration
  • Conversion Rates: Increases overall lead-to-customer conversion
  • Revenue Predictability: Enables better forecasting and planning
  • Customer Quality: Attracts higher-value prospects

How to Measure It

Calculate lead quality scores by combining multiple data points with appropriate weights based on their correlation with conversion rates, validated through historical performance analysis.

Basic Lead Scoring Model

-- Calculate comprehensive lead quality scores
WITH lead_demographics AS (
  SELECT 
    lead_id,
    email,
    job_title,
    seniority_level,
    department,
    CASE 
      WHEN seniority_level IN ('C-Level', 'VP', 'Director') THEN 25
      WHEN seniority_level IN ('Manager', 'Senior Manager') THEN 20
      WHEN seniority_level IN ('Individual Contributor', 'Specialist') THEN 10
      ELSE 5
    END as demographic_score
  FROM leads l
  JOIN lead_enrichment le ON l.lead_id = le.lead_id
),
lead_firmographics AS (
  SELECT 
    lead_id,
    company_size,
    industry,
    annual_revenue,
    CASE 
      WHEN company_size >= 1000 THEN 20
      WHEN company_size >= 100 THEN 15
      WHEN company_size >= 50 THEN 10
      ELSE 5
    END +
    CASE 
      WHEN industry IN ('Technology', 'Financial Services', 'Healthcare') THEN 15
      WHEN industry IN ('Manufacturing', 'Retail', 'Education') THEN 10
      ELSE 5
    END +
    CASE 
      WHEN annual_revenue >= 100000000 THEN 15  -- $100M+
      WHEN annual_revenue >= 10000000 THEN 10   -- $10M+
      WHEN annual_revenue >= 1000000 THEN 5     -- $1M+
      ELSE 0
    END as firmographic_score
  FROM company_data cd
  JOIN leads l ON cd.company_id = l.company_id
),
lead_behavior AS (
  SELECT 
    lead_id,
    COUNT(DISTINCT page_url) as pages_visited,
    COUNT(*) as total_page_views,
    MAX(session_duration_minutes) as max_session_duration,
    COUNT(DISTINCT CASE WHEN page_type = 'pricing' THEN page_url END) as pricing_page_views,
    COUNT(DISTINCT CASE WHEN page_type = 'demo' THEN page_url END) as demo_page_views,
    COUNT(DISTINCT CASE WHEN page_type = 'case_study' THEN page_url END) as case_study_views,
    CASE 
      WHEN COUNT(DISTINCT page_url) >= 10 THEN 15
      WHEN COUNT(DISTINCT page_url) >= 5 THEN 10
      WHEN COUNT(DISTINCT page_url) >= 3 THEN 5
      ELSE 0
    END +
    CASE 
      WHEN COUNT(DISTINCT CASE WHEN page_type = 'pricing' THEN page_url END) > 0 THEN 10
      ELSE 0
    END +
    CASE 
      WHEN COUNT(DISTINCT CASE WHEN page_type = 'demo' THEN page_url END) > 0 THEN 15
      ELSE 0
    END +
    CASE 
      WHEN MAX(session_duration_minutes) >= 10 THEN 10
      WHEN MAX(session_duration_minutes) >= 5 THEN 5
      ELSE 0
    END as behavioral_score
  FROM website_activity
  WHERE activity_date >= CURRENT_DATE - INTERVAL '30 days'
  GROUP BY lead_id
),
lead_engagement AS (
  SELECT 
    lead_id,
    COUNT(CASE WHEN action_type = 'email_open' THEN 1 END) as email_opens,
    COUNT(CASE WHEN action_type = 'email_click' THEN 1 END) as email_clicks,
    COUNT(CASE WHEN action_type = 'form_submission' THEN 1 END) as form_submissions,
    COUNT(CASE WHEN action_type = 'content_download' THEN 1 END) as content_downloads,
    COUNT(CASE WHEN action_type = 'webinar_attendance' THEN 1 END) as webinar_attendance,
    CASE 
      WHEN COUNT(CASE WHEN action_type = 'email_click' THEN 1 END) >= 3 THEN 20
      WHEN COUNT(CASE WHEN action_type = 'email_click' THEN 1 END) >= 1 THEN 10
      ELSE 0
    END +
    CASE 
      WHEN COUNT(CASE WHEN action_type = 'form_submission' THEN 1 END) >= 2 THEN 15
      WHEN COUNT(CASE WHEN action_type = 'form_submission' THEN 1 END) >= 1 THEN 10
      ELSE 0
    END +
    CASE 
      WHEN COUNT(CASE WHEN action_type = 'content_download' THEN 1 END) >= 2 THEN 10
      WHEN COUNT(CASE WHEN action_type = 'content_download' THEN 1 END) >= 1 THEN 5
      ELSE 0
    END +
    CASE 
      WHEN COUNT(CASE WHEN action_type = 'webinar_attendance' THEN 1 END) > 0 THEN 15
      ELSE 0
    END as engagement_score
  FROM lead_activities
  WHERE activity_date >= CURRENT_DATE - INTERVAL '30 days'
  GROUP BY lead_id
),
lead_scores AS (
  SELECT 
    l.lead_id,
    l.email,
    l.created_date,
    l.source,
    COALESCE(ld.demographic_score, 0) as demographic_score,
    COALESCE(lf.firmographic_score, 0) as firmographic_score,
    COALESCE(lb.behavioral_score, 0) as behavioral_score,
    COALESCE(le.engagement_score, 0) as engagement_score,
    COALESCE(ld.demographic_score, 0) + 
    COALESCE(lf.firmographic_score, 0) + 
    COALESCE(lb.behavioral_score, 0) + 
    COALESCE(le.engagement_score, 0) as total_lead_score,
    lb.pages_visited,
    lb.pricing_page_views,
    lb.demo_page_views,
    le.email_clicks,
    le.form_submissions
  FROM leads l
  LEFT JOIN lead_demographics ld ON l.lead_id = ld.lead_id
  LEFT JOIN lead_firmographics lf ON l.lead_id = lf.lead_id
  LEFT JOIN lead_behavior lb ON l.lead_id = lb.lead_id
  LEFT JOIN lead_engagement le ON l.lead_id = le.lead_id
)
SELECT 
  lead_id,
  email,
  source,
  demographic_score,
  firmographic_score,
  behavioral_score,
  engagement_score,
  total_lead_score,
  CASE 
    WHEN total_lead_score >= 80 THEN 'Hot'
    WHEN total_lead_score >= 60 THEN 'Warm'
    WHEN total_lead_score >= 40 THEN 'Qualified'
    ELSE 'Cold'
  END as lead_grade,
  pages_visited,
  pricing_page_views,
  demo_page_views,
  email_clicks,
  form_submissions,
  RANK() OVER (ORDER BY total_lead_score DESC) as score_rank
FROM lead_scores
ORDER BY total_lead_score DESC;

Predictive Scoring with Historical Data

-- Analyze scoring accuracy and optimize weights
WITH historical_conversions AS (
  SELECT 
    ls.lead_id,
    ls.total_lead_score,
    ls.demographic_score,
    ls.firmographic_score,
    ls.behavioral_score,
    ls.engagement_score,
    ls.lead_grade,
    CASE 
      WHEN o.opportunity_id IS NOT NULL THEN 1 
      ELSE 0 
    END as converted,
    CASE 
      WHEN o.opportunity_id IS NOT NULL AND o.stage = 'Closed Won' THEN 1 
      ELSE 0 
    END as closed_won,
    o.opportunity_value,
    EXTRACT(days FROM AGE(o.created_date, ls.created_date)) as days_to_opportunity
  FROM lead_scores ls
  LEFT JOIN opportunities o ON ls.lead_id = o.lead_id
  WHERE ls.created_date >= CURRENT_DATE - INTERVAL '6 months'
),
score_performance AS (
  SELECT 
    lead_grade,
    COUNT(*) as total_leads,
    SUM(converted) as converted_leads,
    SUM(closed_won) as won_deals,
    ROUND(100.0 * SUM(converted) / COUNT(*), 1) as conversion_rate,
    ROUND(100.0 * SUM(closed_won) / COUNT(*), 1) as win_rate,
    ROUND(AVG(opportunity_value), 0) as avg_deal_size,
    ROUND(AVG(days_to_opportunity), 1) as avg_days_to_opportunity,
    SUM(opportunity_value) as total_pipeline_value
  FROM historical_conversions
  GROUP BY lead_grade
),
score_distribution AS (
  SELECT 
    CASE 
      WHEN total_lead_score >= 90 THEN '90-100'
      WHEN total_lead_score >= 80 THEN '80-89'
      WHEN total_lead_score >= 70 THEN '70-79'
      WHEN total_lead_score >= 60 THEN '60-69'
      WHEN total_lead_score >= 50 THEN '50-59'
      WHEN total_lead_score >= 40 THEN '40-49'
      WHEN total_lead_score >= 30 THEN '30-39'
      WHEN total_lead_score >= 20 THEN '20-29'
      WHEN total_lead_score >= 10 THEN '10-19'
      ELSE '0-9'
    END as score_range,
    COUNT(*) as leads_in_range,
    ROUND(100.0 * SUM(converted) / COUNT(*), 1) as range_conversion_rate,
    ROUND(AVG(total_lead_score), 1) as avg_score_in_range
  FROM historical_conversions
  GROUP BY 1
  ORDER BY MIN(total_lead_score) DESC
)
SELECT 
  sp.lead_grade,
  sp.total_leads,
  sp.converted_leads,
  sp.conversion_rate,
  sp.win_rate,
  sp.avg_deal_size,
  sp.avg_days_to_opportunity,
  sp.total_pipeline_value,
  RANK() OVER (ORDER BY sp.conversion_rate DESC) as conversion_rank
FROM score_performance sp
ORDER BY sp.conversion_rate DESC;

Score Optimization Analysis

-- Analyze individual scoring components for optimization
WITH component_analysis AS (
  SELECT 
    hc.lead_id,
    hc.converted,
    hc.demographic_score,
    hc.firmographic_score,
    hc.behavioral_score,
    hc.engagement_score,
    CASE WHEN hc.demographic_score >= 20 THEN 1 ELSE 0 END as high_demo_score,
    CASE WHEN hc.firmographic_score >= 20 THEN 1 ELSE 0 END as high_firm_score,
    CASE WHEN hc.behavioral_score >= 20 THEN 1 ELSE 0 END as high_behavior_score,
    CASE WHEN hc.engagement_score >= 20 THEN 1 ELSE 0 END as high_engagement_score
  FROM historical_conversions hc
),
component_correlations AS (
  SELECT 
    'Demographic' as component,
    ROUND(CORR(demographic_score, converted::numeric), 3) as correlation_with_conversion,
    ROUND(100.0 * SUM(CASE WHEN high_demo_score = 1 THEN converted ELSE 0 END) / 
      NULLIF(SUM(high_demo_score), 0), 1) as high_score_conversion_rate,
    ROUND(100.0 * SUM(CASE WHEN high_demo_score = 0 THEN converted ELSE 0 END) / 
      NULLIF(SUM(CASE WHEN high_demo_score = 0 THEN 1 ELSE 0 END), 0), 1) as low_score_conversion_rate
  FROM component_analysis
  
  UNION ALL
  
  SELECT 
    'Firmographic' as component,
    ROUND(CORR(firmographic_score, converted::numeric), 3) as correlation_with_conversion,
    ROUND(100.0 * SUM(CASE WHEN high_firm_score = 1 THEN converted ELSE 0 END) / 
      NULLIF(SUM(high_firm_score), 0), 1) as high_score_conversion_rate,
    ROUND(100.0 * SUM(CASE WHEN high_firm_score = 0 THEN converted ELSE 0 END) / 
      NULLIF(SUM(CASE WHEN high_firm_score = 0 THEN 1 ELSE 0 END), 0), 1) as low_score_conversion_rate
  FROM component_analysis
  
  UNION ALL
  
  SELECT 
    'Behavioral' as component,
    ROUND(CORR(behavioral_score, converted::numeric), 3) as correlation_with_conversion,
    ROUND(100.0 * SUM(CASE WHEN high_behavior_score = 1 THEN converted ELSE 0 END) / 
      NULLIF(SUM(high_behavior_score), 0), 1) as high_score_conversion_rate,
    ROUND(100.0 * SUM(CASE WHEN high_behavior_score = 0 THEN converted ELSE 0 END) / 
      NULLIF(SUM(CASE WHEN high_behavior_score = 0 THEN 1 ELSE 0 END), 0), 1) as low_score_conversion_rate
  FROM component_analysis
  
  UNION ALL
  
  SELECT 
    'Engagement' as component,
    ROUND(CORR(engagement_score, converted::numeric), 3) as correlation_with_conversion,
    ROUND(100.0 * SUM(CASE WHEN high_engagement_score = 1 THEN converted ELSE 0 END) / 
      NULLIF(SUM(high_engagement_score), 0), 1) as high_score_conversion_rate,
    ROUND(100.0 * SUM(CASE WHEN high_engagement_score = 0 THEN converted ELSE 0 END) / 
      NULLIF(SUM(CASE WHEN high_engagement_score = 0 THEN 1 ELSE 0 END), 0), 1) as low_score_conversion_rate
  FROM component_analysis
)
SELECT 
  component,
  correlation_with_conversion,
  high_score_conversion_rate,
  low_score_conversion_rate,
  ROUND(high_score_conversion_rate - low_score_conversion_rate, 1) as conversion_lift,
  RANK() OVER (ORDER BY ABS(correlation_with_conversion) DESC) as predictive_power_rank
FROM component_correlations
ORDER BY ABS(correlation_with_conversion) DESC;

Scoring Best Practices

Use historical conversion data to validate scoring weights, implement decay for time-sensitive behaviors, and regularly A/B test different scoring models to optimize performance.

Best Practices

1. Data Foundation

  • Ensure comprehensive data collection across all touchpoints
  • Implement proper data hygiene and deduplication
  • Enrich lead data with third-party sources
  • Maintain data quality through validation rules

2. Model Development

  • Base weights on historical conversion analysis
  • Include both explicit and implicit scoring factors
  • Account for negative scoring for disqualifying factors
  • Implement time decay for behavioral activities

3. Implementation Strategy

  • Gradual Rollout: Start with simple models and add complexity
  • Sales Training: Educate teams on score interpretation
  • Threshold Setting: Define clear action triggers for each score range
  • Feedback Loop: Capture sales team input on score accuracy

4. Continuous Optimization

  • Regularly validate model accuracy with conversion data
  • A/B test different scoring approaches
  • Monitor score distribution and adjust thresholds
  • Update models based on market and product changes

5. Integration & Automation

  • Integrate scoring with CRM and marketing automation
  • Automate lead routing based on scores
  • Set up real-time score updates and alerts
  • Create dashboards for score monitoring and analysis