AI Lead Scoring with CHAMP
Overview
SpiderIQ's most powerful feature: AI-powered lead qualification using the CHAMP sales framework. In 20-60 seconds, get a complete lead profile including company analysis, decision makers, pain points, and ICP fit scoring.
CHAMP Framework: Challenges, Authority, Money, Prioritization - the industry-standard sales qualification methodology
What You Get
Emails, phones, addresses, and 14 social media platforms (same as basic extraction)
AI-extracted: Name, summary, industry, services offered, target audience
Names, titles, emails, LinkedIn profiles - identify decision makers
Business challenges inferred from news, blog posts, and job listings
Full framework analysis:
- Challenges: Pain points matched to your solution
- Authority: Decision makers and buying process
- Money: Budget indicators and funding status
- Prioritization: Urgency signals and timeline
0-1 score indicating how well they match your ideal customer profile
Ready-to-use data points for personalized outreach
AI Token Costs
AI features are opt-in. Enable only what you need to control costs.
| Feature | AI Tokens | What You Get | When to Use |
|---|---|---|---|
| Base crawl | 0 tokens | Contact info + compendium | Always included |
extract_company_info | ~500 tokens | Company vitals | Qualifying leads |
extract_team | ~500 tokens | Team members with roles | Finding decision makers |
extract_pain_points | ~500 tokens | Business challenges | Understanding needs |
| CHAMP scoring | +1,500 tokens | Full analysis + ICP fit | High-value prospects only |
| Total (all features) | ~3,000 tokens | Complete lead profile | Enterprise deals |
Cost optimization: Start with basic extraction (0 tokens). Enable AI only for qualified leads that pass initial filters.
Quick Start: Full CHAMP Analysis
1. Submit Job with All AI Features
{
"payload": {
"url": "https://target-company.com",
"max_pages": 20,
// Enable all AI features
"extract_company_info": true,
"extract_team": true,
"extract_pain_points": true,
// CHAMP lead scoring (requires both fields)
"product_description": "AI-powered customer support automation platform that reduces ticket resolution time by 60% using intelligent routing, automated responses, and predictive analytics. Integrates with Zendesk, Intercom, and Salesforce.",
"icp_description": "B2B SaaS companies with 50-500 employees, experiencing rapid growth (>50% YoY), struggling with support team scalability, tech-forward culture, budget >$50k/year for support tools, using modern support platforms."
},
"priority": 8
}
- cURL
- Python
curl -X POST https://spideriq.ai/api/v1/jobs/spiderSite/submit \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"payload": {
"url": "https://target-company.com",
"max_pages": 20,
"extract_company_info": true,
"extract_team": true,
"extract_pain_points": true,
"product_description": "AI-powered customer support automation platform that reduces ticket resolution time by 60%...",
"icp_description": "B2B SaaS companies with 50-500 employees, experiencing rapid growth..."
},
"priority": 8
}'
import requests
response = requests.post(
"https://spideriq.ai/api/v1/jobs/spiderSite/submit",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"payload": {
"url": "https://target-company.com",
"max_pages": 20,
"extract_company_info": True,
"extract_team": True,
"extract_pain_points": True,
"product_description": "AI-powered customer support automation platform...",
"icp_description": "B2B SaaS companies with 50-500 employees..."
},
"priority": 8
}
)
job = response.json()
print(f"Job ID: {job['job_id']}")
2. Get Complete Lead Profile
After 20-60 seconds, retrieve the full analysis:
{
"success": true,
"job_id": "770e8400-e29b-41d4-a716-446655440002",
"type": "spiderSite",
"status": "completed",
"processing_time_seconds": 24.1,
"data": {
"url": "https://techstart.com",
"pages_crawled": 18,
"crawl_status": "success",
// Basic Contact Info
"emails": ["contact@techstart.com", "sales@techstart.com"],
"phones": ["+1-555-987-6543"],
"linkedin": "https://linkedin.com/company/techstart",
"twitter": "https://twitter.com/techstart",
// Company Vitals (AI-extracted)
"company_vitals": {
"name": "TechStart Solutions",
"summary": "AI-powered customer support automation for SaaS companies. Founded 2021, Series B funded.",
"industry": "B2B SaaS - Customer Support Tech",
"services": [
"AI Chatbot Platform",
"Support Ticket Automation",
"Customer Analytics Dashboard",
"Zendesk/Intercom Integration"
],
"target_audience": "Mid-market SaaS companies (50-500 employees) with high support volumes"
},
// Team Members (AI-extracted)
"team_members": [
{
"name": "Sarah Johnson",
"title": "CEO & Founder",
"email": "sarah@techstart.com",
"linkedin": "https://linkedin.com/in/sarahjohnson"
},
{
"name": "Mike Chen",
"title": "VP of Customer Success",
"email": "mike@techstart.com",
"linkedin": "https://linkedin.com/in/mikechen"
},
{
"name": "Lisa Park",
"title": "Head of Product",
"email": "lisa@techstart.com",
"linkedin": "https://linkedin.com/in/lisapark"
}
],
// Pain Points (AI-inferred)
"pain_points": [
"Struggling to scale customer support operations with current headcount",
"High ticket resolution times (avg 18 hours) impacting customer satisfaction scores",
"Manual ticket triage consuming 40% of support team time",
"Difficulty maintaining service quality during rapid growth phase",
"Customer complaints about inconsistent support experiences"
],
// CHAMP Lead Scoring
"lead_scoring": {
"icp_fit_score": 0.85,
"champ_analysis": {
"challenges": [
"Manual ticket triage consuming 40% of support team time - directly addressable by intelligent routing",
"Customer complaints about slow response times (18hr avg) - automated responses could reduce to <2hr",
"Scaling support operations without proportional headcount increase",
"Maintaining service quality during 80% YoY growth phase"
],
"authority": "VP of Customer Success (Mike Chen) leads vendor selection for support tools. CEO (Sarah Johnson) approval required for deals >$50k. Technical evaluation by Head of Product (Lisa Park) for integrations.",
"money": "Series B funded ($20M raised in Q2 2024 from Sequoia). Actively allocating budget for Q1 2025 operational efficiency initiatives. Current support tools budget estimated at $80-120k/year based on team size and mentioned platforms (Zendesk, Intercom).",
"prioritization": "High urgency - support automation listed as top Q1 2025 priority in recent blog post. Job postings for 3 support engineers suggest immediate scaling challenges. CEO mentioned in interview that support scalability is blocking enterprise deals."
}
},
// Personalization Hooks
"personalization_hooks": {
"company_name": "TechStart Solutions",
"decision_maker": "Mike Chen (VP of Customer Success)",
"decision_maker_email": "mike@techstart.com",
"key_challenge": "Manual ticket triage consuming 40% of support team time",
"urgency_signal": "Support automation listed as Q1 2025 top priority",
"budget_indicator": "Series B funded ($20M), $80-120k current support budget",
"personalization_angle": "Show how automation can free up 40% of support team capacity while reducing resolution time from 18hr to <2hr",
"social_proof_angle": "Other Series B SaaS companies scaling support with AI",
"integration_hook": "Already using Zendesk/Intercom - seamless integration",
"best_contact_time": "Q4 2024 for Q1 2025 implementation"
}
}
}
Understanding the CHAMP Framework
C - Challenges
What it identifies:
- Specific pain points the prospect is facing
- How those challenges align with your solution
- Evidence from their website (blog posts, news, job listings)
Example:
"Manual ticket triage consuming 40% of support team time - directly addressable by intelligent routing"
How to use:
- Lead with their specific challenge in outreach
- Show exactly how you solve this problem
- Use their own words when describing the pain
A - Authority
What it identifies:
- Decision makers and their roles
- Who influences vs who approves
- Deal approval thresholds
- Technical evaluators
Example:
"VP of Customer Success (Mike Chen) leads vendor selection. CEO approval for >$50k deals."
How to use:
- Multi-thread your outreach (champion + approver)
- Tailor messaging by role (operational for VP, strategic for CEO)
- Prepare for technical evaluation if integrations needed
M - Money
What it identifies:
- Funding status (bootstrapped, Series A/B/C, etc.)
- Budget indicators (current spend, team size)
- Financial health signals
- Budget allocation timing
Example:
"Series B funded ($20M), actively allocating Q1 2025 budget, current support spend $80-120k/year"
How to use:
- Align your pricing with their budget range
- Time outreach with their budget cycle
- Emphasize ROI if bootstrapped, strategic value if well-funded
P - Prioritization
What it identifies:
- How urgent is this problem?
- Timeline indicators (hiring, blog mentions, strategic initiatives)
- Competitive pressure
- Growth phase urgency
Example:
"High urgency - top Q1 2025 priority in recent blog. 3 support engineer job postings suggest immediate need."
How to use:
- High urgency = immediate outreach, fast timeline
- Low urgency = nurture campaign, educational content
- Mention their stated priorities in outreach
Personalization Hooks Explained
The personalization_hooks object contains ready-to-use data points for your outreach:
{
"company_name": "TechStart Solutions",
"decision_maker": "Mike Chen (VP of Customer Success)",
"decision_maker_email": "mike@techstart.com",
"key_challenge": "Manual ticket triage consuming 40% of support team time",
"urgency_signal": "Support automation listed as Q1 2025 top priority",
"budget_indicator": "Series B funded ($20M), $80-120k current support budget",
"personalization_angle": "Show how automation can free up 40% of support team capacity",
"social_proof_angle": "Other Series B SaaS companies scaling support with AI",
"integration_hook": "Already using Zendesk/Intercom - seamless integration",
"best_contact_time": "Q4 2024 for Q1 2025 implementation"
}
Email Template Using Hooks
Subject: {{urgency_signal}} - {{key_challenge}}?
Hi {{decision_maker.first_name}},
I noticed {{company_name}} is focused on {{urgency_signal}}.
Many {{social_proof_angle}} face the same challenge: {{key_challenge}}.
Our platform {{personalization_angle}} - and integrates seamlessly with
your existing {{integration_hook}}.
Are you open to a 15-minute call in {{best_contact_time}} to discuss?
Best,
[Your name]
ICP Fit Score Interpretation
The icp_fit_score ranges from 0.0 (no fit) to 1.0 (perfect fit):
| Score | Interpretation | Action |
|---|---|---|
| 0.85 - 1.0 | Excellent fit | High-touch sales, executive outreach |
| 0.70 - 0.84 | Good fit | Standard sales process |
| 0.50 - 0.69 | Moderate fit | Nurture campaign, educational content |
| 0.30 - 0.49 | Weak fit | Low priority, automated nurture |
| 0.0 - 0.29 | Poor fit | Disqualify or long-term nurture |
Prioritization strategy: Focus AI analysis on leads >0.70 ICP fit to maximize ROI on AI token spend.
Progressive Lead Qualification
Use a staged approach to optimize costs:
Stage 1: Basic Extraction (0 tokens)
Crawl all prospects with basic contact extraction:
{
"payload": {
"url": "https://prospect.com",
"max_pages": 10
}
}
Decision criteria:
- ✅ Has contact info (emails/phones)
- ✅ Has LinkedIn presence
- ✅ Target industry domain (check URL/content keywords)
Stage 2: Company Analysis (~500 tokens)
For prospects that pass Stage 1, extract company vitals:
{
"payload": {
"url": "https://qualified-prospect.com",
"max_pages": 15,
"extract_company_info": true
}
}
Decision criteria:
- ✅ Company size matches ICP (check team page)
- ✅ Industry matches (from company_vitals.industry)
- ✅ Services align with your solution
Stage 3: Full CHAMP (~3,000 tokens)
For high-value prospects, run complete analysis:
{
"payload": {
"url": "https://hot-lead.com",
"max_pages": 20,
"extract_company_info": true,
"extract_team": true,
"extract_pain_points": true,
"product_description": "...",
"icp_description": "..."
}
}
Result: Complete lead profile with ICP fit score, CHAMP analysis, personalization hooks
Production-Ready Implementation
- Python - Progressive Qualification
- JavaScript - Progressive Qualification
import requests
import time
from typing import Dict, List, Optional
class LeadQualifier:
def __init__(self, api_key: str, product_desc: str, icp_desc: str):
self.api_key = api_key
self.base_url = "https://spideriq.ai/api/v1"
self.headers = {"Authorization": f"Bearer {api_key}"}
self.product_description = product_desc
self.icp_description = icp_desc
def submit_job(self, payload: Dict, priority: int = 0) -> str:
"""Submit job and return job_id"""
response = requests.post(
f"{self.base_url}/jobs/spiderSite/submit",
headers=self.headers,
json={"payload": payload, "priority": priority}
)
response.raise_for_status()
return response.json()['job_id']
def get_results(self, job_id: str, timeout: int = 120) -> Dict:
"""Poll for results"""
url = f"{self.base_url}/jobs/{job_id}/results"
for _ in range(timeout // 3):
response = requests.get(url, headers=self.headers)
if response.status_code == 200:
return response.json()
elif response.status_code == 202:
time.sleep(3)
elif response.status_code == 410:
raise Exception(response.json()['error_message'])
raise TimeoutError(f"Job {job_id} timeout")
def stage1_basic(self, url: str) -> Optional[Dict]:
"""Stage 1: Basic contact extraction (0 tokens)"""
print(f"Stage 1: {url}")
job_id = self.submit_job({"url": url, "max_pages": 10})
results = self.get_results(job_id)
data = results['data']
# Qualification criteria
has_contacts = len(data['emails']) > 0 or len(data['phones']) > 0
has_linkedin = data.get('linkedin') is not None
if not (has_contacts and has_linkedin):
print(f" ✗ Failed Stage 1: No contacts or LinkedIn")
return None
print(f" ✓ Passed Stage 1: {len(data['emails'])} emails, LinkedIn found")
return data
def stage2_company(self, url: str) -> Optional[Dict]:
"""Stage 2: Company analysis (~500 tokens)"""
print(f"Stage 2: {url}")
job_id = self.submit_job({
"url": url,
"max_pages": 15,
"extract_company_info": True
}, priority=5)
results = self.get_results(job_id)
data = results['data']
# Qualification criteria
company = data.get('company_vitals')
if not company:
print(f" ✗ Failed Stage 2: No company info extracted")
return None
# Check industry match (example logic)
target_keywords = ['saas', 'software', 'b2b', 'tech']
industry_match = any(kw in company['industry'].lower() for kw in target_keywords)
if not industry_match:
print(f" ✗ Failed Stage 2: Industry mismatch ({company['industry']})")
return None
print(f" ✓ Passed Stage 2: {company['name']}, {company['industry']}")
return data
def stage3_champ(self, url: str) -> Dict:
"""Stage 3: Full CHAMP analysis (~3,000 tokens)"""
print(f"Stage 3: {url}")
job_id = self.submit_job({
"url": url,
"max_pages": 20,
"extract_company_info": True,
"extract_team": True,
"extract_pain_points": True,
"product_description": self.product_description,
"icp_description": self.icp_description
}, priority=8)
results = self.get_results(job_id, timeout=180)
data = results['data']
icp_score = data.get('lead_scoring', {}).get('icp_fit_score', 0)
print(f" ✓ CHAMP Complete: ICP Score = {icp_score:.2f}")
return data
def qualify_lead(self, url: str) -> Optional[Dict]:
"""Progressive qualification pipeline"""
# Stage 1: Basic (0 tokens)
data = self.stage1_basic(url)
if not data:
return None
# Stage 2: Company (~500 tokens)
data = self.stage2_company(url)
if not data:
return None
# Stage 3: Full CHAMP (~3,000 tokens)
data = self.stage3_champ(url)
return data
# Usage Example
qualifier = LeadQualifier(
api_key="YOUR_API_KEY",
product_desc="AI-powered customer support automation platform...",
icp_desc="B2B SaaS companies with 50-500 employees..."
)
# Process list of prospects
prospects = [
"https://prospect1.com",
"https://prospect2.com",
"https://prospect3.com"
]
qualified_leads = []
for url in prospects:
try:
lead_data = qualifier.qualify_lead(url)
if lead_data:
qualified_leads.append({
'url': url,
'data': lead_data
})
except Exception as e:
print(f"Error processing {url}: {e}")
# Export high-fit leads
import json
high_fit = [
lead for lead in qualified_leads
if lead['data'].get('lead_scoring', {}).get('icp_fit_score', 0) >= 0.70
]
with open('qualified_leads.json', 'w') as f:
json.dump(high_fit, f, indent=2)
print(f"\n✓ Qualified {len(high_fit)}/{len(prospects)} leads (ICP fit ≥0.70)")
class LeadQualifier {
constructor(apiKey, productDesc, icpDesc) {
this.apiKey = apiKey;
this.baseUrl = 'https://spideriq.ai/api/v1';
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
this.productDescription = productDesc;
this.icpDescription = icpDesc;
}
async submitJob(payload, priority = 0) {
const response = await fetch(
`${this.baseUrl}/jobs/spiderSite/submit`,
{
method: 'POST',
headers: this.headers,
body: JSON.stringify({ payload, priority })
}
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
return data.job_id;
}
async getResults(jobId, timeout = 120000) {
const url = `${this.baseUrl}/jobs/${jobId}/results`;
const startTime = Date.now();
while (Date.now() - startTime < timeout) {
const response = await fetch(url, { headers: this.headers });
if (response.status === 200) {
return await response.json();
} else if (response.status === 202) {
await new Promise(resolve => setTimeout(resolve, 3000));
} else if (response.status === 410) {
const error = await response.json();
throw new Error(error.error_message);
}
}
throw new Error(`Job ${jobId} timeout`);
}
async stage1Basic(url) {
console.log(`Stage 1: ${url}`);
const jobId = await this.submitJob({ url, max_pages: 10 });
const results = await this.getResults(jobId);
const { data } = results;
// Qualification criteria
const hasContacts = data.emails.length > 0 || data.phones.length > 0;
const hasLinkedIn = data.linkedin !== null;
if (!hasContacts || !hasLinkedIn) {
console.log(` ✗ Failed Stage 1: No contacts or LinkedIn`);
return null;
}
console.log(` ✓ Passed Stage 1: ${data.emails.length} emails, LinkedIn found`);
return data;
}
async stage2Company(url) {
console.log(`Stage 2: ${url}`);
const jobId = await this.submitJob({
url,
max_pages: 15,
extract_company_info: true
}, 5);
const results = await this.getResults(jobId);
const { data } = results;
// Qualification criteria
if (!data.company_vitals) {
console.log(` ✗ Failed Stage 2: No company info extracted`);
return null;
}
// Check industry match
const targetKeywords = ['saas', 'software', 'b2b', 'tech'];
const industryMatch = targetKeywords.some(kw =>
data.company_vitals.industry.toLowerCase().includes(kw)
);
if (!industryMatch) {
console.log(` ✗ Failed Stage 2: Industry mismatch (${data.company_vitals.industry})`);
return null;
}
console.log(` ✓ Passed Stage 2: ${data.company_vitals.name}, ${data.company_vitals.industry}`);
return data;
}
async stage3Champ(url) {
console.log(`Stage 3: ${url}`);
const jobId = await this.submitJob({
url,
max_pages: 20,
extract_company_info: true,
extract_team: true,
extract_pain_points: true,
product_description: this.productDescription,
icp_description: this.icpDescription
}, 8);
const results = await this.getResults(jobId, 180000);
const { data } = results;
const icpScore = data.lead_scoring?.icp_fit_score || 0;
console.log(` ✓ CHAMP Complete: ICP Score = ${icpScore.toFixed(2)}`);
return data;
}
async qualifyLead(url) {
// Stage 1: Basic (0 tokens)
let data = await this.stage1Basic(url);
if (!data) return null;
// Stage 2: Company (~500 tokens)
data = await this.stage2Company(url);
if (!data) return null;
// Stage 3: Full CHAMP (~3,000 tokens)
data = await this.stage3Champ(url);
return data;
}
}
// Usage
const qualifier = new LeadQualifier(
'YOUR_API_KEY',
'AI-powered customer support automation platform...',
'B2B SaaS companies with 50-500 employees...'
);
const prospects = [
'https://prospect1.com',
'https://prospect2.com',
'https://prospect3.com'
];
const qualifiedLeads = [];
for (const url of prospects) {
try {
const leadData = await qualifier.qualifyLead(url);
if (leadData) {
qualifiedLeads.push({ url, data: leadData });
}
} catch (error) {
console.log(`Error processing ${url}:`, error.message);
}
}
// Export high-fit leads
const highFit = qualifiedLeads.filter(
lead => lead.data.lead_scoring?.icp_fit_score >= 0.70
);
console.log(`\n✓ Qualified ${highFit.length}/${prospects.length} leads (ICP fit ≥0.70)`);
Writing Effective Descriptions
The quality of CHAMP analysis depends heavily on your product and ICP descriptions:
Product Description Best Practices
Be specific about value proposition
Bad:
"We provide customer support software"
Good:
"AI-powered customer support automation platform that reduces ticket resolution time by 60% using intelligent routing, automated responses, and predictive analytics"
Why: Specific metrics help AI match challenges to solutions
Mention integrations
Include:
- Platforms you integrate with (Zendesk, Salesforce, etc.)
- Technical requirements
- Implementation time
Example:
"Integrates with Zendesk, Intercom, and Salesforce. 2-week implementation. No code required."
Highlight differentiators
Include:
- What makes you different
- Key features
- Target use cases
Example:
"Unlike generic chatbots, our AI learns from your existing support tickets to provide contextual responses"
ICP Description Best Practices
Be quantitative
Bad:
"Small to medium businesses"
Good:
"50-500 employees, $5M-$50M ARR, Series A-B funded or profitable bootstrapped"
Why: Specific numbers enable accurate fit scoring
Include firmographics AND psychographics
Firmographics (company attributes):
- Company size (employees, revenue)
- Industry/vertical
- Funding stage
- Geography
Psychographics (company culture/behavior):
- Tech-forward vs traditional
- Growth stage (scaling, stable, declining)
- Budget priorities
- Decision-making style
Example:
"B2B SaaS companies, 100-300 employees, $10M-$30M ARR, Series B funded, tech-forward culture, rapid growth (>50% YoY), budget-conscious but willing to invest in ROI-positive tools"
Mention pain points and buying signals
Include:
- Problems they typically face
- Triggers that indicate buying readiness
- Urgency indicators
Example:
"Experiencing support team burnout, growing customer complaints about response times, recent funding to invest in operations, hiring for support roles, using legacy support platforms"
Real-World Use Cases
1. Enterprise Sales Pipeline
For high-ACV deals ($50k+), qualify every prospect with CHAMP:
# High-touch sales motion
enterprise_prospects = load_prospects() # High-value accounts
for prospect in enterprise_prospects:
# Full CHAMP analysis for every prospect
data = qualifier.stage3_champ(prospect['url'])
# Route to appropriate sales rep based on fit
if data['lead_scoring']['icp_fit_score'] >= 0.80:
assign_to_sales_rep('senior_ae', prospect, data)
elif data['lead_scoring']['icp_fit_score'] >= 0.60:
assign_to_sales_rep('ae', prospect, data)
else:
add_to_nurture_campaign(prospect, data)
2. Inbound Lead Qualification
Automatically qualify and route inbound leads:
# Webhook from CRM when new lead arrives
@app.route('/webhook/new_lead', methods=['POST'])
def handle_new_lead():
lead = request.json
# Run progressive qualification
data = qualifier.qualify_lead(lead['website'])
if data:
icp_score = data['lead_scoring']['icp_fit_score']
# Route based on fit
if icp_score >= 0.75:
# Hot lead - immediate AE notification
notify_sales_team('hot_lead', lead, data)
create_salesforce_opportunity(lead, data)
elif icp_score >= 0.50:
# Warm lead - SDR follow-up
assign_to_sdr(lead, data)
else:
# Cold lead - nurture campaign
add_to_email_campaign('nurture', lead)
return {'status': 'processed'}
3. Account-Based Marketing (ABM)
Build detailed profiles for target accounts:
# ABM target account list
target_accounts = [
{"name": "Acme Corp", "url": "https://acmecorp.com"},
{"name": "TechStart", "url": "https://techstart.com"},
# ... 50 more
]
abm_profiles = []
for account in target_accounts:
data = qualifier.stage3_champ(account['url'])
# Build complete ABM profile
profile = {
'company': data['company_vitals'],
'decision_makers': data['team_members'],
'pain_points': data['pain_points'],
'champ': data['lead_scoring']['champ_analysis'],
'personalization': data['personalization_hooks'],
'icp_score': data['lead_scoring']['icp_fit_score']
}
abm_profiles.append(profile)
# Create personalized campaign
create_abm_campaign(account, profile)
# Export for sales team
export_to_salesforce(abm_profiles)
4. Competitive Intelligence
Monitor competitors and their positioning:
competitors = [
"https://competitor1.com",
"https://competitor2.com",
"https://competitor3.com"
]
for competitor_url in competitors:
data = qualifier.stage2_company(competitor_url)
intel = {
'company': data['company_vitals']['name'],
'positioning': data['company_vitals']['summary'],
'services': data['company_vitals']['services'],
'target_audience': data['company_vitals']['target_audience'],
'pain_points': data.get('pain_points', []),
'markdown': data['markdown_compendium'] # Full content analysis
}
save_competitive_intel(intel)
Best Practices
When to use full CHAMP vs partial AI
Use full CHAMP (all AI features) when:
- High-ACV deals (>$25k)
- Enterprise accounts
- Strategic partnerships
- ABM target accounts
- When you need complete lead profile
Use partial AI (company + team) when:
- Mid-market deals ($5k-$25k)
- Inbound leads that pass basic qualification
- Building prospect database
- Cost-conscious scraping
Use basic extraction only when:
- Cold outreach lists (high volume)
- Initial qualification (contact info only)
- CRM enrichment
- Bulk prospecting
Optimizing product/ICP descriptions
Update descriptions quarterly:
- Refine based on deals won/lost
- Adjust ICP as you move upmarket/downmarket
- Add new differentiators as product evolves
Test variations:
- Run same prospect with different descriptions
- Compare ICP scores
- See which description yields better CHAMP insights
Keep them current:
- Update integrations list
- Reflect pricing changes
- Adjust employee/revenue ranges as you scale
Interpreting low ICP scores
ICP score <0.50 doesn't mean disqualify:
Check why:
- Company size mismatch: Maybe they're smaller but growing fast
- Industry mismatch: Maybe adjacent industry with same pain points
- Limited data: Sometimes AI can't find enough info (manual review)
Manual review if:
- Inbound lead (they raised hand)
- Referral or strategic fit
- High pain point alignment despite low score
Combining with human research
AI + Human = Best results:
- AI does initial analysis (CHAMP framework)
- SDR validates and enriches:
- Verify decision makers on LinkedIn
- Check recent company news
- Look for buying signals (job changes, funding, etc.)
- AE uses for outreach:
- Personalized email using hooks
- Custom deck addressing challenges
- Value prop aligned with pain points
Time saved: 80% research time reduction
Troubleshooting
Why is company_vitals null?
Possible reasons:
- Not enough content: Site has <5 pages or limited text
- Protected content: Content behind JavaScript/auth
- Language barrier: Non-English site (AI works best in English)
- Generic content: Site is mostly images/videos
Solutions:
- Increase
max_pagesto 20-30 - Enable
spa_enabled: truefor JavaScript-heavy sites - Check
markdown_compendium- if it's mostly empty, not much to extract
Why are team_members empty?
Possible reasons:
- No team page: Site doesn't have /team or /about pages
- Images only: Team info is in images, not text
- Target pages not crawled: Team page wasn't prioritized
Solutions:
- Add to
target_pages:["team", "about", "leadership", "management"] - Increase
max_pagesto crawl more pages - Check if site has /team page manually
Why is ICP fit score 0?
Reasons:
- Missing product/ICP descriptions: You forgot to include them
- Too generic descriptions: AI couldn't match specifics
- Complete mismatch: Prospect truly doesn't fit ICP
Check:
- Verify both
product_descriptionandicp_descriptionare set - Review your descriptions - are they specific enough?
- Look at
champ_analysis- does it show any matches?
Cost Management
Token Cost Calculator
def estimate_tokens(prospects: List[str], ai_features: Dict) -> int:
"""Estimate total AI token cost"""
tokens_per_job = 0
if ai_features.get('extract_company_info'):
tokens_per_job += 500
if ai_features.get('extract_team'):
tokens_per_job += 500
if ai_features.get('extract_pain_points'):
tokens_per_job += 500
if ai_features.get('product_description') and ai_features.get('icp_description'):
tokens_per_job += 1500
total_tokens = len(prospects) * tokens_per_job
return total_tokens
# Example
features = {
'extract_company_info': True,
'extract_team': True,
'extract_pain_points': True,
'product_description': 'Your product...',
'icp_description': 'Your ICP...'
}
prospects = ['url1', 'url2', 'url3'] # 100 prospects
total = estimate_tokens(prospects, features)
print(f"Total tokens: {total:,}")
print(f"Cost (assuming $0.01/1k tokens): ${total/1000 * 0.01:.2f}")