Install
$ agentstack add skill-mattsezgin-unofficial-smartlead-cli-upload-leads ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
> Before running: verify exact flag names with smartlead --help. Flag shapes shown below are illustrative — confirm against the actual CLI.
/upload-leads
You're loading a lead list into a Smartlead campaign.
What you need from the user
- Campaign ID to upload to
- Lead source — CSV path, JSON file, or pasted list
- Dedup scope — just this campaign, or check against all campaigns?
Step 1 — Validate the source
Look at the file first. Confirm columns:
email(required)first_name,last_name(recommended)company_name(recommended)linkedin_url,phone_number,website(optional)- Anything else → goes into
custom_fieldsfor personalization
head -5
wc -l
Report row count, column names, and a sample row. Confirm with user before uploading.
Step 2 — Pre-validation
Filter obviously bad emails
# Emails missing @, or with invalid TLD
grep -E '^[^@]+@[^@]+\.[a-z]{2,}$' leads.csv > leads-cleaned.csv
Flag count of dropped rows.
Optional: ZeroBounce / NeverBounce validation
If the user has 1000+ leads and bounces matter, recommend pre-validating with an external service before upload. Smartlead doesn't validate emails at upload time.
Step 3 — Dedupe
Against this campaign
smartlead leads list --output json | jq -r '.[].email' > existing.txt
Then filter the upload CSV:
awk -F, 'NR==FNR{a[$1]; next} !($1 in a)' existing.txt leads.csv > new-leads.csv
Against all live campaigns (broader dedup)
Important for B2B — you don't want the same prospect getting hit by Campaign A AND Campaign B.
# Pull emails from all active campaigns
smartlead campaigns list --output json | jq -r '.[] | select(.status == "ACTIVE") | .id' | \
while read cid; do
smartlead leads list $cid --output json | jq -r '.[].email'
done | sort -u > all-active.txt
# Filter
awk -F, 'NR==FNR{a[$1]; next} !($1 in a)' all-active.txt leads.csv > new-leads.csv
Report: started with X leads, after dedup Y remain (Z dropped).
Step 4 — Batch upload (Smartlead caps at 100 per request)
The CLI handles pagination, but if you're hitting the API directly:
smartlead leads add --csv new-leads.csv
The command splits into 100-row batches automatically and reports per-batch results.
For very large files (10K+), recommend uploading in chunks of 5K with a sleep between, to stay well under rate limits (see docs/learnings/rate-limits.md).
Step 5 — Verify upload
smartlead leads list --output json | jq 'length'
Should match expected count. If short, look at the upload command's error log — Smartlead silently rejects rows with malformed custom_fields.
Step 6 — Report
Summarize for the user:
✓ Uploaded X new leads to campaign
✓ Skipped Y duplicates (already in this or other campaigns)
✓ Dropped Z invalid rows (bad email format / missing required fields)
Campaign now has N total leads.
Important gotcha — leads are shared across campaigns
Smartlead's data model is: email = unique lead at the account level, NOT per-campaign. If you upload the same email to Campaign A then to Campaign B:
- Both campaigns reference the SAME lead record
custom_fieldsset on Campaign A propagate to Campaign B's view of that lead- You CAN'T have per-campaign custom_fields for the same email
Practical implication: if you're A/B testing personalization fields, use DIFFERENT emails (or different campaigns with different lead pools), not the same lead in two campaigns.
(More: docs/learnings/campaign-cloning-runbook.md)
Reference
docs/learnings/campaign-cloning-runbook.md— lead-sharing behaviordocs/learnings/rate-limits.md— pagination and throttling
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: MattSezgin
- Source: MattSezgin/unofficial-smartlead-cli
- License: MIT
- Homepage: https://github.com/MattSezgin/unofficial-smartlead-cli
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.