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