Outbound Sales

This guide walks through a complete outbound workflow with GTM Tools. Start from a target domain, surface buying signals, find the right decision-maker, verify their email, and send a personalized invitation — all through MCP, REST, or the CLI.

The pipeline

domain → signals → company URL → employees (filtered) → profile → email → invitation

Each step is one tool call. Tokens are reserved up front and refunded if anything fails — so a failed email lookup doesn’t cost you the 5 tokens.

Step 1: Qualify the account with signals

Before spending tokens on people lookup, run detect_signal to confirm the company actually has buying intent.

$curl -X POST https://signals.gtm-engine.sh/api/v0/detect_signal \
> -H "Authorization: Bearer $GTM_ENGINE_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"domain": "gymshark.com", "techs": ["zendesk.com", "intercom.com"]}'

Look for the highest-confidence signals:

SignalWhat it tells you
signal_hiring_sales_rep_repostPrevious SDR didn’t stick — strong pain point
signal_trustpilot_negative_support_reviewsActive customer churn risk
signal_hiring_supportSupport team is scaling — budget unlocked
signal_socials_spikeMarketing momentum — likely funded
signal_technologies_identifiedTech-stack qualification (e.g. running Zendesk)

If no signals fire, deprioritize the account and move on. This costs 5 tokens per detector that ran and saves you 30+ tokens you’d have spent on employee search.

Step 2: Find the company on LinkedIn

$curl -X POST https://socials.gtm-engine.sh/api/v0/get_linkedin_company_url \
> -H "Authorization: Bearer $GTM_ENGINE_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"domain": "gymshark.com"}'
1{ "url": "https://www.linkedin.com/company/gymshark", "domain": "gymshark.com" }

Cost: 2 tokens.

Step 3: Search for decision-makers

Use list_linkedin_company_employees with boolean title filters tailored to whichever signal fired.

$curl -X POST https://socials.gtm-engine.sh/api/v0/list_linkedin_company_employees \
> -H "Authorization: Bearer $GTM_ENGINE_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "domain": "gymshark.com",
> "title_filters": "(VP OR Director OR Head) AND (CX OR Support OR Customer Experience) NOT intern",
> "limit": 10,
> "page": 1
> }'

Cost: 30 tokens — this is the most expensive step in the pipeline. Don’t run it speculatively. Always qualify with signals first.

Title filter cheat-sheet

Signal that firedFilter to use
signal_trustpilot_negative_support_reviews"(VP OR Director OR Head) AND (CX OR Support) NOT intern"
signal_hiring_sales_rep_repost"(VP OR Director OR Head) AND Sales NOT intern"
signal_hiring_support"(VP OR Director OR Head) AND (CX OR Support OR Operations)"
signal_socials_spike"(VP OR Director OR Head) AND (Marketing OR Brand OR Growth)"

Step 4: Verify the professional email

For each candidate from step 3, call get_email.

$curl -X POST https://data.gtm-engine.sh/api/v0/get_email \
> -H "Authorization: Bearer $GTM_ENGINE_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{"name": "Camille Tichard", "domain": "gymshark.com"}'
1{
2 "email": "camille@gymshark.com",
3 "is_catch_all": false,
4 "domain": "gymshark.com"
5}

Cost: 5 tokens per email. If is_catch_all is true, treat the result as a hypothesis — see Email Finding.

Step 5: Send a personalized invitation

Bind a LinkedIn session once, then send the connection request.

$# One-time: connect a LinkedIn session
$curl -X POST https://socials.gtm-engine.sh/api/v0/connect_linkedin \
> -H "Authorization: Bearer $GTM_ENGINE_API_KEY"
$
$# Send invitation (5 tokens)
$curl -X POST https://socials.gtm-engine.sh/api/v0/send_linkedin_invitation \
> -H "Authorization: Bearer $GTM_ENGINE_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "profile_url": "https://linkedin.com/in/camilletichard",
> "message": "Hi Camille — saw Gymshark recently posted three CX team lead roles. Curious how youre thinking about ticket volume — we work with brands at your scale."
> }'

Personalize using the signal: a CX hiring spike justifies the angle, the negative-support reviews give you the line of attack.

End-to-end script

1const KEY = process.env.GTM_ENGINE_API_KEY!;
2
3type Server = "admin" | "socials" | "data" | "signals";
4
5async function call<T>(server: Server, tool: string, body: unknown = {}): Promise<T> {
6 const res = await fetch(`https://${server}.gtm-engine.sh/api/v0/${tool}`, {
7 method: "POST",
8 headers: {
9 "Authorization": `Bearer ${KEY}`,
10 "Content-Type": "application/json",
11 },
12 body: JSON.stringify(body),
13 });
14 if (!res.ok) throw new Error(`${tool}: ${res.status} ${await res.text()}`);
15 return res.json();
16}
17
18async function prospect(domain: string) {
19 // 1. Qualify with signals
20 const signals = await call<any>("signals", "detect_signal", {
21 domain,
22 techs: ["zendesk.com", "intercom.com"],
23 });
24 const fired = signals.signals.filter((s: any) => s.fired);
25 if (fired.length === 0) {
26 console.log(`[skip] ${domain} — no signals`);
27 return;
28 }
29
30 // 2. Resolve company URL
31 await call<any>("socials", "get_linkedin_company_url", { domain });
32
33 // 3. Find decision-makers
34 const filter = fired.some((s: any) => s.name.includes("support"))
35 ? "(VP OR Director OR Head) AND (CX OR Support) NOT intern"
36 : "(VP OR Director OR Head) AND Sales NOT intern";
37
38 const { results } = await call<any>("socials", "list_linkedin_company_employees", {
39 domain,
40 title_filters: filter,
41 limit: 5,
42 });
43
44 // 4. Verify emails for the top 3
45 for (const r of results.slice(0, 3)) {
46 const { email, is_catch_all } = await call<any>("data", "get_email", {
47 name: r.name,
48 domain,
49 });
50 console.log(`${r.name} → ${email}${is_catch_all ? " (catch-all)" : ""}`);
51 }
52}
53
54await prospect("gymshark.com");

Token budget

For a single qualified prospect end-to-end:

StepTokens
detect_signal (5 detectors fired)25
get_linkedin_company_url2
list_linkedin_company_employees30
get_email × 3 candidates15
send_linkedin_invitation5
Total77

77 tokens = $0.77 per fully-researched prospect. The free 100-token starter balance covers your first prospect with room to spare.

Next steps