Outbound Relevance Filter (ORF)
This framework defines how to determine whether a business is worth outreach — and the specific reason why.
It is intentionally rules-based, observable, and non-opinionated.
This is the practical companion to “Leads vs Prospects.”
It answers: “Given a business, should we outreach—and what’s the reason?”
Purpose
Below is the full, programmatic spec.
Provide a deterministic filter that:
- decides if a business is worth outreach, and
- produces a single outreach reason anchored to an observable signal.
Core Output (must always produce these fields)
For each business, output:
verdict = {skip | maybe | pursue}primary_reason = one of the allowed reasons (enumerated)evidence = 1–3 short evidence strings (observable)confidence = {low | medium | high}next_action = {send_standard | send_personalized | hold}notes = optional (internal only)
This becomes the shape of your “primary opportunity” column.
Decision Ladder (in order)
Gate 0 — Hard Disqualifiers (auto-skip)
If any are true → verdict=skip immediately.
- No working website
- Website is non-serviceable geography (if you include geo targeting)
- Site is an aggregator/listing only (not the actual business)
- Language mismatch (if you choose to enforce this)
Evidence examples
- “Website unreachable (timeout)”
- “No official website found”
Gate 1 — Basic Readiness (must pass)
If fails → verdict=skip or maybe depending on your policy.
Required:
- Site loads on mobile
- Clear business type / service is identifiable
- At least one conversion path exists (call, form, book)
If missing conversion entirely → verdict=maybe (not skip), because it’s a valid conversion opportunity.
Evidence examples
- “No contact form found”
- “No phone number visible in header/footer”
Gate 2 — Signal Presence (must have ≥1)
verdict=skip.
Signals are grouped and scored below.
Signal Groups and Scoring
Each group produces:
signal_present boolean, severity = {low | medium | high}, and evidence strings.
Then you select a single primary_reason.
Group A — Performance / Speed (Website)
Primary reason candidate: performance_slow_mobile
Scoring thresholds + evidence
High severity
- Mobile LCP > 5s (or Lighthouse performance score < 40)
- CLS visibly broken (layout shift)
Medium
- Lighthouse < 60
Low
- Lighthouse 60–75
Evidence
- “Mobile performance score: 38”
- “Slow initial load on mobile”
Group B — SEO Structure (Index + Service Pages)
Primary reason candidate: seo_thin_or_missing_service_pages
Scoring thresholds + evidence
High
- No service pages OR no location/service targeting pages AND business is local
- Meta titles duplicated across pages
Medium
- Thin content on core service pages
- No internal linking to key services
Low
- Missing basic schema or inconsistent headings
Evidence
- “No dedicated service pages found”
- “Homepage is the only service description”
Group C — Paid Ads Context (if applicable)
Primary reason candidate: ads_running_weak_landing_page
Only if you detect ads activity signals.
Scoring thresholds + evidence
High
- Running ads → landing page mismatch (homepage generic, no dedicated landing)
Medium
- Ads active but site lacks clear funnel
Low
- Pixel present but no clear conversion path
Evidence
- “Meta ads detected; landing page is generic homepage”
- “No dedicated offer/landing page found”
Group D — Conversion Structure (On-site)
Primary reason candidate: conversion_no_clear_next_step
No design critique. Only structural conversion components.
Scoring thresholds + evidence
High
- No primary CTA above the fold
- Forms broken or missing required fields
- No scheduling/contact path
Medium
- CTA exists but buried; no clear next step
Low
- Missing trust elements (not fatal but relevant)
Evidence
- “No primary CTA above fold”
- “Contact form not found; only generic email link”
Group E — Expansion / Hiring (≤90 days)
Primary reason candidate: hiring_recent_growth_signal
Freshness rules apply.
Scoring thresholds + evidence
High
- Hiring for growth/marketing/sales roles recently
Medium
- Multiple openings posted recently
Low
- Careers page exists but stale
Evidence
- “Job postings updated within 30 days”
- “Hiring for marketing role”
Primary Reason Selection (single, deterministic)
Choose one primary_reason per business using this priority:
ads_running_weak_landing_pageconversion_no_clear_next_stepseo_thin_or_missing_service_pagesperformance_slow_mobilehiring_recent_growth_signal
Why this order:
- Ads + conversion gaps are most immediately monetizable for agencies
- SEO structure is next
- Speed is supportive (often paired with SEO)
- Hiring is contextual
Verdict Rules (simple, consistent)
After signals computed:
pursue
- At least one signal with
severity=high, OR - Two signals with
severity=medium
maybe
- Only low signals, OR
- One medium signal but low confidence
skip
- No signals, OR
- Hard disqualifier, OR
- Cannot verify due to blocks (optional policy)
Confidence Rules
-
high: evidence from structured sources (Lighthouse score, explicit page absence, explicit ad activity) medium: evidence from DOM inspection onlylow: partial fetch, incomplete page render, conflicting signals
Example Output (one row)
verdict: pursue primary_reason: seo_thin_or_missing_service_pages evidence: “No dedicated service pages found” “Homepage is only services description” confidence: high next_action: send_standard
Related frameworks
- Leads vs Prospects (classification)
- Message–Signal Alignment (message constraints)
- Signal Decay Model (signal freshness and validity)
- Prospecting Cost Curve (why relevance reduces cost)
Positioning
Frameworks are: how to think, how to decide, how to reason about outbound.
Zendory is built using these principles, not presented as a perfect implementation of them.