Smartlead is built for volume: many sending mailboxes, rotation between them, analytics per campaign. Your agent creates the campaign, drafts the sequence and loads the leads, then stops and waits for your approval before a single email goes.
Smartlead is activation for high volume. Everything upstream feeds it a validated list.
volume sending punishes a bad list hardest
personalisation at the scale volume sending needs
fill a large list before it goes near a mailbox
replies land on the record automatically
Ask for the outcome and your agent composes the run itself. Or start from a skill, a whole pipeline it already knows end to end.
browse all skills →Every tool ships with a written playbook, and the agent loads it before the first call. Auth, rate limits, what each call costs, which actions need your approval, and the mistakes worth avoiding. It is the difference between an agent that knows the tool and one that guesses at it.
Read the SmartLead docs →HOW in lib/smartlead.py. Docs cached at reference/docs/smartlead/raw/llms.txt.
https://server.smartlead.ai/api/v1 · Auth: API key as query param ?api_key= (env SMARTLEAD_API_KEY; never hardcode). The client injects it automatically.update_campaign_status(id, "START") begins sending. add_leads_to_campaign into an active campaign feeds live sending. Approval-gate both: build in a paused campaign / lead list, pilot, confirm, then start.Campaigns: list_campaigns, create_campaign, get_campaign, update_campaign_status, save_campaign_sequence, get_campaign_analytics. Leads: add_leads_to_campaign, list_leads_by_campaign. Email accounts: list_email_accounts, add_email_account_to_campaign. Else → generic request().
Activation layer: enriched + validated leads → add_leads_to_campaign → review → START. Mailboxes via InboxKit feed list_email_accounts.
Field-shape note: these are vendor-native operational notes. The client returns the raw vendor JSON and uses the method names in this file — read field shapes accordingly (no normalized-wrapper /
result.data.prefix).
Activation order: create/list campaign -> add email accounts -> save sequences -> set schedule -> set settings -> push leads -> start -> monitor. Always resolve the campaign ID before any write.
Gotchas (vendor-native):
PAUSED, STOPPED, START - it's START, not STARTED/RUNNING.seq_number must be contiguous from 1 (no gaps); step 1 must have a subject; delay_in_days is days (0 = immediate) - never hours/minutes.America/New_York); start_hour/end_hour 24h HH:MM, start strictly before end; days_of_the_week 0=Sun..6=Sat, >=1 required. min_time_btw_emails is canonical (min_time_btwn_emails legacy alias).DONT_TRACK_EMAIL_OPEN, DONT_TRACK_LINK_CLICK, DONT_TRACK_REPLY_TO_AN_EMAIL. Stop-lead: REPLY_TO_AN_EMAIL, CLICK_ON_A_LINK, OPEN_AN_EMAIL.YYYY-MM-DD.EMAIL_SENT, EMAIL_OPEN, EMAIL_LINK_CLICK, EMAIL_REPLY, LEAD_UNSUBSCRIBED, LEAD_CATEGORY_UPDATED.200 {} when missing (treat as no-result); unsubscribe can return 200 {"ok":false} for unknown lead (treat as failure); lead export returns CSV text, not JSON.lib/smartlead.pyImport: from lib.smartlead import Smartlead → instantiate Smartlead() (reads key from env). Base: https://server.smartlead.ai/api/v1. Generic passthrough: request(method, path, *, params, json).
add_email_account_to_campaign(campaign_id: str, email_account_ids: list[int]) -> Anyadd_leads_to_campaign(campaign_id: str, lead_list: list[dict], **settings) -> Any — POST /campaigns/{id}/leads — add leads. Feeds an active campaign into sending — approval-gate.create_campaign(name: str, **opts) -> Any — POST /campaigns/create — create a campaign.get_campaign(campaign_id: str) -> Anyget_campaign_analytics(campaign_id: str) -> Anylist_campaigns() -> Any — GET /campaigns — all campaigns.list_email_accounts(**params) -> Any — GET /email-accounts/ — sending mailboxes.list_leads_by_campaign(campaign_id: str, **params) -> Anysave_campaign_sequence(campaign_id: str, sequences: list[dict]) -> Any — POST /campaigns/{id}/sequences — define the email steps/A-B variants.update_campaign_status(campaign_id: str, status: str) -> Any — POST /campaigns/{id}/status — status: PAUSED | STOPPED | START. START begins sending (outreach!).