inbound-lead-qualification
Qualifies inbound leads against full ICP criteria — company size, industry, use case fit, role/seniority of the person. Checks CRM and existing customer base for duplicates and existing relationships. Outputs a scored CSV with qualification status, reasoning, and pipeline overlap flags. Tool-agnostic — works with any CRM, enrichment tool, or data source.
Best use case
inbound-lead-qualification is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Qualifies inbound leads against full ICP criteria — company size, industry, use case fit, role/seniority of the person. Checks CRM and existing customer base for duplicates and existing relationships. Outputs a scored CSV with qualification status, reasoning, and pipeline overlap flags. Tool-agnostic — works with any CRM, enrichment tool, or data source.
Teams using inbound-lead-qualification should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/inbound-lead-qualification/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How inbound-lead-qualification Compares
| Feature / Agent | inbound-lead-qualification | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Qualifies inbound leads against full ICP criteria — company size, industry, use case fit, role/seniority of the person. Checks CRM and existing customer base for duplicates and existing relationships. Outputs a scored CSV with qualification status, reasoning, and pipeline overlap flags. Tool-agnostic — works with any CRM, enrichment tool, or data source.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
Related Guides
SKILL.md Source
# Inbound Lead Qualification
Takes a set of inbound leads and validates each against your full ICP criteria. Not a fast-pass triage (that's `inbound-lead-triage`) — this is the thorough qualification step that determines whether a lead is genuinely worth pursuing, and produces a scored CSV for the team.
## When to Auto-Load
Load this composite when:
- User says "qualify these inbound leads", "check if these leads are ICP", "score my inbound"
- An upstream triage has been completed and leads need deeper qualification
- User has a batch of leads and wants a qualified/disqualified verdict on each
## Architecture
```
[Inbound Leads] → Step 1: Load ICP & Config → Step 2: CRM/Pipeline Check → Step 3: Company Qualification → Step 4: Person Qualification → Step 5: Use Case Fit → Step 6: Score & Verdict → Step 7: Output CSV
```
---
## Step 0: Configuration (Once Per Client)
On first run, establish the ICP definition and CRM access. Save to `clients/<client-name>/config/lead-qualification.json`.
```json
{
"icp_definition": {
"company_size": {
"min_employees": null,
"max_employees": null,
"sweet_spot": "",
"notes": ""
},
"industry": {
"target_industries": [],
"excluded_industries": [],
"notes": ""
},
"use_case": {
"primary_use_cases": [],
"secondary_use_cases": [],
"anti_use_cases": [],
"notes": ""
},
"company_stage": {
"target_stages": [],
"excluded_stages": [],
"notes": ""
},
"geography": {
"target_regions": [],
"excluded_regions": [],
"notes": ""
}
},
"buyer_personas": [
{
"name": "",
"titles": [],
"seniority_levels": [],
"departments": [],
"is_economic_buyer": false,
"is_champion": false,
"is_user": false
}
],
"hard_disqualifiers": [],
"hard_qualifiers": [],
"crm_access": {
"tool": "Supabase | HubSpot | Salesforce | CSV export | none",
"access_method": "",
"tables_or_objects": []
},
"existing_customer_source": {
"tool": "Supabase | CRM | CSV | none",
"access_method": ""
},
"qualification_prompt_path": "path/to/lead-qualification/prompt.md or null"
}
```
**If `lead-qualification` capability already has a saved qualification prompt:** Reference it directly — don't rebuild ICP criteria from scratch.
**On subsequent runs:** Load config silently.
---
## Step 1: Load ICP Criteria & Parse Leads
### Process
1. Load the client's ICP config (or qualification prompt from `lead-qualification` capability)
2. Parse the inbound lead list — accept any format:
- Output from `inbound-lead-triage` (already normalized)
- Raw CSV with any column structure
- Pasted list of names/emails/companies
- CRM export
3. Identify what data is available vs. missing per lead:
- **Have:** Fields present in the input
- **Need:** Fields required for qualification but missing
- **Gap report:** "X leads have company name, Y have title, Z have nothing but email"
### Output
- Parsed lead list with available/missing field inventory
- Gap report for the user
### Human Checkpoint
If >50% of leads are missing critical fields (company name or person title), recommend running `inbound-lead-enrichment` first. Ask: "Many leads are missing company/title data. Want me to enrich them first, or qualify with what's available?"
---
## Step 2: CRM & Pipeline Check
### Process
For each lead, check against existing data sources to identify overlaps:
**Check 1 — Existing customer?**
- Search customer database by company domain/name
- If match found: Flag as `existing_customer` with customer details (plan, account owner, contract status)
- This is NOT a disqualification — it's a routing flag (upsell vs. new business)
**Check 2 — Already in pipeline?**
- Search CRM/Supabase for the company in active deals
- If match found: Flag as `in_pipeline` with deal details (stage, owner, last activity)
- Critical: Sales rep should know before reaching out that a colleague already has this account
**Check 3 — Previous engagement?**
- Search outreach logs for the email/company
- If match found: Flag as `previously_contacted` with history summary (when, what channel, outcome)
**Check 4 — Known from signal composites?**
- Search Supabase signals table for the company
- If match found: Flag as `signal_flagged` with signal type and date
### Output
Each lead tagged with:
- `pipeline_status`: `new` | `existing_customer` | `in_pipeline` | `previously_contacted`
- `pipeline_detail`: One sentence explaining the overlap (or null)
- `signal_flags`: Any signal composite matches
### Handling Overlaps
- **Existing customer:** Don't disqualify. Mark separately. Might be expansion/upsell.
- **In pipeline:** Don't disqualify. Flag for sales rep coordination. Note the existing deal owner.
- **Previously contacted but no response:** Still qualify. The inbound signal means they're now warmer.
- **Previously contacted and rejected:** Still qualify the inbound. People change their minds. Note the prior context.
---
## Step 3: Company Qualification
### Process
For each lead's company, evaluate against every ICP company dimension:
**Dimension 1 — Company Size**
- Check employee count against ICP range
- Sources: enrichment data, LinkedIn company page, web search
- Score: `match` | `borderline` | `mismatch` | `unknown`
- Note: If the lead is from a subsidiary or division, evaluate the relevant unit, not the parent company
**Dimension 2 — Industry**
- Check against target and excluded industry lists
- Be smart about classification: "AI-powered HR platform" matches both "AI/ML" and "HR Tech"
- Score: `match` | `adjacent` (related but not core target) | `mismatch` | `unknown`
**Dimension 3 — Company Stage**
- Seed, Series A, Series B+, Growth, Public, Bootstrapped
- Sources: Crunchbase, news, enrichment data
- Score: `match` | `borderline` | `mismatch` | `unknown`
**Dimension 4 — Geography**
- Check HQ location and/or the specific person's location
- For remote-first companies, check where the majority of the team is
- Score: `match` | `borderline` | `mismatch` | `unknown`
**Dimension 5 — Use Case Fit**
- Based on what the company does, could they plausibly use the product?
- This is the most nuanced dimension — requires understanding both the product and the company's operations
- Sources: company website, product description, job postings (hint at internal tools/processes)
- Score: `strong_fit` | `moderate_fit` | `weak_fit` | `no_fit` | `unknown`
### Output
Each lead gets a `company_qualification` block:
```
{
"company_size": { "score": "", "value": "", "reasoning": "" },
"industry": { "score": "", "value": "", "reasoning": "" },
"stage": { "score": "", "value": "", "reasoning": "" },
"geography": { "score": "", "value": "", "reasoning": "" },
"use_case": { "score": "", "value": "", "reasoning": "" },
"company_verdict": "qualified | borderline | disqualified | insufficient_data"
}
```
---
## Step 4: Person Qualification
### Process
For each lead's contact person, evaluate against buyer persona criteria:
**Dimension 1 — Title/Role Match**
- Check title against buyer persona title lists
- Handle variations: "VP of Marketing" = "Vice President, Marketing" = "VP Marketing"
- Be smart about title inflation at small companies (a "Director" at a 10-person startup ≠ "Director" at a 10,000-person enterprise)
- Score: `exact_match` | `close_match` | `adjacent` | `mismatch` | `unknown`
**Dimension 2 — Seniority Level**
- Map to: Individual Contributor, Manager, Director, VP, C-Level, Founder
- Check against ICP seniority requirements
- Score: `match` | `too_junior` | `too_senior` | `unknown`
**Dimension 3 — Department**
- Engineering, Product, Marketing, Sales, Operations, Finance, HR, etc.
- Check against ICP department targets
- Score: `match` | `adjacent` | `mismatch` | `unknown`
**Dimension 4 — Authority Type**
- Based on title + seniority, classify:
- `economic_buyer` — Can sign the check
- `champion` — Wants it, can influence the decision
- `user` — Would use it daily, can validate need
- `evaluator` — Tasked with research, limited decision power
- `gatekeeper` — Can block but not approve
- `unknown`
**Dimension 5 — Right Person, Wrong Company (or Vice Versa)**
- If company qualifies but person doesn't: Flag as `right_company_wrong_person` — this is a referral opportunity
- If person qualifies but company doesn't: Flag as `right_person_wrong_company` — rare for inbound, but possible with job changers
### Output
Each lead gets a `person_qualification` block:
```
{
"title_match": { "score": "", "value": "", "reasoning": "" },
"seniority": { "score": "", "value": "", "reasoning": "" },
"department": { "score": "", "value": "", "reasoning": "" },
"authority_type": "",
"person_verdict": "qualified | borderline | disqualified | insufficient_data",
"mismatch_type": "null | right_company_wrong_person | right_person_wrong_company"
}
```
---
## Step 5: Use Case Fit Assessment
### Process
This step connects the company's likely needs to your product's actual capabilities. It goes deeper than Step 3's company-level use case check.
1. **Infer the lead's intent** from their inbound action:
- Demo request message → What did they say they need?
- Content downloaded → What topic were they researching?
- Webinar attended → What problem were they trying to solve?
- Free trial signup → What feature did they try first?
- Chatbot conversation → What questions did they ask?
2. **Map intent to product capabilities:**
- Does the product actually solve what they seem to need?
- Is this a primary use case or a stretch?
- Are there known limitations that would disappoint them?
3. **Assess implementation feasibility:**
- Based on company size and stage, can they realistically implement?
- Do they likely have the technical resources / team to adopt?
- Any known blockers for companies like this? (e.g., "banks need SOC2 and we don't have it yet")
### Output
```
{
"inferred_intent": "",
"intent_source": "",
"product_fit": "strong | moderate | weak | unknown",
"product_fit_reasoning": "",
"implementation_feasibility": "easy | moderate | complex | unlikely",
"known_blockers": []
}
```
---
## Step 6: Score & Verdict
### Scoring Logic
Combine all dimensions into a final qualification verdict.
**Composite Score Calculation:**
| Dimension | Weight | Possible Values |
|-----------|--------|-----------------|
| Company Size | 15% | match=100, borderline=50, mismatch=0, unknown=30 |
| Industry | 20% | match=100, adjacent=60, mismatch=0, unknown=30 |
| Company Stage | 10% | match=100, borderline=50, mismatch=0, unknown=30 |
| Geography | 10% | match=100, borderline=50, mismatch=0, unknown=30 |
| Use Case Fit | 25% | strong=100, moderate=60, weak=20, no_fit=0, unknown=30 |
| Person Title/Role | 15% | exact=100, close=75, adjacent=40, mismatch=0, unknown=30 |
| Person Seniority | 5% | match=100, too_junior=20, too_senior=60, unknown=30 |
**Hard overrides (bypass the score):**
- Any hard disqualifier present → `disqualified` regardless of score
- Any hard qualifier present → `qualified` regardless of score (but still show the full breakdown)
- Existing customer → Route separately, don't score as new lead
**Verdict thresholds:**
- **Score ≥ 75:** `qualified` — Pursue actively
- **Score 50-74:** `borderline` — Qualified with caveats, may need manual review
- **Score 30-49:** `near_miss` — Not qualified now, but close enough to consider (referral or nurture)
- **Score < 30:** `disqualified` — Does not fit ICP
**Sub-verdicts for routing:**
- `qualified_hot` — Score ≥ 75 AND Tier 1/2 urgency from triage
- `qualified_warm` — Score ≥ 75 AND Tier 3/4 urgency
- `borderline_review` — Score 50-74, needs human judgment call
- `near_miss_referral` — Score 30-49 AND right_company_wrong_person (referral opportunity)
- `near_miss_nurture` — Score 30-49, might fit in the future
- `disqualified_polite` — Score < 30, needs polite decline
- `disqualified_competitor` — Competitor employee
- `existing_customer_upsell` — Existing customer with expansion signal
### Output
Each lead gets:
```
{
"composite_score": 0-100,
"verdict": "",
"sub_verdict": "",
"top_qualification_reasons": [],
"top_disqualification_reasons": [],
"summary": "One sentence: why this lead is/isn't a fit"
}
```
---
## Step 7: Output CSV
### CSV Structure
Produce a CSV with ALL input fields preserved plus qualification columns appended:
**Core qualification columns:**
- `qualification_verdict` — qualified | borderline | near_miss | disqualified
- `qualification_sub_verdict` — qualified_hot | qualified_warm | borderline_review | near_miss_referral | near_miss_nurture | disqualified_polite | disqualified_competitor | existing_customer_upsell
- `composite_score` — 0-100
- `summary` — One sentence qualification reasoning
**Pipeline check columns:**
- `pipeline_status` — new | existing_customer | in_pipeline | previously_contacted
- `pipeline_detail` — One sentence on the overlap
- `signal_flags` — Any signal composite matches
**Company qualification columns:**
- `company_size_score` — match | borderline | mismatch | unknown
- `industry_score` — match | adjacent | mismatch | unknown
- `stage_score` — match | borderline | mismatch | unknown
- `geography_score` — match | borderline | mismatch | unknown
- `use_case_score` — strong | moderate | weak | no_fit | unknown
**Person qualification columns:**
- `title_match_score` — exact_match | close_match | adjacent | mismatch | unknown
- `seniority_score` — match | too_junior | too_senior | unknown
- `authority_type` — economic_buyer | champion | user | evaluator | gatekeeper | unknown
- `mismatch_type` — null | right_company_wrong_person | right_person_wrong_company
**Use case columns:**
- `inferred_intent` — What they seem to need
- `product_fit` — strong | moderate | weak | unknown
- `implementation_feasibility` — easy | moderate | complex | unlikely
### Save Location
`clients/<client-name>/leads/inbound-qualified-[date].csv`
### Summary Report
After producing the CSV, present a summary:
```markdown
## Inbound Lead Qualification: [Period]
**Total leads processed:** X
**Qualified:** X (Y%) — X hot, X warm
**Borderline (manual review):** X (Y%)
**Near miss:** X (Y%) — X referral opportunities, X nurture
**Disqualified:** X (Y%)
**Pipeline overlaps:**
- Existing customers: X (route to CS)
- Already in pipeline: X (coordinate with deal owner)
- Previously contacted: X (now warmer — re-engage)
**Top qualification reasons:**
1. [reason] — X leads
2. [reason] — X leads
**Top disqualification reasons:**
1. [reason] — X leads
2. [reason] — X leads
**Data quality:**
- Leads with full data: X
- Leads with partial data (some dimensions scored as 'unknown'): X
- Leads needing enrichment: X
**CSV saved to:** [path]
```
---
## Handling Edge Cases
**Lead with only an email (no name, no company):**
- Extract company domain from email
- If corporate domain: look up the company, proceed with company qualification (person qualification will be mostly "unknown")
- If personal email (gmail, yahoo): Score as `insufficient_data`, recommend enrichment or manual review
**Same company, multiple leads:**
- Qualify the company once, apply to all leads from that company
- Person qualification runs individually for each
- Flag the multi-contact opportunity: "3 people from [Company] came inbound — potential committee buy"
**Contradictory signals:**
- Company is strong fit but person is completely wrong (e.g., intern at a perfect company)
- Score honestly. The sub-verdict `right_company_wrong_person` routes this to referral handling in `disqualification-handling`
**Borderline calls:**
- When the score is 50-74 and could go either way, lean toward qualifying for inbound leads
- Rationale: they came to YOU. The intent signal tips borderline cases toward "worth a conversation"
- Note this lean in the reasoning: "Borderline on [dimension], but inbound intent suggests pursuing"
**Scoring with missing data:**
- Unknown dimensions score at 30 (not 0, not 50) — absence of data is mildly negative but not disqualifying
- If >3 dimensions are "unknown", the lead is `insufficient_data` regardless of score — recommend enrichment first
---
## Tools Required
- **CRM access** — to check pipeline, existing customers, outreach history
- **Supabase client** — for pipeline/signal lookups
- **Web search** — for company research when enrichment data is sparse
- **Enrichment tools** — Apollo, LinkedIn scraper, or similar (optional, enhances accuracy)
- **Read/Write** — for CSV I/O and config managementRelated Skills
lead-discovery
Orchestrator that runs first for lead generation requests. Gathers business context via website analysis or questions, identifies competitors, builds ICP, and routes to signal skills with pre-filled inputs.
leadership-change-outreach
End-to-end leadership change signal composite. Takes any set of companies, detects recent leadership changes (new VP+, C-suite hires and promotions), evaluates relevance to your product, and drafts personalized outreach. Uses Apollo People Search (free) for fast detection + Apollo Enrichment (1 credit/person) for employment history, start dates, LinkedIn URLs, and verified emails.
inbound-lead-triage
Triages all inbound leads from a given period — demo requests, free trial signups, content downloads, webinar registrations, chatbot conversations. Classifies by urgency, qualifies against ICP, enriches with context, and produces a prioritized action queue with recommended response for each lead. Tool-agnostic — works with any CRM, form tool, or lead source.
inbound-lead-enrichment
Fills in missing data for inbound leads — researches the company, identifies the person's role and seniority, finds other stakeholders at the company, checks for existing CRM relationships, and updates the lead record. Produces enriched lead data ready for qualification or outreach. Tool-agnostic.
get-qualified-leads-from-luma
End-to-end lead prospecting from Luma events. Searches Luma for events by topic and location, extracts all attendees/hosts, qualifies them against a qualification prompt, outputs results to a Google Sheet, and sends a Slack alert with top leads. Use this skill whenever someone wants to find qualified leads from events, prospect event attendees, or run an event-based lead gen workflow. Also triggers for "find people at events and qualify them" or "who's attending X events that matches our ICP."
disqualification-handling
Handles disqualified and near-miss inbound leads gracefully. Drafts polite rejection emails, referral requests (right company wrong person), and nurture routing (future fit). Ensures no inbound lead gets ignored and every disqualification preserves the relationship. Tool-agnostic.
lead-qualification
Lead qualification engine with conversational intake. Asks structured questions to understand your qualification criteria, generates a reusable qualification prompt, then batch-enriches leads via Apify LinkedIn scraping and scores them with parallel processing. Outputs qualified/disqualified verdicts with confidence scores and reasoning to Google Sheets (via Rube) or CSV. Supports calibration mode for prompt refinement.
apollo-lead-finder
Two-phase Apollo.io prospecting: free People Search to discover ICP-matching leads, then selective enrichment to reveal emails/phones (credits per contact). Creates Apollo lists. Deduplicates against Supabase.
signal-detection-pipeline
Detect buying signals from multiple sources, qualify leads, and generate outreach context
seo-content-engine
Build and run an SEO content engine: audit current state, identify gaps, build keyword architecture, generate content calendar, draft content.
outbound-prospecting-engine
End-to-end outbound prospecting: detect intent signals, research companies, find decision-maker contacts, personalize messaging, launch campaign.
event-prospecting-pipeline
Find attendees at conferences/events, research their companies, qualify against ICP, and launch outreach