Setup Outreach Campaign
The single entry point for launching an outbound campaign from scratch. Instead of manually configuring ICP definitions, picking signal sources, finding contacts, and drafting sequences across multiple skills — this composite walks through the entire process in one session and wires up the right downstream skills automatically.
Why this exists: Most users don't know which signal composite to start with. They just know "I want to run outreach." This skill asks the right questions, picks the right approach, builds the prospect list, drafts the sequences, and hands off to the outreach tool — all in one flow.
When to Auto-Load
Load this composite when:
- User says "set up an outreach campaign", "launch outbound", "build a campaign", "I want to start doing outreach"
- User wants to go from zero to a running outreach campaign in one session
- User has a new product/company and needs to define ICP + build their first campaign
- User says "help me find and reach out to prospects"
Step 0: Company Context & ICP Definition
Purpose: Understand what the user sells, who they sell to, and what makes a good prospect. This is the foundation everything else builds on.
Questions to Collect
Your Product
| Question |
Purpose |
Stored As |
| What does your company do? (1-2 sentences) |
Core positioning for outreach |
company_description |
| What problem do you solve? |
Email hook — the pain point you address |
pain_point |
| What's your product category? |
Signal matching |
product_category |
| Name 2-3 proof points (customers, metrics, case studies) |
Credibility in outreach |
proof_points |
| What's your key differentiator vs. alternatives? |
Competitive angle |
differentiator |
Your ICP
| Question |
Purpose |
Stored As |
| What job titles do you sell to? (decision makers) |
Contact finding + email angle |
buyer_titles |
| What job titles champion your product internally? |
Secondary contacts |
champion_titles |
| What industries do you target? |
Company filtering |
target_industries |
| What company sizes? (employee count or revenue) |
Company filtering |
target_company_sizes |
| Any geographic focus? |
Company filtering |
target_geographies |
| Any hard disqualifiers? (industries, company types to exclude) |
Negative filtering |
disqualifiers |
Outreach Preferences
| Question |
Purpose |
Stored As |
| What outreach channels? |
Email / LinkedIn / Both |
outreach_channels |
| What outreach tool do you use? |
Export formatting |
email_tool (Smartlead, Instantly, CSV, etc.) |
| LinkedIn outreach tool? (if applicable) |
Export formatting |
linkedin_tool (Dripify, Expandi, CSV, etc.) |
| Preferred tone? |
Sequence style |
tone (casual-professional, thought-leader, direct, formal) |
| How many touches per sequence? |
Sequence length |
sequence_touches (default: 3) |
| Any existing email templates or angles that work? |
Reuse what's proven |
existing_templates |
Store config in: clients/<client-name>/config/outreach-campaign.json
Human Checkpoint
## Campaign Configuration
Company: {company_description}
Problem solved: {pain_point}
Proof points: {proof_points}
ICP:
- Titles: {buyer_titles}
- Industries: {target_industries}
- Company size: {target_company_sizes}
- Geography: {target_geographies}
Outreach:
- Channels: {outreach_channels}
- Email tool: {email_tool}
- Tone: {tone}
- Touches: {sequence_touches}
Does this look right? (Y/n)
Step 1: Select Signal Sources & Build Prospect List
Purpose: Determine where prospects will come from and build the initial list. The user can bring their own list or we generate one from signal sources.
Input Contract
icp_criteria: {
buyer_titles: string[]
champion_titles: string[]
target_industries: string[]
target_company_sizes: string[]
target_geographies: string[]
disqualifiers: string[]
}
your_company: {
company_description: string
pain_point: string
product_category: string
}
Process
Ask where prospects come from:
| Source |
Description |
When to Use |
| Existing list |
User has a CSV, CRM export, or Supabase list |
They already have targets — skip to enrichment |
| Signal-based discovery |
Find companies showing buying signals |
They need to build a list from scratch |
| LinkedIn prospecting |
Find people engaging with relevant topics on LinkedIn |
They want warm LinkedIn-first outreach |
| Hybrid |
Existing list + signal-based expansion |
They have some targets and want more |
If signal-based discovery, select which signals to monitor:
Present the signal menu and recommend based on the user's product:
| Signal |
Best For |
Downstream Skill |
| Hiring signals |
Products that replace or augment a hire |
hiring-signal-outreach |
| Funding signals |
Products sold to growing/well-funded companies |
funding-signal-outreach |
| News signals |
Products relevant to companies in the news (launches, expansions, challenges) |
news-signal-outreach |
| Leadership changes |
Products sold to new leaders rebuilding their stack |
leadership-change-outreach |
| Champion tracking |
Companies with existing relationships (past buyers, users who left) |
champion-move-outreach |
Recommend signals based on product type:
- SaaS tools replacing manual work → Hiring signals (primary) + Funding signals (secondary)
- Enterprise sales → Leadership changes (primary) + Funding signals (secondary)
- SMB tools → Funding signals (primary) + News signals (secondary)
- Existing customer base → Champion tracking (primary) + any other signal (secondary)
If existing list, ingest and validate:
- Accept CSV, spreadsheet, or manual input
- Required fields: company name, domain
- Optional fields: industry, size, any existing contact info
- Validate domains are reachable
- Deduplicate
If LinkedIn prospecting:
- Collect target topics, competitor names, KOLs to monitor
- Hand off to
linkedin-outreach-campaign composite
- Return here for email follow-up layer if multi-channel
Output Contract
prospect_source: "existing_list" | "signal_discovery" | "linkedin" | "hybrid"
selected_signals: string[] # Which signals to run
companies: [
{
name: string
domain: string
source: string # "uploaded", "hiring_signal", "funding_signal", etc.
industry: string | null
size: string | null
}
]
campaign_target_count: integer
Human Checkpoint
## Prospect Source
Source: {prospect_source}
Signals selected: {selected_signals}
Companies: {count}
| Company | Domain | Source | Industry |
|---------|--------|-------|----------|
| Acme Corp | acme.com | Hiring signal | SaaS |
| Beta Inc | beta.io | Uploaded | Fintech |
| ... | ... | ... | ... |
Proceed to enrichment and contact finding? (Y/n)
Step 2: Enrich Companies & Find Contacts
Purpose: Research each company for relevance, find the right people to contact, and get their email addresses.
Input Contract
companies: [...] # From Step 1
buyer_titles: string[] # From config
champion_titles: string[] # From config
max_contacts_per_company: integer # Default: 3
Process
Company enrichment — For each company, gather:
- What the company does (1-2 sentences)
- Industry classification
- Employee count
- Location/HQ
- Recent news or signals (funding, hiring, product launches)
- Why they might need your product (relevance reasoning)
ICP scoring — Score each company against ICP criteria:
- Strong fit: Matches industry, size, and geography. Clear use case.
- Moderate fit: Matches 2 of 3 criteria. Likely use case.
- Weak fit: Matches 1 criterion. Possible use case.
- No fit: Doesn't match ICP. Drop with reason.
Contact finding — For each company that passes ICP scoring:
- Search for people with
buyer_titles first (decision makers)
- Then
champion_titles (internal advocates)
- For each person, find: name, title, email, LinkedIn URL
- Cap at
max_contacts_per_company
Email verification — Flag email confidence:
- Verified: Email confirmed deliverable
- Likely: Pattern-matched email (firstname@domain.com)
- Not found: Route to LinkedIn channel
Output Contract
enriched_companies: [
{
company: {
name: string
domain: string
description: string
industry: string
employee_count: string
location: string
icp_score: "strong" | "moderate" | "weak"
relevance_reasoning: string
}
contacts: [
{
full_name: string
first_name: string
last_name: string
title: string
email: string | null
linkedin_url: string | null
role_type: "buyer" | "champion"
email_confidence: "verified" | "likely" | "not_found"
}
]
}
]
dropped_companies: [
{ name: string, domain: string, drop_reason: string }
]
Human Checkpoint
## Company Enrichment & Contacts
### Strong Fit ({count} companies)
| Company | Industry | Size | Contacts Found | Top Contact |
|---------|----------|------|---------------|-------------|
| Acme Corp | SaaS | 200 | 3 | Jane Doe, VP Sales |
| ... | ... | ... | ... | ... |
### Moderate Fit ({count} companies)
| ... |
### Dropped ({count} companies)
| Company | Reason |
|---------|--------|
| TinyCo | Below minimum size |
Total: {X} contacts across {Y} companies
Approve before we draft sequences? (Y/n)
Step 3: Draft Personalized Sequences
Purpose: For each contact, draft a personalized outreach sequence. The sequence framework adapts based on the signal source that brought this company in and the contact's role type.
Input Contract
enriched_companies: [...] # From Step 2
your_company: {
company_description: string
pain_point: string
proof_points: string[]
differentiator: string
}
sequence_config: {
touches: integer # From config (default: 3)
timing: integer[] # Default: [1, 5, 12]
tone: string # From config
outreach_channels: string[] # From config
}
Process
Select framework based on signal source:
| Source |
Framework |
Hook Strategy |
| Hiring signal |
Signal-Proof-Ask |
Reference the job posting they're hiring for |
| Funding signal |
Trigger-Proof-Ask |
Reference the funding round |
| News signal |
Relevance-Proof-Ask |
Reference the news event |
| Leadership change |
Congrats-Proof-Ask |
Reference the new appointment |
| Uploaded list (no signal) |
Pain-Proof-Ask |
Lead with the pain point your product solves |
| LinkedIn signal |
Comment-Reference-Ask |
Reference their LinkedIn activity |
Adapt email angle by role type:
| Role Type |
Angle |
Example |
| Buyer |
ROI / business outcome |
"Companies like yours are saving X by..." |
| Champion |
Operational pain relief |
"Your team spends X hours on... there's a faster way" |
Draft each touch:
| Touch |
Day |
Purpose |
Word Count |
| Touch 1 |
1 |
Hook with signal/pain + proof point + soft ask |
50-90 words |
| Touch 2 |
5 |
Different angle or proof point + specific ask |
30-50 words |
| Touch 3 |
12 |
Social proof or breakup + final ask |
20-40 words |
If multi-channel (email + LinkedIn):
- Draft LinkedIn connection request (300 chars max) referencing the same signal
- Draft 2-3 LinkedIn follow-up messages
- Coordinate timing: send connection request Day 1, email Touch 1 Day 2 (don't hit both channels simultaneously)
Follow email-drafting skill hard rules:
- No filler words ("just", "honestly", "actually")
- No rhetorical questions as openers
- No "I hope this email finds you well" or similar
- Subject lines under 6 words
- Every sentence earns its place
Output Contract
email_sequences: [
{
contact: {
full_name: string
email: string
title: string
role_type: string
company_name: string
}
signal_source: string
sequence: [
{
touch_number: integer
send_day: integer
channel: "email" | "linkedin"
subject: string | null # Email only
body: string
framework: string
personalization_elements: {
signal_hook: string # What signal/pain was referenced
proof_point: string # What credibility was used
company_relevance: string # Why their company specifically
}
word_count: integer
}
]
}
]
linkedin_sequences: [ # Only if multi-channel
{
contact: {
full_name: string
linkedin_url: string
title: string
company_name: string
}
connection_request: string # 300 chars max
followups: [
{
step: string
send_day: integer
message: string
character_count: integer
}
]
}
]
Human Checkpoint
Present 3-5 sample sequences covering different signal sources and role types:
## Sample Sequences for Review
### Acme Corp — Jane Doe, VP Sales (Buyer)
Signal: Hiring 2x SDRs | Framework: Signal-Proof-Ask
**Email Touch 1 — Day 1**
Subject: Those 2 SDR roles
> Hi Jane — noticed Acme is hiring two SDRs. Companies like [customer]
> found they could handle the same pipeline with one SDR plus [product].
> Worth a 15-min look?
**Email Touch 2 — Day 5**
Subject: Quick math on the SDR hires
> One more thought: two SDRs fully loaded is ~$140K/year.
> [Product] covers the same call volume for a fraction of that.
> [Customer] saw the numbers in 30 days. Want me to share the case study?
**Email Touch 3 — Day 12**
Subject: Last note
> Totally understand if the timing isn't right. If the SDR hiring
> is still in play, happy to show what [customer] did instead.
> Either way — no hard feelings.
---
### Beta Inc — Tom Lee, Director Ops (Champion)
Signal: Uploaded list (no signal) | Framework: Pain-Proof-Ask
**Email Touch 1 — Day 1**
Subject: {pain_point} at Beta
> [sequence content]
---
Approve these samples? I'll generate the rest in the same style.
Step 4: Review & Finalize Campaign
Purpose: Final review of the complete campaign before export. Catch any issues, make last-minute edits, and confirm the campaign is ready.
Process
Campaign summary:
- Total contacts and companies
- Breakdown by signal source
- Breakdown by channel (email vs. LinkedIn)
- Sequence structure and timing
- Estimated send schedule
Quality checks:
- No duplicate contacts across companies
- All emails have valid-looking addresses
- Subject lines are unique (no copy-paste feel)
- Personalization elements are present in every touch
- Word counts within guidelines
- LinkedIn messages under character limits
Final edits:
- Allow user to adjust tone, timing, or specific sequences
- Swap proof points if user prefers different ones
- Add/remove contacts
Human Checkpoint
## Campaign Review
### Overview
- Companies: {X}
- Contacts: {Y}
- Channel: {email/linkedin/both}
- Sequence: {touches} touches over {days} days
### Breakdown by Signal Source
| Source | Companies | Contacts |
|--------|----------|----------|
| Hiring signal | X | Y |
| Uploaded list | X | Y |
| ... | ... | ... |
### Breakdown by Role Type
| Role | Count |
|------|-------|
| Buyer | X |
| Champion | Y |
### Quality Check
- Unique subject lines: PASS
- Personalization in all touches: PASS
- Word counts within range: PASS
- No duplicate contacts: PASS
Everything look good? Ready to export? (Y/n)
Step 5: Export & Launch
Purpose: Package the campaign for the user's outreach tool and launch.
Process
Generate export file(s):
For email campaigns:
- Format CSV for the configured
email_tool:
- Smartlead:
email, first_name, last_name, company, custom1 (subject_1), custom2 (body_1), custom3 (subject_2), ...
- Instantly:
email, first_name, last_name, company_name, personalization
- Outreach.io: API-ready JSON with sequence steps
- Lemlist:
email, firstName, lastName, companyName, icebreaker
- CSV (generic):
email, first_name, last_name, company, title, subject_1, body_1, subject_2, body_2, subject_3, body_3
For LinkedIn campaigns:
- Format CSV for the configured
linkedin_tool:
- Dripify:
Profile URL, Note, Message 1, Message 2, Message 3
- Expandi:
LinkedIn URL, Connection message, Follow-up #1, Follow-up #2
- CSV (generic):
linkedin_url, first_name, last_name, connection_request, followup_1, followup_2, followup_3
Save export files:
- Email:
output/{campaign-name}-email-{YYYY-MM-DD}.csv
- LinkedIn:
output/{campaign-name}-linkedin-{YYYY-MM-DD}.csv
Log to Supabase (if configured):
- Insert records into
outreach_log with campaign metadata
- Update
last_contacted on people records
- Activate 84-day cooldown across channels
Output Contract
campaign_package: {
campaign_name: string
email_campaign: {
tool: string
file_path: string
contact_count: integer
sequence_touches: integer
estimated_send_days: integer
} | null
linkedin_campaign: {
tool: string
file_path: string
contact_count: integer
sequence_structure: string
} | null
total_contacts: integer
total_companies: integer
signal_breakdown: {
[signal_name]: integer
}
next_actions: string[]
}
Human Checkpoint
## Campaign Ready to Launch
Campaign: {campaign_name}
Created: {date}
### Email Campaign
- Tool: {email_tool}
- File: {file_path}
- Contacts: {count}
- Sequence: {touches} touches over {days} days
### LinkedIn Campaign
- Tool: {linkedin_tool}
- File: {file_path}
- Contacts: {count}
- Sequence: Connection + {followup_count} follow-ups
### Total
- {total_contacts} contacts across {total_companies} companies
- Signals used: {signal_list}
### Next Steps
1. Import {email_file} into {email_tool}
2. Import {linkedin_file} into {linkedin_tool}
3. Set sending schedule (recommended: {X} emails/day, {Y} connections/day)
4. Monitor replies and move responders to CRM
Ready to finalize? (Y/n)
Execution Summary
| Step |
Tool Dependency |
Human Checkpoint |
Typical Time |
| 0. Company context & ICP |
None |
Confirm configuration |
5 min |
| 1. Signal sources & prospect list |
Configurable (signals, CSV, LinkedIn) |
Review prospect sources |
3-5 min |
| 2. Enrich & find contacts |
Web search + contact finder |
Approve enriched list |
5-10 min |
| 3. Draft sequences |
None (LLM reasoning) |
Review sample sequences |
5-10 min |
| 4. Review & finalize |
None |
Final quality check |
2-3 min |
| 5. Export & launch |
CSV generation |
Launch approval |
1-2 min |
Total human review time: ~20-35 minutes
Tips
- Start with one signal source. Don't try to run all five signal types in the first campaign. Pick the one most relevant to your product, prove it works, then layer on more.
- Quality over quantity. 50 highly personalized emails will outperform 500 generic ones. This skill prioritizes personalization depth.
- Let the ICP definition do the filtering. The tighter your ICP, the smaller but higher-quality your prospect list. A 5% reply rate on 50 perfect-fit prospects beats a 0.5% rate on 500 mediocre ones.
- Multi-channel compounds results. Email + LinkedIn together typically yields 2-3x the reply rate of either alone. The LinkedIn connection request warms them up before the email arrives.
- Reuse what works. After the first campaign, save winning subject lines, proof points, and angles. Future campaigns should build on proven messaging, not start from scratch.
- Monitor and iterate. After 50-100 sends, check open rates, reply rates, and positive reply rates. Adjust subject lines, proof points, and CTAs based on data. This skill sets up the campaign — the iteration happens in follow-up runs.
- Don't skip the human checkpoints. Each checkpoint exists because outreach quality drops dramatically without human review. Automated-and-sent is worse than reviewed-and-sent.
1---2name: setup-outreach-campaign3description: End-to-end outreach campaign setup composite. Walks through ICP definition, signal source selection, outreach channel configuration, prospect list building, email/LinkedIn sequence drafting, and campaign launch. The one-stop orchestrator that replaces doing each step manually — go from "I want to run outreach" to a live campaign in a single session. Tool-agnostic — works with any signal source, contact finder, and outreach platform.4---56# Setup Outreach Campaign78The single entry point for launching an outbound campaign from scratch. Instead of manually configuring ICP definitions, picking signal sources, finding contacts, and drafting sequences across multiple skills — this composite walks through the entire process in one session and wires up the right downstream skills automatically.910**Why this exists:** Most users don't know which signal composite to start with. They just know "I want to run outreach." This skill asks the right questions, picks the right approach, builds the prospect list, drafts the sequences, and hands off to the outreach tool — all in one flow.1112## When to Auto-Load1314Load this composite when:15- User says "set up an outreach campaign", "launch outbound", "build a campaign", "I want to start doing outreach"16- User wants to go from zero to a running outreach campaign in one session17- User has a new product/company and needs to define ICP + build their first campaign18- User says "help me find and reach out to prospects"1920---2122## Step 0: Company Context & ICP Definition2324**Purpose:** Understand what the user sells, who they sell to, and what makes a good prospect. This is the foundation everything else builds on.2526### Questions to Collect2728#### Your Product2930| Question | Purpose | Stored As |31|----------|---------|-----------|32| What does your company do? (1-2 sentences) | Core positioning for outreach | `company_description` |33| What problem do you solve? | Email hook — the pain point you address | `pain_point` |34| What's your product category? | Signal matching | `product_category` |35| Name 2-3 proof points (customers, metrics, case studies) | Credibility in outreach | `proof_points` |36| What's your key differentiator vs. alternatives? | Competitive angle | `differentiator` |3738#### Your ICP3940| Question | Purpose | Stored As |41|----------|---------|-----------|42| What job titles do you sell to? (decision makers) | Contact finding + email angle | `buyer_titles` |43| What job titles champion your product internally? | Secondary contacts | `champion_titles` |44| What industries do you target? | Company filtering | `target_industries` |45| What company sizes? (employee count or revenue) | Company filtering | `target_company_sizes` |46| Any geographic focus? | Company filtering | `target_geographies` |47| Any hard disqualifiers? (industries, company types to exclude) | Negative filtering | `disqualifiers` |4849#### Outreach Preferences5051| Question | Purpose | Stored As |52|----------|---------|-----------|53| What outreach channels? | Email / LinkedIn / Both | `outreach_channels` |54| What outreach tool do you use? | Export formatting | `email_tool` (Smartlead, Instantly, CSV, etc.) |55| LinkedIn outreach tool? (if applicable) | Export formatting | `linkedin_tool` (Dripify, Expandi, CSV, etc.) |56| Preferred tone? | Sequence style | `tone` (casual-professional, thought-leader, direct, formal) |57| How many touches per sequence? | Sequence length | `sequence_touches` (default: 3) |58| Any existing email templates or angles that work? | Reuse what's proven | `existing_templates` |5960**Store config in:** `clients/<client-name>/config/outreach-campaign.json`6162### Human Checkpoint6364```65## Campaign Configuration6667Company: {company_description}68Problem solved: {pain_point}69Proof points: {proof_points}7071ICP:72- Titles: {buyer_titles}73- Industries: {target_industries}74- Company size: {target_company_sizes}75- Geography: {target_geographies}7677Outreach:78- Channels: {outreach_channels}79- Email tool: {email_tool}80- Tone: {tone}81- Touches: {sequence_touches}8283Does this look right? (Y/n)84```8586---8788## Step 1: Select Signal Sources & Build Prospect List8990**Purpose:** Determine where prospects will come from and build the initial list. The user can bring their own list or we generate one from signal sources.9192### Input Contract9394```95icp_criteria: {96 buyer_titles: string[]97 champion_titles: string[]98 target_industries: string[]99 target_company_sizes: string[]100 target_geographies: string[]101 disqualifiers: string[]102}103your_company: {104 company_description: string105 pain_point: string106 product_category: string107}108```109110### Process1111121. **Ask where prospects come from:**113114 | Source | Description | When to Use |115 |--------|-------------|-------------|116 | **Existing list** | User has a CSV, CRM export, or Supabase list | They already have targets — skip to enrichment |117 | **Signal-based discovery** | Find companies showing buying signals | They need to build a list from scratch |118 | **LinkedIn prospecting** | Find people engaging with relevant topics on LinkedIn | They want warm LinkedIn-first outreach |119 | **Hybrid** | Existing list + signal-based expansion | They have some targets and want more |1201212. **If signal-based discovery, select which signals to monitor:**122123 Present the signal menu and recommend based on the user's product:124125 | Signal | Best For | Downstream Skill |126 |--------|----------|-----------------|127 | **Hiring signals** | Products that replace or augment a hire | `hiring-signal-outreach` |128 | **Funding signals** | Products sold to growing/well-funded companies | `funding-signal-outreach` |129 | **News signals** | Products relevant to companies in the news (launches, expansions, challenges) | `news-signal-outreach` |130 | **Leadership changes** | Products sold to new leaders rebuilding their stack | `leadership-change-outreach` |131 | **Champion tracking** | Companies with existing relationships (past buyers, users who left) | `champion-move-outreach` |132133 **Recommend signals based on product type:**134 - SaaS tools replacing manual work → Hiring signals (primary) + Funding signals (secondary)135 - Enterprise sales → Leadership changes (primary) + Funding signals (secondary)136 - SMB tools → Funding signals (primary) + News signals (secondary)137 - Existing customer base → Champion tracking (primary) + any other signal (secondary)1381393. **If existing list, ingest and validate:**140 - Accept CSV, spreadsheet, or manual input141 - Required fields: company name, domain142 - Optional fields: industry, size, any existing contact info143 - Validate domains are reachable144 - Deduplicate1451464. **If LinkedIn prospecting:**147 - Collect target topics, competitor names, KOLs to monitor148 - Hand off to `linkedin-outreach-campaign` composite149 - Return here for email follow-up layer if multi-channel150151### Output Contract152153```154prospect_source: "existing_list" | "signal_discovery" | "linkedin" | "hybrid"155selected_signals: string[] # Which signals to run156companies: [157 {158 name: string159 domain: string160 source: string # "uploaded", "hiring_signal", "funding_signal", etc.161 industry: string | null162 size: string | null163 }164]165campaign_target_count: integer166```167168### Human Checkpoint169170```171## Prospect Source172173Source: {prospect_source}174Signals selected: {selected_signals}175Companies: {count}176177| Company | Domain | Source | Industry |178|---------|--------|-------|----------|179| Acme Corp | acme.com | Hiring signal | SaaS |180| Beta Inc | beta.io | Uploaded | Fintech |181| ... | ... | ... | ... |182183Proceed to enrichment and contact finding? (Y/n)184```185186---187188## Step 2: Enrich Companies & Find Contacts189190**Purpose:** Research each company for relevance, find the right people to contact, and get their email addresses.191192### Input Contract193194```195companies: [...] # From Step 1196buyer_titles: string[] # From config197champion_titles: string[] # From config198max_contacts_per_company: integer # Default: 3199```200201### Process2022031. **Company enrichment** — For each company, gather:204 - What the company does (1-2 sentences)205 - Industry classification206 - Employee count207 - Location/HQ208 - Recent news or signals (funding, hiring, product launches)209 - Why they might need your product (relevance reasoning)2102112. **ICP scoring** — Score each company against ICP criteria:212 - **Strong fit:** Matches industry, size, and geography. Clear use case.213 - **Moderate fit:** Matches 2 of 3 criteria. Likely use case.214 - **Weak fit:** Matches 1 criterion. Possible use case.215 - **No fit:** Doesn't match ICP. Drop with reason.2162173. **Contact finding** — For each company that passes ICP scoring:218 - Search for people with `buyer_titles` first (decision makers)219 - Then `champion_titles` (internal advocates)220 - For each person, find: name, title, email, LinkedIn URL221 - Cap at `max_contacts_per_company`2222234. **Email verification** — Flag email confidence:224 - **Verified:** Email confirmed deliverable225 - **Likely:** Pattern-matched email (firstname@domain.com)226 - **Not found:** Route to LinkedIn channel227228### Output Contract229230```231enriched_companies: [232 {233 company: {234 name: string235 domain: string236 description: string237 industry: string238 employee_count: string239 location: string240 icp_score: "strong" | "moderate" | "weak"241 relevance_reasoning: string242 }243 contacts: [244 {245 full_name: string246 first_name: string247 last_name: string248 title: string249 email: string | null250 linkedin_url: string | null251 role_type: "buyer" | "champion"252 email_confidence: "verified" | "likely" | "not_found"253 }254 ]255 }256]257dropped_companies: [258 { name: string, domain: string, drop_reason: string }259]260```261262### Human Checkpoint263264```265## Company Enrichment & Contacts266267### Strong Fit ({count} companies)268| Company | Industry | Size | Contacts Found | Top Contact |269|---------|----------|------|---------------|-------------|270| Acme Corp | SaaS | 200 | 3 | Jane Doe, VP Sales |271| ... | ... | ... | ... | ... |272273### Moderate Fit ({count} companies)274| ... |275276### Dropped ({count} companies)277| Company | Reason |278|---------|--------|279| TinyCo | Below minimum size |280281Total: {X} contacts across {Y} companies282283Approve before we draft sequences? (Y/n)284```285286---287288## Step 3: Draft Personalized Sequences289290**Purpose:** For each contact, draft a personalized outreach sequence. The sequence framework adapts based on the signal source that brought this company in and the contact's role type.291292### Input Contract293294```295enriched_companies: [...] # From Step 2296your_company: {297 company_description: string298 pain_point: string299 proof_points: string[]300 differentiator: string301}302sequence_config: {303 touches: integer # From config (default: 3)304 timing: integer[] # Default: [1, 5, 12]305 tone: string # From config306 outreach_channels: string[] # From config307}308```309310### Process3113121. **Select framework based on signal source:**313314 | Source | Framework | Hook Strategy |315 |--------|-----------|--------------|316 | Hiring signal | Signal-Proof-Ask | Reference the job posting they're hiring for |317 | Funding signal | Trigger-Proof-Ask | Reference the funding round |318 | News signal | Relevance-Proof-Ask | Reference the news event |319 | Leadership change | Congrats-Proof-Ask | Reference the new appointment |320 | Uploaded list (no signal) | Pain-Proof-Ask | Lead with the pain point your product solves |321 | LinkedIn signal | Comment-Reference-Ask | Reference their LinkedIn activity |3223232. **Adapt email angle by role type:**324325 | Role Type | Angle | Example |326 |-----------|-------|---------|327 | **Buyer** | ROI / business outcome | "Companies like yours are saving X by..." |328 | **Champion** | Operational pain relief | "Your team spends X hours on... there's a faster way" |3293303. **Draft each touch:**331332 | Touch | Day | Purpose | Word Count |333 |-------|-----|---------|------------|334 | Touch 1 | 1 | Hook with signal/pain + proof point + soft ask | 50-90 words |335 | Touch 2 | 5 | Different angle or proof point + specific ask | 30-50 words |336 | Touch 3 | 12 | Social proof or breakup + final ask | 20-40 words |3373384. **If multi-channel (email + LinkedIn):**339 - Draft LinkedIn connection request (300 chars max) referencing the same signal340 - Draft 2-3 LinkedIn follow-up messages341 - Coordinate timing: send connection request Day 1, email Touch 1 Day 2 (don't hit both channels simultaneously)3423435. **Follow `email-drafting` skill hard rules:**344 - No filler words ("just", "honestly", "actually")345 - No rhetorical questions as openers346 - No "I hope this email finds you well" or similar347 - Subject lines under 6 words348 - Every sentence earns its place349350### Output Contract351352```353email_sequences: [354 {355 contact: {356 full_name: string357 email: string358 title: string359 role_type: string360 company_name: string361 }362 signal_source: string363 sequence: [364 {365 touch_number: integer366 send_day: integer367 channel: "email" | "linkedin"368 subject: string | null # Email only369 body: string370 framework: string371 personalization_elements: {372 signal_hook: string # What signal/pain was referenced373 proof_point: string # What credibility was used374 company_relevance: string # Why their company specifically375 }376 word_count: integer377 }378 ]379 }380]381linkedin_sequences: [ # Only if multi-channel382 {383 contact: {384 full_name: string385 linkedin_url: string386 title: string387 company_name: string388 }389 connection_request: string # 300 chars max390 followups: [391 {392 step: string393 send_day: integer394 message: string395 character_count: integer396 }397 ]398 }399]400```401402### Human Checkpoint403404Present 3-5 sample sequences covering different signal sources and role types:405406```407## Sample Sequences for Review408409### Acme Corp — Jane Doe, VP Sales (Buyer)410Signal: Hiring 2x SDRs | Framework: Signal-Proof-Ask411412**Email Touch 1 — Day 1**413Subject: Those 2 SDR roles414> Hi Jane — noticed Acme is hiring two SDRs. Companies like [customer]415> found they could handle the same pipeline with one SDR plus [product].416> Worth a 15-min look?417418**Email Touch 2 — Day 5**419Subject: Quick math on the SDR hires420> One more thought: two SDRs fully loaded is ~$140K/year.421> [Product] covers the same call volume for a fraction of that.422> [Customer] saw the numbers in 30 days. Want me to share the case study?423424**Email Touch 3 — Day 12**425Subject: Last note426> Totally understand if the timing isn't right. If the SDR hiring427> is still in play, happy to show what [customer] did instead.428> Either way — no hard feelings.429430---431432### Beta Inc — Tom Lee, Director Ops (Champion)433Signal: Uploaded list (no signal) | Framework: Pain-Proof-Ask434435**Email Touch 1 — Day 1**436Subject: {pain_point} at Beta437> [sequence content]438439---440441Approve these samples? I'll generate the rest in the same style.442```443444---445446## Step 4: Review & Finalize Campaign447448**Purpose:** Final review of the complete campaign before export. Catch any issues, make last-minute edits, and confirm the campaign is ready.449450### Process4514521. **Campaign summary:**453 - Total contacts and companies454 - Breakdown by signal source455 - Breakdown by channel (email vs. LinkedIn)456 - Sequence structure and timing457 - Estimated send schedule4584592. **Quality checks:**460 - No duplicate contacts across companies461 - All emails have valid-looking addresses462 - Subject lines are unique (no copy-paste feel)463 - Personalization elements are present in every touch464 - Word counts within guidelines465 - LinkedIn messages under character limits4664673. **Final edits:**468 - Allow user to adjust tone, timing, or specific sequences469 - Swap proof points if user prefers different ones470 - Add/remove contacts471472### Human Checkpoint473474```475## Campaign Review476477### Overview478- Companies: {X}479- Contacts: {Y}480- Channel: {email/linkedin/both}481- Sequence: {touches} touches over {days} days482483### Breakdown by Signal Source484| Source | Companies | Contacts |485|--------|----------|----------|486| Hiring signal | X | Y |487| Uploaded list | X | Y |488| ... | ... | ... |489490### Breakdown by Role Type491| Role | Count |492|------|-------|493| Buyer | X |494| Champion | Y |495496### Quality Check497- Unique subject lines: PASS498- Personalization in all touches: PASS499- Word counts within range: PASS500- No duplicate contacts: PASS501502Everything look good? Ready to export? (Y/n)503```504505---506507## Step 5: Export & Launch508509**Purpose:** Package the campaign for the user's outreach tool and launch.510511### Process5125131. **Generate export file(s):**514515 **For email campaigns:**516 - Format CSV for the configured `email_tool`:517 - **Smartlead:** `email, first_name, last_name, company, custom1 (subject_1), custom2 (body_1), custom3 (subject_2), ...`518 - **Instantly:** `email, first_name, last_name, company_name, personalization`519 - **Outreach.io:** API-ready JSON with sequence steps520 - **Lemlist:** `email, firstName, lastName, companyName, icebreaker`521 - **CSV (generic):** `email, first_name, last_name, company, title, subject_1, body_1, subject_2, body_2, subject_3, body_3`522523 **For LinkedIn campaigns:**524 - Format CSV for the configured `linkedin_tool`:525 - **Dripify:** `Profile URL, Note, Message 1, Message 2, Message 3`526 - **Expandi:** `LinkedIn URL, Connection message, Follow-up #1, Follow-up #2`527 - **CSV (generic):** `linkedin_url, first_name, last_name, connection_request, followup_1, followup_2, followup_3`5285292. **Save export files:**530 - Email: `output/{campaign-name}-email-{YYYY-MM-DD}.csv`531 - LinkedIn: `output/{campaign-name}-linkedin-{YYYY-MM-DD}.csv`5325333. **Log to Supabase** (if configured):534 - Insert records into `outreach_log` with campaign metadata535 - Update `last_contacted` on people records536 - Activate 84-day cooldown across channels537538### Output Contract539540```541campaign_package: {542 campaign_name: string543 email_campaign: {544 tool: string545 file_path: string546 contact_count: integer547 sequence_touches: integer548 estimated_send_days: integer549 } | null550 linkedin_campaign: {551 tool: string552 file_path: string553 contact_count: integer554 sequence_structure: string555 } | null556 total_contacts: integer557 total_companies: integer558 signal_breakdown: {559 [signal_name]: integer560 }561 next_actions: string[]562}563```564565### Human Checkpoint566567```568## Campaign Ready to Launch569570Campaign: {campaign_name}571Created: {date}572573### Email Campaign574- Tool: {email_tool}575- File: {file_path}576- Contacts: {count}577- Sequence: {touches} touches over {days} days578579### LinkedIn Campaign580- Tool: {linkedin_tool}581- File: {file_path}582- Contacts: {count}583- Sequence: Connection + {followup_count} follow-ups584585### Total586- {total_contacts} contacts across {total_companies} companies587- Signals used: {signal_list}588589### Next Steps5901. Import {email_file} into {email_tool}5912. Import {linkedin_file} into {linkedin_tool}5923. Set sending schedule (recommended: {X} emails/day, {Y} connections/day)5934. Monitor replies and move responders to CRM594595Ready to finalize? (Y/n)596```597598---599600## Execution Summary601602| Step | Tool Dependency | Human Checkpoint | Typical Time |603|------|----------------|-----------------|--------------|604| 0. Company context & ICP | None | Confirm configuration | 5 min |605| 1. Signal sources & prospect list | Configurable (signals, CSV, LinkedIn) | Review prospect sources | 3-5 min |606| 2. Enrich & find contacts | Web search + contact finder | Approve enriched list | 5-10 min |607| 3. Draft sequences | None (LLM reasoning) | Review sample sequences | 5-10 min |608| 4. Review & finalize | None | Final quality check | 2-3 min |609| 5. Export & launch | CSV generation | Launch approval | 1-2 min |610611**Total human review time: ~20-35 minutes**612613---614615## Tips616617- **Start with one signal source.** Don't try to run all five signal types in the first campaign. Pick the one most relevant to your product, prove it works, then layer on more.618- **Quality over quantity.** 50 highly personalized emails will outperform 500 generic ones. This skill prioritizes personalization depth.619- **Let the ICP definition do the filtering.** The tighter your ICP, the smaller but higher-quality your prospect list. A 5% reply rate on 50 perfect-fit prospects beats a 0.5% rate on 500 mediocre ones.620- **Multi-channel compounds results.** Email + LinkedIn together typically yields 2-3x the reply rate of either alone. The LinkedIn connection request warms them up before the email arrives.621- **Reuse what works.** After the first campaign, save winning subject lines, proof points, and angles. Future campaigns should build on proven messaging, not start from scratch.622- **Monitor and iterate.** After 50-100 sends, check open rates, reply rates, and positive reply rates. Adjust subject lines, proof points, and CTAs based on data. This skill sets up the campaign — the iteration happens in follow-up runs.623- **Don't skip the human checkpoints.** Each checkpoint exists because outreach quality drops dramatically without human review. Automated-and-sent is worse than reviewed-and-sent.