Smartlead Campaign Upload skill

Upload a CSV of leads + a variants YAML (produced by /campaign-copywriting) to Smartlead as a DRAFT campaign.

by growthenginenowoslawski·MIT license·★ 730 Stars on the repo·GitHub ↗

Use now

Files of Smartlead Campaign Upload

growthenginenowoslawski/main1 file shown
SKILL.md
Show the full text113 lines

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:

  • email
  • first_name
  • last_name
  • company_name

Optional columns (passed through to Smartlead as custom fields):

  • company_domain
  • title
  • linkedin_url
  • situation_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

  1. Load env (SMARTLEAD_API_KEY required)
  2. Parse leads.csv — validate required columns, count rows
  3. Parse variants.yaml — built-in minimal parser (~30 lines, no external dep)
  4. POST /campaigns/create → get campaignId
  5. POST /campaigns/{id}/sequences with all A/B/C variants
  6. Query /email-accounts?limit=100, filter by tag, sort by daily_sent_count ASC (LRU), attach top N
  7. Batch-upload leads (100 per batch) with standard custom fields mapped from CSV
  8. POST /campaigns/{id}/settings (track off, stop on reply)
  9. POST /campaigns/{id}/schedule with YAML values
  10. Print campaign URL. Do NOT activate.

Gotchas

  • Tag must exist and be applied to inboxes first. Use /smartlead-inbox-manager to tag inboxes as active before running this upload.
  • Inbox count. If inbox_selection.count exceeds 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-copywriting didn'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-scoring on 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.

  • /campaign-copywriting — produces variants.yaml
  • /smartlead-inbox-manager — required prep: inboxes must be tagged active before 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 script
  • references/variants-schema.yaml — blank schema reference (no example copy content)
  • references/leads-csv-schema.md — column spec
1---
2name: smartlead-campaign-upload-public
3description: 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.
4---
5 
6# Smartlead Campaign Upload
7 
8Takes 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.
9 
10**This skill does NOT ship any email copy.** Copy comes from `/campaign-copywriting`. This skill is the mechanical upload layer — API calls only.
11 
12## Why DRAFT only
13 
14Cold email launches should never happen from a script. You hit Start in the Smartlead UI after reviewing:
15- Subject lines + body previews
16- Inbox assignments (correct tag? correct count?)
17- Lead count and a few random lead rows
18- Schedule (timezone + hours + throttle)
19 
20The script sets all of this up in DRAFT so the review is trivial — verify and click Start.
21 
22## Inputs
23 
24### `leads.csv`
25 
26Required columns:
27- `email`
28- `first_name`
29- `last_name`
30- `company_name`
31 
32Optional columns (passed through to Smartlead as custom fields):
33- `company_domain`
34- `title`
35- `linkedin_url`
36- `situation_line` (AI-generated per-lead context)
37- `value_line` (AI-generated value mapping)
38- `cta_line` (AI-generated CTA angle)
39 
40Additional 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.
41 
42### `variants.yaml`
43 
44Produced by `/campaign-copywriting`. Schema is in `references/variants-schema.yaml`.
45 
46Minimum required: `name`, `schedule`, `inbox_selection`, `sequences` with at least one step.
47 
48## Usage
49 
50```bash
51export SMARTLEAD_API_KEY=xxx
52npx tsx scripts/upload.ts \
53 --leads=profiles/<slug>/campaigns/<campaign-slug>/leads.csv \
54 --variants=profiles/<slug>/campaigns/<campaign-slug>/variants.yaml
55```
56 
57Output:
58```
59✓ Campaign created: #12345678
60✓ Sequence saved (3 steps, 3 variants on step 1)
61✓ 20 inboxes attached (tag=active, LRU by daily_sent_count)
62✓ 1,847 leads uploaded (20 batches)
63✓ Schedule set (M-F 08:00-17:00 EST, 30/day/inbox)
64 
65Campaign is in DRAFT. Review + Start:
66→ https://app.smartlead.ai/app/email-campaign/12345678
67```
68 
69## Script flow
70 
711. Load env (`SMARTLEAD_API_KEY` required)
722. Parse `leads.csv` — validate required columns, count rows
733. Parse `variants.yaml` — built-in minimal parser (~30 lines, no external dep)
744. `POST /campaigns/create` → get campaignId
755. `POST /campaigns/{id}/sequences` with all A/B/C variants
766. Query `/email-accounts?limit=100`, filter by `tag`, sort by `daily_sent_count` ASC (LRU), attach top N
777. Batch-upload leads (100 per batch) with standard custom fields mapped from CSV
788. `POST /campaigns/{id}/settings` (track off, stop on reply)
799. `POST /campaigns/{id}/schedule` with YAML values
8010. Print campaign URL. **Do NOT activate.**
81 
82## Gotchas
83 
84- **Tag must exist and be applied to inboxes first.** Use `/smartlead-inbox-manager` to tag inboxes as `active` before running this upload.
85- **Inbox count.** If `inbox_selection.count` exceeds tagged inboxes, the script attaches all available and warns.
86- **Leads CSV size.** Tested up to 10K rows; larger runs may hit API rate limits. Script has built-in retry with exponential backoff.
87- **Variants.yaml mismatch.** If `/campaign-copywriting` didn't produce the exact schema, the script fails fast with a clear error pointing at the offending field.
88- **Email duplicates.** Smartlead deduplicates per campaign server-side. Still, dedupe your CSV first with `/list-quality-scorecard`.
89 
90## What to do next
91 
92**Open the Smartlead URL printed at the end. Review the campaign. Hit Start when satisfied.** The script deliberately does not auto-activate.
93 
94After Start:
95- Wait 21 days, then run `/positive-reply-scoring` on the campaign to measure.
96- Every Monday: run `/email-deliverability-audit --days=7` (see `/cold-email-weekly-rhythm`).
97 
98**Or wait:** if the best-practice check flagged issues, go back to `/campaign-copywriting` and revise before uploading.
99 
100## Related skills
101 
102- `/campaign-copywriting` — produces `variants.yaml`
103- `/smartlead-inbox-manager` — required prep: inboxes must be tagged `active` before upload
104- `/list-quality-scorecard` — dedupe + verify leads.csv before upload
105- `/positive-reply-scoring` — run 21 days post-launch to measure
106- `/cold-email-weekly-rhythm` — operational cadence after launch
107 
108## Files
109 
110- `scripts/upload.ts` — the upload script
111- `references/variants-schema.yaml` — blank schema reference (no example copy content)
112- `references/leads-csv-schema.md` — column spec
113 

Discussion

Alternatives

Ad library teardownUse when the user wants to analyze active ads from Meta/Facebook, Google, or LinkedIn ad libraries; tear down a competitor's messaging; extract hooks, offers, CTAs, video transcripts, landing page claims, and test ideas from public ads.Creator · MITPricing Page (High‑Conversion) — Web Design SkillTell us about your plans and prices, and get back a ready-to-build pricing page: plan layout, what each tier includes, buttons, and answers to common buyer questions.Business & ops · MITCopywriting hooksWrites opening hooks and post titles for long-form articles in EN or FR — blog posts, Substack/Medium/dev.to, LinkedIn long-form, newsletters, essays. Trigger whenever the user asks for a hook, opening, lede, intro, first sentence/paragraph, opener, accroche, attaque, phrase d'accroche, or première phrase — including punching up a flat intro or draft opening — or for a post title, titre d'article, or headline. Do NOT trigger for social posts (LinkedIn feed, Twitter/X, TikTok, Bluesky), READMEs, taglines, email subjects, ad copy, landing-page headlines, press releases, SEO meta, or body rewrites. Do NOT use for end-of-article CTAs — use samber/cc-skills@copywriting-cta instead.Marketing · MITEW Skill — Sales CopyWrite sales pages, email sequences, and direct-response copy that converts through clarity and specificity rather than manipulation. Use for launches, offers, and conversion-focused email. Enforces the EW anti-AI rules, proof standards, and the writer's voice profile.Marketing · MIT