Agent skill
smartlead-campaign-upload-public
Upload a CSV of leads + a variants YAML (produced by /campaign-copywriting) to Smartlead as a DRAFT campaign.
Filed under Outbound email.
From growthenginenowoslawski/coldoutboundskills · 50 skills · 668 · pushed 2026-08-18
What it does when it runs
Upload a CSV of leads + a variants YAML (produced by /campaign-copywriting) to Smartlead as a DRAFT campaign. Handles tag-scoped inbox selection, A/B/C variant assembly, custom field mapping, schedule config, and batch lead upload. ALWAYS creates in DRAFT — you review in Smartlead UI and hit Start manually. Use after /campaign-copywriting, just before the campaign goes live.
Read from the skill and the 3 files bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.
- Keys and connectors you must supply
- API_KEY
- SMARTLEAD_API_KEY
- Hosts it reaches
- app.smartlead.ai
- server.smartlead.ai
- Tool permissions it declares
- No
allowed-toolsin the frontmatter. It does act, so it runs under whatever permissions your session already grants. - Actions present in the files
- shellwrites filesnetwork
Install it
View source on GitHub ↗git clone --depth 1 --filter=blob:none --sparse https://github.com/growthenginenowoslawski/coldoutboundskills.git /tmp/coldoutboundskills git -C /tmp/coldoutboundskills sparse-checkout set "skills/smartlead-campaign-upload-public" mkdir -p ~/.claude/skills/smartlead-campaign-upload-public cp -R "/tmp/coldoutboundskills/skills/smartlead-campaign-upload-public/." ~/.claude/skills/smartlead-campaign-upload-public/
Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗
The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.
Before you install: this skill will not complete its job on a bare agent. It needs API_KEY, SMARTLEAD_API_KEY, which you have to obtain separately.
The skill
Source on GitHub ↗Reproduced in full from growthenginenowoslawski/coldoutboundskills/blob/f24320d4ab3ddb717402a065a3679aca5a7a8665/skills/smartlead-campaign-upload-public/SKILL.md, which is licensed MIT (repository). 607 words, 11 headings.
Smartlead Campaign Upload
Takes a variants.yaml (written by /campaign-copywriting) and a leads.csv (from your list-building skills) and creates a DRAFT campaign in Smartlead. You review the result in the Smartlead UI and press Start manually.
This skill does NOT ship any email copy. Copy comes from /campaign-copywriting. This skill is the mechanical upload layer — API calls only.
Why DRAFT only
Cold email launches should never happen from a script. You hit Start in the Smartlead UI after reviewing:
- Subject lines + body previews
- Inbox assignments (correct tag? correct count?)
- Lead count and a few random lead rows
- Schedule (timezone + hours + throttle)
The script sets all of this up in DRAFT so the review is trivial — verify and click Start.
Inputs
leads.csv
Required columns:
emailfirst_namelast_namecompany_name
Optional columns (passed through to Smartlead as custom fields):
company_domaintitlelinkedin_urlsituation_line(AI-generated per-lead context)value_line(AI-generated value mapping)cta_line(AI-generated CTA angle)
Additional AI variable columns produced by /campaign-copywriting or /personalization-subagent-pattern — named fields only. The script does NOT accept arbitrary columns; this is intentional. If you need to add a field, update this skill.
variants.yaml
Produced by /campaign-copywriting. Schema is in references/variants-schema.yaml.
Minimum required: name, schedule, inbox_selection, sequences with at least one step.
Usage
export SMARTLEAD_API_KEY=xxx
npx tsx scripts/upload.ts \
--leads=profiles/<slug>/campaigns/<campaign-slug>/leads.csv \
--variants=profiles/<slug>/campaigns/<campaign-slug>/variants.yaml
Output:
✓ Campaign created: #12345678
✓ Sequence saved (3 steps, 3 variants on step 1)
✓ 20 inboxes attached (tag=active, LRU by daily_sent_count)
✓ 1,847 leads uploaded (20 batches)
✓ Schedule set (M-F 08:00-17:00 EST, 30/day/inbox)
Campaign is in DRAFT. Review + Start:
→ https://app.smartlead.ai/app/email-campaign/12345678
Script flow
- Load env (
SMARTLEAD_API_KEYrequired) - Parse
leads.csv— validate required columns, count rows - Parse
variants.yaml— built-in minimal parser (~30 lines, no external dep) POST /campaigns/create→ get campaignIdPOST /campaigns/{id}/sequenceswith all A/B/C variants- Query
/email-accounts?limit=100, filter bytag, sort bydaily_sent_countASC (LRU), attach top N - Batch-upload leads (100 per batch) with standard custom fields mapped from CSV
POST /campaigns/{id}/settings(track off, stop on reply)POST /campaigns/{id}/schedulewith YAML values- Print campaign URL. Do NOT activate.
Gotchas
- Tag must exist and be applied to inboxes first. Use
/smartlead-inbox-managerto tag inboxes asactivebefore running this upload. - Inbox count. If
inbox_selection.countexceeds tagged inboxes, the script attaches all available and warns. - Leads CSV size. Tested up to 10K rows; larger runs may hit API rate limits. Script has built-in retry with exponential backoff.
- Variants.yaml mismatch. If
/campaign-copywritingdidn't produce the exact schema, the script fails fast with a clear error pointing at the offending field. - Email duplicates. Smartlead deduplicates per campaign server-side. Still, dedupe your CSV first with
/list-quality-scorecard.
What to do next
Open the Smartlead URL printed at the end. Review the campaign. Hit Start when satisfied. The script deliberately does not auto-activate.
After Start:
- Wait 21 days, then run
/positive-reply-scoringon the campaign to measure. - Every Monday: run
/email-deliverability-audit --days=7(see/cold-email-weekly-rhythm).
Or wait: if the best-practice check flagged issues, go back to /campaign-copywriting and revise before uploading.
Related skills
/campaign-copywriting— producesvariants.yaml/smartlead-inbox-manager— required prep: inboxes must be taggedactivebefore upload/list-quality-scorecard— dedupe + verify leads.csv before upload/positive-reply-scoring— run 21 days post-launch to measure/cold-email-weekly-rhythm— operational cadence after launch
Files
scripts/upload.ts— the upload scriptreferences/variants-schema.yaml— blank schema reference (no example copy content)references/leads-csv-schema.md— column spec
Files bundled with it
These load only when the skill asks for them, so they cost nothing until it runs.
Other skills for the same job
Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.
- public-relations by coreyhaines31 · 46,928
- campaign-postmortem by zapier · 334
- mega-campaign-generator by zapier · 334
- campaign-dashboard by Othmane-Khadri · 290
- campaign-strategy by Othmane-Khadri · 290
- launch-linkedin-campaign by Othmane-Khadri · 290
- campaign-angle-finder by Othmane-Khadri · 290
- outbound-campaign-architect by Othmane-Khadri · 290
Need help setting it up?
This page tells you what smartlead-campaign-upload-public does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.
Book a call →The directory stays free. There is nothing gated behind this.