Signal-Driven Outreach

Start from a signal, work backwards to the right person and the right message.

Signal-driven outreach inverts the usual prospecting motion. Instead of starting with a target account list and looking for buying intent, you start with a signal stream (e.g. weekly Trustpilot scrape, LinkedIn job posting feed) and let the signal pick the accounts.

When this pattern wins

  • You have a small product team and can’t afford to research a 1,000-account list.
  • Your motion is event-driven: you sell churn-prevention to companies actively losing customers, or you sell sales tooling to companies actively hiring SDRs.
  • You want a stream of fresh targets rather than a static list.

The flow

INPUT: signal type (e.g. "negative support reviews")
1. signal_* (run the detector on a target list)
↓ (filter to fired)
2. get_linkedin_company_url (only for fired domains)
3. list_linkedin_company_employees (filtered by signal-relevant title)
4. get_email
5. send_linkedin_invitation (with signal evidence quoted)

Concrete example: churn-prevention motion

You sell a CX agent that handles support tickets. Your highest-converting prospects are companies with rising negative support reviews. Skip qualification, because the signal is the qualification.

const KEY = process.env.GTM_TOOLS_API_KEY!;
const TARGETS = [
"gymshark.com",
"mammaly.de",
"kettleandfire.com",
"spanx.com",
// ... your watchlist
];
async function call<T>(tool: string, body: unknown): Promise<T> {
const res = await fetch(`https://api.gtm-tools.sh/api/v0/${tool}`, {
method: "POST",
headers: {
"Authorization": `Bearer ${KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`${tool}: ${res.status}`);
return res.json();
}
for (const domain of TARGETS) {
// 1. Single-signal probe (5 credits)
const sig = await call<any>("signal_trustpilot_negative_support_reviews", {
domain,
});
if (!sig.fired) continue;
// 2. Find CX leadership (2 + 30 credits)
await call("get_linkedin_company_url", { domain });
const { results } = await call<any>("list_linkedin_company_employees", {
domain,
title_filters: "(VP OR Director OR Head) AND (CX OR Support OR \"Customer Experience\") NOT intern",
limit: 5,
});
if (!results.length) continue;
// 3. Verify email for top candidate (5 credits)
const lead = results[0];
const { email, status, reason } = await call<any>("get_email", {
name: lead.name,
domain,
});
// 4. Compose message with signal evidence
const evidence = sig.evidence?.[0]?.snippet ?? "negative support reviews";
console.log({
domain,
name: lead.name,
email,
email_status: status,
email_reason: reason,
angle: `Saw recent feedback: "${evidence.slice(0, 80)}..."`,
});
}

Credit math

StepCredits (per fired domain)
signal_trustpilot_negative_support_reviews5
get_linkedin_company_url2
list_linkedin_company_employees30
get_email5
Total42

Plus 5 credits for each non-fired domain. At a 20% fire rate: 100 domains = 100 × 5 + 20 × 37 = 1,240 credits ($12.40).

Why this beats account-first prospecting

In account-first prospecting, you commit 30 credits to employee search before knowing the account is actually qualified. Signal-first defers that 30-credit call until the signal has fired, so you only spend it on hot leads.

For a 1,000-account watchlist with a 5% fire rate:

ApproachCredits spent
Account-first (30 + 5 + 5 every account)40,000
Signal-first (5 every account, 37 only on fired)6,850

Same end result, 6× cheaper.