Logo
Search
API Docs

BANT Outbound Assistant Walkthrough

Guides

Lead Qualification: BANT Outbound Assistant Walkthrough

Overview

This is a full worked example of building an outbound sales-qualification assistant, using an Assistant-based approach (a single focused assistant, not a squad) and the same underlying techniques covered in Custom Function Tools, Files API, and Scheduling Outbound Calls. The assistant places outbound calls to prospects, gets permission to continue, qualifies the lead using BANT (Budget, Authority, Need, Timeline), handles common objections, and books a meeting when the lead is a fit.

Note on the structured-output schema: Real Estate Lead Qualification: Structured Output Template is a different resource — a ready-made JSON schema for a real-estate-specific lead qualification call. This page is a full assistant build for a general BANT sales-qualification flow, from knowledge base and tools through system prompt and outbound trigger; use it as the walkthrough pattern, and adapt the Real Estate template (or build your own schema per Structured Outputs (Post-Call Data Extraction)) for the structured-output side of your own use case.


Step 1: Upload the Knowledge Base Files

Upload three CSV files through the Files API before building anything else:

  • leads.csv — columns: lead_id, name, phone, company, prior_call_notes
  • products.csv — product/plan details the assistant can reference when a prospect asks what's on offer
  • call_outcomes.csv — a reference list of standard outcome categories to log the call under
curl --location 'https://api.sulus.ai/file' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--form 'file=@"leads.csv"'

curl --location 'https://api.sulus.ai/file' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--form 'file=@"products.csv"'

curl --location 'https://api.sulus.ai/file' \
--header 'Authorization: Bearer <YOUR_API_KEY>' \
--form 'file=@"call_outcomes.csv"'

Save each returned file id — the tools built in Step 3 reference these files. See Files API for the complete field reference.


Step 2: Create the Assistant

import { CoreSystemClient } from "@core-system/server-sdk";

const client = new CoreSystemClient({ token: process.env.CORE_SYSTEM_API_KEY });

const assistant = await client.assistants.create({
  name: "Outbound SDR",
  firstMessage: "Hi, this is Alex from TechFlow. Is now a good time to chat for 2 minutes?",
  model: {
    provider: "openai",
    model: "gpt-4o",
    messages: [
      { role: "system", content: systemPrompt }
    ]
  }
});

systemPrompt is built out in full further down this page.


Step 3: The Four Tools

The assistant uses four function tools, defined the same way described in Custom Function Tools:

ToolPurpose
lookup_leadRetrieves the prospect's lead record and prior call history from leads.csv
score_leadTakes the four BANT answers and returns a qualification score/priority
update_crmLogs the call outcome and next steps back to the CRM
book_meetingSchedules a meeting on a calendar once the lead is qualified — this is a separate concern from Scheduling Outbound Calls' schedulePlan, which delays when the outbound call itself goes out; book_meeting instead books a future meeting on the prospect's calendar as an outcome of a call that's already happened

Step 4: Attach the Tools

const updatedAssistant = await client.assistants.update(assistant.id, {
  model: {
    toolIds: [
      lookupLeadTool.id,
      scoreLeadTool.id,
      updateCrmTool.id,
      bookMeetingTool.id
    ]
  }
});

As with any assistant update, this replaces the entire model object — include every field you want to keep, not just toolIds.


Writing the System Prompt

A good outbound BANT system prompt has five distinct parts:

  1. Identity & purpose — who the assistant is, who it's calling on behalf of, and what the call is for.
  2. Permission gate — asking whether now is a good time before qualifying anything.
  3. BANT qualification — a clear sequence for surfacing Budget, Authority, Need, and Timeline.
  4. Objection handling — how to respond to common pushback without being pushy.
  5. Booking & wrap-up — when to offer a meeting, and how to close the call either way.

Full System Prompt Example

# Outbound SDR Agent Prompt

## Identity & Purpose
You are Alex, an outbound sales development rep calling on behalf of TechFlow. Your goal is to qualify the prospect using BANT and book a meeting with a closer if they're a fit.

## Permission Gate
Always start by asking if now is a good time to talk for two minutes. If not, offer to call back at a better time and end the call politely -- do not attempt to qualify an unwilling prospect.

## Data Sources
- leads.csv: lead_id, name, phone, company, prior_call_notes
- products.csv: product and plan details
- call_outcomes.csv: standard outcome categories

## Available Tools
1. lookup_lead - retrieve the prospect's record and history
2. score_lead - score the qualification once BANT is gathered
3. update_crm - log the outcome and next steps
4. book_meeting - schedule a meeting once qualified

## BANT Qualification Flow
1. Budget - ask about current spend or budget range for this type of solution
2. Authority - confirm who else is involved in a decision like this
3. Need - understand the problem they're trying to solve
4. Timeline - ask when they'd want a solution in place
Call score_lead once all four are gathered.

## Objection Handling
- "Not interested" -> ask one clarifying question before disengaging gracefully
- "Send me info" -> offer a brief call instead, or confirm the best email and log it
- "Too expensive" -> acknowledge, then ask what budget range would work

## Booking & Wrap-Up
- If qualified: call book_meeting and confirm the date/time back to the prospect
- If not qualified or not interested: call update_crm with the outcome and end politely
- Always call update_crm before ending the call, regardless of outcome

## Style & Tone
- Friendly, concise, no more than two sentences per turn
- One question at a time
- Never pressure a prospect who has said no

Structured Outputs to Capture

Attach a structured-output schema (see Structured Outputs (Post-Call Data Extraction)) to pull these fields cleanly off every call:

FieldDescription
permission_statusWhether the prospect agreed to continue the call
bant_budgetBudget signal captured during qualification
bant_authorityDecision-making authority signal
bant_needThe problem or need the prospect described
bant_timelineWhen the prospect wants a solution in place
meeting_timeThe booked meeting time, if any
call_outcomeThe final logged outcome category for the call

Triggering the Outbound Call

await client.calls.create({
  phoneNumberId: "your-phone-number-id",
  customer: { number: "+15551234567" },
  assistantId: assistant.id
});

Or via cURL:

curl -X POST "https://api.sulus.ai/call" \
  -H "Authorization: Bearer $CORE_SYSTEM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "assistantId": "your-assistant-id",
    "phoneNumberId": "your-phone-number-id",
    "customer": { "number": "+15551234567" }
  }'

To run this against a large lead list instead of one prospect at a time, see Outbound Campaigns; to delay the call to a future time window rather than dialing immediately, see Scheduling Outbound Calls.