Campaign launchpad v2
Skill UmertheGTME/claude-skills-for-heyreach/campaign-launchpad-v2
Claude skills for running HeyReach LinkedIn outreach in plain English: campaign building, ICP sourcing via Prospeo, sequence templates, and read-only analytics.
npx -y skills add UmertheGTME/claude-skills-for-heyreach --skill campaign-launchpad-v2Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Source leads live from Prospeo by describing your ideal customer in plain English, then build and launch a HeyReach LinkedIn campaign — end to end. Use when the user wants to find/source prospects AND run outreach: "find me [role] at [type of company] and launch a campaign", "build a campaign targeting X", "source leads and start outreach", or "I don't have a list yet, find the people". The skill asks guided, selectable questions one at a time, translates the ICP into Prospeo search filters, confirms the lead count and credit cost before extracting anything (strict gate), imports the leads to HeyReach, lets you paste your own copy or have AI write it from your offer, then runs the same sequence / schedule / senders / pre-flight / launch flow as V1. Requires a Prospeo API key and a HeyReach API key. Pairs with heyreach-sequence-templates.
SKILL.md
11.0 KB, ~2.7k tokens by cl100k_base, as published. Nobody here has run it
HeyReach Campaign Launchpad V2 — Prospeo-sourced
V1 started from a CSV or an existing list. V2 sources the leads for you from Prospeo: the user describes
their ICP in plain English, the skill finds and enriches matching people, imports them to HeyReach, and then
builds the campaign exactly like V1. Two reference files do the heavy lifting:
references/prospeo-api.md (the API spec) and
references/icp-to-filters.md (how to turn an ICP into search filters).
Triggers
"find me [role] at [type of company] and launch a campaign", "build a campaign targeting …", "source leads and start outreach", "I don't have a list — find the people and run a campaign", "prospect + campaign".
Use V1 (heyreach-campaign-launchpad) instead when the user already has the leads (a CSV or an existing HeyReach list) and just wants to launch.
Prerequisites
- Prospeo API key —
export PROSPEO_API_KEY=...(sent as theX-KEYheader). - HeyReach workspace key —
export HEYREACH_API_KEY=...(verify withheyreach auth check). - At least one connected, authenticated LinkedIn sender (
heyreach li-accounts list→authIsValid: true).
Set expectations
This skill spends Prospeo credits and launches real outreach. Be calm and explicit:
"I'll ask a few quick questions, show you exactly how many leads and credits before extracting anything, and nothing is pulled or charged until you confirm."
The golden rule of the question flow
Ask ONE question at a time, as selectable options, using the AskUserQuestion tool — that renders as
clickable choices in the app and numbered (press 1/2/3) choices in the terminal. Wait for each answer before
the next question. Free-text is only for the two things that can't be enumerated: the ICP description and the
offer/copy instructions.
How it works
0. Auth + account check (read-only, no charge)
heyreach auth check
curl -s https://api.prospeo.io/account-information -H "X-KEY: $PROSPEO_API_KEY"
From the Prospeo response, note response.current_plan and response.remaining_credits — you'll need both for
the cost gate and for plan-gating. Confirm a healthy HeyReach sender exists.
1. Ask the ICP (free text)
"Who do you want to target? Describe your ideal customer in your own words — role, type of company, location, size, anything that matters."
2. Translate ICP → Prospeo filters, then confirm (selectable)
Using references/icp-to-filters.md:
- Pick the sourcing mode — attribute search (default), named-accounts (user gave target companies/domains →
company.websites), or enrichment-only (user already has LinkedIn URLs/emails → skip search). - Build the
filtersobject. Validate every location / job-title / industry / technology value againstPOST /search-suggestions(free) so you use Prospeo's canonical strings, not raw user text. - Respect plan-gating: if a needed filter is above
current_plan, either drop it or flag it. - Play the interpretation back and let the user confirm or adjust with
AskUserQuestion, e.g.:"Here's how I read that: VPs/Heads of Sales · Series B SaaS · United States · verified emails only. Good to go?" Options:
Looks right — continue·Adjust targeting·Add target companies - Ask 1–2 selectable clarifiers only if genuinely ambiguous (seniority band, region, "verified emails only?").
3. 🚦 STRICT count gate — nothing is extracted before this
Do not call /search-person or /bulk-enrich-person until the user has explicitly confirmed the data depth,
the count, AND the cost. This is a hard stop.
-
Data depth — ask with
AskUserQuestion:"What do you need for each lead?" Options:
LinkedIn only (cheapest — all a LinkedIn campaign needs)·LinkedIn + verified email·LinkedIn + email + mobileA LinkedIn connection-request + message campaign needs only the profile URL, which search already returns — so LinkedIn-only is the default and ~25× cheaper. Choose email/mobile only for an email/multichannel step or to export contacts.
-
Ask how many leads with
AskUserQuestion(presets + custom):25·100·250·500·Custom. -
Estimate credits by depth (search = 1 credit / 25 results; email = 1 credit/found; mobile = 10/found):
- LinkedIn only →
ceil(N / 25)(e.g. 250 leads ≈ 10 credits) - + verified email →
ceil(N/25)+ up toN - + mobile →
ceil(N/25)+ up to10 × N
Enrichment only charges on found, so actual ≤ estimate.
- LinkedIn only →
-
Compare to
remaining_credits. If short, offer a smaller N, a lighter depth, or stop. -
Final confirmation with
AskUserQuestion:"Extract up to {N} leads ({depth}) — about {est} credits (you have {remaining_credits}). Proceed?" Options:
Yes, extract now·Change the number·Cancel -
Only on
Yesdo you proceed to step 4. If the user never confirms, stop — do nothing.
4. Extract
Per references/prospeo-api.md:
- Search loop (always):
POST /search-personwith{filters, page}, page = 1,2,3… (25/page) until you've collectedNperson_ids orpagination.total_pageis exhausted. This already returns the LinkedIn URL, name, title, company, location, and headline — everything a LinkedIn campaign needs. Self-throttle to the plan's search rate limit. - Enrich loop (ONLY if the user chose email/mobile in step 3): batch the
person_ids into groups of 50 →POST /bulk-enrich-personwithdata:[{identifier, person_id}],only_verified_email: true(andenrich_mobile: trueonly if mobiles were chosen). Collectmatched[]; dropnot_matched/UNAVAILABLE. Skip this entirely for LinkedIn-only — no enrichment credits spent. - Report the real result: "Sourced {found} leads ({depth}) · {credits} credits used."
5. Import to HeyReach
- Create the list:
heyreach lists create --name "<ICP> — <date>".Known CLI quirk:
lists createprints an unmarshal error but the list is created — get its id from the error body orheyreach lists list --keyword "<name>". - Map each enriched record and
heyreach lists add-leadsin batches of ≤100. Field mapping:
Prospeo (matched[].person / .company) | HeyReach lead field |
|---|---|
linkedin_url | profileUrl (required) |
first_name / last_name | firstName / lastName |
company.name | companyName |
current_job_title | position |
enriched email.email | emailAddress |
location.city / country | location |
headline, company.industry, recent job-change, etc. | customUserFields: [{ "name": "...", "value": "..." }] → usable as {VARIABLE} |
(Use the {name,value} shape — it's the validated one. {fieldName,fieldValue} is rejected.)
emailAddress is only populated when the user chose an email/mobile depth in step 3 — LinkedIn-only runs leave it empty, which is fine for a connection-request + message campaign.
6. Copy fork (selectable)
Ask with AskUserQuestion:
"How do you want the messages written?" Options:
I'll write my own·Let AI write it from my offer
- Write your own → user pastes their connection note / messages; you place them into the chosen sequence verbatim.
- AI writes it → ask (free text) for their offer + any rules ("what do you sell, to whom, the angle, tone").
Generate short, value-first messages using the personalization tokens available from the imported fields
(
{FIRST_NAME},{COMPANY},{POSITION}, plus any custom field). EveryMESSAGE/INMAILmust have afallbackMessage. Show the drafts and let the user approve/tweak before applying.
7. Build & launch the campaign (identical to V1)
Hand off to the standard flow — use the heyreach-sequence-templates skill for the sequence:
- Pick a sequence template matching connection degree; drop in the copy from step 6.
- Set the schedule (audience timezone), assign senders, set exclusions.
- Assemble
heyreach campaigns create(sequence rules that the live API enforces:CONNECTION_REQUESTneeds apayload, every non-root node incl.ENDneedsactionDelay≥ 3h, everyMESSAGE/INMAILneeds afallbackMessage). - Run the pre-flight checklist, then
heyreach campaigns start, verifyIN_PROGRESS, and print the launch summary.
Cost & safety
- LinkedIn-only is the default and ~25× cheaper. Search returns the LinkedIn URL + profile for ~1 credit per 25 leads; emails cost ~1 credit each. A connection-request + message campaign needs only the profile URL, so skip email enrichment unless running an email/multichannel step or exporting contacts.
- The count gate (step 3) is non-negotiable — never search or enrich before explicit confirmation.
- Prefer
only_verified_email: trueso credits are only spent on usable emails. - Mobiles cost 10× — only request them if the user explicitly wants phones.
- Pace requests to the plan's rate limits (search 1–5/s, enrich 5–30/s); read the
x-*-request-leftheaders. INSUFFICIENT_CREDITS(HTTP 400) is the safety net if an estimate runs short mid-extraction — stop and report.
Edge cases
PLAN_REQUIRED(400) — a filter needs a higher Prospeo plan; thefilter_errornames it. Drop the filter or tell the user which plan unlocks it.NO_RESULTS— filters too narrow; suggest loosening one constraint (pericp-to-filters.md).- Low enrich match rate — normal; search finds people, but not everyone has a verified email. Report found vs. requested.
- 25,000-lead ceiling per search, and a single large pull can exhaust the daily search quota on lower plans — warn for big N.
- Connection degree, USER_LIST type, 100-leads-per-add-leads — same rules as V1.
References
references/prospeo-api.md— endpoints, the two-step pipeline, credit model, rate limits, plan-gating.references/icp-to-filters.md— ICP →search-personfilters, value validation, worked examples.- heyreach-sequence-templates — the sequence JSON + the live-validated node rules.