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 ↗
npx degit growthenginenowoslawski/coldoutboundskills/skills/smartlead-campaign-upload-public#main ~/.claude/skills/smartlead-campaign-upload-publicChecked ·commit main
Files of Smartlead Campaign Upload
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:
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
| 1 | |
| 2 | name smartlead-campaign-upload-public |
| 3 | description 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 | |
| 8 | 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. |
| 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 | |
| 14 | Cold 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 | |
| 20 | The 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 | |
| 26 | Required columns: |
| 27 | `email` |
| 28 | `first_name` |
| 29 | `last_name` |
| 30 | `company_name` |
| 31 | |
| 32 | Optional 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 | |
| 40 | 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. |
| 41 | |
| 42 | ### `variants.yaml` |
| 43 | |
| 44 | Produced by `/campaign-copywriting`. Schema is in `references/variants-schema.yaml`. |
| 45 | |
| 46 | Minimum required: `name`, `schedule`, `inbox_selection`, `sequences` with at least one step. |
| 47 | |
| 48 | ## Usage |
| 49 | |
| 50 | |
| 51 | export SMARTLEAD_API_KEY=xxx |
| 52 | npx tsx scripts/upload.ts \ |
| 53 | --leads=profiles/<slug>/campaigns/<campaign-slug>/leads.csv \ |
| 54 | --variants=profiles/<slug>/campaigns/<campaign-slug>/variants.yaml |
| 55 | |
| 56 | |
| 57 | Output: |
| 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 | |
| 65 | Campaign is in DRAFT. Review + Start: |
| 66 | → https://app.smartlead.ai/app/email-campaign/12345678 |
| 67 | |
| 68 | |
| 69 | ## Script flow |
| 70 | |
| 71 | Load env (`SMARTLEAD_API_KEY` required) |
| 72 | Parse `leads.csv` — validate required columns, count rows |
| 73 | Parse `variants.yaml` — built-in minimal parser (~30 lines, no external dep) |
| 74 | `POST /campaigns/create` → get campaignId |
| 75 | `POST /campaigns/{id}/sequences` with all A/B/C variants |
| 76 | Query `/email-accounts?limit=100`, filter by `tag`, sort by `daily_sent_count` ASC (LRU), attach top N |
| 77 | Batch-upload leads (100 per batch) with standard custom fields mapped from CSV |
| 78 | `POST /campaigns/{id}/settings` (track off, stop on reply) |
| 79 | `POST /campaigns/{id}/schedule` with YAML values |
| 80 | 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 | |
| 94 | After 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
Browse more free Claude skills or everything in Marketing.