Framework

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.
No opinions. No audits. No promises.

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)

If zero signals → it’s a “lead,” not a prospect → verdict=skip.

Signals are grouped and scored below.

Signal Groups and Scoring

Signals must be observable and verifiable.

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 exactly one primary reason.

Choose one primary_reason per business using this priority:

  1. ads_running_weak_landing_page
  2. conversion_no_clear_next_step
  3. seo_thin_or_missing_service_pages
  4. performance_slow_mobile
  5. hiring_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 only
  • low: 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

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.