Smartlead API Guide: Keys, Rate Limits, Campaigns and Leads
Smartlead API: api_key auth, plans and rate limits, then the full flow in curl: mailboxes, warmup, campaign, sequence, schedule, 400 leads per call, webhooks.

On this page
Short answer: the Smartlead API lives at https://server.smartlead.ai/api/v1, and every request carries your key as the api_key query parameter; Smartlead documents no header auth. API access and webhooks come with the Pro plan ($94 a month) and above; Base ($39) has none. Smartlead's rate-limit guide gives 60 requests a minute per key on the standard tier and 120 on Pro. A campaign takes up to 400 leads per request.
This guide walks through the order a new campaign needs: add the sending mailboxes, set warmup, create the campaign, save the sequence, set the schedule, attach the mailboxes, add leads, start it and listen for replies with a webhook. Endpoints, fields and limits come from Smartlead's own API reference and help center, read on 15 October 2026 and linked in each section. Where Smartlead's pages disagree with each other, the section says so. For the AI-assistant side, see Smartlead MCP vs Outreach2day MCP.
Smartlead API at a Glance
Smartlead API | Source | |
|---|---|---|
Base URL |
| |
Auth |
| |
Keys | Up to 25 named admin keys per account, sharing one rate limit; client keys for white-label clients, 60 requests a minute each by default | |
Plans | API and webhooks on Pro ($94), Smart ($174) and Prime ($379) a month; Base ($39) without | |
Rate limit | Standard: 60 a minute, 1,000 an hour, 10 a second burst; Pro: 120 a minute, 3,000 an hour, 20 a second burst; per key, all endpoints | |
Pagination |
| |
Errors | JSON | |
Leads per request | 400 |
Get an API Key
The API docs put the key under your profile icon, Settings, API Keys, Generate New API Key (authentication). The help center describes the same place as Settings, Activate API, which generates a key when your plan includes the API (full API documentation). Admin keys can be named, so give each script its own.
Test the key with the campaign list, which returns a plain array:
export SMARTLEAD_API_KEY="your_key"
curl "https://server.smartlead.ai/api/v1/campaigns/?api_key=${SMARTLEAD_API_KEY}"
A missing or wrong key answers 401. A key in a URL ends up in server logs and shell history, so keep it in an environment variable and out of shared scripts.
Rate Limits
Smartlead's rate-limit guide sets the limits per API key across all endpoints: on the standard tier 60 requests a minute, 1,000 an hour and a burst of 10 a second; on Pro 120 a minute, 3,000 an hour and 20 a second; Enterprise is custom. All admin keys of one account share the account's limit. Three endpoints have an extra limit of 10 requests per 60 seconds: campaign lead statistics, all leads activities and domain-wise mailbox health (rate limits).
Over the limit you get 429, with Retry-After and X-RateLimit-* headers per the guide. The three special endpoints answer with plain text and no headers, so back off for a full minute there.
Smartlead's other pages disagree: the API introduction and the help center say limits vary by plan and to contact support, and the help center's error table mentions 10 requests per 2 seconds. Build for the lower number if your script runs on a standard key.
Step 1: Add Sending Mailboxes
POST /email-accounts/save adds an SMTP/IMAP account. Required: from_name, from_email, user_name, password, smtp_host, smtp_port, imap_host, imap_port and warmup_enabled. Useful optional fields: max_email_per_day (it counts warmup and campaign emails together), time_to_wait_in_mins, custom_tracking_url, signature, and id to update an existing account (add SMTP account).
For a mailbox from Outreach2day (every one uses the same host and ports):
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/save?api_key=${SMARTLEAD_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"from_name": "Anna Lee",
"from_email": "anna@acmemail.com",
"user_name": "anna@acmemail.com",
"password": "MAILBOX_PASSWORD",
"smtp_host": "outreachmailstream.com",
"smtp_port": 465,
"imap_host": "outreachmailstream.com",
"imap_port": 993,
"warmup_enabled": false,
"max_email_per_day": 25
}'
warmup_enabled is false here because Outreach2day warms these mailboxes itself and keeps doing so after export. For mailboxes from elsewhere, POST /email-accounts/{email_account_id}/warmup sets Smartlead's warmup: total_warmup_per_day 1 to 50, daily_rampup 5 to 20, reply_rate_percentage 20 to 100 (warmup settings).
Step 2: Create the Campaign
POST /campaigns/create takes only name (and client_id for agency clients). The campaign starts as a draft; everything else is set by the calls that follow (create campaign).
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/create?api_key=${SMARTLEAD_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"name": "Q4 SaaS founders"}'
Keep the id from the response.
Step 3: Save the Sequence
POST /campaigns/{campaign_id}/sequences saves all steps at once. Each step needs seq_number, email_body (HTML, with {{variables}}) and seq_delay_details.delay_in_days (0 to 365); id: null creates a new step. A follow-up with an empty subject goes out as a reply in the same thread. Sequences cannot change while the campaign is active, so pause it first (update sequences).
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/sequences?api_key=${SMARTLEAD_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"sequences": [
{"id": null, "seq_number": 1,
"subject": "Hello {{first_name}}",
"email_body": "<p>Hi {{first_name}},</p><p>...</p>",
"seq_delay_details": {"delay_in_days": 0}},
{"id": null, "seq_number": 2, "subject": "",
"email_body": "<p>Just following up...</p>",
"seq_delay_details": {"delay_in_days": 3}}
]
}'
Step 4: Set the Schedule
POST /campaigns/{campaign_id}/schedule takes a schedule object with an IANA timezone, days (0 is Sunday, 6 is Saturday), start_hour and end_hour in 24-hour format and an optional min_time_btw_emails in minutes (update schedule).
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/schedule?api_key=${SMARTLEAD_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"schedule": {
"timezone": "America/New_York",
"days": [1, 2, 3, 4, 5],
"start_hour": "09:00",
"end_hour": "17:00",
"min_time_btw_emails": 10
}
}'
Step 5: Attach the Mailboxes
POST /campaigns/{campaign_id}/email-accounts takes email_account_ids. Smartlead checks that the accounts are yours but does not check that they connect: an account whose SMTP or IMAP test failed is added anyway, so check is_smtp_success and is_imap_success on the accounts first (add email accounts).
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/email-accounts?api_key=${SMARTLEAD_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"email_account_ids": [456, 457, 458]}'
Step 6: Add Leads
POST /campaigns/{campaign_id}/leads takes up to 400 leads in lead_list; a longer list fails with 422. Each lead needs email; first_name, last_name, company_name, website, linkedin_profile and up to 200 custom_fields are optional. The settings object controls the filters, all false by default: ignore_global_block_list, ignore_unsubscribe_list, ignore_duplicate_leads_in_other_campaign and ignore_community_bounce_list. Leave them false unless you mean to bypass the block and bounce lists (add leads).
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads?api_key=${SMARTLEAD_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"lead_list": [
{"email": "john@company.com", "first_name": "John",
"company_name": "ACME Corp",
"custom_fields": {"industry": "SaaS"}}
],
"settings": {"return_lead_ids": true}
}'
A larger file in Python, 400 rows per call and a pause when the API says to wait:
import os, time, requests
KEY = os.environ["SMARTLEAD_API_KEY"]
BASE = "https://server.smartlead.ai/api/v1"
def add_leads(campaign_id, leads):
url = f"{BASE}/campaigns/{campaign_id}/leads"
for i in range(0, len(leads), 400):
body = {"lead_list": leads[i:i + 400]}
while True:
r = requests.post(url, params={"api_key": KEY},
json=body, timeout=60)
if r.status_code != 429:
break
time.sleep(int(r.headers.get("Retry-After", 60)))
r.raise_for_status()
Step 7: Start the Campaign
POST /campaigns/{campaign_id}/status changes the status. The reference says to send START to start or resume (and adds that it is not ACTIVE), PAUSED to pause and STOPPED to stop for good; a stopped campaign cannot be restarted (update status). The Python and JavaScript samples on that same page send ACTIVE, and Smartlead's llms.txt lists the call as PATCH, so test the curl form first:
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/status?api_key=${SMARTLEAD_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"status": "START"}'
Free guide19 min read
Send 100,000 cold emails a month
Domains and mailboxes you need, DNS, warmup, lists, copy and follow-ups, with a launch checklist, sent to your inbox.
Step 8: Read Results and Replies
GET /campaigns/{campaign_id}/analyticsreturns the top-level numbers of a campaign (analytics).GET /campaigns/{campaign_id}/statisticsreturns per-email rows, up to 1,000 per page, filtered by step, status and send date (statistics).POST /campaigns/{campaign_id}/reply-email-threadreplies in a thread withemail_stats_idandemail_body, optionally at ascheduled_time(reply).
Webhooks
POST /webhook/create registers a webhook with name, webhook_url, association_type (user, client or campaign) and an event_type_map (create webhook). Event keys include EMAIL_SENT, FIRST_EMAIL_SENT, EMAIL_OPEN, EMAIL_LINK_CLICK, EMAIL_REPLY, EMAIL_BOUNCE, LEAD_UNSUBSCRIBED, LEAD_CATEGORY_UPDATED and CAMPAIGN_STATUS_CHANGED; the events page adds EMAIL_ACCOUNT_DISCONNECTED (events).
curl -X POST "https://server.smartlead.ai/api/v1/webhook/create?api_key=${SMARTLEAD_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "Reply Notifications",
"webhook_url": "https://your-domain.com/webhook",
"email_campaign_id": 123,
"association_type": "campaign",
"event_type_map": {"EMAIL_REPLY": true}
}'
The reply event has three names across Smartlead's pages: EMAIL_REPLY on the webhook reference, LEAD_REPLIED in the campaign webhook example and EMAIL_REPLIED in the core docs. Log the first payloads you receive and match on what arrives. Smartlead retries a delivery that does not get a 200 in time.
Connect Outreach2day Mailboxes With the API Key
For mailboxes you buy from Outreach2day, steps 1 and 5 shrink to one click. Paste your Smartlead API key once in the Outreach2day app (Export to sequencer) and export: each mailbox is created in Smartlead through /email-accounts/save with its SMTP/IMAP logins and Smartlead's warmup off, and new mailboxes follow automatically; with auto reconnect on, disconnected ones are reconnected. The settings inside Smartlead (daily cap, tracking domain, errors) are on the Smartlead integration page; the same export through our REST API is in add email accounts to Instantly or Smartlead via API.
Outreach2day mailboxes cost $2.50 a month each with a 12-mailbox minimum; warmup and a sending engine are included, and setup on your domains takes about 12 minutes. You can also run the campaign in Outreach2day's own sequencer and skip the sequencer bill; for 1,000 mailboxes and more the volume price is set on a call. The cold email API covers domains, mailboxes and warmup on our side, and the Instantly API guide covers the same flow in Instantly.
Smartlead From an AI Assistant
Smartlead's help center documents an MCP server for Claude Desktop over SSE (https://mcp.smartlead.ai/sse with the key in the URL), while a Smartlead blog post sets up a local @smartlead/mcp-server package instead. Both, and what they can do next to the Outreach2day MCP server, are on Smartlead MCP vs Outreach2day MCP.
FAQ
Which Smartlead plan includes the API?
Pro ($94 a month) and above, per Smartlead's pricing table; Base ($39) has no API or webhooks.
What is the Smartlead API rate limit?
Smartlead's rate-limit guide: 60 requests a minute on the standard tier and 120 on Pro, per key, with hourly caps of 1,000 and 3,000. Three statistics endpoints allow 10 requests a minute. Other Smartlead pages say limits depend on the plan, so watch the X-RateLimit-Remaining header.
How many leads can I add per request?
400 per POST /campaigns/{campaign_id}/leads. Split larger files into chunks of 400.
Can I send the API key in a header?
Smartlead documents only the api_key query parameter, or api_key in the body of POST and PATCH requests.
Does Smartlead's API add Google or Microsoft accounts?
/email-accounts/save has a type field (GMAIL, OUTLOOK or SMTP) and a token object for OAuth accounts. SMTP/IMAP mailboxes, like Outreach2day's, need only the logins.
Get Started
Create an Outreach2day account, order mailboxes on your domains and connect Smartlead with its API key; the mailboxes arrive in Smartlead warm.
Keep reading
Send 100,000 cold emails a month
How to send 100,000 cold emails a month while keeping quality, engagement and conversion rates high: domains, mailboxes, warmup, leads, copy and scaling
Step-by-step playbook · 19 min readEmail tools8 min read
Instantly API Guide: Keys, Rate Limits, Leads and Campaigns
Email tools9 min read
Smartlead Pricing 2026: Plans, Add-Ons and Real Cost
Email tools6 min read
Add Email Accounts to Instantly or Smartlead via API
Answer2 min read
Should I Send Cold Email to Personal Gmail Addresses?
Agent skill
Cold email lead list cleaner