mcpField
P
phone-verification-waterfall

phone-verification-waterfall

github.com/scientiacapitalMarketing & growth2847 installsUpdated 3w ago
Repository

About phone-verification-waterfall

phone-verification-waterfall is a lead phone-verification workflow for sales development teams. It enriches HubSpot contacts through Apollo and Clay, syncs verified numbers back, and ranks callable leads by role, industry, and intent.

Key features

  1. 01Filter HubSpot leads with exclusion rules
  2. 02Find phones with Apollo, then Clay
  3. 03Write verified numbers to HubSpot
  4. 04Rank by role, industry, and intent
  5. 05Produce chat and CSV call queues
  6. 06Run on schedule or handle urgent leads

Use cases

  1. 01Prepare callable leads for sales teams
  2. 02Enrich contacts Apollo could not match
  3. 03Prioritize high-intent prospects
  4. 04Export a queue for dialer tools

MCP support

The skill describes using HubSpot, Apollo, and Clay tools for lead search, phone lookup, enrichment, and HubSpot updates; it does not specify an MCP interface.

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/scientiacapital/skills --skill phone-verification-waterfall

After installing, type/phone-verification-waterfallin Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

config.json
EXAMPLE_OUTPUTS.md
golden-rules-filter.md
IMPLEMENTATION.md
INTEGRATION_MAP.md
README.md
reference/
callable-queue-format.md
waterfall-example.md

Details

From the project README
Maintain a continuously refreshed inventory of callable leads with verified phone numbers. Automates the waterfall from HubSpot lead identification → Apollo phone verification → Clay enrichment (for Apollo misses) → HubSpot sync. Ensures Tim ALWAYS has 50+ verified dial prospects queued and ready, eliminating "nobody to call" downtime and maximizing daily dial velocity.

Built on: Lead lifecycle → phone verification → queue prioritization by ICP + intent signals.

<quick_start> Standalone run (manual trigger): "verify phones" or "phone waterfall" or "callable leads" or "who can I call" → pulls all HubSpot leads missing phones → enriches via Apollo + Clay → writes back to HubSpot → outputs sortable callable queue

Scheduled run: Every Monday & Wednesday 6:15 AM (between prospect-enrich 6:00 AM and prospect-refresh 6:30 AM) — keeps phone inventory fresh twice-weekly and allows newly refreshed leads to be phone-verified before daily calls

Trigger phrases:

  • "verify phones"
  • "phone waterfall"
  • "callable leads"
  • "who can I call"
  • "dial list"
  • "always have someone to call"
  • "phone check"
  • "enrich phones" </quick_start>

<success_criteria>

  • HubSpot lead pull returns 100+ contacts missing phones from all ICP verticals
  • Apollo phone lookup succeeds for 40-50% of contacts (baseline)
  • Clay waterfall fills 60-70% of remaining Apollo misses
  • HubSpot phone field updated for 70%+ of missing numbers
  • Final callable queue contains 50+ contacts sorted by ICP score + intent
  • Zero contacts belong to customers (lifecycle_stage = 'customer') — Golden Rules block them
  • Zero contacts owned by Account Executives (Lex, Phil, Ron, Anthony) — no AE lead theft
  • Zero channel partners or existing device owners included
  • Execution time under 8 minutes (HubSpot → Apollo → Clay → sync) </success_criteria>

Pipeline Stages

STAGE 1: PULL LEADS          STAGE 2: APOLLO PHONE      STAGE 3: CLAY WATERFALL    STAGE 4: HUBSPOT SYNC    STAGE 5: CALLABLE QUEUE
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
HubSpot Query       →     Apollo People Match    →    Clay Enrichment       →   Update Phone Field   →    Prioritized CLI
phone = null/empty  →     (Name + Email + Org)   →    (Multiple Providers)  →   (API bulk update)    →    ICP Score Sort
lifecycle_stage     →     Return: Verified #     →    Return: Verified #    →   Mark: enriched_at    →    Intent Signals
!= 'customer'       →     Success Rate: 40-50%   →    Success Rate: 30-40%  →   (Contact & Company) →    Output: CSV + Chat
No Excluded Owner   →     (No cost)              →    (Find + Enrich)        →   Log completion       →    Time-to-dial: <5s
Golden Rules Pass   →                            →                          →                        →

Stage 1: Pull Leads Needing Phones

HubSpot Query:

Criteria (ALL must match):
- phone IS NULL OR phone = '' (empty string)
- lifecyclestage != 'customer'
- AE-owned (82625923, 423155215, 190030668): EXCLUDE if <90d activity. KEEP as STALE AE LEAD if >90d inactive (Tim reviews ATL/BTL + value). Ron=all, Lex/Phil=NA only.

Golden Rules Hard Gate (SKIP if ANY match):
- first_conversion contains ['Pearl', 'setup', 'Connect', 'signup']
  (Existing product engagers — not cold prospects)
- company.device_count >= 1
  (Already owns equipment — likely existing relationship)
- is_channel = true
  (Channel partners excluded)
- engagement_overview contains ['Pearl', 'trial', 'demo', 'customer']
  (Existing touchpoints)
ATL/BTL Classification Gate (applied after Golden Rules)

Classify each contact by job title using approved ATL/BTL definitions (see CLAUDE.md § ATL/BTL Classification v1.0):

ATL Title Keywords (budget authority — PRIORITY DIAL): Chief (CIO, CTO, CFO, COO) • VP (AVP, SVP, EVP) • President • Provost • Vice Provost • Superintendent • Director (of IT, Technology, Facilities, Academic Technology, Procurement, Materials Mgmt, Medical Education, Court Administration) • Dean • Court Administrator • Clerk of Court • City Manager • County Manager • Senior Pastor • Executive Pastor

BTL Title Keywords (no budget authority — LOWER PRIORITY): Technician • Specialist • Coordinator • Support • Administrator (Systems/Network/Database) • Engineer (AV/Network/Systems) • Operator • Instructor/Professor/Faculty • Designer • Assistant • Clerk (non-Court Admin) • Volunteer • Intern • Student • Resident • Help Desk

NEVER ATL — Auto-classify BTL regardless of other signals: Warehouse Manager • Network Manager • Systems Administrator • AV Technician • Graphic Design Instructor • Program Administrator • Web Designer • Classroom Support • Lab Coordinator • Maintenance • Building Engineer • Multimedia Services Manager • Video Production Specialist • Streaming Crew

Gray Zone — Flag for manual review: Manager (AV/Facilities/IT) — ATL only if reports to Director+ AND has delegated budget >$25K Department Chair • Program Director • Director of Educational Technology

Tag each contact: atl_btl_tier = 'ATL' | 'BTL' | 'GRAY'

Output: Unsorted list of 100+ contacts with:

  • contact_id (HubSpot)
  • first_name, last_name
  • email (primary business email)
  • company_name
  • hs_job_title
  • hubspot_owner_id, hubspot_owner_name
  • company.industry, company.num_employees, company.hs_lead_status
  • first_conversion (for Golden Rules check)

Tool: hubspot_search_contacts with filters applied

</Stage 1>

Stage S — Suppression Gate

Before phone enrichment spend, exclude suppressed contacts:

  • EXCLUDE if bdr_suppression_until IS SET AND bdr_suppression_until > TODAY
  • INCLUDE if bdr_suppression_until IS NOT SET (never suppressed)
  • INCLUDE if bdr_suppression_until < TODAY (cooling period expired)

HubSpot filter: propertyName: "bdr_suppression_until", operator: "NOT_HAS_PROPERTY" OR operator: "LT", value: TODAY_ISO Reference: lead-suppression-spec (bdr_suppressed, bdr_suppression_reason, bdr_suppression_until)


Stage 2: Apollo Phone Lookup

For each contact from Stage 1, run in parallel batches:

Input:  contact_id, first_name, last_name, email, company_name
        ↓
apollo_people_match(
  first_name: "{first_name}",
  last_name: "{last_name}",
  email: "{email}",
  organization_name: "{company_name}",
  domain: "{company_domain}",
  reveal_personal_emails: false
)
        ↓
Output: phone (mobile_phone or corporate_phone, verified)
        ↓
Match rate: 40-50% success (Apollo baseline)
        ↓
NO COST — Apollo is included free

Logic:

  • Apollo returns mobile_phone or corporate_phone (both acceptable for dial)
  • If phone returned: tag contact apollo_phone_source = true
  • If no phone: move to Stage 3 (Clay waterfall)
  • Keep all results for final merge

Tool: apollo_people_match (batch parallel)

</Stage 2>

Stage 3: Clay Waterfall Enrichment

For contacts where Apollo returned NO phone, use Clay:

Option A: Company-level enrichment (recommended for speed)

find-and-enrich-contacts-at-company(
  companyIdentifier: "{company_domain}",
  contactFilters: {
    job_title_keywords: extracted from hs_job_title,
    locations: optional if available
  },
  dataPoints: {
    contactDataPoints: [
      { type: "Email" },
      { type: "Summarize Work History" }
    ]
  }
)

Then for contacts found, run add-contact-data-points to enrich phones:

add-contact-data-points(
  taskId: "{from find-and-enrich response}",
  dataPoints: [
    { type: "Custom", customDataPoint: "phone number from multiple providers" }
  ],
  entityIds: [extracted contact IDs]
)

Option B: Direct contact enrichment (if company approach yields few)

find-and-enrich-list-of-contacts(
  contactIdentifiers: [
    {
      contactName: "{first_name} {last_name}",
      companyIdentifier: "{company_domain}"
    }
  ],
  dataPoints: {
    contactDataPoints: [
      { type: "Custom", customDataPoint: "verified phone number" }
    ]
  }
)

Expected yield:

  • 30-40% of Apollo misses will get phones via Clay
  • Combined success rate: 40-50% (Apollo) + 30-40% of remainder (Clay) ≈ 65-70% total

Cost: Clay credits consumed (monitor spend against monthly allocation)

Tool: find-and-enrich-contacts-at-company or find-and-enrich-list-of-contacts

</Stage 3>

Stage 4: HubSpot Sync

For all contacts with verified phones (Apollo + Clay combined):

Batch update HubSpot contacts:
For each contact:
  UPDATE contact {contact_id}
  SET:
    phone = "{verified_phone}"
    phone_source = "apollo" OR "clay" (track origin)
    phone_verified_at = NOW()
    phone_waterfall_pass = true

Log event to company:
  ADD ACTIVITY: "Phone verified via Apollo/Clay waterfall"
  (Creates audit trail for Sales)

Sync strategy:

  • Use HubSpot API in batches (500 contacts per batch)
  • Tag with phone_source (apollo, clay, manual)
  • Tag with phone_verified_at timestamp
  • Log completion to deal/company object if linked

Tool: HubSpot REST API (contacts batch update) via hubspot_update_contact (per-contact; no batch MCP tool) or direct HTTP

</Stage 4>

Stage 5: Callable Queue & Prioritization

Build final output sorted by:

  1. ATL/BTL Tier (primary): ATL contacts first, then GRAY, then BTL

  2. ICP Vertical Score (secondary):

    Higher Ed ..................... 90
    Courts/Legal ................... 85
    Government ..................... 80
    Corporate AV ................... 80
    Healthcare ..................... 75
    Houses of Worship .............. 70
    K-12 Schools ................... 65
    
  3. Intent Signals (tertiary):

    • Hiring active AV/IT roles: +15 points
    • Recent facility expansion news: +10 points
    • Tech stack shows obsolete AV (Extron, Matrox replacement signal): +12 points
    • Published RFP or procurement event: +10 points
    • Website mentions studio/control room/broadcast: +8 points
    • Recent funding/acquisition: +5 points
  4. Engagement Recency (quaternary):

    • Touched within 30 days: top of queue
    • Touched 31-60 days: middle
    • No recent touch: bottom (but still callable)

Final Callable Queue Format:

See reference/callable-queue-format.md for the full ASCII queue output template (summary block, ready-to-dial table, dialer quick links, next steps).

Output formats:

  • Chat: Rich formatted table (template in reference/callable-queue-format.md) with top 10-20 by ICP score
  • CSV download: Full queue with all data for import to dialpad/Aircall
  • By Vertical: Secondary view grouped by industry for vertical hunting
  • Integration: Link to import queue to Dialpad, Aircall, or sales engagement tool

Tool: Assemble from Stage 4 output, sort, format, and present

</Stage 5>

Reply-Scan Integration

Automated queuing from reply scans (10 AM, 1 PM, 3 PM):

When reply scans discover new leads with missing phone numbers:

  • These leads are automatically queued for the next scheduled phone waterfall run (Monday or Wednesday 6:15 AM)
  • Standard enrichment workflow applies (Apollo → Clay waterfall → HubSpot sync)

Urgent high-ICP lead handling:

  • For leads scoring 80+ ICP and deemed high-priority prospects, trigger an immediate single-contact Apollo lookup
  • If Apollo succeeds, append phone to contact record and add to current day's dial queue
  • If Apollo fails, hold for next scheduled waterfall run (standard workflow)

Logic:

IF reply_scan_found_lead AND lead.phone IS NULL
  IF lead.icp_score >= 80 AND lead.priority = 'high'
    → TRIGGER immediate apollo_people_match(lead)
    → IF success: append phone, mark urgent_dial = true
    → ELSE: queue for next waterfall run
  ELSE
    → Queue for next scheduled waterfall (Mon or Wed 6:15 AM)

This ensures urgent prospects get callable status same-day while maintaining efficiency of batch enrichment for standard leads.

Scheduled Automation

Cron: Every Monday & Wednesday 6:15 AM (UTC, or Tim's local timezone)

MONDAY MORNING SEQUENCE:
6:00 AM  → bdr-v3-prospect-enrich (refresh prospect company data)
6:15 AM  → phone-verification-waterfall-skill (verify phones on refreshed data)
6:30 AM  → bdr-v3-prospect-refresh (refresh deal velocity metrics)

WEDNESDAY MORNING SEQUENCE (mid-week refresh):
6:00 AM  → bdr-v3-prospect-enrich (refresh prospect company data)
6:15 AM  → bdr-v3-phone-waterfall-midweek (verify phones on mid-week refreshed data)
6:30 AM  → bdr-v3-prospect-refresh (refresh deal velocity metrics)

Why 6:15 AM Monday & Wednesday?

  • Monday: Sunday evening prospect research populates HubSpot with new prospects; 6:00 AM enrich ensures firmographic data is current; 6:15 AM phone verification catches those prospects while fresh; 6:30 AM velocity refresh gives Tim complete picture before first calls
  • Wednesday: Mid-week lead refresh captures newly added prospects from Tue-Wed research; ensures stable of callable leads remains 50+ through week; separate task (bdr-v3-phone-waterfall-midweek) allows independent scheduling and monitoring

Operational notes:

  • If phone waterfall takes >8 min, send Slack alert (indicates API slowness or large backlog)
  • Log success rate to dashboard (aim for 65%+ total verified)
  • If Apple/Apollo API rate limits hit, queue and retry with exponential backoff
  • On error: skip Clay enrichment and return Apollo-only results (better to have some phones than none)
## Required MCP Tools
Epiphan CRM (primary data source)
  • hubspot_search_contacts — Pull leads with phone = null, apply Golden Rules filters
  • hubspot_get_contact — Retrieve full contact details if needed
  • crm_search_customers — Check company against Epiphan customer database (device_count, channel flag)
Apollo (phone verification stage 2)
  • apollo_people_match — Look up person by name + email + company, return verified phone
  • (No cost — included in Apollo plan)
Clay (phone waterfall stage 3)
  • find-and-enrich-contacts-at-company — Batch enrich by company + job title filters
  • add-contact-data-points — Add custom phone data point to enrich results
  • find-and-enrich-list-of-contacts — Enrich specific contacts by name + company
  • get-task — Poll for async enrichment results
  • (Costs Clay credits — monitor spend)
HubSpot API (sync stage 4)
  • hubspot_update_contact (per-contact loop; batch only via direct REST API) — Write verified phones back to HubSpot
  • Or native HubSpot bulk import if preferred

Sibling Skills & Related Tasks Referenced

  • prospect-research-to-cadence-skill — Lead quality gates, Golden Rules filter, ICP scoring
  • sales-revenue-skill — ICP vertical definitions, intent signal weighting
  • hubspot-revops-skill — HubSpot bulk operations, contact filtering patterns, owner ID mapping
  • CLAUDE.md § ATL/BTL Classification v1.0 — Approved title keyword patterns for ATL/BTL/Gray classification (2026-03-17)

Upstream & Downstream Scheduled Tasks

  • bdr-v3-prospect-enrich — Monday 6:00 AM firmographic refresh (runs before phone waterfall)
  • bdr-v3-phone-waterfall-midweek — Wednesday 6:15 AM mid-week phone verification run (NEW)
  • bdr-v3-prospect-refresh — Monday 6:30 AM velocity refresh (runs after phone waterfall)

External Dependencies

  • HubSpot API: Contact search + bulk update
  • Apollo API: People match (no additional cost)
  • Clay API: Waterfall enrichment (requires active subscription + available credits)
  • Dialpad/Aircall API: Optional integration for direct dial queue sync

Estimated Monthly Cost

  • Apollo: $0 (included)
  • Clay: $150-300 depending on contacts enriched (monitor waterfall stage)
  • HubSpot: Already in use
  • Total variable: ~$200-300/month (Clay credits)

<scheduled_automation>

Task IDs:

  • bdr-v3-phone-waterfall (Monday 6:15 AM run)
  • bdr-v3-phone-waterfall-midweek (Wednesday 6:15 AM run)

Trigger: Recurring, every Monday & Wednesday at 6:15 AM (user's local timezone)

Slack Notification on Completion:

✅ Phone Waterfall Complete (Mon 6:15 AM)
   Pulled:       {N} leads
   Verified:     {X+Y} phones ({%})
   HubSpot Sync: ✓
   Queue:        Ready to dial
   Leads/hour:   {rate}

On Error:

⚠️ Phone Waterfall Partial (Mon 6:15 AM)
   Apollo completed ({X%})
   Clay failing — check credits
   Manual action: Continue with Apollo-only queue

</scheduled_automation>


Reference: Golden Rules Filter

These are hard gates — if ANY condition matches, skip the contact entirely:

ConditionValueAction
lifecyclestage'customer'SKIP
first_conversioncontains 'Pearl' OR 'setup' OR 'Connect'SKIP
Company device_count>= 1SKIP
Company is_channeltrueSKIP
hubspot_owner_id82625923, 423155215, 19003066890-day stale exception: KEEP if no activity >90d (Tim reviews ATL/BTL + value). SKIP if <90d. Ron=all, Lex/Phil=NA only.

</Golden Rules>


Example: Phone Waterfall in Action

See reference/waterfall-example.md for a full worked run (247 leads pulled -> 159 verified callable, 64.4% success, 7 min 30 sec).

Emit Outcome Sidecar

Write ~/.claude/skill-analytics/last-outcome-phone-verification-waterfall.json: {"ts":"[UTC ISO8601]","skill":"phone-verification-waterfall","version":"1.0.0","variant":"default","status":"[success|partial|error]","runtime_ms":[ms],"metrics":{"contacts_processed":[n],"apollo_verified":[n],"clay_verified":[n],"total_callable":[n],"verification_rate_pct":[n]},"error":null,"session_id":"[YYYY-MM-DD]"}

Comments

Markdown supported