Rex Automaton
All posts
Lead GenerationSeptember 4, 20268 min read

How we built an inbound growth engine for VenueX AI

Named case study: we shipped a custom inbound engine for VenueX AI with directory scrapes, hyper-personalized outreach, LinkedIn autopilot, and client-owned infra. Closed at $2,800/mo, first agent live in under a week.

By Jacky Lei

We designed, built, and launched an inbound growth engine for VenueX AI that sources venue prospects from niche directories, enriches and personalizes at scale, runs cold email and LinkedIn in parallel, and routes replies for fast human follow-up. It was built for a vertical SaaS founder who needed a repeatable channel not dependent on partners.

Inbound growth engine: a system that continuously turns targeted traffic and prospect data into qualified demos and pipeline using owned infrastructure and automated workflows.

The problem it solves

VenueX AI relied on an unreliable partnership channel and had no scalable owned engine. Generic data vendors underperformed for wedding and event venues, prior cold outreach had weak targeting, and content was irregular. The ask: stand up a durable inbound motion that the founder owns end to end.

TaskManual status quoAutomated with our build
Lead sourcingHand-built lists from generic tools, high noiseCustom directory scrapes for The Knot, WeddingWire, Here Comes the Guide, Zola with dedup and city filters
Enrichment + targetingAd hoc lookups, slow personalizationLayered enrichment, buy-signal checks, dynamic segments per market and venue type
Email sendingOne account, inconsistent cadenceMultiple warmed domains, daily caps, safe schedules, atomic verify-then-activate
PersonalizationSparse or templatizedHyper-personalized openers from scraped profiles and pages, human tone guardrails
LinkedIn presenceFounder posts sporadicallyQueue-driven LinkedIn autopilot for company and founder pages
Reply routingInbox chaosReply monitor and Gmail deep-links, single owner per conversation

Answer-first: we replaced a partner-dependent trickle with a repeatable, owned engine that finds the right venues, speaks to them with on-brand context, and books qualified demos.

How the automation works

Answer-first: data flows from niche directories into a segmentation and personalization engine, then into parallel channels: cold email and LinkedIn. Replies route to a lightweight dashboard that points to the right inbox and thread.

  • Lead sources: custom scrapers for the four dominant venue directories plus client-provided seed lists. Each record carries venue name, city, URL, and basic signals.
  • Enrichment and segmentation: light website reads and social handles when available. We score and segment by market, capacity hints, and offering fit before any email is drafted.
  • Personalization engine: an LLM-assisted writer produces short, specific openers anchored to scraped facts, with deterministic guardrails so we never invent claims.
  • Email delivery: warmed sender pool on look-alike domains, daily caps, verifier-first workflow, and campaign templates with safe spintax. Activation only after verify and dedup.
  • LinkedIn autopilot: a queue posts founder and company updates on a fixed cadence with a first-comment link pattern and persona themes tied to the product's wins.
  • Reply routing: a small Next.js panel polls providers, shows which inbox to reply from, and deep-links to the live thread for speed-to-human.

VenueX AI inbound growth engine: directory scrapes feed a personalization engine, which powers email + LinkedIn in parallel, with replies routed to a monitor panel

Step-by-step: how to build it

1) Set up sending domains and warmup

Answer-first: configure look-alike domains, add SPF, DKIM, and DMARC, then warm steadily before volume. We keep this on the client's registrar and workspace for ownership.

# DNS checklist (per sending domain)
A       @           -> host IP or provider record
MX      @           -> workspace MX
TXT     @           v=spf1 include:workspace ~all
TXT     _dmarc      v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain; fo=1
CNAME   selector1._domainkey -> provider DKIM
CNAME   selector2._domainkey -> provider DKIM
# Warmup: start ~10/day, +10 per day, pause on >3% bounce

Key gotcha: never activate sequences until verification completes and bounces are under control.

2) Build directory scrapers for accurate venue data

Answer-first: scrape the four venue directories with polite rate limiting and selectors hardened to layout drift. We dedup across sources by domain and name:city keys.

import time, random, requests
from bs4 import BeautifulSoup
 
UA = {"User-Agent": "Mozilla/5.0"}
 
def fetch_list(url):
    r = requests.get(url, headers=UA, timeout=20)
    r.raise_for_status()
    soup = BeautifulSoup(r.text, "html.parser")
    for card in soup.select("article.venue-card"):
        name = card.select_one("h3").get_text(strip=True)
        city = card.select_one(".city").get_text(strip=True)
        href = card.select_one("a")["href"]
        yield {"name": name, "city": city, "url": href}
    time.sleep(random.uniform(2, 5))  # polite delay

Key gotcha: generic data vendors underperformed for this niche. Custom scrapes were required to reach real buyers.

3) Enrich and segment before you write a single email

Answer-first: light-touch enrichment finds the homepage and any obvious signals, then segments by market and fit. Personalization always anchors to something we actually saw.

// segment.mjs
export function segment(record) {
  const city = (record.city || "").toLowerCase();
  const metro = city.includes("seattle") ? "PNW" : city.includes("detroit") ? "Midwest" : "Other";
  const capacityHint = /ballroom|banquet|resort/i.test(record.pageText || "") ? "Larger" : "General";
  return { ...record, metro, capacityHint };
}

Key gotcha: keep feature claims out of templates unless verified on the page. We used explicit allowlists for claims.

4) Generate hyper-personalized openers with guardrails

Answer-first: use an LLM to write short openers constrained by structured inputs and hard stops against fabrication.

from llm import chat  # thin wrapper around your chosen model
 
def opener(name, city, snippet):
    sys = "You write 1-line openers. Use only provided facts. No claims."
    user = f"Venue: {name} in {city}. Fact: {snippet[:180]}"
    out = chat(system=sys, user=user, model="MODEL", max_tokens=60)
    line = out.strip().splitlines()[0]
    return line[:200]

Key gotcha: keep state. Store the exact snippet used so reviewers can see proof-of-fact next to the line.

5) Verify, then create and activate campaigns

Answer-first: submit leads to a verifier, delete invalid or catch-all results, then create campaigns and activate in the same atomic pass to avoid drift.

# one-time run pattern
python verify.py leads.csv --output verified.csv --purge invalid,catchall
python push.py verified.csv --campaign "Venues Midwest" --activate

Key gotcha: never flip a campaign active before verification finishes. We paused early runs that skipped this and cleaned them before reactivating.

6) Run LinkedIn autopilot in parallel

Answer-first: publish founder and company posts on a queue with a first-comment link and consistent themes that mirror outbound angles.

# queue.yml
schedule:
  timezone: America/Detroit
  slots: [Mon 09:10, Wed 11:40, Fri 14:20]
posts:
  - theme: Buyer stories
    body: |
      The fastest venue wins the inquiry. Here is how we shave response time.
    link_comment: https://venuex.ai/demo
  - theme: Product notes
    body: |
      How we cut manual entry from proposals with structured intake.
    link_comment: https://venuex.ai/blog/intake

Key gotcha: LinkedIn composers shift under automation. Our harness posts the link in the first comment and ensures company-page authorship.

7) Route replies and protect ownership

Answer-first: a small monitor surfaces new replies with the correct sender to respond from. Everything, including domains and provider accounts, lives on the client.

// next/api/replies.ts
import type { NextRequest } from "next/server";
export async function GET(_req: NextRequest) {
  const rows = await fetchReplies(); // provider SDK or webhook store
  return new Response(JSON.stringify(rows.map(r => ({
    from: r.inbox,
    subject: r.subject,
    deeplink: r.url
  }))), { headers: { "content-type": "application/json" } });
}

Key gotcha: we keep all vendors client-owned to support future exit valuation and avoid account-transfer friction.

Where it gets complicated

Generic data sources looked good on paper. Apollo or Clay could not reliably cover venues. We had to scrape the niche directories and maintain selectors over time.

Deliverability is an operations discipline. Warm slowly, verify first, and activate atomically. We paused and cleaned any list that jumped the gun.

Suppression across systems matters. A partner's follow-up can collide with your sends. We added suppression lists to protect deliverability until suppression was confirmed.

Personalization must be provable. We log the exact snippet behind every opener so a reviewer can point to the source line on the venue site.

LinkedIn automation has platform quirks. Composer elements move, comment submit buttons shift, and author context can flip between person and page without guardrails.

What this actually changes

VenueX AI moved from partner dependency to an owned, repeatable engine. We closed the engagement at $2,800 per month, scheduled the first email agent to go live in under a week, and set a one-month path to a full engine spanning email and LinkedIn. The structural win: data accuracy from niche scrapes, provable personalization, and client-owned infrastructure.

One reason this works: speed-to-lead and timely response meaningfully lift qualification. Harvard Business Review reported that firms responding within an hour were nearly seven times as likely to qualify a lead as those responding after an hour, and much more likely than those responding after a day (HBR). Our reply monitor and daily sends support that cadence.

Frequently asked questions

Did you use off-the-shelf data for venues?

No. For this niche, generic tools missed a lot of real buyers. We scraped the dominant venue directories and layered light enrichment. That produced cleaner targets and better personalization anchors.

How did you avoid hurting deliverability?

We warmed new sending domains, verified every lead before activation, and enforced daily caps. Campaigns were activated only after verification completed. A suppression layer protected against partner overlap.

What parts does the client own vs the agency?

Everything that matters long term lives on the client: domains, workspace inboxes, provider accounts, and the data itself. We built and operated the engine, but there is no lock-in hidden in account ownership.

How fast did this stand up for VenueX AI?

We scheduled the first email agent to go live in under a week and scoped the full engine to about a month. That timeline included scraping, enrichment, campaign setup, LinkedIn queue, and reply routing.

What about content and founder posting?

We added a queue-driven LinkedIn autopilot for the founder and the company. Posts follow consistent themes that mirror outbound angles, with links placed in the first comment.

Can you replicate this for a different vertical SaaS?

Yes, if the niche has identifiable sources we can scrape or integrate. The pattern stays the same: accurate sources, segmentation, provable personalization, safe delivery, and fast routing to a human.

If you want an owned inbound engine that books qualified demos without relying on partners, we have shipped this exact system. See our service overview at /services#ai-sales-outreach, read why most cold outreach fails in /blog/why-most-cold-outreach-fails, and when you are ready to scope your build, /book.

Want us to build this for you?

15-minute discovery call. No pitch. We tell you what to automate first.

Book a Discovery Call

Related reading