Most B2B outreach fails for one boring reason: timing. You send a perfect email to a perfect prospect who has zero reason to care today. The message isn't wrong. The moment is.
Intent-based outreach flips this. Instead of a fixed cadence firing at everyone on a list, you wait for a signal - then trigger a personalized message within minutes. This is very buildable with tools you probably already have. Here's the architecture.
What Counts as a Buyer Intent Signal
Intent data is anything that suggests a prospect is actively evaluating a solution. It falls into two buckets:
First-party signals happen on your own properties:
- Pricing page visits (especially repeat visits)
- Docs or integration page views
- Free trial signups that stall
- Demo form abandons
Third-party signals happen off your site:
- Job postings mentioning tools you complement
- Funding announcements
- New hires in relevant roles (a new Head of RevOps is a buying committee forming)
- Technographic changes (they just installed a competitor's tag)
The strongest triggers combine both. A prospect who visits your pricing page and just posted a job for the exact problem you solve is a green light.
The Core Loop
Every intent engine has the same shape:
- Capture a signal
- Enrich the account and contact
- Score whether it's worth acting on
- Generate a personalized message grounded in the signal
- Route it - to a rep or an automated send
Miss any step and quality collapses. Skip enrichment and your AI writes generic copy. Skip scoring and you spam every tire-kicker.
Capturing the Signal
Start with what's free. A simple script on your pricing page tells you more than most paid intent vendors.
// Track high-intent page views and push to your automation webhook
async function trackIntent(pageType) {
const visitorId = getVisitorId(); // from your cookie / analytics
const account = await identifyAccount(visitorId); // reverse-IP or Clearbit
if (!account?.domain) return;
await fetch('https://your-n8n-instance/webhook/intent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
domain: account.domain,
page: pageType,
timestamp: Date.now(),
sessionCount: account.sessions
})
});
}
// Fire on the pages that actually indicate buying intent
if (window.location.pathname.includes('/pricing')) {
trackIntent('pricing');
}
Scoring Before You Act
Don't let one page view trigger an email. Weight signals and set a threshold. A pricing visit is worth more than a blog read. A repeat pricing visit within 48 hours is worth a lot more.
SIGNAL_WEIGHTS = {
"pricing_view": 30,
"pricing_repeat": 50,
"docs_view": 20,
"demo_abandon": 45,
"job_post_match": 40,
"recent_funding": 25,
}
def score_account(signals: list[str]) -> int:
return sum(SIGNAL_WEIGHTS.get(s, 0) for s in signals)
def should_trigger(signals: list[str], threshold: int = 60) -> bool:
score = score_account(signals)
return score >= threshold
# Example
signals = ["pricing_repeat", "job_post_match"]
print(score_account(signals)) # 90
print(should_trigger(signals)) # True
The threshold is a dial. Set it high early, then loosen it as you trust the pipeline.
Where AI Actually Earns Its Keep
The AI's job is not to invent a persona or fabricate flattery. It's to write a message that references the specific signal in a way a human would.
Feed the model the raw context - the signal, the enriched account data, the role - and constrain it hard.
prompt = f"""
Write a 3-sentence outreach email.
Context:
- Company: {account['name']} ({account['industry']})
- Signal: visited pricing page twice in 48h, recently posted a
job for a RevOps Manager
- Recipient role: VP of Sales
Rules:
- Reference the RevOps hire naturally, not the page visit
(that's creepy).
- No superlatives, no 'I hope this finds you well'.
- One clear, low-friction ask.
"""
Notice the guardrail: reference the public signal (the job post), not the private one (their browsing). Using the browsing signal to time the send is smart. Mentioning it in the copy is a trust-killer.
Route, Don't Auto-Send Everything
High-score accounts should go to a human with a pre-drafted message and full context. Mid-score accounts can enter a lighter automated sequence. This tiering keeps your best prospects in front of your best closers while automation handles volume.
A simple rule set:
- Score 80+ → Slack alert to the account owner with draft ready
- Score 60-79 → Automated 3-touch sequence
- Below 60 → Nurture, no direct outreach
Build This in Stages
Don't try to boil the ocean. A realistic first quarter:
- Week 1-2: Instrument your pricing and docs pages. Pipe events to a webhook.
- Week 3-4: Add enrichment and a basic scoring threshold.
- Week 5-6: Wire up AI drafting with strict prompts and human review.
- Week 7+: Layer in a third-party signal source, then start automating the mid-tier.
The teams winning at outbound right now aren't sending more. They're sending at the right moment, with context that proves they were paying attention. That's not a bigger list. It's a better trigger.
Start with one signal, one message template, and one human in the loop. Get the timing right, and the rest is tuning.
Originally published at getmichaelai.com
Top comments (0)