← Blog

How to Build a Claude-Powered Lead Qualification Bot

2026-11-03 · 6 min read · SubToAPI Team

A Claude-powered lead qualification bot reads an inbound message, chat transcript, or form submission, asks clarifying questions if needed, scores the lead against your ICP criteria, and outputs a structured result your CRM or sales team can act on immediately. The core pieces are a well-designed system prompt with explicit scoring rules, tool use (or structured JSON output) so the result is machine-readable, and an API layer that your website, chatbot widget, or Slack app can call reliably.

This guide walks through the actual implementation: prompt structure, conversation flow, structured output with tool use, and how to wire it into a web form or chat widget without building your own Claude infrastructure from scratch.

What "lead qualification" actually means for a bot

Before writing any code, define what qualifies a lead in your business. Most B2B teams use some variant of BANT (Budget, Authority, Need, Timeline) or a custom ICP checklist (company size, industry, use case, urgency). Your bot needs to:

  1. Collect the missing fields through natural conversation, not a rigid form.
  2. Score the lead based on your rules once enough information is gathered.
  3. Output a structured result — not prose — so it can flow into a CRM or alert.
  4. Know when to stop and hand off to a human, especially for high-intent leads.

Claude is well suited to this because it can hold a natural conversation, ask follow-up questions only when needed, and still return disciplined structured output via tool use.

Step 1: Design the system prompt

The system prompt should encode your qualification criteria explicitly. Vague instructions produce inconsistent scores.

You are a lead qualification assistant for a B2B SaaS company selling
project management software to teams of 20-500 people.

Qualification criteria:
- Company size: 20-500 employees (ideal), 10-20 or 500-2000 (acceptable), outside this = disqualified
- Role: must be a manager, director, VP, or founder (decision-maker)
- Timeline: actively evaluating tools within 90 days
- Budget: has authority to approve or recommend a purchase

Ask only the questions needed to fill gaps. Keep responses under 2 sentences.
Do not reveal scoring logic to the user. Once you have enough information,
call the `submit_lead_score` tool.

Keep the tone conversational in the parts the user sees, and keep the scoring logic strict and internal.

Step 2: Use tool use for structured output

Free-text scoring is unreliable to parse. Define a tool so Claude returns a fixed schema instead of prose.

{
  "name": "submit_lead_score",
  "description": "Submit the final qualification result for this lead",
  "input_schema": {
    "type": "object",
    "properties": {
      "score": { "type": "integer", "minimum": 0, "maximum": 100 },
      "tier": { "type": "string", "enum": ["hot", "warm", "cold", "disqualified"] },
      "company_size": { "type": "string" },
      "role": { "type": "string" },
      "timeline": { "type": "string" },
      "notes": { "type": "string" },
      "recommended_action": { "type": "string" }
    },
    "required": ["score", "tier", "recommended_action"]
  }
}

When Claude calls this tool, you get a clean JSON payload you can insert directly into a database row, CRM field, or Slack alert — no regex parsing of free text. This is the same pattern covered in more depth in the tool use docs, and it's the single biggest reliability improvement you can make over a plain chat-completion approach.

Step 3: Run the conversation loop

A qualification bot is a multi-turn conversation, not a single request. Each turn:

  1. Sends the conversation history plus the new user message.
  2. Checks whether Claude's response is a tool call (submit_lead_score) or a regular follow-up question.
  3. If it's a follow-up question, displays it and waits for the next user reply.
  4. If it's a tool call, extracts the structured result and ends the conversation.

Here's a simplified loop using SubToAPI, which exposes Claude over a standard HTTPS API with application API keys, so you don't need to manage your own backend credentials or proxy:

async function qualifyTurn(messages) {
  const res = await fetch("https://api.subtoapi.app/v1/messages", {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      model: "claude-sonnet-4-5",
      system: QUALIFICATION_SYSTEM_PROMPT,
      max_tokens: 500,
      tools: [submitLeadScoreTool],
      messages,
    }),
  });

  const data = await res.json();
  const toolCall = data.content.find((b) => b.type === "tool_use");

  if (toolCall) {
    return { done: true, result: toolCall.input };
  }

  const reply = data.content.find((b) => b.type === "text")?.text;
  return { done: false, reply };
}

Each new user message gets appended to messages, and the loop continues until done is true. The quickstart and messages docs cover the request/response shape in detail if you want to extend this with system prompt caching or longer context windows.

Step 4: Handle the handoff

Once you have a score and tier, route the lead:

Keep this routing logic outside the prompt — Claude should only produce the score and tier, your application code decides what happens next. This separation makes the system much easier to debug and tune over time: you can change routing rules without touching the prompt, and vice versa.

Step 5: Add streaming for a better chat UX

If the bot lives in a chat widget, streaming tokens as they're generated makes the follow-up questions feel instant instead of making the user wait for a full response. SubToAPI supports streaming over the same endpoint — see the streaming docs for the event format and how to consume it with fetch or a server-sent-events client.

Production considerations

A few things matter once this is live on a real website:

Questions

Does the bot need a separate scoring model, or can Claude do it directly? Claude can do the scoring itself if you give it explicit criteria in the system prompt and force structured output via tool use. A separate scoring model is unnecessary complexity for most teams.

How do I prevent the bot from revealing its scoring logic to prospects? Instruct Claude explicitly not to disclose scoring criteria, and never expose the system prompt or tool schema in the frontend. Keep all qualification logic server-side.

Can this integrate with an existing CRM like HubSpot or Salesforce? Yes — once Claude returns the structured submit_lead_score JSON, your backend code pushes it into the CRM via its standard API. The bot only needs to produce clean structured data; the CRM integration is a normal application-layer task.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →