Back to blog
lead-qualificationsalescrmopenclawtutorial

Build an AI Lead Qualification Bot (Score & Route Leads 24/7)

How to build an OpenClaw agent that qualifies inbound leads, scores them, routes them to the right team, and triggers CRM updates automatically.

By ClawPort Team

Leads don't come in at 9am on weekdays. They come in at 11pm on Sunday, during your team's vacation, and while everyone is on a call. A lead qualification agent that runs 24/7 means no lead goes cold while waiting for someone to respond.

This guide builds a full qualification agent: scoring logic, BANT-style questions, CRM routing, and follow-up automation.

What a Lead Qualification Agent Does

  • Engages inbound leads the moment they make contact
  • Asks qualification questions naturally (not like a form)
  • Scores leads based on fit criteria
  • Routes qualified leads to the right sales rep
  • Pushes data to your CRM automatically
  • Sends follow-up resources if they're not ready to buy yet

Defining Your Qualification Criteria

Before building the bot, define what "qualified" means for your business. A common framework is BANT:

  • Budget: Do they have the budget for your product?
  • Authority: Are they a decision-maker or influencer?
  • Need: Do they have a genuine problem your product solves?
  • Timeline: Are they planning to buy within a reasonable window?

Translate these into scoring rules:

qualification:
  scores:
    budget:
      ">$50k": 30
      "$10k-$50k": 20
      "$1k-$10k": 10
      "no budget yet": 0
    
    authority:
      "decision maker": 25
      "influencer": 15
      "end user": 5
    
    need:
      "critical pain": 30
      "nice to have": 15
      "exploring options": 5
    
    timeline:
      "this quarter": 20
      "within 6 months": 10
      "no timeline": 0
    
  thresholds:
    hot: 75        # route to senior sales
    warm: 40       # route to SDR
    cold: 0        # nurture sequence

The SOUL.md

# LeadBot — [Company Name] Sales Assistant

You qualify inbound leads for [Company Name], a [brief product description].

## Persona
You're friendly and professional — curious rather than salesy.
You ask questions to understand their situation, not to interrogate them.
You're honest if we're probably not the right fit.

## Qualification Flow

Your goal is to understand:
1. What problem they're trying to solve
2. The scale of the problem (team size, volume, etc.)
3. Their timeline for addressing it
4. Whether they're evaluating solutions actively
5. Their role (decision maker, champion, end user)

Do NOT ask all these questions at once. Have a natural conversation.
Start with their situation, let the other answers emerge naturally.
If they ask a direct question, answer it before continuing qualification.

## When Enough is Enough

After 4-5 exchanges, you should have enough to qualify them.
At that point:
- If they look like a strong fit: offer to connect them with the team
- If they need more nurturing: offer relevant resources
- If they're clearly not a fit: be honest and helpful anyway

## Resource Library

For leads not ready to buy:
- Getting started guide: [URL]
- Case study (enterprise): [URL]
- Case study (SMB): [URL]
- Pricing page: [URL]
- Product demo video: [URL]

## What You're Not

You are not a closing agent. You don't push for commitment.
Your job is qualification and handoff, not selling.

Building the Lead Scoring Tool

// tools/score_lead.js
export default function scoreLead({ budget, authority, need, timeline }) {
  const scores = {
    budget: {
      'over_50k': 30, '10k_to_50k': 20, '1k_to_10k': 10, 'under_1k': 0, 'unknown': 5
    },
    authority: {
      'decision_maker': 25, 'influencer': 15, 'end_user': 5, 'unknown': 10
    },
    need: {
      'critical': 30, 'moderate': 15, 'exploring': 5
    },
    timeline: {
      'this_quarter': 20, 'within_6_months': 10, 'no_timeline': 0, 'unknown': 5
    }
  };
  
  const total = (scores.budget[budget] || 0) +
                (scores.authority[authority] || 0) +
                (scores.need[need] || 0) +
                (scores.timeline[timeline] || 0);
  
  let tier, nextAction;
  
  if (total >= 75) {
    tier = 'hot';
    nextAction = 'route_to_senior_sales';
  } else if (total >= 40) {
    tier = 'warm';
    nextAction = 'route_to_sdr';
  } else {
    tier = 'cold';
    nextAction = 'add_to_nurture';
  }
  
  return { score: total, tier, nextAction };
}

Building the CRM Push Tool

Using HubSpot as an example:

// tools/create_crm_contact.js
export default async function createCRMContact({
  name, email, company, phone,
  leadData, score, tier, conversationId
}) {
  const [firstName, ...lastNameParts] = name.split(' ');
  const lastName = lastNameParts.join(' ');
  
  // Create contact
  const response = await fetch('https://api.hubapi.com/crm/v3/objects/contacts', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.HUBSPOT_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      properties: {
        firstname: firstName,
        lastname: lastName,
        email,
        company,
        phone: phone || '',
        hs_lead_status: tier === 'hot' ? 'IN_PROGRESS' : 'NEW',
        lead_score: score.toString(),
        lead_tier: tier,
        lead_source: 'openclaw_chatbot',
        openclaw_conversation_id: conversationId,
        budget_range: leadData.budget,
        buying_timeline: leadData.timeline,
        primary_use_case: leadData.useCase,
      }
    })
  });
  
  const contact = await response.json();
  
  // Create a task for the assigned rep
  if (tier === 'hot' || tier === 'warm') {
    await createFollowUpTask(contact.id, tier);
  }
  
  return { 
    contact_id: contact.id,
    hubspot_url: `https://app.hubspot.com/contacts/${contact.id}`
  };
}

async function createFollowUpTask(contactId, tier) {
  const urgency = tier === 'hot' ? 1 : 3; // hours until follow-up
  
  await fetch('https://api.hubapi.com/crm/v3/objects/tasks', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.HUBSPOT_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      properties: {
        hs_task_subject: `${tier.toUpperCase()} lead follow-up`,
        hs_task_body: `Lead came in via chatbot. Score: ${tier}. Contact within ${urgency} hours.`,
        hs_timestamp: new Date(Date.now() + urgency * 3600000).toISOString(),
        hs_task_priority: tier === 'hot' ? 'HIGH' : 'MEDIUM',
        hs_task_type: 'CALL',
        associations: [{ to: { id: contactId }, types: [{ category: 'HUBSPOT_DEFINED', typeId: 204 }] }]
      }
    })
  });
}

Routing Logic

After scoring, the agent needs to handle routing differently:

## Handoff Instructions (SOUL.md addition)

After scoring a lead:

**Hot lead (score 75+):**
"Based on our conversation, I think there's a really strong fit here. 
Our team would love to give you a personalized demo. Can I send you 
a calendar link so you can pick a time that works? Or would you 
prefer someone reach out to you directly?"

**Warm lead (score 40-74):**
"This sounds like something we could genuinely help with. Our sales 
team will follow up within one business day to learn more and answer 
your questions. Is [email] the best way to reach you?"

**Cold lead (score <40):**
"You might be earlier in your evaluation than our product is designed 
for right now, but here's what I'd suggest: [relevant resource]. 
When your needs evolve, we'd love to reconnect."

Slack Notification for Hot Leads

When a hot lead comes in, notify the sales team immediately:

// Called after CRM contact creation
async function notifySlackHotLead({ leadData, score, hubspotUrl }) {
  await fetch(process.env.SLACK_WEBHOOK_URL, {
    method: 'POST',
    body: JSON.stringify({
      text: "🔥 Hot lead just came in!",
      blocks: [
        {
          type: "section",
          text: {
            type: "mrkdwn",
            text: `*🔥 Hot Lead — Score: ${score}*\n*${leadData.name}* at *${leadData.company}*\nBudget: ${leadData.budget} | Timeline: ${leadData.timeline}\nUse case: ${leadData.useCase}`
          }
        },
        {
          type: "actions",
          elements: [
            {
              type: "button",
              text: { type: "plain_text", text: "View in HubSpot" },
              url: hubspotUrl,
              style: "primary"
            }
          ]
        }
      ]
    })
  });
}

Measuring Qualification Quality

Track these metrics weekly:

  • Lead volume: total conversations
  • Qualification rate: % who engage with qualification questions
  • Score distribution: % hot / warm / cold
  • CRM conversion rate: % of leads that become opportunities
  • False positive rate: % of "hot" leads that don't convert (adjust scoring)

If your hot-lead-to-opportunity rate is below 40%, your scoring threshold is too low. If it's above 80%, it might be too high and you're missing real opportunities.

Deploy and Stay Online

A lead qualification agent needs to be running 24/7. If it goes down at 10pm on a Sunday (when many people browse), you lose leads.

ClawPort handles the uptime, monitoring, and automatic restarts. For a sales use case where one missed hot lead might represent $10,000+ in revenue, the $10/month hosting cost is trivially justified.

Seven-day free trial at clawport.io.

Ready to deploy your AI agent?

Get started with ClawPort in 60 seconds. No credit card required.

Get Started Free