# Get Campaign List
Source: https://api.smartlead.ai/api-reference/analytics/campaign-list
GET https://server.smartlead.ai/api/v1/analytics/campaign/list
Retrieve list of all campaigns for building selectors and filtering
## Query Parameters
Your SmartLead API key
Comma-separated client IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/campaign/list?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/campaign/list",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/campaign/list?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"campaign_list": [
{
"id": 12345,
"name": "Q1 Cold Outreach"
},
{
"id": 12346,
"name": "Product Launch Follow-up"
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Campaign Performance
Source: https://api.smartlead.ai/api-reference/analytics/campaign-performance
GET https://server.smartlead.ai/api/v1/analytics/campaign/overall-stats
Get performance metrics for each campaign with engagement rates and lead counts
## Path Parameters
No path parameters
## Query Parameters
Your SmartLead API key
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
Timezone string (e.g. "America/New\_York"), optional
Comma-separated client IDs (optional)
Comma-separated campaign IDs (optional)
Max number of results to return (optional)
Pagination offset (optional)
Set to "true" to return full data set (optional)
## Request Body
No request body required
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/campaign/overall-stats?api_key=YOUR_KEY&start_date=2024-01-01&end_date=2024-01-31&timezone=America%2FNew_York"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/campaign/overall-stats",
params={
"api_key": API_KEY,
"start_date": "2024-01-01",
"end_date": "2024-01-31",
"timezone": "America/New_York"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/campaign/overall-stats?api_key=${API_KEY}&start_date=2024-01-01&end_date=2024-01-31&timezone=America%2FNew_York`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"campaign_wise_performance": [
{
"id": 12345,
"campaign_name": "Q1 Cold Outreach",
"sent": 500,
"opened": 250,
"replied": 45,
"bounced": 8,
"open_rate": "50%",
"reply_rate": "9%",
"bounce_rate": "1.6%",
"positive_reply_rate": "5%",
"positive_replied": 25,
"unique_lead_count": 480,
"unique_open_count": 230
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## How these metrics are calculated
Shared rules (inclusive date boundaries, unique vs raw counts, rate formulas) are documented once in [How Analytics Metrics Are Calculated](/api-reference/analytics/how-metrics-are-calculated).
One row is returned per campaign. All metrics are scoped to emails **sent** within the date range (`sent_time`), inclusive on both ends; a single date returns that one full day.
| Field | How it's calculated |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sent` / `opened` / `replied` / `bounced` | Raw event counts within the range. Additive. |
| `positive_replied` | Distinct leads tagged **positive** (`sentiment_type = 'positive'`). **Note:** the date attribution on this breakdown endpoint differs from the [`overall-stats-v2` tile](/api-reference/analytics/overview) (which is reply-date) — don't assume the two match for the same window. Use `overall-stats-v2` or the day-wise positive endpoints as the source of truth for positive counts. |
| `unique_lead_count` | `COUNT(DISTINCT lead)` sent at least one email in the range (deduplicated per campaign by email). **Not** additive across days. |
| `unique_open_count` | `COUNT(DISTINCT lead)` that opened in the range. Not additive across days. |
| `open_rate` | `unique_open_count / unique_lead_count` |
| `reply_rate` | `replied / unique_open_count` (falls back to `unique_lead_count` when open tracking is off, e.g. plain-text sends) |
| `positive_reply_rate` | `positive_replied / replied` |
| `bounce_rate` | `bounced / unique_lead_count` (per unique lead, not per email sent) |
# Campaign Response Stats
Source: https://api.smartlead.ai/api-reference/analytics/campaign-response-stats
GET https://server.smartlead.ai/api/v1/analytics/campaign/response-stats
Get detailed response analysis per campaign with sentiment breakdown
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
Set to "true" to return full data set
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/campaign/response-stats?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/campaign/response-stats",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/campaign/response-stats?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"campaign_wise_response_stats": [
{
"campaign_id": 12345,
"campaign_name": "Q1 Outreach",
"positive_reply": 25,
"neutral_reply": 10,
"negative_reply": 5
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## How these metrics are calculated
Shared rules (inclusive date boundaries, how positive replies are counted) are documented once in [How Analytics Metrics Are Calculated](/api-reference/analytics/how-metrics-are-calculated).
One row is returned per campaign, breaking its replies down by the **sentiment category** of the lead, attributed to the **date the reply was received**.
| Field | How it's calculated |
| ---------------- | -------------------------------------------------------------------- |
| `positive_reply` | Response events from leads whose category sentiment is **positive**. |
| `neutral_reply` | Response events from leads whose category sentiment is **neutral**. |
| `negative_reply` | Response events from leads whose category sentiment is **negative**. |
Unlike `positive_replied` on the other endpoints, these are **response-event counts, not distinct leads** — a lead that replies twice is counted twice. As a result, `positive_reply` here can be **higher** than the `positive_replied` shown by [overall-stats-v2](/api-reference/analytics/overview) for the same window, which counts each lead once. Don't expect the two to match.
Counts are scoped to the date range inclusive on both ends; a single date returns that one full day. The lead category is mutable, so re-categorising a lead changes historical counts.
# Campaign Status Stats
Source: https://api.smartlead.ai/api-reference/analytics/campaign-status-stats
GET https://server.smartlead.ai/api/v1/analytics/campaign/status-stats
Get count of campaigns in each status for operational overview
## Query Parameters
Your SmartLead API key
Comma-separated client IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/campaign/status-stats?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/campaign/status-stats",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/campaign/status-stats?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"campaign_status_stats": [
{
"status": "STARTED",
"count": 5
},
{
"status": "PAUSED",
"count": 2
},
{
"status": "COMPLETED",
"count": 8
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Get Client List
Source: https://api.smartlead.ai/api-reference/analytics/client-list
GET https://server.smartlead.ai/api/v1/analytics/client/list
Get list of all clients for agency account filtering and selection
## Query Parameters
Your SmartLead API key
Comma-separated client IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/client/list?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/client/list",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/client/list?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"client_list": [
{
"id": 1,
"name": "Acme Corp"
},
{
"id": 2,
"name": "TechStart Inc"
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Client Overall Stats
Source: https://api.smartlead.ai/api-reference/analytics/client-performance
GET https://server.smartlead.ai/api/v1/analytics/client/overall-stats
Get performance metrics by client for agency reporting and analysis
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Filter value for client results
Set to "true" to return full data set
Max number of results to return
Pagination offset
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/client/overall-stats?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/client/overall-stats",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/client/overall-stats?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"client_wise_performance": [
{
"client_id": 1,
"client_name": "Acme Corp",
"total_campaigns_count": 10,
"campaign_stats": {
"sent": 1000,
"opened": 500,
"replied": 80,
"positive_replied": 40,
"client_health": "85%",
"open_rate": "50%",
"reply_rate": "8%",
"positive_reply_rate": "4%",
"unique_open_count": 450,
"unique_lead_count": 900
}
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## How these metrics are calculated
Shared rules (inclusive date boundaries, unique vs raw counts, rate formulas) are documented once in [How Analytics Metrics Are Calculated](/api-reference/analytics/how-metrics-are-calculated).
One row is returned per client, aggregating every campaign that belongs to that client. All metrics are scoped to emails **sent** within the date range (`sent_time`), inclusive on both ends; a single date returns that one full day.
| Field | How it's calculated |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `total_campaigns_count` | `COUNT(DISTINCT campaign)` for the client with sends in the range. |
| `sent` / `opened` / `replied` / `bounced` | Raw event counts, summed across the client's campaigns. Additive. |
| `positive_replied` | Distinct leads tagged **positive** (`sentiment_type = 'positive'`). **Note:** the date attribution on this breakdown endpoint differs from the [`overall-stats-v2` tile](/api-reference/analytics/overview) (which is reply-date) — don't assume the two match for the same window. Use `overall-stats-v2` or the day-wise positive endpoints as the source of truth for positive counts. |
| `unique_lead_count` | `COUNT(DISTINCT lead)` sent at least one email in the range (deduplicated per campaign by email). **Not** additive across days. |
| `unique_open_count` | `COUNT(DISTINCT lead)` that opened in the range. Not additive across days. |
| `client_health` | `positive_replied / unique_lead_count` |
| `open_rate` | `unique_open_count / unique_lead_count` |
| `reply_rate` | `replied / unique_open_count` (falls back to `unique_lead_count` when open tracking is off) |
| `positive_reply_rate` | `positive_replied / replied` |
| `bounce_rate` | `bounced / unique_lead_count` (per unique lead, not per email sent) |
# Day-wise Positive Reply Stats
Source: https://api.smartlead.ai/api-reference/analytics/day-wise-positive-reply
GET https://server.smartlead.ai/api/v1/analytics/day-wise-positive-reply-stats
Get daily positive reply metrics filtered to interested/positive categories only
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/day-wise-positive-reply-stats?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/day-wise-positive-reply-stats",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/day-wise-positive-reply-stats?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"day_wise_stats": [
{
"date": "2024-01-15",
"positive_replied": 5
},
{
"date": "2024-01-16",
"positive_replied": 7
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## How these metrics are calculated
Shared rules (inclusive date boundaries, send-date attribution, unique vs raw counts) are documented once in [How Analytics Metrics Are Calculated](/api-reference/analytics/how-metrics-are-calculated).
| Field | How it's calculated |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `positive_replied` | `COUNT(DISTINCT lead)` for leads tagged as **positive** (`sentiment_type = 'positive'`) that sent a genuine reply (replied, not ignored, not bounced), bucketed on the **date the reply was received**. |
This is the same definition and reply-date axis as the headline tile (`overall-stats-v2`). Because each positive lead's reply falls on a single date, the **daily values here sum to the overall range total** for the same window. (If you instead want positives attributed to the day the email was *sent*, use the [by sent time](/api-reference/analytics/day-wise-positive-sent-time) variant.)
`positive_replied` is a **distinct-lead** count. The lead category is mutable, so re-categorising a lead changes historical days. Dates are inclusive on both ends, and a single date returns that one full day.
# Positive Reply Stats by Sent Time
Source: https://api.smartlead.ai/api-reference/analytics/day-wise-positive-sent-time
GET https://server.smartlead.ai/api/v1/analytics/day-wise-positive-reply-stats-by-sent-time
Get positive replies by sent time to optimize sending schedule
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/day-wise-positive-reply-stats-by-sent-time?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/day-wise-positive-reply-stats-by-sent-time",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/day-wise-positive-reply-stats-by-sent-time?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"day_wise_stats": [
{
"date": "2024-01-15",
"positive_replied": 5
},
{
"date": "2024-01-16",
"positive_replied": 7
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## How these metrics are calculated
Shared rules (inclusive date boundaries, send-date attribution, unique vs raw counts) are documented once in [How Analytics Metrics Are Calculated](/api-reference/analytics/how-metrics-are-calculated).
| Field | How it's calculated |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `positive_replied` | `COUNT(DISTINCT lead)` for leads tagged as **positive** (`sentiment_type = 'positive'`) that sent a genuine reply (replied, not ignored, not bounced), bucketed by the day their email was **sent** (`sent_time`). |
This is the **send-date** view of positive replies — use it to see which *sending* days produced positive replies. It differs from the [day-wise positive endpoint](/api-reference/analytics/day-wise-positive-reply) and the `overall-stats-v2` tile, which attribute positives to the **date the reply was received**; a reply that arrives days after the send lands on a different day across the two views.
`positive_replied` is a **distinct-lead** count. The lead category is mutable, so re-categorising a lead changes historical days. Dates are inclusive on both ends — `sent_time >= start 00:00:00 AND sent_time <= end 23:59:59` — and a single date returns that one full day.
# Day-wise Stats by Sent Time
Source: https://api.smartlead.ai/api-reference/analytics/day-wise-sent-time
GET https://server.smartlead.ai/api/v1/analytics/day-wise-overall-stats-by-sent-time
Get daily breakdown organized by email sent time for schedule analysis
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/day-wise-overall-stats-by-sent-time?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/day-wise-overall-stats-by-sent-time",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/day-wise-overall-stats-by-sent-time?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"day_wise_stats": [
{
"date": "2024-01-15",
"sent": 150,
"opened": 52
},
{
"date": "2024-01-16",
"sent": 175,
"opened": 61
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## How these metrics are calculated
Shared rules (inclusive date boundaries, unique vs raw counts, rate formulas) are documented once in [How Analytics Metrics Are Calculated](/api-reference/analytics/how-metrics-are-calculated).
Unlike the [event-date day-wise endpoint](/api-reference/analytics/day-wise-stats), **every metric here is bucketed by the day the email was sent** (`sent_time`). An open or reply is counted on the date its email went out, regardless of when the open/reply actually happened — which is what makes this view useful for analysing send-schedule performance.
| Field | How it's calculated |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `sent` | Emails sent that day. Raw additive count. |
| `opened` | Emails (sent that day) that were later opened. Raw additive count. |
| `replied` | Emails (sent that day) that later received a genuine reply. Raw additive count. |
| `bounced` | Emails sent that day that bounced. Raw additive count. |
| `unsubscribed` | Leads who unsubscribed. Raw additive count. |
| `unique_lead_reached` | `COUNT(DISTINCT lead)` reached that day, deduplicated per campaign by email. This is a **unique** count, not additive across days. |
The raw counts are additive across days; `unique_lead_reached` is not (a lead reached on two days is counted once per day). Dates are inclusive on both ends — `sent_time >= start 00:00:00 AND sent_time <= end 23:59:59` — and a single date returns that one full day. `timezone` is required so the daily boundaries are drawn in your local time.
# Get Day-wise Overall Stats
Source: https://api.smartlead.ai/api-reference/analytics/day-wise-stats
GET https://server.smartlead.ai/api/v1/analytics/day-wise-overall-stats
Get day-by-day email engagement breakdown with daily metrics
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/day-wise-overall-stats?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/day-wise-overall-stats",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/day-wise-overall-stats?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"day_wise_stats": [
{
"date": "2024-01-15",
"sent": 150,
"opened": 52,
"replied": 8,
"bounced": 2
},
{
"date": "2024-01-16",
"sent": 175,
"opened": 61,
"replied": 11,
"bounced": 1
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## How these metrics are calculated
Shared rules (inclusive date boundaries, unique vs raw counts, rate formulas) are documented once in [How Analytics Metrics Are Calculated](/api-reference/analytics/how-metrics-are-calculated).
This endpoint returns a daily breakdown where **each metric sits on its own event date**:
| Field | How it's calculated |
| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `sent` | Counted on the day the email was **sent**. Raw additive count. |
| `opened` | Counted on the day the **open happened**. Raw additive count (a lead opening twice counts twice). |
| `replied` | Counted on the day the **reply arrived**. Raw additive count. |
| `bounced` / `unsubscribed` | Returned as `0` on this endpoint. For a daily bounce breakdown, use [Day-wise Stats by Sent Time](/api-reference/analytics/day-wise-sent-time). |
Because each metric is anchored to the day its own event occurred, an email sent on one day and the reply it generated on a later day land on **different rows**. If you want every metric attributed to the **send date** instead (so opens and replies line up with the day the email went out), use the [by sent time](/api-reference/analytics/day-wise-sent-time) variant.
All counts here are raw event counts, so they are additive across days. Dates are inclusive on both ends; a single date (start equal to end) returns that one full day.
# Domain-wise Health Metrics
Source: https://api.smartlead.ai/api-reference/analytics/domain-wise-health
GET https://server.smartlead.ai/api/v1/analytics/mailbox/domain-wise-health-metrics
Get performance metrics aggregated by email domain for domain analysis
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
Set to "true" to return full data set
Max number of results to return
Pagination offset
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/mailbox/domain-wise-health-metrics?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/mailbox/domain-wise-health-metrics",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/mailbox/domain-wise-health-metrics?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"domain_health_metrics": [
{
"domain": "example.com",
"sent": 1000,
"opened": 500,
"replied": 60,
"bounced": 10
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Email-ID-wise Health Metrics
Source: https://api.smartlead.ai/api-reference/analytics/email-wise-health
GET https://server.smartlead.ai/api/v1/analytics/mailbox/name-wise-health-metrics
Get detailed health metrics by individual email account address
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
Set to "true" to return full data set
Max number of results to return
Pagination offset
Set to "true" or "false" to filter by bounce status
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/mailbox/name-wise-health-metrics?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/mailbox/name-wise-health-metrics",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/mailbox/name-wise-health-metrics?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"email_health_metrics": [
{
"email_account": "user@example.com",
"sent": 500,
"opened": 250,
"replied": 30,
"bounced": 5
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Follow-up Reply Rate
Source: https://api.smartlead.ai/api-reference/analytics/followup-reply-rate
GET https://server.smartlead.ai/api/v1/analytics/campaign/follow-up-reply-rate
Analyze reply rates specifically for follow-up sequences (2, 3, 4+)
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/campaign/follow-up-reply-rate?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/campaign/follow-up-reply-rate",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/campaign/follow-up-reply-rate?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"followup_reply_rate": 3.2
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# How Analytics Metrics Are Calculated
Source: https://api.smartlead.ai/api-reference/analytics/how-metrics-are-calculated
The shared rules behind every Global Analytics endpoint — date boundaries, time axes, unique vs raw counts, and rate formulas
This page explains the rules that apply across **all** Global Analytics endpoints. Each endpoint page also has its own per-field breakdown, but the concepts below are the same everywhere — read this once and the individual endpoints make a lot more sense.
## Two kinds of numbers
The fields in an analytics response are not all the same kind of metric. This is the single most important thing to understand, and it's the usual cause of "the numbers don't add up".
* **Raw event counts** — `sent`, `opened`, `replied`, `bounced`, `unsubscribed`. These count events. They are **additive**: the value for a date range equals the sum of the per-day values.
* **Unique counts** — `unique_lead_count`, `unique_open_count`, `positive_replied`. These count **distinct leads** over the requested range (`COUNT(DISTINCT lead)`, deduplicated per campaign by email address). They are **not additive**.
A lead emailed on two different days counts **once** in a range query, but once in **each** single-day query. So if you pull each day separately and add them up, the unique counts (and every rate derived from them) come out inflated.
You cannot reconstruct a multi-day range by summing per-day responses. The raw counts will match, but the unique counts and all rates will not. To get an accurate figure for any period, **query that period directly** rather than summing individual days.
## Date range behaviour
`start_date` and `end_date` are **inclusive on both ends**. Internally the window runs from `start_date 00:00:00` to `end_date 23:59:59`:
```text theme={null}
sent_time >= 'start_date 00:00:00' AND sent_time <= 'end_date 23:59:59'
```
* Passing the **same date** for start and end returns that one full day (`00:00:00`–`23:59:59`), not an empty result.
* When a `timezone` is supplied, the day boundaries are calculated in that timezone; otherwise UTC is used.
## Time axes: send date vs reply date
Every record is anchored to a point in time. Endpoints differ in **which timestamp** they filter and group by:
* **Send date** (`sent_time`) — the day the email went out. This is the axis for `sent`, `opened`, `replied`, and `bounced`. The `*-by-sent-time` endpoints make this explicit, including for positive replies.
* **Reply date** (`reply_time`) — the day the reply came in. This is the default axis for **positive replies** on the `overall-stats-v2` tile and `day-wise-positive-reply-stats` (see [How positive replies are counted](#how-positive-replies-are-counted) below).
* **Event date** — some day-wise breakdowns bucket opens by open time and replies by reply time, so each metric lands on the day the event happened.
When comparing two endpoints that look similar, check which axis each uses — a reply that arrives days after the send lands on a different day depending on the axis.
## Rate formulas
All rates are percentages computed against the **unique** counts, not raw sends:
| Rate | Formula |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `open_rate` | `unique_open_count / unique_lead_count` |
| `reply_rate` | `replied / unique_open_count` — falls back to `unique_lead_count` when open tracking is off (plain-text sends, or tracking disabled) |
| `positive_reply_rate` | `positive_replied / replied` |
| `bounce_rate` | `bounced / unique_lead_count` |
| `client_health` | `positive_replied / unique_lead_count` |
`bounce_rate` is calculated per **unique lead** (`bounced / unique_lead_count`), not per email sent. If you want the deliverability-style figure (`bounced / sent`), the raw `bounced` and `sent` counts are both in the response and you can compute it yourself.
## How positive replies are counted
A **positive reply** is a lead whose lead-category sentiment is **positive** (`lead_categories.sentiment_type = 'positive'`), tied to a **genuine reply** — one that actually replied, is not marked ignored, and did not bounce.
Three things vary by endpoint, and getting them mixed up is the usual reason two positive-reply numbers don't agree:
* **Reply-date vs send-date attribution.** Most surfaces (the `overall-stats-v2` tile and `day-wise-positive-reply-stats`) attribute a positive to the **date the reply was received**. The `*-by-sent-time` variant instead attributes it to the **date the email was sent**. A reply that arrives days after the send lands on a different day depending on which you use.
* **Unique leads vs response events.** Most positive counts are **distinct leads** (a lead is counted once no matter how many times it replied). `campaign/response-stats` is the exception — it counts **response events**, so a lead replying twice counts twice. This is why its `total_positive_response` can be *higher* than the tile's `positive_replied`.
* **Deduplication across the range.** Distinct-lead counts are deduplicated over the whole requested range, so they are **not additive** — summing single-day calls over-counts. Always query the exact date range you want.
The lead category is **mutable**: re-categorising a lead (marking it positive, or changing it later) changes historical counts, because the number reflects each lead's *current* category, not what it was on the reply date.
See each endpoint's own page for its exact attribution — they are deliberately not all the same.
# Lead Category-wise Response
Source: https://api.smartlead.ai/api-reference/analytics/lead-category-response
GET https://server.smartlead.ai/api/v1/analytics/lead/category-wise-response
Get lead response breakdown by category type with sentiment distribution
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/lead/category-wise-response?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/lead/category-wise-response",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/lead/category-wise-response?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"lead_responses_by_category": [
{
"category": "Interested",
"total_response": 45,
"percentage": "15%"
},
{
"category": "Not Interested",
"total_response": 30,
"percentage": "10%"
},
{
"category": "Out of Office",
"total_response": 12,
"percentage": "4%"
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Lead Statistics
Source: https://api.smartlead.ai/api-reference/analytics/lead-stats
GET https://server.smartlead.ai/api/v1/analytics/lead/overall-stats
Get comprehensive lead engagement statistics by status and category
## Path Parameters
No path parameters
## Query Parameters
Your SmartLead API key
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
Timezone string (e.g. "America/New\_York"), optional
Comma-separated client IDs (optional)
Comma-separated campaign IDs (optional)
## Request Body
No request body required
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/lead/overall-stats?api_key=YOUR_KEY&start_date=2024-01-01&end_date=2024-01-31&timezone=America%2FNew_York"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/lead/overall-stats",
params={
"api_key": API_KEY,
"start_date": "2024-01-01",
"end_date": "2024-01-31",
"timezone": "America/New_York"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/lead/overall-stats?api_key=${API_KEY}&start_date=2024-01-01&end_date=2024-01-31&timezone=America%2FNew_York`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"lead_stats": {
"count": {
"total": 1000,
"new": 600,
"follow_up": 400
},
"percentage": {
"new": 60,
"follow_up": 40
}
}
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Lead to Reply Time
Source: https://api.smartlead.ai/api-reference/analytics/lead-to-reply-time
GET https://server.smartlead.ai/api/v1/analytics/campaign/lead-to-reply-time
Measure average time from first email sent to first reply received
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/campaign/lead-to-reply-time?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/campaign/lead-to-reply-time",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/campaign/lead-to-reply-time?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"lead_to_reply_time": [
{
"time_range": "0-1h",
"count": 15
},
{
"time_range": "1-6h",
"count": 25
},
{
"time_range": "6-24h",
"count": 18
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Leads Take for First Reply
Source: https://api.smartlead.ai/api-reference/analytics/leads-for-first-reply
GET https://server.smartlead.ai/api/v1/analytics/campaign/leads-take-for-first-reply
Calculate average leads contacted before receiving first reply
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/campaign/leads-take-for-first-reply?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/campaign/leads-take-for-first-reply",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/campaign/leads-take-for-first-reply?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"leads_take_for_first_reply": 42
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Mailbox Overall Stats
Source: https://api.smartlead.ai/api-reference/analytics/mailbox-health
GET https://server.smartlead.ai/api/v1/analytics/mailbox/overall-stats
Get overall health and performance statistics for all mailboxes
## Query Parameters
Your SmartLead API key
Comma-separated client IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/mailbox/overall-stats?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/mailbox/overall-stats",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/mailbox/overall-stats?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"overall_mailbox_stats": {
"total_connected": 25,
"in_use": 20,
"disconnected": 3,
"enabled_without_warmup": 2
}
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Related Endpoints
* [Domain-wise Health Metrics](/api-reference/analytics/domain-wise-health)
* [Name-wise Health Metrics](/api-reference/analytics/email-wise-health)
# Get Month-wise Client Count
Source: https://api.smartlead.ai/api-reference/analytics/month-wise-client-count
GET https://server.smartlead.ai/api/v1/analytics/client/month-wise-count
Get monthly breakdown of active clients showing growth trends
## Query Parameters
Your SmartLead API key
Comma-separated client IDs
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/client/month-wise-count?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/client/month-wise-count",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/client/month-wise-count?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"monthly_stats": [
{
"month": "2024-01",
"count": 5
},
{
"month": "2024-02",
"count": 7
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Get Overall Analytics
Source: https://api.smartlead.ai/api-reference/analytics/overview
GET https://server.smartlead.ai/api/v1/analytics/overall-stats-v2
Get account-wide overall statistics for date range with sent, opened, replied metrics
## Path Parameters
No path parameters
## Query Parameters
Your SmartLead API key
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
Timezone string (e.g. "America/New\_York"), optional
Comma-separated client IDs (optional)
Comma-separated campaign IDs (optional)
Set to "true" to filter for agency accounts (optional)
Set to "true" to return full data set (optional)
## Request Body
No request body required
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/overall-stats-v2?api_key=YOUR_KEY&start_date=2024-01-01&end_date=2024-01-31&timezone=America%2FNew_York"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/overall-stats-v2",
params={
"api_key": API_KEY,
"start_date": "2024-01-01",
"end_date": "2024-01-31",
"timezone": "America/New_York"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/overall-stats-v2?api_key=${API_KEY}&start_date=2024-01-01&end_date=2024-01-31&timezone=America%2FNew_York`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"message": "Overall Stats fetched successfully!",
"data": {
"overall_stats": {
"sent": "345805",
"opened": "0",
"replied": "1732",
"bounced": "2015",
"unique_lead_count": "299503",
"unique_open_count": "0",
"positive_replied": 280,
"open_rate": "0.00%",
"reply_rate": "0.58%",
"positive_reply_rate": "16.17%",
"bounce_rate": "0.67%"
}
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## How these metrics are calculated
The rules below (inclusive date boundaries, unique vs raw counts, the rate formulas, and how positive replies are counted) are shared across every Global Analytics endpoint. See [How Analytics Metrics Are Calculated](/api-reference/analytics/how-metrics-are-calculated) for the full explanation.
The fields in `overall_stats` are not all the same kind of number. Some are raw event counts and some are unique (deduplicated) counts, and this affects how they behave across date ranges.
### Field definitions
Total emails sent in the range. Raw event count.
Total open events in the range. Raw event count (a single lead opening twice counts twice).
Total reply events in the range. Raw event count.
Total bounce events in the range. Raw event count.
Count of **distinct leads** that were sent at least one email in the range, deduplicated per campaign by email address. This is `COUNT(DISTINCT lead)` across the whole range, **not** a sum of per-day values.
Count of **distinct leads** that opened at least one email in the range. Like `unique_lead_count`, this is deduplicated across the whole range.
Count of **distinct leads tagged as positive** (`sentiment_type = 'positive'`) that sent a genuine reply (replied, not ignored, not bounced), attributed to the **date the reply was received**, within the range. Because it's a distinct-lead count deduplicated across the range, it is **not additive** — summing per-day calls over-counts. The lead category is mutable, so re-categorising a lead changes historical counts.
### Rates
All rates are computed against the unique counts above, not against raw sends:
| Rate | Formula |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `open_rate` | `unique_open_count / unique_lead_count` |
| `reply_rate` | `replied / unique_open_count` (falls back to `unique_lead_count` when open tracking is disabled, e.g. plain-text sends) |
| `positive_reply_rate` | `positive_replied / replied` |
| `bounce_rate` | `bounced / unique_lead_count` |
`bounce_rate` is reported per unique lead (`bounced / unique_lead_count`), not per email sent. If you need the deliverability-style figure (`bounced / sent`), both `bounced` and `sent` are in the response and you can compute it yourself.
### Date range behaviour (important)
`start_date` and `end_date` are **inclusive on both ends** (from `00:00:00` to `23:59:59` in the requested timezone), and they filter on the time the email was **sent**.
Because the unique counts are deduplicated across the entire requested range, **you cannot reconstruct a multi-day range by summing per-day responses**:
* `sent`, `opened`, `replied` and `bounced` are additive — summing three single-day responses equals the 3-day range response.
* `unique_lead_count` and `unique_open_count` are **not** additive. A lead emailed on two different days counts once in a range query, but once in each single-day query — so summing days inflates the unique totals (and every rate derived from them).
For an accurate figure over any period, query that period directly rather than summing individual days.
# Provider-wise Performance
Source: https://api.smartlead.ai/api-reference/analytics/provider-performance
GET https://server.smartlead.ai/api/v1/analytics/mailbox/provider-wise-overall-performance
Compare performance across email service providers (Gmail, Outlook, SMTP)
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
Set to "true" to return full data set
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/mailbox/provider-wise-overall-performance?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/mailbox/provider-wise-overall-performance",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/mailbox/provider-wise-overall-performance?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"email_providers_performance_overview": {
"overall": [
{
"provider": "Gmail",
"sent": 500,
"opened": 250,
"replied": 30
}
],
"tag_wise": [
{
"tag": "cold-outreach",
"provider": "Gmail",
"sent": 200,
"opened": 100
}
]
}
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Team Board Stats
Source: https://api.smartlead.ai/api-reference/analytics/team-board-stats
GET https://server.smartlead.ai/api/v1/analytics/team-board/overall-stats
Get performance metrics by team member for collaboration features
## Query Parameters
Your SmartLead API key
Start date (YYYY-MM-DD format)
End date (YYYY-MM-DD format)
IANA timezone string (e.g., "America/New\_York")
Comma-separated client IDs
Comma-separated campaign IDs
Set to "true" to return full data set
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/analytics/team-board/overall-stats?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/analytics/team-board/overall-stats",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/analytics/team-board/overall-stats?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"team_board_stats": [
{
"id": 1,
"name": "John Doe",
"profile_pic_url": "https://example.com/pic.jpg",
"lead_count": 250,
"campaign_count": 5,
"reply_count": 30,
"positive_reply_count": 15,
"reply_rate": "12%",
"positive_reply_rate": "6%",
"average_reply_time": "2h 15m",
"unique_open_count": 180
}
]
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Fetch Campaign Statistics by Date Range
Source: https://api.smartlead.ai/api-reference/campaign-statistics/get-by-date-range
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/analytics-by-date
Fetch campaign statistics using the campaign's ID filtered by date range
## Path Parameters
The ID of the campaign
## Query Parameters
Your API key
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
IANA timezone string (e.g. "America/New\_York")
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/12345/analytics-by-date?api_key=YOUR_API_KEY&start_date=2024-01-01&end_date=2024-01-31"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
CAMPAIGN_ID = 12345
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{CAMPAIGN_ID}/analytics-by-date",
params={
"api_key": API_KEY,
"start_date": "2024-01-01",
"end_date": "2024-01-31"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const CAMPAIGN_ID = 12345;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${CAMPAIGN_ID}/analytics-by-date?api_key=${API_KEY}&start_date=2024-01-01&end_date=2024-01-31`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource does not exist or you don't have access to it
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Fetch Campaign Statistics by Campaign ID
Source: https://api.smartlead.ai/api-reference/campaign-statistics/get-by-id
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/statistics
Fetch campaign statistics using the campaign's ID
## Path Parameters
Campaign ID
## Query Parameters
Your API key
List offset
Max number of stats to return (max 1000)
Single sequence number (min: 1, max: 20)
Filter by email status. Possible values: `opened`, `clicked`, `replied`, `unsubscribed`, `bounced`
Filters campaign stats with sent time greater than this date. Format: `2023-10-16 10:33:02.000Z`
Filters campaign stats with sent time less than this date. Format: `2023-10-16 10:33:02.000Z`
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/12345/statistics?api_key=YOUR_API_KEY&limit=100&offset=0"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
CAMPAIGN_ID = 12345
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{CAMPAIGN_ID}/statistics",
params={
"api_key": API_KEY,
"limit": 100,
"offset": 0
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const CAMPAIGN_ID = 12345;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${CAMPAIGN_ID}/statistics?api_key=${API_KEY}&limit=100&offset=0`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource does not exist or you don't have access to it
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"campaign_id": 123,
"sequence_number": 1,
"sent": 1240,
"opened": 372,
"clicked": 89,
"replied": 23,
"unsubscribed": 4,
"bounced": 18
},
{
"campaign_id": 123,
"sequence_number": 2,
"sent": 892,
"opened": 267,
"clicked": 54,
"replied": 12,
"unsubscribed": 2,
"bounced": 9
}
],
"offset": 0,
"limit": 100
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Fetch Campaign Lead Statistics
Source: https://api.smartlead.ai/api-reference/campaign-statistics/lead-statistics
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads-statistics
Fetch campaign lead statistics using the campaign's ID
## Path Parameters
The ID of the campaign
## Query Parameters
Your API key
The number of leads you want to fetch in one go (optional, max 100)
Replied/Sent at date in YYYY-MM-DD format. If you want to filter by when the last event for the lead was received by. This can be a reply event, send event etc (optional)
Used to paginate lead data (optional)
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/12345/leads-statistics?api_key=YOUR_API_KEY&limit=100&offset=1"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
CAMPAIGN_ID = 12345
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{CAMPAIGN_ID}/leads-statistics",
params={
"api_key": API_KEY,
"limit": 100,
"offset": 1
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const CAMPAIGN_ID = 12345;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${CAMPAIGN_ID}/leads-statistics?api_key=${API_KEY}&limit=100&offset=1`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource does not exist or you don't have access to it
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Fetch Campaign Mailbox Statistics
Source: https://api.smartlead.ai/api-reference/campaign-statistics/mailbox-statistics
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/mailbox-statistics
Fetch mailbox statistics specific to a campaign
## Path Parameters
The ID of the campaign
## Query Parameters
Your API key
The ID of your client if this campaign is client specific
Pagination offset
Number of results to return. Min 1, max 20.
Start date for filtering in YYYY-MM-DD format. Both start\_date and end\_date must be provided, otherwise data will be for the full campaign length.
End date for filtering in YYYY-MM-DD format. Both start\_date and end\_date must be provided, otherwise data will be for the full campaign length.
The campaign timezone, e.g. `America/Los_Angeles`. Same format as shown in your campaign UI next to the date filter.
Private API key for additional authorization (optional)
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/12345/mailbox-statistics?api_key=YOUR_API_KEY&limit=10&offset=0"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
CAMPAIGN_ID = 12345
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{CAMPAIGN_ID}/mailbox-statistics",
params={
"api_key": API_KEY,
"limit": 10,
"offset": 0
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const CAMPAIGN_ID = 12345;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${CAMPAIGN_ID}/mailbox-statistics?api_key=${API_KEY}&limit=10&offset=0`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource does not exist or you don't have access to it
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Fetch Campaign Top Level Analytics
Source: https://api.smartlead.ai/api-reference/campaign-statistics/top-level
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/analytics
Fetch a campaign's top level analytics
## Path Parameters
Campaign ID
## Query Parameters
Your API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/12345/analytics?api_key=YOUR_API_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
CAMPAIGN_ID = 12345
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{CAMPAIGN_ID}/analytics",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const CAMPAIGN_ID = 12345;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${CAMPAIGN_ID}/analytics?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource does not exist or you don't have access to it
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Fetch Campaign Top Level Analytics by Date Range
Source: https://api.smartlead.ai/api-reference/campaign-statistics/top-level-by-date
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/top-level-analytics-by-date
Fetch campaign top-level analytics filtered by date range
## Path Parameters
The ID of the campaign
## Query Parameters
Your API key
Start date in YYYY-MM-DD format
End date in YYYY-MM-DD format
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/12345/top-level-analytics-by-date?api_key=YOUR_API_KEY&start_date=2024-01-01&end_date=2024-01-31"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
CAMPAIGN_ID = 12345
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{CAMPAIGN_ID}/top-level-analytics-by-date",
params={
"api_key": API_KEY,
"start_date": "2024-01-01",
"end_date": "2024-01-31"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const CAMPAIGN_ID = 12345;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${CAMPAIGN_ID}/top-level-analytics-by-date?api_key=${API_KEY}&start_date=2024-01-01&end_date=2024-01-31`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource does not exist or you don't have access to it
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Add Email Accounts to Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/add-email-accounts
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts
Associates one or more email accounts with a campaign for automatic sender rotation.
Associates one or more email accounts with a campaign for automatic sender rotation SmartLead distributes emails across added accounts to maximize deliverability, avoid ESP limits, and build sender reputation
## Overview
Associates one or more email accounts with a campaign for automatic sender rotation
**Key Features**:
* Validates account ownership and connection status before adding
Accounts must be successfully connected (is\_smtp\_success=true, is\_imap\_success=true) and not suspended
## Path Parameters
The campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Array of email account IDs to add to the campaign
Example: `[456, 457, 458]`
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/email-accounts?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email_account_ids": [456, 457, 458]}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
payload = {
"email_account_ids": [456, 457, 458]
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts",
params={"api_key": API_KEY},
json=payload
)
print("Email accounts added successfully!")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/email-accounts?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email_account_ids: [456, 457, 458]
})
}
);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Best Practices
**Use Multiple Accounts**: Add 5-10 email accounts for better deliverability and higher sending volume
**Ensure Warmup**: Only add accounts that are warmed up (reputation >80%)
**Check Limits**: Make sure accounts have sufficient daily sending capacity
## Account Rotation
SmartLead automatically rotates between added accounts to:
* Distribute sending load
* Improve deliverability
* Build sender reputation
* Maximize daily volume
## Implementation Details
Accounts are immediately available for rotation. Ensure accounts are warmed up before adding to campaigns.
**Response Format**: object
## Related Endpoints
* [Get Campaign Email Accounts](/api-reference/campaigns/get-email-accounts)
* [Remove Email Accounts](/api-reference/campaigns/remove-email-accounts)
* [Get All Email Accounts](/api-reference/email-accounts/get-all)
# Add Leads to Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/add-leads
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads
Add new leads to a campaign with custom fields and validation settings
Import leads into your campaign. Supports bulk upload (max 400 leads per request) with custom fields and duplicate/validation controls.
## Overview
Adds leads to a campaign with comprehensive validation and duplicate handling options.
**Key Features:**
* Bulk import: Up to 400 leads per request
* Custom fields support (max 200 fields)
* Duplicate detection controls
* Global block list checking
* Community bounce list validation
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Array of lead objects (max 400 leads)
Lead email address (required)
First name (optional)
Last name (optional)
Company name (optional)
Phone number (optional)
Website URL (optional)
Geographic location (optional)
LinkedIn profile URL (optional)
Company website (optional)
Custom field key-value pairs (max 200 fields)
Example: `{"job_title": "CEO", "industry": "SaaS", "company_size": "50-200"}`
Array of lead list IDs (if importing from existing lists)
Import type (optional)
Validation and duplicate handling settings
Skip global block list validation (default: false)
Skip unsubscribe list check (default: false)
Allow leads that exist in other campaigns (default: false)
Skip community bounce list validation (default: false)
Return array of created lead IDs in response
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"lead_list": [
{
"email": "john@company.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "ACME Corp",
"custom_fields": {
"job_title": "CEO",
"industry": "SaaS"
}
},
{
"email": "jane@startup.io",
"first_name": "Jane",
"last_name": "Smith",
"company_name": "Startup Inc"
}
],
"settings": {
"ignore_duplicate_leads_in_other_campaign": false,
"return_lead_ids": true
}
}'
```
```python Python theme={null}
import requests
import csv
API_KEY = "YOUR_API_KEY"
campaign_id = 123
# Example 1: Add leads with custom fields
leads = [
{
"email": "john@company.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "ACME Corp",
"custom_fields": {
"job_title": "CEO",
"industry": "SaaS",
"company_size": "50-200"
}
},
{
"email": "jane@startup.io",
"first_name": "Jane",
"last_name": "Smith",
"company_name": "Startup Inc",
"linkedin_profile": "https://linkedin.com/in/janesmith"
}
]
payload = {
"lead_list": leads,
"settings": {
"ignore_duplicate_leads_in_other_campaign": False,
"ignore_global_block_list": False,
"return_lead_ids": True
}
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
result = response.json()
print(f"✅ Added {result.get('added_count', 0)} leads")
if result.get('lead_ids'):
print(f"Lead IDs: {result['lead_ids']}")
# Example 2: Import from CSV
def import_csv_to_campaign(csv_path, campaign_id):
leads = []
with open(csv_path, 'r') as f:
reader = csv.DictReader(f)
for row in reader:
lead = {
"email": row['email'],
"first_name": row.get('first_name', ''),
"last_name": row.get('last_name', ''),
"company_name": row.get('company', ''),
"custom_fields": {
k: v for k, v in row.items()
if k not in ['email', 'first_name', 'last_name', 'company']
}
}
leads.append(lead)
# Batch every 400 leads (max per request)
if len(leads) >= 400:
add_leads_batch(campaign_id, leads)
leads = []
# Add remaining leads
if leads:
add_leads_batch(campaign_id, leads)
def add_leads_batch(campaign_id, leads):
payload = {"lead_list": leads}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY},
json=payload
)
print(f"Batch added: {len(leads)} leads")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
// Add leads to campaign
async function addLeads(campaignId, leads, settings = {}) {
const payload = {
lead_list: leads,
settings: {
ignore_duplicate_leads_in_other_campaign: false,
return_lead_ids: true,
...settings
}
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`Added ${result.added_count} leads`);
return result;
}
// Example usage
const newLeads = [
{
email: 'john@company.com',
first_name: 'John',
last_name: 'Doe',
company_name: 'ACME Corp',
custom_fields: {
job_title: 'CEO',
industry: 'SaaS'
}
}
];
await addLeads(123, newLeads);
```
## Response Example
```json 200 - Success theme={null}
{
"success": true,
"added_count": 2,
"skipped_count": 0,
"lead_ids": [789, 790],
"message": "Leads added successfully"
}
```
```json 422 - Validation Error theme={null}
{
"error": "lead_list cannot exceed 400 leads per request",
"provided_count": 500,
"max_allowed": 400
}
```
## Related Endpoints
* [Get Campaign Leads](/api-reference/campaigns/get-leads)
* [Update Lead](/api-reference/campaigns/update-lead)
* [Delete Lead](/api-reference/campaigns/delete-lead)
# Get All Leads Activities
Source: https://api.smartlead.ai/api-reference/campaigns/all-leads-activities
GET https://server.smartlead.ai/api/v1/campaigns/all-leads-activities
Retrieve lead activities across all campaigns for the authenticated user
Track lead engagement and activities across your entire account. Essential for cross-campaign analytics and lead behavior analysis.
## Overview
Retrieves lead activities across ALL campaigns, not just one. Useful for account-wide reporting and analytics.
## Query Parameters
Your SmartLead API key
Pagination offset (min 0)
Records per page (min 1, max 1000)
Filter activities from this date (ISO 8601)
Filter activities until this date (ISO 8601)
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/all-leads-activities?api_key=YOUR_KEY&limit=100"
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
# Get today's activities across all campaigns
today_start = datetime.now().replace(hour=0, minute=0, second=0).isoformat()
params = {
"api_key": API_KEY,
"event_time_from": today_start,
"limit": 100
}
response = requests.get(
"https://server.smartlead.ai/api/v1/campaigns/all-leads-activities",
params=params
)
activities = response.json()
print(f"Today's activities: {len(activities['data'])}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/all-leads-activities?api_key=${API_KEY}&limit=100`
);
const activities = await response.json();
console.log(`Total activities: ${activities.data.length}`);
```
## Response Example
```json 200 theme={null}
{
"total": 250,
"data": [
{
"lead_email": "john@company.com",
"campaign_id": 123,
"campaign_name": "Q1 Outreach",
"activity_type": "email_opened",
"event_time": "2025-01-20T14:30:00Z"
}
]
}
```
## Related Endpoints
* [Get Campaign Leads](/api-reference/campaigns/get-leads)
* [Get Lead History](/api-reference/campaigns/get-lead-history)
# Create Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/create
POST https://server.smartlead.ai/api/v1/campaigns/create
Creates a new email campaign with default settings in DRAFTED status.
Creates a new email campaign with default settings in DRAFTED status Campaign name defaults to 'Untitled Campaign' if not provided
## Overview
Creates a new email campaign with default settings in DRAFTED status
**Key Features**:
* Returns campaign ID and metadata.
## Query Parameters
Your SmartLead API key for authentication
## Request Body
Campaign name. If not provided, defaults to "Untitled Campaign". Can be changed later via update settings.
Associate campaign with a specific client (for agency/white-label accounts). If not provided and user has client\_id, automatically uses that value.
**Minimal Required Fields**: This endpoint only accepts `name` and `client_id`. Other campaign settings (track\_settings, schedule, sequences, etc.) must be configured using separate update endpoints after creation.
## Response
Always `true` for successful creation
Unique identifier for the newly created campaign
Campaign name (either provided or "Untitled Campaign")
ISO 8601 timestamp when campaign was created
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/create?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Q1 2024 Cold Outreach"
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
url = "https://server.smartlead.ai/api/v1/campaigns/create"
payload = {
"name": "Q1 2024 Cold Outreach"
}
response = requests.post(
url,
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(f"Campaign created with ID: {result['id']}")
print(f"Campaign name: {result['name']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function createCampaign() {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/create?api_key=${API_KEY}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Q1 2024 Cold Outreach'
}),
}
);
const data = await response.json();
console.log(`Campaign created with ID: ${data.id}`);
return data;
}
createCampaign();
```
## Response Codes
Campaign created successfully
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Request validation failed. Check parameter types and required fields.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"id": 125,
"name": "Q1 2024 Cold Outreach",
"created_at": "2024-01-25T10:30:00Z"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid campaign name format"
}
```
```json 500 - Internal Server Error theme={null}
{
"error": "Error while creating email campaign - Database connection failed"
}
```
## Implementation Details
**What Happens**:
1. Campaign is created with minimal data (just name and optional client\_id)
2. Campaign starts in **DRAFTED** status
3. Campaign name defaults to "Untitled Campaign" if not provided
4. Client ID is automatically set if user is a client
5. Returns campaign ID immediately for further configuration
**Default Settings**:
* Status: `DRAFTED`
* Track Settings: Not set (configure later)
* Schedule: Not set (configure later)
* Sequences: Empty (add later)
* Email Accounts: None (add later)
* Leads: None (add later)
**Response Format**: Direct object with `ok`, `id`, `name`, `created_at`
**Newly created campaigns cannot send emails yet**. You must configure sequences, add email accounts, and add leads before starting the campaign.
## Next Steps
After creating a campaign, follow this workflow:
Create your email sequence (initial email + follow-ups)
```bash theme={null}
POST /v1/campaigns/{campaign_id}/sequences
```
[Update Sequences](/api-reference/campaigns/update-sequences)
Associate sender email accounts with the campaign
```bash theme={null}
POST /v1/campaigns/{campaign_id}/email-accounts
```
[Add Email Accounts](/api-reference/campaigns/add-email-accounts)
Upload your prospect list (up to 400 leads per request)
```bash theme={null}
POST /v1/campaigns/{campaign_id}/leads
```
[Add Leads](/api-reference/leads/add-to-campaign)
Set sending hours, timezone, and frequency
```bash theme={null}
PATCH /v1/campaigns/{campaign_id}/schedule
```
[Update Schedule](/api-reference/campaigns/update-schedule)
Set tracking, limits, and stop conditions
```bash theme={null}
PATCH /v1/campaigns/{campaign_id}/settings
```
[Update Settings](/api-reference/campaigns/update-settings)
Activate the campaign to begin sending
```bash theme={null}
PATCH /v1/campaigns/{campaign_id}/status
```
[Update Status](/api-reference/campaigns/update-status)
## Campaign Naming Best Practices
Choose names that clearly indicate the campaign purpose and timeframe
* ✅ Good: "SaaS Founders Q1 2024"
* ❌ Bad: "Campaign 1"
Add the quarter or month to track performance over time
* "Q1 2024 Enterprise Outreach"
* "Jan 2024 Product Launch"
Make it clear who you're targeting
* "Healthcare CFOs - Q1"
* "Tech Startup CTOs"
## Complete Example Workflow
```python Python - Complete Campaign Setup theme={null}
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://server.smartlead.ai/api/v1"
# 1. Create campaign
campaign = requests.post(
f"{BASE_URL}/campaigns/create",
params={"api_key": API_KEY},
json={"name": "Q1 2024 Outreach"}
).json()
campaign_id = campaign['id']
print(f"Created campaign {campaign_id}")
# 2. Add sequences
requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/sequences",
params={"api_key": API_KEY},
json={
"sequences": [
{
"seq_number": 1,
"subject": "Quick question",
"email_body": "Hi {{first_name}}...",
"seq_delay_details": {"delay_in_days": 0}
}
]
}
)
print("Added sequences")
# 3. Add email accounts
requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/email-accounts",
params={"api_key": API_KEY},
json={"email_account_ids": [456, 457]}
)
print("Added email accounts")
# 4. Add leads
requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY},
json={
"lead_list": [
{"email": "john@example.com", "first_name": "John"}
]
}
)
print("Added leads")
# 5. Start campaign
requests.patch(
f"{BASE_URL}/campaigns/{campaign_id}/status",
params={"api_key": API_KEY},
json={"status": "ACTIVE"}
)
print(f"Campaign {campaign_id} is now ACTIVE!")
```
## Related Endpoints
* [Get Campaign by ID](/api-reference/campaigns/get-by-id)
* [Update Campaign Settings](/api-reference/campaigns/update-settings)
* [Update Campaign Schedule](/api-reference/campaigns/update-schedule)
* [Add Email Sequences](/api-reference/campaigns/update-sequences)
* [Add Email Accounts](/api-reference/campaigns/add-email-accounts)
* [Add Leads to Campaign](/api-reference/leads/add-to-campaign)
* [Start Campaign](/api-reference/campaigns/update-status)
# Create Subsequence Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/create-subsequence
POST https://server.smartlead.ai/api/v1/campaigns/create-subsequence
Create a child campaign (subsequence) with conditional logic
Create branching campaign logic by defining subsequences that triggers based on lead behavior. Essential for sophisticated nurture workflows.
## Query Parameters
Your SmartLead API key
## Request Body
Parent campaign ID
Name for the subsequence campaign
Events that trigger moving lead to subsequence
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/create-subsequence?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"parent_campaign_id": 123,
"subsequence_name": "Follow-up Sequence",
"condition_events": []
}'
```
```python Python theme={null}
import requests
response = requests.post(
"https://server.smartlead.ai/api/v1/campaigns/create-subsequence",
params={"api_key": "YOUR_API_KEY"},
json={
"parent_campaign_id": 123,
"subsequence_name": "Follow-up Sequence",
"condition_events": []
}
)
```
## Response Example
```json 200 theme={null}
{
"success": true,
"subsequence_id": 456
}
```
## Related Endpoints
* [Push to Subsequence](/api-reference/inbox/push-to-subsequence)
* [Update Subsequence Conditions](/api-reference/campaigns/update-subsequence-conditions)
# Delete Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/delete
DELETE https://server.smartlead.ai/api/v1/campaigns/{campaign_id}
Permanently and irreversibly deletes a campaign and ALL associated data: sequences, lead-campaign mappings, email statis
Strongly recommended: Export all important data first and consider using ARCHIVED status instead to preserve data while hiding from active views.
Permanently and irreversibly deletes a campaign and ALL associated data: sequences, lead-campaign mappings, email statistics, webhook configurations, scheduled emails, and conversation history
## Path Parameters
The ID of the campaign to delete
## Query Parameters
Your SmartLead API key
**This action is permanent and cannot be undone!**
Deleting a campaign will remove:
* All campaign sequences
* All lead associations
* All statistics and analytics data
* All webhook configurations
* All email threads and history
Consider using **ARCHIVED** status instead if you want to keep data.
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/campaigns/123?api_key=YOUR_API_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
# Confirm before deleting
confirm = input(f"Delete campaign {campaign_id}? (yes/no): ")
if confirm.lower() == 'yes':
response = requests.delete(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}",
params={"api_key": API_KEY}
)
if response.status_code == 200:
print("Campaign deleted successfully")
else:
print(f"Error: {response.text}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
// Confirm before deleting
const confirmed = confirm(`Delete campaign ${campaignId}? This cannot be undone!`);
if (confirmed) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}?api_key=${API_KEY}`,
{ method: 'DELETE' }
);
console.log('Campaign deleted');
}
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json Success theme={null}
{
"success": true,
"message": "Campaign deleted successfully"
}
```
```json Error - Campaign Active theme={null}
{
"success": false,
"error": {
"code": "CAMPAIGN_ACTIVE",
"message": "Cannot delete active campaign. Please stop it first."
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Before Deleting
Export leads, statistics, and any important data before deleting
```bash theme={null}
# Export leads first
curl "https://server.smartlead.ai/api/v1/campaigns/123/leads-export?api_key=YOUR_KEY"
```
Some systems require campaigns to be stopped before deletion
```bash theme={null}
# Stop first
curl -X PATCH "https://server.smartlead.ai/api/v1/campaigns/123/status?api_key=YOUR_KEY" \
-d '{"status": "STOPPED"}'
# Then delete
curl -X DELETE "https://server.smartlead.ai/api/v1/campaigns/123?api_key=YOUR_KEY"
```
If you might need the data later, use ARCHIVED status instead
```bash theme={null}
curl -X PATCH "https://server.smartlead.ai/api/v1/campaigns/123/status?api_key=YOUR_KEY" \
-d '{"status": "ARCHIVED"}'
```
## Alternative: Archive Campaign
Instead of deleting, you can archive:
```bash Archive Instead theme={null}
curl -X PATCH "https://server.smartlead.ai/api/v1/campaigns/123/status?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "ARCHIVED"}'
```
**Benefits of Archiving**:
* ✅ Keeps all data
* ✅ Reversible
* ✅ Can analyze later
* ✅ Hides from active list
## Implementation Details
PERMANENT deletion. Cannot be undone. Exports data before deleting if you need it later.
**Response Format**: object
## Related Endpoints
* [Update Campaign Status](/api-reference/campaigns/update-status)
* [Get Campaign by ID](/api-reference/campaigns/get-by-id)
* [Get All Campaigns](/api-reference/campaigns/get-all)
# Delete Lead from Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/delete-lead
DELETE https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}
Remove a lead from a campaign
Permanently remove a lead from a campaign. This does not delete the lead from your account, only removes them from this specific campaign.
## Path Parameters
Campaign ID
Lead ID to delete
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/campaigns/123/leads/789?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def delete_lead_from_campaign(campaign_id, lead_id):
response = requests.delete(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}",
params={"api_key": API_KEY}
)
if response.status_code == 200:
print(f"✅ Lead {lead_id} removed from campaign")
return response.json()
delete_lead_from_campaign(123, 789)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function deleteLead(campaignId, leadId) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}?api_key=${API_KEY}`,
{ method: 'DELETE' }
);
return response.json();
}
await deleteLead(123, 789);
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Lead deleted from campaign successfully"
}
```
## Related Endpoints
* [Add Leads to Campaign](/api-reference/campaigns/add-leads)
* [Get Campaign Leads](/api-reference/campaigns/get-leads)
# Delete Campaign Webhook
Source: https://api.smartlead.ai/api-reference/campaigns/delete-webhook
DELETE https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/webhooks/{webhook_id}
Remove a webhook from a campaign
## Path Parameters
Campaign ID
Webhook ID to delete
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/campaigns/123/webhooks/456?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
def delete_webhook(campaign_id, webhook_id):
response = requests.delete(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/webhooks/{webhook_id}",
params={"api_key": "YOUR_API_KEY"}
)
if response.status_code == 200:
print(f"✅ Webhook {webhook_id} deleted")
return response.json()
delete_webhook(123, 456)
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Webhook deleted successfully"
}
```
# Duplicate Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/duplicate
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/duplicate
Creates a copy of an existing campaign including sequences, settings, and optionally sub-sequences and client labels.
Duplicates an existing campaign with all its configuration — sequences, variants, settings, schedule, email accounts, and LinkedIn cookies. Leads are **not** copied.
## Overview
Creates a full copy of a campaign, preserving its sequences (with variants), schedule, settings, email account mappings, and LinkedIn cookie mappings. Useful for replicating a proven campaign setup without manually recreating it.
**What Gets Duplicated:**
* Campaign settings (tracking, sending limits, stop conditions, AI categorisation, etc.)
* All email sequences with variants and A/B test settings
* Schedule and timezone configuration
* Email account associations
* LinkedIn cookie mappings
* Optionally: sub-sequences and client label
**What Does Not Get Duplicated:**
* Leads — the new campaign starts empty
* Campaign analytics and statistics
* Webhook configurations
## Path Parameters
ID of the campaign to duplicate
## Query Parameters
Your SmartLead API key for authentication
## Request Body
Whether to also duplicate sub-sequences (conditional follow-up sequences) attached to the campaign. Defaults to `false` if not provided.
Whether to retain the same client association on the duplicated campaign. Useful for agency accounts that want the copy assigned to the same client. Defaults to `false` if not provided.
## Response
Always `true` for successful duplication
Unique identifier for the newly created duplicate campaign
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/125/duplicate?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"duplicate_sub_sequence": true,
"duplicate_client_label": true
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
CAMPAIGN_ID = 125
url = f"https://server.smartlead.ai/api/v1/campaigns/{CAMPAIGN_ID}/duplicate"
payload = {
"duplicate_sub_sequence": True,
"duplicate_client_label": True
}
response = requests.post(
url,
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(f"Duplicated campaign created with ID: {result['newCampaignId']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const CAMPAIGN_ID = 125;
async function duplicateCampaign() {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${CAMPAIGN_ID}/duplicate?api_key=${API_KEY}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
duplicate_sub_sequence: true,
duplicate_client_label: true,
}),
}
);
const data = await response.json();
console.log(`Duplicated campaign created with ID: ${data.newCampaignId}`);
return data;
}
duplicateCampaign();
```
## Response Codes
Campaign duplicated successfully
Invalid request parameters or malformed request body
Invalid or missing API key
Invalid campaign ID or the campaign does not belong to your account
```json 200 - Success theme={null}
{
"ok": true,
"newCampaignId": 842
}
```
```json 500 - Invalid Campaign theme={null}
{
"message": "Invalid campaign Id!"
}
```
The duplicated campaign is created in **DRAFTED** status. You will need to add leads and start it separately.
## Related Endpoints
* [Create Campaign](/api-reference/campaigns/create)
* [Get Campaign by ID](/api-reference/campaigns/get-by-id)
* [Add Leads to Campaign](/api-reference/campaigns/add-leads)
* [Update Campaign Status](/api-reference/campaigns/update-status)
# Export Campaign Leads
Source: https://api.smartlead.ai/api-reference/campaigns/export-leads
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads-export
Export all campaign leads as CSV file
Download all leads from a campaign in CSV format. Essential for reporting, backup, and external analysis.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/123/leads-export?api_key=YOUR_KEY" \
--output campaign_leads.csv
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads-export",
params={"api_key": API_KEY}
)
# Save to file
with open(f'campaign_{campaign_id}_leads.csv', 'w') as f:
f.write(response.text)
print(f"✅ Leads exported to campaign_{campaign_id}_leads.csv")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads-export?api_key=${API_KEY}`
);
const csvData = await response.text();
// In browser: trigger download
const blob = new Blob([csvData], { type: 'text/csv' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `campaign_${campaignId}_leads.csv`;
a.click();
```
## Response Example
```csv CSV Format theme={null}
email,first_name,last_name,company_name,phone_number,status,category,created_at
john@company.com,John,Doe,ACME Corp,+1-555-0100,INPROGRESS,Interested,2025-01-15T10:00:00Z
jane@startup.io,Jane,Smith,Startup Inc,,COMPLETED,Meeting Request,2025-01-10T09:00:00Z
```
## Related Endpoints
* [Get Campaign Leads](/api-reference/campaigns/get-leads)
* [Add Leads](/api-reference/campaigns/add-leads)
# Forward Campaign Email
Source: https://api.smartlead.ai/api-reference/campaigns/forward-email
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/forward-email
Forward a campaign email to other recipients
Forward campaign emails to team members or external recipients. Maintains thread context.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Based on email campaigns forward schema - likely similar to reply-email-thread with forward-specific fields.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/forward-email?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
# Implementation details need verification from controller
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/123/forward-email",
params={"api_key": "YOUR_API_KEY"},
json={}
)
```
## Response Example
```json 200 theme={null}
{
"success": true
}
```
Schema needs verification from controller implementation - check `/server/controller/v1/campaigns/forwardEmailByReplyId.js`
# Get All Campaigns
Source: https://api.smartlead.ai/api-reference/campaigns/get-all
GET https://server.smartlead.ai/api/v1/campaigns/
Retrieves all email campaigns for the authenticated user with comprehensive campaign data including status, schedule set
Retrieves all email campaigns for the authenticated user with comprehensive campaign data including status, schedule settings, tracking configuration, AI matching preferences, and sending limits Essential for dashboard displays, campaign selection interfaces, and bulk operations across portfolio.
## Overview
Retrieves all email campaigns for the authenticated user with comprehensive campaign data including status, schedule settings, tracking configuration, AI matching preferences, and sending limits
**Key Features**:
* Returns campaigns ordered by ID descending (newest first)
* Supports optional client\_id filtering for agency/white-label accounts managing multiple clients
* When include\_tags=true, returns campaign tags with tag IDs, names, and colors for categorization and filtering
* Returns direct array of campaign objects (not wrapped)
## Query Parameters
Your SmartLead API key
Filter campaigns by specific client ID
Include campaign tags in the response
## Response
Indicates if the request was successful
Array of campaign objects
Unique campaign identifier
ID of the user who owns this campaign
Campaign name set by user
Current campaign status: `ACTIVE`, `PAUSED`, `STOPPED`, `ARCHIVED`, `DRAFTED`
ISO 8601 timestamp when campaign was created
ISO 8601 timestamp of last modification
Tracking configuration. Array can contain:
* `"DONT_EMAIL_OPEN"` - Disable open tracking
* `"DONT_LINK_CLICK"` - Disable click tracking
* Empty array `[]` - Track everything
Sending schedule configuration
Timezone (IANA format, e.g., "America/New\_York")
Days of week to send (0=Sunday, 1=Monday, ..., 6=Saturday)
Start sending time (24-hour format, e.g., "09:00")
Stop sending time (24-hour format, e.g., "17:00")
Minimum minutes to wait between consecutive emails. Higher values (120+) appear more natural and improve deliverability.
Maximum number of leads to contact per day across all email accounts
When to stop emailing a lead: `REPLY_TO_AN_EMAIL`, `OPENED_EMAIL`, `CLICKED_LINK`, or `NEVER`
Scheduled start time for campaign (ISO 8601 format), `null` if starting immediately
When `true`, SmartLead's AI automatically matches leads with optimal email accounts based on provider and deliverability history
When `true`, emails are sent as plain text instead of HTML for better deliverability with technical audiences
Percentage of leads that receive follow-up emails (0-100)
Custom unsubscribe footer text
If this is a subsequence, references the parent campaign ID. `null` for main campaigns.
Associated client ID for agency/white-label accounts. `null` for direct user campaigns.
Campaign tags (only included if `include_tags=true`)
Tag identifier
Tag name
Tag color (hex format, e.g., "#FF5733")
```bash cURL theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/campaigns/?api_key=YOUR_API_KEY&include_tags=true"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
url = "https://server.smartlead.ai/api/v1/campaigns/"
response = requests.get(
url,
params={
"api_key": API_KEY,
"include_tags": True
}
)
campaigns = response.json()
print(f"Total campaigns: {len(campaigns['campaigns'])}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function getAllCampaigns() {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/?api_key=${API_KEY}&include_tags=true`
);
const data = await response.json();
return data.campaigns;
}
getAllCampaigns().then(campaigns => {
console.log(`Found ${campaigns.length} campaigns`);
});
```
```php PHP theme={null}
```
```json Response (Actual from API - Direct Array) theme={null}
[
{
"id": 2710262,
"user_id": 196026,
"created_at": "2025-11-25T10:43:46.826Z",
"updated_at": "2025-11-25T14:02:21.776Z",
"status": "ACTIVE",
"name": "Cold Outreach Q1 2024",
"track_settings": ["DONT_EMAIL_OPEN", "DONT_LINK_CLICK"],
"scheduler_cron_value": {
"tz": "America/New_York",
"days": [1, 2, 3, 4, 5],
"endHour": "19:00",
"startHour": "09:00"
},
"min_time_btwn_emails": 24,
"max_leads_per_day": 100,
"stop_lead_settings": "REPLY_TO_AN_EMAIL",
"schedule_start_time": null,
"enable_ai_esp_matching": true,
"send_as_plain_text": false,
"follow_up_percentage": 20,
"unsubscribe_text": "",
"parent_campaign_id": null,
"client_id": null,
"tags": [
{
"tag_id": 1,
"tag_name": "Q1",
"tag_color": "#FF5733"
}
]
}
]
```
**Response Format**: This endpoint returns a direct array of campaigns, not wrapped in a success object. Each campaign contains comprehensive configuration including schedule, tracking settings, AI preferences, and sending limits.
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Response Codes
Campaigns retrieved successfully
Invalid or missing API key
Server error occurred
## Filtering Campaigns
You can filter campaigns by:
* **Client ID**: Get campaigns for a specific client
* **Status**: Use the campaign status filter in your application logic after fetching
* **Tags**: Include tags to filter on your end
## Pagination
Currently, this endpoint returns all campaigns. For large accounts with many campaigns, consider implementing pagination on your end or contact support for enterprise pagination options.
Cache campaign lists to reduce API calls. Only fetch when you need fresh data.
## Common Use Cases
### Get Active Campaigns Only
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
url = "https://server.smartlead.ai/api/v1/campaigns/"
response = requests.get(url, params={"api_key": API_KEY})
campaigns = response.json()
active_campaigns = [
c for c in campaigns['campaigns']
if c['status'] == 'ACTIVE'
]
print(f"Active campaigns: {len(active_campaigns)}")
```
### Get Campaigns by Client
```python Python theme={null}
client_id = 456
response = requests.get(
url,
params={
"api_key": API_KEY,
"client_id": client_id
}
)
campaigns = response.json()
```
## Related Endpoints
* [Get Campaign by ID](/api-reference/campaigns/get-by-id)
* [Create Campaign](/api-reference/campaigns/create)
* [Update Campaign Status](/api-reference/campaigns/update-status)
* [Get Campaign Statistics](/api-reference/campaigns/statistics)
# Get Campaign Analytics
Source: https://api.smartlead.ai/api-reference/campaigns/get-analytics
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/analytics
Retrieve comprehensive analytics for a campaign
Get complete campaign performance metrics including open rates, click rates, reply rates, and engagement statistics.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/123/analytics?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/analytics",
params={"api_key": API_KEY}
)
analytics = response.json()
# Display key metrics
print(f"Campaign: {analytics['campaign_name']}")
print(f"Total Sent: {analytics['total_sent']}")
print(f"Open Rate: {analytics['open_rate']}%")
print(f"Click Rate: {analytics['click_rate']}%")
print(f"Reply Rate: {analytics['reply_rate']}%")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/123/analytics?api_key=${API_KEY}`
);
const analytics = await response.json();
console.log(`Reply Rate: ${analytics.reply_rate}%`);
```
## Response Example
```json 200 theme={null}
{
"campaign_id": 123,
"campaign_name": "Q1 Outreach",
"total_sent": 1000,
"total_opened": 450,
"total_clicked": 120,
"total_replied": 85,
"open_rate": 45.0,
"click_rate": 12.0,
"reply_rate": 8.5,
"bounce_rate": 2.0,
"unsubscribe_rate": 0.5
}
```
## Related Endpoints
* [Get Analytics by Date](/api-reference/campaigns/get-analytics-by-date)
* [Get Campaign Statistics](/api-reference/campaigns/statistics)
# Get Campaign Analytics by Date Range
Source: https://api.smartlead.ai/api-reference/campaigns/get-analytics-by-date
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/analytics-by-date
Retrieve campaign analytics for a specific date range
Analyze campaign performance over a specific time period. Essential for tracking improvements and identifying trends.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
Start date (ISO 8601 format)
End date (ISO 8601 format)
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/123/analytics-by-date?api_key=YOUR_KEY&start_date=2025-01-01T00:00:00Z&end_date=2025-01-31T23:59:59Z"
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
campaign_id = 123
# Get this month's analytics
start = datetime.now().replace(day=1, hour=0, minute=0).isoformat() + 'Z'
end = datetime.now().isoformat() + 'Z'
params = {
"api_key": API_KEY,
"start_date": start,
"end_date": end
}
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/analytics-by-date",
params=params
)
analytics = response.json()
print(f"This month reply rate: {analytics['reply_rate']}%")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Get last 30 days analytics
const end = new Date();
const start = new Date();
start.setDate(start.getDate() - 30);
const params = new URLSearchParams({
api_key: API_KEY,
start_date: start.toISOString(),
end_date: end.toISOString()
});
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/123/analytics-by-date?${params}`
);
const analytics = await response.json();
console.log(`30-day reply rate: ${analytics.reply_rate}%`);
```
## Response Example
```json 200 theme={null}
{
"campaign_id": 123,
"start_date": "2025-01-01T00:00:00Z",
"end_date": "2025-01-31T23:59:59Z",
"total_sent": 500,
"open_rate": 48.0,
"click_rate": 13.0,
"reply_rate": 9.0
}
```
## Related Endpoints
* [Get Campaign Analytics](/api-reference/campaigns/get-analytics)
* [Get Top Level Analytics](/api-reference/campaigns/get-top-level-analytics)
# Get Campaign by ID
Source: https://api.smartlead.ai/api-reference/campaigns/get-by-id
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}
Retrieves comprehensive details for a specific campaign including all configuration settings, schedule, tracking prefere
Retrieves comprehensive details for a specific campaign including all configuration settings, schedule, tracking preferences, AI options, and associated metadata For client API keys, additionally filters by client\_id
## Overview
Retrieves comprehensive details for a specific campaign including all configuration settings, schedule, tracking preferences, AI options, and associated metadata
**Key Features**:
* Automatically validates campaign ownership - returns 404 if campaign doesn't exist or user lacks access
* Returns single campaign object with all 18 CAMPAIGN\_ATTRIBUTES fields including: status, track\_settings array, complete scheduler\_cron\_value object, sending limits, stop conditions, AI ESP matching preferences, and plain text mode
* Optionally includes campaign tags with tag IDs, names, and colors
## Path Parameters
The ID of the campaign to retrieve
## Query Parameters
Your SmartLead API key
Include campaign tags in the response
## Response
Campaign ID
Campaign name
Campaign status (ACTIVE, PAUSED, STOPPED, ARCHIVED, DRAFTED)
ISO 8601 timestamp
Sending schedule configuration
Tracking settings (DONT\_EMAIL\_OPEN, DONT\_LINK\_CLICK)
```bash cURL theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/campaigns/123?api_key=YOUR_API_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}",
params={"api_key": API_KEY}
)
campaign = response.json()
print(f"Campaign: {campaign['name']}")
print(f"Status: {campaign['status']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}?api_key=${API_KEY}`
);
const campaign = await response.json();
console.log(`Campaign: ${campaign.name}`);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"data": {
"id": 123,
"name": "Q2 2026 Outreach",
"status": "ACTIVE",
"created_at": "2026-03-15T10:30:00Z",
"updated_at": "2026-04-01T14:22:00Z",
"client_id": 456,
"track_settings": ["DONT_EMAIL_OPEN"],
"stop_lead_settings": "REPLY_TO_AN_EMAIL",
"sending_limit": 500,
"total_leads": 5240,
"leads_contacted": 4128,
"leads_replied": 312
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Get Campaign Email Accounts
Source: https://api.smartlead.ai/api-reference/campaigns/get-email-accounts
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts
Retrieves all email accounts (sender accounts) associated with and actively rotating for this specific campaign.
Retrieves all email accounts (sender accounts) associated with and actively rotating for this specific campaign Essential for monitoring sender distribution, checking account health, and troubleshooting delivery issues.
## Overview
Retrieves all email accounts (sender accounts) associated with and actively rotating for this specific campaign
**Key Features**:
* Returns account details including from\_email, from\_name, type (SMTP/GMAIL/OUTLOOK), daily sending limits, warmup status and reputation, connection status (is\_smtp\_success/is\_imap\_success), and number of campaigns using each account
* Shows which accounts SmartLead will rotate between when sending campaign emails
## Path Parameters
The campaign ID
## Query Parameters
Your SmartLead API key
Include email account tags in response
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaign_id}/email-accounts?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"id": 2001,
"from_email": "sales@mycompany.com",
"from_name": "Sarah Lee",
"type": "SMTP",
"warmup_enabled": true,
"warmup_reputation": "excellent"
},
{
"id": 2002,
"from_email": "outreach@mycompany.com",
"from_name": "David Smith",
"type": "SMTP",
"warmup_enabled": true,
"warmup_reputation": "excellent"
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Response Fields
Email account ID
Sender email address
Account type (SMTP, GMAIL, OUTLOOK)
Whether warmup is active
Current warmup reputation score
## Implementation Details
Only returns accounts linked to this specific campaign. Check is\_smtp\_success and is\_imap\_success for connection status.
**Response Format**: array
## Related Endpoints
* [Add Email Accounts to Campaign](/api-reference/campaigns/add-email-accounts)
* [Remove Email Accounts](/api-reference/campaigns/remove-email-accounts)
* [Get All Email Accounts](/api-reference/email-accounts/get-all)
# Get Lead by ID
Source: https://api.smartlead.ai/api-reference/campaigns/get-lead-by-id
GET https://server.smartlead.ai/api/v1/leads/{lead_id}
Retrieve detailed information about a specific lead
Get complete lead details including contact info, engagement stats, category, and custom fields. This is a global lead lookup across all campaigns.
## Path Parameters
Lead ID
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/leads/789?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
response = requests.get(
"https://server.smartlead.ai/api/v1/leads/789",
params={"api_key": "YOUR_API_KEY"}
)
lead = response.json()
print(f"Lead: {lead['email']}")
print(f"Status: {lead['status']}")
print(f"Category: {lead.get('category_name', 'Uncategorized')}")
```
## Response Example
```json 200 theme={null}
{
"id": 789,
"email": "john@company.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "ACME Corp",
"status": "INPROGRESS",
"category_id": 1,
"category_name": "Interested",
"email_stats": {
"is_opened": true,
"is_clicked": true,
"is_replied": true
},
"custom_fields": {
"job_title": "CEO"
}
}
```
# Get Lead Message History
Source: https://api.smartlead.ai/api-reference/campaigns/get-lead-history
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/message-history
Retrieve complete email conversation history for a specific lead
View full email thread history with a lead. Essential for understanding conversation context and lead engagement.
## Path Parameters
Campaign ID
Lead ID
## Query Parameters
Your SmartLead API key
Filter messages after this timestamp (ISO 8601)
Include plain text version of emails
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/123/leads/789/message-history?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/123/leads/789/message-history",
params={"api_key": "YOUR_API_KEY", "show_plain_text_response": True}
)
history = response.json()
for msg in history['messages']:
direction = "➡️ " if msg['direction'] == 'outbound' else "⬅️ "
print(f"{direction}{msg['subject']} - {msg['sent_at']}")
```
## Response Example
```json 200 theme={null}
{
"messages": [
{
"id": "msg_1",
"subject": "Partnership Opportunity",
"direction": "outbound",
"sent_at": "2025-01-15T10:00:00Z",
"opened_at": "2025-01-15T10:30:00Z"
},
{
"id": "msg_2",
"subject": "Re: Partnership Opportunity",
"direction": "inbound",
"received_at": "2025-01-20T14:00:00Z"
}
]
}
```
# Get Campaign Leads
Source: https://api.smartlead.ai/api-reference/campaigns/get-leads
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads
Retrieve all leads in a campaign with comprehensive filtering and pagination
Fetch all leads in a campaign with advanced filtering by status, category, engagement, and date ranges. Essential for lead management, reporting, and analysis.
## Overview
Retrieves all leads associated with a campaign with comprehensive filtering options similar to Master Inbox endpoints.
**Key Features:**
* Pagination support (offset/limit, max 100 per request)
* Filter by lead status (STARTED, INPROGRESS, COMPLETED, PAUSED, STOPPED)
* Filter by email engagement (opened, clicked, replied, bounced, etc.)
* Filter by lead category
* Date range filtering (created\_at, last\_sent\_time, event\_time)
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
Pagination offset (minimum 0)
Records per page (minimum 1, maximum 100)
Filter leads created after this date (ISO 8601 format)
Filter leads with last email sent after this date (ISO 8601 format)
Filter by last event time (ISO 8601 format)
Lead status filter
Valid values:
* `STARTED` - Lead added, sequence not started
* `INPROGRESS` - Currently in sequence
* `COMPLETED` - Sequence completed
* `PAUSED` - Lead paused
* `STOPPED` - Lead stopped
Filter by specific category ID
Filter by email engagement status
Valid values:
* `is_opened` - Email was opened
* `is_clicked` - Link was clicked
* `is_bounced` - Email bounced
* `is_replied` - Lead replied
* `is_unsubscribed` - Lead unsubscribed
* `is_spam` - Marked as spam
* `is_accepted` - Email accepted by server
* `not_replied` - Opened but didn't reply
* `is_sender_bounced` - Sender bounce
```bash cURL theme={null}
# Get replied leads
curl "https://server.smartlead.ai/api/v1/campaigns/123/leads?api_key=YOUR_KEY&emailStatus=is_replied&limit=100"
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
campaign_id = 123
# Example 1: Get all replied leads
params = {
"api_key": API_KEY,
"emailStatus": "is_replied",
"limit": 100,
"offset": 0
}
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads",
params=params
)
leads = response.json()
print(f"Replied leads: {leads['total']}")
# Example 2: Get leads added in last 7 days
seven_days_ago = (datetime.now() - timedelta(days=7)).isoformat()
params = {
"api_key": API_KEY,
"created_at_gt": seven_days_ago,
"limit": 100
}
new_leads = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads",
params=params
).json()
print(f"New leads (7 days): {new_leads['total']}")
# Example 3: Get in-progress leads with high engagement
params = {
"api_key": API_KEY,
"status": "INPROGRESS",
"emailStatus": "is_clicked",
"limit": 100
}
engaged_leads = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads",
params=params
).json()
# Example 4: Paginate through all leads
def get_all_leads(campaign_id):
all_leads = []
offset = 0
limit = 100
while True:
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY, "offset": offset, "limit": limit}
)
data = response.json()
leads = data.get('leads', [])
if not leads:
break
all_leads.extend(leads)
offset += limit
if offset >= data.get('total', 0):
break
return all_leads
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
// Get replied leads
async function getRepliedLeads(campaignId) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads?api_key=${API_KEY}&emailStatus=is_replied&limit=100`
);
const data = await response.json();
console.log(`Replied leads: ${data.total}`);
return data.leads;
}
// Get leads by category
async function getLeadsByCategory(campaignId, categoryId) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads?api_key=${API_KEY}&lead_category_id=${categoryId}&limit=100`
);
return response.json();
}
await getRepliedLeads(123);
```
## Response Example
```json 200 - Success theme={null}
{
"total": 150,
"leads": [
{
"id": 789,
"email": "john@company.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "ACME Corp",
"status": "INPROGRESS",
"category_id": 1,
"category_name": "Interested",
"created_at": "2025-01-15T10:00:00Z",
"last_sent_time": "2025-01-20T09:00:00Z",
"email_stats": {
"is_opened": true,
"is_clicked": true,
"is_replied": true,
"is_bounced": false
},
"custom_fields": {
"job_title": "CEO",
"industry": "SaaS"
}
}
],
"offset": 0,
"limit": 100
}
```
## Common Workflows
### Export Interested Leads
```python theme={null}
# Get all interested leads
interested = get_leads(
campaign_id=123,
filters={"lead_category_id": 1}
)
# Export to CSV
import csv
with open('interested_leads.csv', 'w') as f:
writer = csv.DictWriter(f, fieldnames=['email', 'name', 'company'])
for lead in interested['leads']:
writer.writerow({
'email': lead['email'],
'name': f"{lead['first_name']} {lead['last_name']}",
'company': lead.get('company_name', '')
})
```
## Related Endpoints
* [Add Leads to Campaign](/api-reference/campaigns/add-leads)
* [Get Lead by ID](/api-reference/campaigns/get-lead-by-id)
* [Export Leads](/api-reference/campaigns/export-leads)
# Get Bulk Lead Message History
Source: https://api.smartlead.ai/api-reference/campaigns/get-leads-history-bulk
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/message-history-for-leads/bbfbdsFGHlBr76ruhjvh6fhHL
Retrieve message history for multiple leads at once
Get email conversation history for multiple leads in a single API call. Efficient for bulk operations and reporting.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
Filter messages after this timestamp
## Request Body
Array of lead IDs (nullable - if null, returns for all leads)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/message-history-for-leads/bbfbdsFGHlBr76ruhjvh6fhHL?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"lead_ids": [789, 790, 791]}'
```
```python Python theme={null}
import requests
def get_bulk_lead_history(campaign_id, lead_ids=None):
payload = {"lead_ids": lead_ids}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/message-history-for-leads/bbfbdsFGHlBr76ruhjvh6fhHL",
params={"api_key": "YOUR_API_KEY"},
json=payload
)
return response.json()
# Get history for specific leads
history = get_bulk_lead_history(123, [789, 790, 791])
# Get history for all leads (pass null)
all_history = get_bulk_lead_history(123, None)
```
## Response Example
```json 200 theme={null}
{
"data": {
"789": [
{"subject": "Email 1", "sent_at": "2025-01-15T10:00:00Z"}
],
"790": [
{"subject": "Email 1", "sent_at": "2025-01-15T10:05:00Z"}
]
}
}
```
# Get Campaign Sequences
Source: https://api.smartlead.ai/api-reference/campaigns/get-sequences
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/sequences
Retrieves all email sequences configured for a campaign, ordered by sequence number.
Retrieves all email sequences configured for a campaign, ordered by sequence number Essential for sequence editors, email preview interfaces, A/B testing configuration, and understanding campaign flow
## Overview
Retrieves all email sequences configured for a campaign, ordered by sequence number
**Key Features**:
* Returns complete sequence data including subject lines, email bodies (HTML/plain text), delay configurations, and A/B test variants if configured
* Shows delayInDays for each sequence indicating spacing between emails
Includes sequence IDs required for updates
## Path Parameters
The campaign ID
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/sequences?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/sequences",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaign_id}/sequences?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"data": [
{
"id": 1001,
"created_at": "2026-02-10T10:30:00Z",
"updated_at": "2026-02-10T10:30:00Z",
"email_campaign_id": 123,
"seq_number": 1,
"subject": "Quick question about {{company_name}}",
"email_body": "Hi {{first_name}},
I noticed {{company_name}} is doing some interesting work...
",
"sequence_variants": [
{
"id": 5001,
"variant_name": "Variant A",
"subject": "Quick question about {{company_name}}",
"email_body": "Hi {{first_name}},
I noticed {{company_name}} is doing some interesting work...
"
}
]
},
{
"id": 1002,
"created_at": "2026-02-10T10:30:00Z",
"updated_at": "2026-02-10T10:30:00Z",
"email_campaign_id": 123,
"seq_number": 2,
"subject": "Re: Quick question about {{company_name}}",
"email_body": "Following up on my previous email...
",
"sequence_variants": [
{
"id": 5002,
"variant_name": "Variant A",
"subject": "Re: Quick question about {{company_name}}",
"email_body": "Following up on my previous email...
"
}
]
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Response Fields
Sequence ID
Sequence position (1, 2, 3, etc.)
Email subject line (can include variables)
Email content (HTML or plain text)
Delay configuration
Number of days to wait before sending this sequence
## Implementation Details
Returns sequences ordered by seq\_number. Includes variant information if A/B testing is configured.
**Response Format**: array
## Related Endpoints
* [Update Campaign Sequences](/api-reference/campaigns/update-sequences)
* [Create Campaign](/api-reference/campaigns/create)
* [Sequences Concept Guide](/core/sequences)
# Get Top Level Analytics by Date
Source: https://api.smartlead.ai/api-reference/campaigns/get-top-level-analytics
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/top-level-analytics-by-date
Retrieve high-level campaign metrics for a date range
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
Start date (ISO 8601)
End date (ISO 8601)
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/123/top-level-analytics-by-date?api_key=YOUR_KEY&start_date=2025-01-01T00:00:00Z&end_date=2025-01-31T23:59:59Z"
```
```python Python theme={null}
import requests
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/123/top-level-analytics-by-date",
params={
"api_key": "YOUR_API_KEY",
"start_date": "2025-01-01T00:00:00Z",
"end_date": "2025-01-31T23:59:59Z"
}
)
analytics = response.json()
print(f"Period metrics: {analytics}")
```
## Response Example
```json 200 theme={null}
{
"total_sent": 500,
"total_delivered": 490,
"open_rate": 45.0,
"reply_rate": 8.5
}
```
# Get Webhook Summary
Source: https://api.smartlead.ai/api-reference/campaigns/get-webhook-summary
GET https://server.smartlead.ai/api/v1/campaigns/{campaignId}/webhooks/summary
Get webhook execution summary and statistics for a campaign
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
Start date in ISO format (e.g. `2024-01-01T00:00:00.000Z`)
End date in ISO format (e.g. `2024-01-31T23:59:59.999Z`)
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/123/webhooks/summary?api_key=YOUR_KEY&fromTime=2024-01-01T00:00:00.000Z&toTime=2024-01-31T23:59:59.999Z"
```
```python Python theme={null}
import requests
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/123/webhooks/summary",
params={
"api_key": "YOUR_API_KEY",
"fromTime": "2024-01-01T00:00:00.000Z",
"toTime": "2024-01-31T23:59:59.999Z"
}
)
summary = response.json()
print(f"Total webhook calls: {summary.get('total_calls', 0)}")
print(f"Success rate: {summary.get('success_rate', 0)}%")
```
## Response Example
```json 200 theme={null}
{
"total_calls": 150,
"successful_calls": 145,
"failed_calls": 5,
"success_rate": 96.7
}
```
# Get Campaign Webhooks
Source: https://api.smartlead.ai/api-reference/campaigns/get-webhooks
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/webhooks
Retrieve all webhooks configured for a campaign
View all webhook integrations set up for campaign events. Essential for managing integrations with external systems.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/123/webhooks?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/123/webhooks",
params={"api_key": API_KEY}
)
webhooks = response.json()
print(f"Configured webhooks: {len(webhooks['data'])}")
for webhook in webhooks['data']:
print(f" - {webhook['name']}: {webhook['webhook_url']}")
print(f" Events: {', '.join(webhook['event_types'])}")
```
## Response Example
```json 200 theme={null}
{
"success": true,
"data": [
{
"id": 456,
"name": "CRM Integration",
"webhook_url": "https://crm.example.com/webhook",
"event_types": ["LEAD_REPLIED", "LEAD_OPENED"],
"is_active": true
}
]
}
```
## Related Endpoints
* [Save Webhooks](/api-reference/campaigns/save-webhooks)
* [Delete Webhook](/api-reference/campaigns/delete-webhook)
* [Webhooks Overview](/api-reference/webhooks/events)
# Mark Lead as Complete
Source: https://api.smartlead.ai/api-reference/campaigns/mark-lead-complete
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_map_id}/manual-complete
Manually mark a lead as completed in the campaign sequence
Manually complete a lead to stop further emails without categorizing as unsubscribed or stopped. Useful for deals closed or leads no longer relevant.
## Path Parameters
Campaign ID
Lead map ID (campaign\_lead\_map\_id from other endpoints)
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/2433664091/manual-complete?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
def mark_lead_complete(campaign_id, lead_map_id):
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_map_id}/manual-complete",
params={"api_key": "YOUR_API_KEY"}
)
if response.status_code == 200:
print(f"✅ Lead marked as complete")
return response.json()
mark_lead_complete(123, 2433664091)
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Lead marked as complete"
}
```
# Pause Campaign Lead
Source: https://api.smartlead.ai/api-reference/campaigns/pause-lead
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/pause
Temporarily pause a specific lead in a campaign
Pause outreach to a specific lead without removing them from the campaign. Can be resumed later.
## Path Parameters
Campaign ID
Lead ID to pause
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/789/pause?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def pause_lead(campaign_id, lead_id):
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/pause",
params={"api_key": API_KEY}
)
if response.status_code == 200:
print(f"✅ Lead {lead_id} paused")
return response.json()
pause_lead(123, 789)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function pauseLead(campaignId, leadId) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}/pause?api_key=${API_KEY}`,
{ method: 'POST' }
);
return response.json();
}
await pauseLead(123, 789);
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Lead paused successfully"
}
```
## Related Endpoints
* [Resume Lead](/api-reference/campaigns/resume-lead)
* [Get Campaign Leads](/api-reference/campaigns/get-leads)
# Remove Email Accounts from Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/remove-email-accounts
DELETE https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts
Disassociates email accounts from a campaign's sender rotation pool.
Disassociates email accounts from a campaign's sender rotation pool Does NOT delete accounts themselves - only removes from this campaign
## Overview
Disassociates email accounts from a campaign's sender rotation pool
**Key Features**:
* Validates at least one account remains if campaign is ACTIVE (returns error if trying to remove all)
## Path Parameters
The campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Array of email account IDs to remove
Example: `[456, 457]`
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.delete(
"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/email-accounts",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaign_id}/email-accounts?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
Removing email accounts may affect campaign delivery if no other accounts are available. Ensure at least one account remains connected.
## When to Remove Accounts
* Account reputation declined
* Account disconnected or failed
* Rebalancing account usage
* Account no longer available
## Implementation Details
Cannot remove all accounts from active campaign. Pause campaign first or add replacement accounts.
**Response Format**: object
## Related Endpoints
* [Get Campaign Email Accounts](/api-reference/campaigns/get-email-accounts)
* [Add Email Accounts](/api-reference/campaigns/add-email-accounts)
# Reply to Campaign Lead
Source: https://api.smartlead.ai/api-reference/campaigns/reply-email-thread
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/reply-email-thread
Send a reply email to a lead within campaign context
Reply to leads directly from campaign view. Maintains conversation thread and tracks reply in campaign statistics.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Email statistics ID of the message to reply to
Reply email body content
Recipient email (optional, defaults to lead email)
Recipient first name
Recipient last name
Schedule reply for later (ISO 8601)
Message ID being replied to
Original email body (for context)
Original email timestamp
CC recipients (comma-separated)
BCC recipients (comma-separated)
Scheduling condition
Include email signature
Sequence type
File attachments
File name
File URL
MIME type
File size in bytes
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/reply-email-thread?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_stats_id": "abc-123",
"email_body": "Thanks for your interest! Let me know if you have any questions.",
"add_signature": true
}'
```
```python Python theme={null}
import requests
def reply_to_lead(campaign_id, email_stats_id, body, add_signature=True):
payload = {
"email_stats_id": email_stats_id,
"email_body": body,
"add_signature": add_signature
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/reply-email-thread",
params={"api_key": "YOUR_API_KEY"},
json=payload
)
if response.status_code == 200:
print("✅ Reply sent")
return response.json()
reply_to_lead(123, "abc-123", "Happy to help! Let me know your questions.")
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Reply sent successfully"
}
```
# Resume Campaign Lead
Source: https://api.smartlead.ai/api-reference/campaigns/resume-lead
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/resume
Resume a paused lead with optional delay
Resume a paused lead in the campaign sequence. Optionally add a delay before resuming.
## Path Parameters
Campaign ID
Lead ID to resume
## Query Parameters
Your SmartLead API key
## Request Body
Optional delay in days before resuming (nullable)
```bash cURL theme={null}
# Resume immediately
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/789/resume?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# Resume with 7-day delay
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/789/resume?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"resume_lead_with_delay_days": 7}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def resume_lead(campaign_id, lead_id, delay_days=None):
payload = {}
if delay_days is not None:
payload["resume_lead_with_delay_days"] = delay_days
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/resume",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
if delay_days:
print(f"✅ Lead will resume in {delay_days} days")
else:
print("✅ Lead resumed immediately")
return response.json()
# Resume immediately
resume_lead(123, 789)
# Resume after 30 days
resume_lead(123, 790, delay_days=30)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function resumeLead(campaignId, leadId, delayDays = null) {
const payload = delayDays !== null ?
{ resume_lead_with_delay_days: delayDays } : {};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}/resume?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
return response.json();
}
// Resume after 7 days
await resumeLead(123, 789, 7);
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Lead resumed successfully",
"will_resume_at": "2025-01-27T00:00:00Z"
}
```
## Related Endpoints
* [Pause Lead](/api-reference/campaigns/pause-lead)
* [Get Campaign Leads](/api-reference/campaigns/get-leads)
# Retrigger Campaign Webhooks
Source: https://api.smartlead.ai/api-reference/campaigns/retrigger-webhooks
POST https://server.smartlead.ai/api/v1/campaigns/{campaignId}/webhooks/retrigger-failed-events
Manually retry failed webhook deliveries
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Start date in ISO format (e.g. `2024-01-01T00:00:00.000Z`)
End date in ISO format (e.g. `2024-01-31T23:59:59.999Z`)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/webhooks/retrigger-failed-events?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"fromTime": "2024-01-01T00:00:00.000Z",
"toTime": "2024-01-31T23:59:59.999Z"
}'
```
```python Python theme={null}
import requests
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/123/webhooks/retrigger-failed-events",
params={"api_key": "YOUR_API_KEY"},
json={
"fromTime": "2024-01-01T00:00:00.000Z",
"toTime": "2024-01-31T23:59:59.999Z"
}
)
print("Webhooks retriggered")
```
## Response Example
```json 200 theme={null}
{
"success": true,
"retriggered_count": 5
}
```
# Create/Update Campaign Webhook
Source: https://api.smartlead.ai/api-reference/campaigns/save-webhooks
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/webhooks
Create a new webhook or update existing webhook for campaign events
Configure webhooks to receive real-time notifications when campaign events occur. Integrate with CRM, Slack, or custom systems.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Webhook ID (null for new webhook, number to update existing)
Webhook name for identification
URL to receive webhook POST requests
Array of event types to trigger webhook
Common events:
* `LEAD_REPLIED`
* `LEAD_OPENED`
* `LEAD_CLICKED`
* `LEAD_BOUNCED`
* `LEAD_UNSUBSCRIBED`
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/webhooks?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": null,
"name": "CRM Integration",
"webhook_url": "https://crm.example.com/smartlead-webhook",
"event_types": ["LEAD_REPLIED", "LEAD_OPENED"]
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def create_webhook(campaign_id, name, url, events):
payload = {
"id": None, # null for new
"name": name,
"webhook_url": url,
"event_types": events
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/webhooks",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
webhook_id = response.json()['data']['id']
print(f"✅ Webhook created (ID: {webhook_id})")
return response.json()
# Create CRM webhook for replies
create_webhook(
campaign_id=123,
name="CRM Reply Integration",
url="https://crm.example.com/webhook",
events=["LEAD_REPLIED", "LEAD_CLICKED"]
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function createWebhook(campaignId, name, url, events) {
const payload = {
id: null,
name,
webhook_url: url,
event_types: events
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/webhooks?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
return response.json();
}
await createWebhook(123, 'Slack Notifications',
'https://hooks.slack.com/...', ['LEAD_REPLIED']);
```
## Response Example
```json 200 theme={null}
{
"success": true,
"data": {
"id": 456,
"name": "CRM Integration",
"webhook_url": "https://crm.example.com/webhook",
"event_types": ["LEAD_REPLIED", "LEAD_OPENED"]
}
}
```
## Related Endpoints
* [Get Campaign Webhooks](/api-reference/campaigns/get-webhooks)
* [Delete Webhook](/api-reference/campaigns/delete-webhook)
* [Webhook Events Reference](/api-reference/webhooks/events)
# Send Test Email
Source: https://api.smartlead.ai/api-reference/campaigns/send-test-email
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/send-test-email
Send a test email from a specific sequence to verify content and deliverability
Test your email sequences before launching. Send to yourself or team to review content, formatting, and personalization.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Lead ID to use for personalization variables
Which sequence to test (1, 2, 3, etc.)
Specific email account to send from (optional)
Custom recipient email (if different from lead's email)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/send-test-email?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"leadId": 789,
"sequenceNumber": 1,
"customEmailAddress": "test@mycompany.com"
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def send_test_email(campaign_id, lead_id, sequence_num, test_email=None):
payload = {
"leadId": lead_id,
"sequenceNumber": sequence_num
}
if test_email:
payload["customEmailAddress"] = test_email
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/send-test-email",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
print(f"✅ Test email sent to {test_email or 'lead email'}")
return response.json()
# Send test to yourself
send_test_email(123, 789, 1, "myself@mycompany.com")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function sendTestEmail(campaignId, leadId, sequenceNum, testEmail) {
const payload = {
leadId,
sequenceNumber: sequenceNum,
customEmailAddress: testEmail
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/send-test-email?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
return response.json();
}
await sendTestEmail(123, 789, 1, 'test@mycompany.com');
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Test email sent successfully"
}
```
## Related Endpoints
* [Get Campaign Sequences](/api-reference/campaigns/get-sequences)
* [Update Sequences](/api-reference/campaigns/update-sequences)
# Get Campaign Statistics
Source: https://api.smartlead.ai/api-reference/campaigns/statistics
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/statistics
Retrieves detailed email-level statistics for all emails sent in a campaign.
Retrieves detailed email-level statistics for all emails sent in a campaign Essential for detailed campaign analysis, A/B test evaluation, lead engagement scoring, and identifying best-performing sequences
## Overview
Retrieves detailed email-level statistics for all emails sent in a campaign
**Key Features**:
* Returns individual email stats including opens, clicks, replies, bounces with precise timestamps
* Supports comprehensive filtering by sequence number (1-20), email status (opened/clicked/replied/bounced), and date ranges
* Includes pagination with configurable offset/limit (max 1000)
## Path Parameters
The campaign ID
## Query Parameters
Your SmartLead API key
Pagination offset
Number of records to return
Filter by sequence number (1-20)
Filter by status: opened, clicked, replied, unsubscribed, bounced
Start date filter (ISO format)
End date filter (ISO format)
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/statistics?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/statistics",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaign_id}/statistics?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"data": {
"campaign_id": 123,
"total_leads": 5240,
"contacted": 4128,
"opened": 1236,
"clicked": 412,
"replied": 312,
"bounced": 58,
"unsubscribed": 24,
"open_rate": 29.9,
"click_rate": 9.98,
"reply_rate": 7.56
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Statistics Fields
Total number of email statistics records
Array of email statistics
Lead's full name
Lead's email address
Which email in sequence (1, 2, 3, etc.)
When email was sent
Email was opened
Link was clicked
Lead replied
Email bounced
## Use Cases
### Get All Opens
```python theme={null}
response = requests.get(
f"{base_url}/campaigns/{campaign_id}/statistics",
params={"api_key": API_KEY, "email_status": "opened", "limit": 1000}
)
```
### Get Sequence 1 Performance
```python theme={null}
response = requests.get(
f"{base_url}/campaigns/{campaign_id}/statistics",
params={"api_key": API_KEY, "email_sequence_number": 1}
)
```
### Get This Week's Stats
```python theme={null}
from datetime import datetime, timedelta
end_date = datetime.now().isoformat()
start_date = (datetime.now() - timedelta(days=7)).isoformat()
response = requests.get(
f"{base_url}/campaigns/{campaign_id}/statistics",
params={
"api_key": API_KEY,
"sent_time_start_date": start_date,
"sent_time_end_date": end_date
}
)
```
## Implementation Details
Returns paginated results. Use filters to narrow down large datasets. Statistics updated in real-time as events occur.
**Response Format**: object
## Related Endpoints
* [Get Campaign Analytics](/api-reference/analytics/campaign-performance)
* [Get All Campaigns](/api-reference/campaigns/get-all)
# Unsubscribe Lead from Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/unsubscribe-lead
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/unsubscribe
Unsubscribe a lead from a campaign to stop all future emails
Permanently unsubscribe a lead from receiving emails. Lead will be marked as unsubscribed and excluded from future campaigns.
## Path Parameters
Campaign ID
Lead ID to unsubscribe
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/789/unsubscribe?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
def unsubscribe_lead(campaign_id, lead_id):
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/unsubscribe",
params={"api_key": "YOUR_API_KEY"}
)
if response.status_code == 200:
print(f"✅ Lead {lead_id} unsubscribed")
return response.json()
unsubscribe_lead(123, 789)
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Lead unsubscribed successfully"
}
```
# Update Campaign Lead Details
Source: https://api.smartlead.ai/api-reference/campaigns/update-lead
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/
Update lead information including contact details and custom fields
Update lead's contact information, company details, and custom fields within a campaign.
## Path Parameters
Campaign ID
Lead ID
## Query Parameters
Your SmartLead API key
## Request Body
Lead email address
First name
Last name
Company name
Phone number
Website URL
Geographic location
LinkedIn profile URL
Company website
Custom field key-value pairs (max 200 fields)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/789/?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "john.doe@company.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "ACME Corp Updated",
"custom_fields": {
"job_title": "CEO",
"company_size": "50-200"
}
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def update_lead(campaign_id, lead_id, **fields):
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/",
params={"api_key": API_KEY},
json=fields
)
if response.status_code == 200:
print(f"✅ Lead {lead_id} updated")
return response.json()
# Update lead details
update_lead(
123, 789,
email="john.doe@company.com",
first_name="John",
last_name="Doe",
company_name="ACME Corp",
custom_fields={"job_title": "CEO", "industry": "SaaS"}
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function updateLead(campaignId, leadId, fields) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}/?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(fields)
}
);
return response.json();
}
await updateLead(123, 789, {
email: 'john.doe@company.com',
company_name: 'ACME Corp',
custom_fields: { job_title: 'CEO' }
});
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Lead updated successfully"
}
```
## Related Endpoints
* [Add Leads](/api-reference/campaigns/add-leads)
* [Get Campaign Leads](/api-reference/campaigns/get-leads)
# Update Lead Category in Campaign
Source: https://api.smartlead.ai/api-reference/campaigns/update-lead-category
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/category
Assign or change the category for a lead within a campaign
Categorize leads (Interested, Not Interested, etc.) for better organization and reporting.
## Path Parameters
Campaign ID
Lead ID
## Query Parameters
Your SmartLead API key
## Request Body
Category ID to assign (use `null` to remove category)
Pause the lead after categorizing
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/789/category?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"category_id": 1, "pause_lead": false}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def update_lead_category(campaign_id, lead_id, category_id, pause=False):
payload = {
"category_id": category_id,
"pause_lead": pause
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/category",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
print(f"✅ Lead categorized as {category_id}")
return response.json()
# Mark as interested and pause
update_lead_category(123, 789, category_id=1, pause=True)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function updateCategory(campaignId, leadId, categoryId, pause = false) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}/category?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ category_id: categoryId, pause_lead: pause })
}
);
return response.json();
}
await updateCategory(123, 789, 1, true);
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Lead category updated"
}
```
## Related Endpoints
* [Get Lead Categories](/api-reference/leads/categories)
* [Update Category (Master Inbox)](/api-reference/inbox/update-category)
# Update Lead Email Account
Source: https://api.smartlead.ai/api-reference/campaigns/update-lead-email-account
POST https://server.smartlead.ai/api/v1/campaigns/update-lead-email-account
Change which email account is used to send to a specific lead
Override the email account used for a specific lead. Useful for deliverability optimization or when specific senders perform better with certain leads.
## Query Parameters
Your SmartLead API key
## Request Body
New email account ID to use
Campaign ID
Lead ID
Force override even if lead has specific account assigned
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/update-lead-email-account?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_account_id": 999,
"email_campaign_id": 123,
"email_lead_id": 789,
"override_lead_email_account": true
}'
```
```python Python theme={null}
import requests
def update_lead_sending_account(campaign_id, lead_id, new_account_id):
payload = {
"email_account_id": new_account_id,
"email_campaign_id": campaign_id,
"email_lead_id": lead_id,
"override_lead_email_account": True
}
response = requests.post(
"https://server.smartlead.ai/api/v1/campaigns/update-lead-email-account",
params={"api_key": "YOUR_API_KEY"},
json=payload
)
if response.status_code == 200:
print(f"✅ Lead {lead_id} now uses account {new_account_id}")
return response.json()
update_lead_sending_account(123, 789, 999)
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Lead email account updated"
}
```
# Update Campaign Schedule
Source: https://api.smartlead.ai/api-reference/campaigns/update-schedule
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/schedule
Configures when and how frequently campaign emails are sent.
Configures when and how frequently campaign emails are sent Sets timezone (IANA format), sending hours (start/end in 24-hour format), active days of week (0=Sunday through 6=Saturday), and minimum time between consecutive emails (in minutes)
## Overview
Configures when and how frequently campaign emails are sent
**Key Features**:
* Validates timezone string and time format before saving
## Path Parameters
The ID of the campaign to update
## Query Parameters
Your SmartLead API key
## Request Body
Sending schedule configuration
IANA timezone (e.g., "America/New\_York", "Europe/London")
Days of week to send (0=Sunday, 1=Monday, ..., 6=Saturday)
Example: `[1, 2, 3, 4, 5]` for Monday-Friday
Start sending time (24-hour format, e.g., "09:00")
Stop sending time (24-hour format, e.g., "17:00")
Minimum minutes between consecutive emails
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/schedule?api_key=YOUR_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": 120
}
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
schedule = {
"schedule": {
"timezone": "America/New_York",
"days": [1, 2, 3, 4, 5], # Monday-Friday
"start_hour": "09:00",
"end_hour": "17:00",
"min_time_btw_emails": 120 # 2 hours between emails
}
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/schedule",
params={"api_key": API_KEY},
json=schedule
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const schedule = {
schedule: {
timezone: 'America/New_York',
days: [1, 2, 3, 4, 5],
start_hour: '09:00',
end_hour: '17:00',
min_time_btw_emails: 120
}
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/schedule?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(schedule)
}
);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"data": {
"message": "Schedule updated successfully",
"schedule": {
"timezone": "America/New_York",
"days_of_week": [1, 2, 3, 4, 5],
"start_time": "09:00",
"end_time": "17:00",
"min_time_between_emails": 120
}
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Schedule Best Practices
### Business Hours
Send during recipient's business hours:
* **B2B**: 9 AM - 5 PM local time
* **B2C**: 10 AM - 8 PM local time
* **Global**: Consider multiple timezones
### Days of Week
```
Monday-Friday [1,2,3,4,5] - Best for B2B
Tuesday-Thursday [2,3,4] - Highest open rates
All 7 days [0,1,2,3,4,5,6] - For B2C or urgent campaigns
```
### Time Between Emails
* **120+ minutes**: Appears more natural
* **60-120 minutes**: Moderate pacing
* **30-60 minutes**: Aggressive (use carefully)
Longer delays between emails (2-3 hours) result in better deliverability and appear more natural to recipients.
## Common Timezones
* `America/New_York` - US Eastern
* `America/Los_Angeles` - US Pacific
* `America/Chicago` - US Central
* `Europe/London` - UK
* `Europe/Paris` - Central Europe
* `Asia/Tokyo` - Japan
* `Asia/Dubai` - UAE
* `Asia/Kolkata` - India
* `Australia/Sydney` - Australia
[See full list of timezones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
## Implementation Details
Schedule timezone must be valid IANA timezone. Start/end hours in 24-hour format. Min time between emails prevents rapid-fire sending.
**Response Format**: object
## Related Endpoints
* [Get Campaign by ID](/api-reference/campaigns/get-by-id)
* [Update Campaign Settings](/api-reference/campaigns/update-settings)
* [Update Campaign Status](/api-reference/campaigns/update-status)
# Update Campaign Sequences
Source: https://api.smartlead.ai/api-reference/campaigns/update-sequences
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/sequences
Create or update email sequences for multi-step campaigns
Creates new sequences (id: null) or updates existing ones. Each sequence needs: seq\_number, email\_body, and delay in days. Cannot modify while campaign is ACTIVE - pause first.
## Overview
Create new email sequences or update existing ones for a campaign. Sequences define your multi-step email outreach flow.
**Key Features**:
* Create new sequences by setting `id: null`
* Update existing sequences by including their `id`
* Configure delays between emails (0-365 days)
* Add A/B testing variants with `seq_variants`
* Subject line optional for follow-ups (uses "Re:" on previous)
Cannot modify sequences while campaign is **ACTIVE**. Pause campaign first, make changes, then resume.
## Path Parameters
The campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Array of sequence objects
Sequence ID (null for new, number for update)
Sequence position (1, 2, 3, etc.)
Email subject line (can include )
Email content (supports HTML and )
Delay configuration
Days to wait before sending
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/sequences?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"sequences": [
{
"id": null,
"seq_number": 1,
"subject": "Hello {{first_name}}",
"email_body": "Hi {{first_name}},
I wanted to reach out...
",
"seq_delay_details": {
"delay_in_days": 0
}
},
{
"id": null,
"seq_number": 2,
"subject": "",
"email_body": "Just following up on my previous email...
",
"seq_delay_details": {
"delay_in_days": 3
}
}
]
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/sequences",
params={"api_key": API_KEY},
json={
"sequences": [
{
"id": None,
"seq_number": 1,
"subject": "Hello {{first_name}}",
"email_body": "Hi {{first_name}},
I wanted to reach out...
",
"seq_delay_details": {"delay_in_days": 0}
},
{
"id": None,
"seq_number": 2,
"subject": "",
"email_body": "Just following up on my previous email...
",
"seq_delay_details": {"delay_in_days": 3}
}
]
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/sequences?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
sequences: [
{
id: null,
seq_number: 1,
subject: 'Hello {{first_name}}',
email_body: 'Hi {{first_name}},
I wanted to reach out...
',
seq_delay_details: { delay_in_days: 0 }
},
{
id: null,
seq_number: 2,
subject: '',
email_body: 'Just following up on my previous email...
',
seq_delay_details: { delay_in_days: 3 }
}
]
})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"id": 1001,
"seq_number": 1,
"subject": "Hello {{first_name}}",
"email_body": "Hi {{first_name}},
I wanted to reach out...
"
},
{
"id": 1002,
"seq_number": 2,
"subject": "Re: Hello {{first_name}}",
"email_body": "Just following up on my previous email...
"
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Personalization Variables
Use these in subject and body:
* `{{first_name}}`, `{{last_name}}`
* `{{company_name}}`, `{{website}}`
* `{{location}}`, `{{linkedin_profile}}`
* Any custom field: `{{job_title}}`, `{{industry}}`, etc.
## Sequence Best Practices
Keep first email under 125 words for best response rates
Wait 3-5 days between follow-ups - don't be too aggressive
Each email should provide new value, not just "checking in"
## Implementation Details
Use id:null to create new sequences. Include existing id to update. Cannot modify sequences while campaign is active.
**Response Format**: object
## Related Endpoints
* [Get Campaign Sequences](/api-reference/campaigns/get-sequences)
* [Sequences Concept Guide](/core/sequences)
# Update Campaign Settings
Source: https://api.smartlead.ai/api-reference/campaigns/update-settings
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/settings
Updates campaign configuration including: tracking settings (enable/disable opens and clicks - array format with DONT_EM
Updates campaign configuration including: tracking settings (enable/disable opens and clicks - array format with DONT\_EMAIL\_OPEN/DONT\_LINK\_CLICK values), sending limits (max\_leads\_per\_day, min\_time\_between\_emails), stop conditions (when to stop emailing leads - REPLY\_TO\_AN\_EMAIL/OPENED\_EMAIL/CLIC...
## Overview
Updates campaign configuration including: tracking settings (enable/disable opens and clicks - array format with DONT\_EMAIL\_OPEN/DONT\_LINK\_CLICK values), sending limits (max\_leads\_per\_day, min\_time\_between\_emails), stop conditions (when to stop emailing leads - REPLY\_TO\_AN\_EMAIL/OPENED\_EMAIL/CLICKED\_LINK), AI ESP matching (intelligently pair leads with optimal email accounts), plain text mode (send\_as\_plain\_text for better deliverability with technical audiences), follow-up percentage, and unsubscribe text
**Key Features**:
* Validates settings before applying
## Path Parameters
The ID of the campaign to update
## Query Parameters
Your SmartLead API key
## Request Body
Campaign name
Email tracking configuration. Pass an array of string values to disable specific tracking. Allowed values: `DONT_TRACK_EMAIL_OPEN`, `DONT_TRACK_LINK_CLICK`, `DONT_TRACK_REPLY_TO_AN_EMAIL`. Pass an empty array `[]` to enable all tracking.
When to stop emailing a lead. Allowed values: `CLICK_ON_A_LINK`, `OPEN_AN_EMAIL`
Unsubscribe text to append to emails
Send emails as plain text (no HTML)
Force convert all emails to plain text
Follow-up percentage (0-100)
Client ID. Leave as null if not needed
Use AI to match leads with best email accounts
Pause leads from same domain after reply
Ignore SmartSenders mailbox sending limit
Bounce auto-pause threshold
Enable domain-level rate limiting
Out of office detection configuration
When true, out-of-office responses are not counted as replies and will not stop the sequence
Automatically reactivate leads after their out-of-office period ends
Number of days to wait before reactivating a lead after an out-of-office response
Automatically categorize out-of-office replies using AI
Add an unsubscribe tag to outgoing emails
AI categorisation options
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/settings?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My Campaign",
"track_settings": ["DONT_TRACK_EMAIL_OPEN"],
"stop_lead_settings": "CLICK_ON_A_LINK",
"send_as_plain_text": false,
"follow_up_percentage": 100,
"enable_ai_esp_matching": true
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/settings",
params={"api_key": API_KEY},
json={
"name": "My Campaign",
"track_settings": ["DONT_TRACK_EMAIL_OPEN"],
"stop_lead_settings": "CLICK_ON_A_LINK",
"send_as_plain_text": False,
"follow_up_percentage": 100,
"enable_ai_esp_matching": True
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/settings?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'My Campaign',
track_settings: ['DONT_TRACK_EMAIL_OPEN'],
stop_lead_settings: 'CLICK_ON_A_LINK',
send_as_plain_text: false,
follow_up_percentage: 100,
enable_ai_esp_matching: true
})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"data": {
"message": "Settings updated successfully"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Settings Explained
### Track Settings
Control what gets tracked in your emails:
* **track\_open**: Adds tracking pixel to detect opens
* **track\_click**: Wraps links to track clicks
Disable tracking for privacy-focused outreach or when targeting technical audiences who may block tracking.
### Sending Limits
* **sending\_limit**: Daily cap across all email accounts
* **min\_time\_btwn\_emails**: Prevents rapid-fire sending (appears more natural)
### Stop Lead Settings
* **REPLY\_TO\_AN\_EMAIL**: Most common - stop when they engage
* **OPENED\_EMAIL**: Conservative - stop after they show interest
* **CLICKED\_LINK**: Stop when they click a link
### AI ESP Matching
When enabled, SmartLead's AI:
* Matches leads with appropriate sender accounts
* Considers lead's email provider
* Optimizes for deliverability
* Balances account usage
## Implementation Details
Settings changes affect only future sends. In-progress leads continue with old settings.
**Response Format**: object
## Related Endpoints
* [Update Campaign Schedule](/api-reference/campaigns/update-schedule)
* [Get Campaign by ID](/api-reference/campaigns/get-by-id)
* [Update Campaign Status](/api-reference/campaigns/update-status)
# Update Campaign Status
Source: https://api.smartlead.ai/api-reference/campaigns/update-status
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/status
Change the status of a campaign (start, pause, stop).
Change the status of a campaign (start, pause, stop) Updates campaign status to START, PAUSE, or STOP
## Path Parameters
The ID of the campaign to update
## Query Parameters
Your SmartLead API key
## Request Body
New campaign status
Valid values (from API\_EMAIL\_CAMPAIGN\_STATUS):
* `START` - Start or resume campaign (not "ACTIVE")
* `PAUSED` - Temporarily pause sending
* `STOPPED` - Permanently stop campaign
Note: Use "START" not "ACTIVE" when activating a campaign
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/status?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "START"}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/status",
params={"api_key": API_KEY},
json={"status": "ACTIVE"}
)
print("Campaign started!" if response.status_code == 200 else "Error")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/status?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ status: 'ACTIVE' })
}
);
console.log('Campaign started!');
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json Success theme={null}
{
"success": true,
"message": "Campaign status updated successfully",
"campaign": {
"id": 123,
"status": "ACTIVE"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Status Descriptions
| Status | What It Does | Reversible? |
| ------------ | ------------------------------------------- | ----------- |
| **ACTIVE** | Starts sending emails according to schedule | Yes |
| **PAUSED** | Temporarily stops all sending | Yes |
| **STOPPED** | Permanently stops campaign | No |
| **ARCHIVED** | Hides from active campaigns list | Yes |
**STOPPED** status is permanent and cannot be undone. Use **PAUSED** if you might want to resume later.
## When to Use Each Status
### ACTIVE
* Campaign is fully configured
* All sequences added
* Email accounts connected
* Leads imported
* Ready to send
### PAUSED
* Need to make adjustments
* Waiting for more leads
* Testing sequences
* Temporary hold
### STOPPED
* Campaign completed its goal
* Pivoting strategy
* No longer needed
* Permanently ending
### ARCHIVED
* Campaign is done but keep for records
* Want to hide from active list
* May reference later
## Implementation Details
START status triggers campaign validation and begins sending. STOP is permanent. Use PAUSE for temporary holds.
**Response Format**: object
## Related Endpoints
* [Get Campaign by ID](/api-reference/campaigns/get-by-id)
* [Update Campaign Settings](/api-reference/campaigns/update-settings)
* [Delete Campaign](/api-reference/campaigns/delete)
# Update Campaign Team Member
Source: https://api.smartlead.ai/api-reference/campaigns/update-team-member
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/team-member
Assign or change the team member responsible for a campaign
Assign campaign ownership to specific team members for accountability and workload distribution.
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Team member ID to assign (use `null` to unassign)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/team-member?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"teamMemberId": 456}'
```
```python Python theme={null}
import requests
def assign_campaign_to_member(campaign_id, member_id):
payload = {"teamMemberId": member_id}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/team-member",
params={"api_key": "YOUR_API_KEY"},
json=payload
)
if response.status_code == 200:
print(f"✅ Campaign assigned to member {member_id}")
return response.json()
assign_campaign_to_member(123, 456)
```
## Response Example
```json 200 theme={null}
{
"success": true,
"message": "Team member updated"
}
```
# Manage Client API Keys
Source: https://api.smartlead.ai/api-reference/clients/api-keys
POST https://server.smartlead.ai/api/v1/client/api-key
Create, list, delete, and reset API keys for client sub-accounts
Each client can have multiple API keys with custom names. Use these endpoints to manage programmatic access for your client sub-accounts.
## Overview
Client API keys provide programmatic access to SmartLead on behalf of a specific client. You can create multiple keys per client, filter by status, and reset keys as needed.
**Available Operations:**
* **Create**: POST `/api/v1/client/api-key` - Generate a new API key
* **List**: GET `/api/v1/client/api-key` - List all client API keys
* **Delete**: DELETE `/api/v1/client/api-key/:id` - Remove an API key
* **Reset**: PUT `/api/v1/client/api-key/reset/:id` - Regenerate an API key
## Query Parameters
Your SmartLead API key
## Request Body
The ID of the client to create the API key for
A descriptive name for the API key. Must match pattern: letters, numbers, spaces, hyphens, and underscores only.
## List Client API Keys
```
GET https://server.smartlead.ai/api/v1/client/api-key
```
### Query Parameters
Your SmartLead API key
Filter by client ID
Filter by key status. Values: `active`, `inactive`
Filter by key name (partial match)
## Delete Client API Key
```
DELETE https://server.smartlead.ai/api/v1/client/api-key/:id
```
### Path Parameters
The ID of the API key to delete
## Reset Client API Key
```
PUT https://server.smartlead.ai/api/v1/client/api-key/reset/:id
```
### Path Parameters
The ID of the API key to reset. This generates a new key value while keeping the same key record.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/client/api-key?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"clientId": 301, "keyName": "Production Key"}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 45,
"client_id": 301,
"key_name": "Production Key",
"api_key": "cl_live_xxxxxxxxxxxxxxxx",
"status": "active",
"created_at": "2025-12-01T10:00:00.000Z"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Create Client
Source: https://api.smartlead.ai/api-reference/clients/create
POST https://server.smartlead.ai/api/v1/client/save
Create a new client (whitelabel sub-account) under your account
Create client sub-accounts to manage multiple brands or agencies from a single SmartLead account. Each client gets their own isolated workspace with configurable permissions.
## Overview
Creates a new client sub-account under your main SmartLead account. Clients are whitelabel sub-accounts that allow agencies to manage multiple brands with isolated data and configurable permissions.
## Query Parameters
Your SmartLead API key
## Request Body
Client email address. Must be unique across the platform.
Client display name (company or brand name)
Login password for the client. If not provided, the client will need to set one.
Base64 encoded logo image for whitelabel branding
URL to the client logo image for whitelabel branding
Array of permission strings defining what the client can access. Controls feature visibility and access.
Whether email/lead credits are specifically assigned to this client
Number of email credits allocated to this client (when `is_credit_assigned` is true)
Number of lead credits allocated to this client (when `is_credit_assigned` is true)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/client/save?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "admin@acme.com",
"name": "Acme Agency",
"permission": ["campaigns", "email_accounts", "leads"],
"is_credit_assigned": true,
"email_credits": 10000,
"lead_credits": 5000
}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 301,
"name": "Acme Agency",
"email": "admin@acme.com",
"api_key": "cl_xxxxxxxxxxxxxxxx",
"created_at": "2025-12-01T10:00:00.000Z"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get All Clients
Source: https://api.smartlead.ai/api-reference/clients/get-all
GET https://server.smartlead.ai/api/v1/client/
Retrieve all client sub-accounts under your main account
Returns a list of all whitelabel client sub-accounts. Use this to manage and monitor your agency clients.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/client/?api_key=YOUR_KEY"
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"id": 301,
"name": "Acme Agency",
"email": "admin@acme.com",
"created_at": "2025-12-01T10:00:00.000Z"
},
{
"id": 302,
"name": "Beta Corp",
"email": "admin@beta.com",
"created_at": "2025-12-05T14:00:00.000Z"
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Update Client
Source: https://api.smartlead.ai/api-reference/clients/update
POST https://server.smartlead.ai/api/v1/client/save
Update an existing client sub-account by providing the client ID
To update a client, include the `id` field in the request body along with the fields you want to change. The same endpoint is used for both creating and updating clients.
## Query Parameters
Your SmartLead API key
## Request Body
The ID of the client to update. This makes the request an update instead of a create.
Client email address
Client display name
New login password for the client
Base64 encoded logo image
URL to the client logo image
Unique identifier for the client
Array of permission strings
Whether credits are assigned to this client
Email credits allocated
Lead credits allocated
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/client/save?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": 301,
"email": "admin@acme.com",
"name": "Acme Agency Updated",
"email_credits": 20000
}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 301,
"name": "Acme Agency Updated",
"email": "admin@acme.com"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Assign Tags to Email Accounts
Source: https://api.smartlead.ai/api-reference/email-account-tags/assign
POST https://server.smartlead.ai/api/v1/email-accounts/tag-mapping
Add tags to one or more email accounts
Assign existing tags to email accounts for better organization. You can tag up to 25 email accounts at once.
## Query Parameters
Your SmartLead API key
## Request Body
Array of email account IDs to tag. Minimum 1, maximum 25 accounts.
Array of tag IDs to assign. Minimum 1 tag required.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/tag-mapping?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email_account_ids": [101, 102, 103], "tag_ids": [1, 2]}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"message": "Tags assigned successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Update Email Account Tag
Source: https://api.smartlead.ai/api-reference/email-account-tags/create
POST https://server.smartlead.ai/api/v1/email-accounts/tag-manager
Update an existing email account tag's name and color
Update an existing tag's name or color. To **create a new tag**, use the [Create Tag](/api-reference/email-account-tags/create-new) endpoint instead — it does not require an ID.
## Query Parameters
Your SmartLead API key
## Request Body
Tag ID of the existing tag to update. Get tag IDs from [Get All Tags](/api-reference/email-account-tags/get-all).
Tag display name
Hex color code for the tag (e.g., `#FF5733`). Must be a valid 6-character hex color with `#` prefix.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/tag-manager?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"id": 1, "name": "Primary Senders", "color": "#4CAF50"}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 1,
"name": "Primary Senders",
"color": "#4CAF50"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Create Tag
Source: https://api.smartlead.ai/api-reference/email-account-tags/create-new
POST https://server.smartlead.ai/api/v1/tags
Create a new email account tag with a name and optional color
Create tags to organize your email accounts into groups for easy filtering and management. Each tag can have a custom color for visual identification.
## Overview
Creates a new tag that can be assigned to email accounts. Unlike the [Update Tag](/api-reference/email-account-tags/create) endpoint, this does not require an existing tag ID — the system generates one automatically.
## Query Parameters
Your SmartLead API key
## Request Body
Display name for the tag
Hex color code for the tag (e.g., `#FF5733`). Must be a valid 6-character hex color with `#` prefix. If not provided, a default color will be assigned.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/tags?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Primary Senders", "color": "#4CAF50"}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://server.smartlead.ai/api/v1/tags",
params={"api_key": API_KEY},
json={
"name": "Primary Senders",
"color": "#4CAF50"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/tags?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Primary Senders',
color: '#4CAF50'
})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Tag created successfully
Invalid or missing API key
Request validation failed. Common issues:
* Missing `name` field
* Invalid hex color format (must match `#RRGGBB`)
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 42,
"name": "Primary Senders",
"color": "#4CAF50"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "\"name\" is required"
}
```
## Related Endpoints
* [Update Tag](/api-reference/email-account-tags/create) — Update an existing tag's name or color
* [Get All Tags](/api-reference/email-account-tags/get-all) — List all email account tags
* [Assign Tag](/api-reference/email-account-tags/assign) — Assign a tag to an email account
* [Remove Tag](/api-reference/email-account-tags/remove) — Remove a tag from an email account
# Get Email Account Tags
Source: https://api.smartlead.ai/api-reference/email-account-tags/get-all
POST https://server.smartlead.ai/api/v1/email-accounts/tag-list
Get tags associated with specific email accounts by email address
Retrieve tag information for email accounts. Provide email addresses to get their associated tags and account IDs.
## Request Body
Array of email address strings to look up. Minimum 1 email required.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/tag-list" \
-H "Content-Type: application/json" \
-d '{"email_ids": ["sender@company.com", "outreach@company.com"]}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"email_account_id": 101,
"from_email": "sender@company.com",
"tags": [
{"id": 1, "name": "Primary Senders", "color": "#4CAF50"},
{"id": 2, "name": "Campaign A", "color": "#2196F3"}
]
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Remove Tags from Email Accounts
Source: https://api.smartlead.ai/api-reference/email-account-tags/remove
DELETE https://server.smartlead.ai/api/v1/email-accounts/tag-mapping
Remove tags from one or more email accounts
Remove tag associations from email accounts. This does not delete the tags themselves.
## Query Parameters
Your SmartLead API key
## Request Body
Array of email account IDs to remove tags from. Minimum 1 required.
Array of tag IDs to remove. Minimum 1 required.
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/email-accounts/tag-mapping?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email_account_ids": [101, 102], "tag_ids": [1]}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"message": "Tags removed successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Add OAuth Email Account
Source: https://api.smartlead.ai/api-reference/email-accounts/add-oauth
POST https://server.smartlead.ai/api/v1/email-accounts/save-oauth
Connect Gmail or Outlook account using OAuth 2.0 with automatic token refresh
Adds an OAuth-authenticated email account (Gmail or Outlook). SmartLead manages token refresh automatically. Use this endpoint after obtaining OAuth tokens from the respective provider.
## Query Parameters
Your SmartLead API key
## Request Body
Display name for outgoing emails
Email address (must match OAuth account)
Email username (typically same as from\_email)
Provider type. Valid values: `GMAIL`, `OUTLOOK`
OAuth token object obtained from provider
OAuth scopes granted (e.g., "[https://mail.google.com/](https://mail.google.com/)")
Token type, must be `Bearer`
OAuth access token
OAuth refresh token for automatic renewal
Token expiry timestamp (Unix timestamp in milliseconds)
OpenID Connect ID token (optional)
Token expiry ISO string (optional)
Seconds until token expires (optional)
Extended expiry time for Microsoft tokens (optional)
Whether to enable email warmup for this account
Whether to use whitelabel OAuth credentials. Must be `true` or `false`
Email account ID (only for updates, null for new accounts)
Maximum emails allowed per day (including warmup and campaigns)
Custom domain for tracking links
BCC email address for all outgoing emails
Minimum time to wait between emails in minutes
Email signature HTML
Number of warmup emails per day (if warmup\_enabled is true)
Daily increase in warmup email count
Target reply rate percentage for warmup
Client ID for multi-tenant accounts
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/save-oauth?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_name": "John Doe",
"from_email": "john@gmail.com",
"username": "john@gmail.com",
"type": "GMAIL",
"token": {
"scope": "https://mail.google.com/",
"token_type": "Bearer",
"access_token": "ya29.a0AfH6SMBx...",
"refresh_token": "1//0gvJf9X...",
"expiry_date": 1732627200000
},
"warmup_enabled": true,
"use_whitelabel_credentials": true,
"total_warmup_per_day": 20,
"daily_rampup": 2,
"max_email_per_day": 50
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
# Gmail OAuth account
payload = {
"from_name": "John Doe",
"from_email": "john@gmail.com",
"username": "john@gmail.com",
"type": "GMAIL",
"token": {
"scope": "https://mail.google.com/",
"token_type": "Bearer",
"access_token": "ya29.a0AfH6SMBx...",
"refresh_token": "1//0gvJf9X...",
"expiry_date": 1732627200000
},
"warmup_enabled": True,
"use_whitelabel_credentials": True,
"total_warmup_per_day": 20,
"daily_rampup": 2,
"max_email_per_day": 50,
"time_to_wait_in_mins": 5
}
response = requests.post(
"https://server.smartlead.ai/api/v1/email-accounts/save-oauth",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
if result.get('ok'):
print(f"OAuth account added successfully. ID: {result['data']['id']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Outlook OAuth account
const payload = {
from_name: 'Jane Smith',
from_email: 'jane@outlook.com',
username: 'jane@outlook.com',
type: 'OUTLOOK',
token: {
scope: 'https://outlook.office.com/.default',
token_type: 'Bearer',
access_token: 'EwBwA8l6BAAU...',
refresh_token: 'M.R3_BAY...',
expiry_date: 1732627200000
},
warmup_enabled: true,
use_whitelabel_credentials: true,
total_warmup_per_day: 15,
daily_rampup: 3,
max_email_per_day: 40
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/save-oauth?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
if (result.ok) {
console.log(`OAuth account added. ID: ${result.data.id}`);
}
```
## Response Codes
OAuth email account added successfully
Invalid OAuth token or connection validation failed
Invalid or missing API key
Missing required fields or invalid type value
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"message": "OAuth account added successfully",
"data": {
"id": 123,
"from_email": "john@gmail.com",
"type": "GMAIL",
"is_smtp_success": true,
"is_imap_success": true
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "type must be one of [GMAIL, OUTLOOK]"
}
```
```json 400 - Token Error theme={null}
{
"ok": false,
"message": "Invalid or expired OAuth token"
}
```
## OAuth Flow
Use Google or Microsoft OAuth flow to obtain access and refresh tokens with appropriate mail scopes.
**Gmail Scope Required:** `https://mail.google.com/`
**Outlook Scope Required:** `https://outlook.office.com/.default` or `https://outlook.office.com/SMTP.Send https://outlook.office.com/IMAP.AccessAsUser.All`
Send the OAuth tokens and account information to this endpoint. SmartLead will validate the connection.
Set `warmup_enabled: true` and configure warmup parameters to gradually build sender reputation.
## Usage Notes
OAuth tokens must be fresh and have the correct mail scopes. Expired tokens will cause connection failures.
Use `use_whitelabel_credentials: true` to leverage SmartLead's OAuth app for Gmail/Outlook. This simplifies the OAuth flow as you don't need to create your own OAuth application.
SmartLead automatically refreshes expired OAuth tokens using the refresh\_token. Ensure the refresh\_token is included in the token object.
## Related Endpoints
* [Add SMTP Email Account](/api-reference/email-accounts/add-smtp) - For non-OAuth accounts
* [Update Email Account](/api-reference/email-accounts/update)
* [Get All Email Accounts](/api-reference/email-accounts/get-all)
# Add SMTP Email Account
Source: https://api.smartlead.ai/api-reference/email-accounts/add-smtp
POST https://server.smartlead.ai/api/v1/email-accounts/save
Add new SMTP/IMAP email account with connection validation and optional warmup configuration
Creates a new email account with SMTP and IMAP configuration. SmartLead will validate the connection and optionally enable email warmup. Supports both standard SMTP accounts and OAuth providers (Gmail, Outlook).
## Query Parameters
Your SmartLead API key
## Request Body
Display name for outgoing emails (e.g., "John Doe")
Email address (must be valid email format)
SMTP username (usually the email address)
SMTP password or app-specific password
SMTP server hostname (e.g., "smtp.gmail.com")
SMTP server port (common ports: 587 for TLS, 465 for SSL, 25 for plain)
IMAP server hostname (e.g., "imap.gmail.com")
IMAP server port (common ports: 993 for SSL, 143 for plain)
Whether to enable email warmup for this account
Email account ID (only for updates, null for new accounts)
Email provider type. Valid values: `GMAIL`, `OUTLOOK`, `SMTP`
OAuth token object (for Gmail/Outlook OAuth accounts)
OAuth scope granted
OAuth access token
OAuth refresh token
OAuth ID token
Token expiry timestamp
Custom reply-to email address (if different from from\_email)
IMAP username (if different from SMTP username)
IMAP password (if different from SMTP password)
Maximum emails allowed per day (including warmup and campaign emails)
Custom domain for tracking links
BCC email address for all outgoing emails
Minimum time to wait between emails in minutes
Email signature HTML
Number of warmup emails to send per day (if warmup\_enabled is true)
Daily increase in warmup email count
Target reply rate percentage for warmup emails
Client ID for multi-tenant accounts
Whether the account should be suspended upon creation
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/save?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_name": "John Doe",
"from_email": "john@example.com",
"user_name": "john@example.com",
"password": "your_app_password",
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"imap_host": "imap.gmail.com",
"imap_port": 993,
"warmup_enabled": true,
"total_warmup_per_day": 20,
"daily_rampup": 2,
"max_email_per_day": 50,
"time_to_wait_in_mins": 5,
"type": "GMAIL"
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
payload = {
"from_name": "John Doe",
"from_email": "john@example.com",
"user_name": "john@example.com",
"password": "your_app_password",
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"imap_host": "imap.gmail.com",
"imap_port": 993,
"warmup_enabled": True,
"total_warmup_per_day": 20,
"daily_rampup": 2,
"max_email_per_day": 50,
"time_to_wait_in_mins": 5,
"type": "GMAIL",
"signature": "Best regards,
John
"
}
response = requests.post(
"https://server.smartlead.ai/api/v1/email-accounts/save",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
if result.get('ok'):
print(f"Email account added successfully. ID: {result['data']['id']}")
else:
print(f"Error: {result.get('message')}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const payload = {
from_name: 'John Doe',
from_email: 'john@example.com',
user_name: 'john@example.com',
password: 'your_app_password',
smtp_host: 'smtp.gmail.com',
smtp_port: 587,
imap_host: 'imap.gmail.com',
imap_port: 993,
warmup_enabled: true,
total_warmup_per_day: 20,
daily_rampup: 2,
max_email_per_day: 50,
time_to_wait_in_mins: 5,
type: 'GMAIL',
signature: 'Best regards,
John
'
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/save?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
if (result.ok) {
console.log(`Email account added successfully. ID: ${result.data.id}`);
} else {
console.log(`Error: ${result.message}`);
}
```
## Response Codes
Email account added successfully with connection validation
SMTP or IMAP connection failed - check credentials and server settings
Invalid or missing API key
Missing required fields or invalid field values
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"message": "Email account added successfully",
"data": {
"id": 123,
"from_email": "john@example.com",
"is_smtp_success": true,
"is_imap_success": true,
"warmup_details": {
"status": "ACTIVE",
"total_warmup_per_day": 20
}
}
}
```
```json 400 - Connection Failed theme={null}
{
"ok": false,
"message": "SMTP connection failed",
"error": "Invalid credentials"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "from_name is required"
}
```
## Configuration Examples
```json theme={null}
{
"from_name": "Your Name",
"from_email": "your.email@gmail.com",
"user_name": "your.email@gmail.com",
"password": "your_app_specific_password",
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"imap_host": "imap.gmail.com",
"imap_port": 993,
"type": "GMAIL",
"warmup_enabled": true
}
```
```json theme={null}
{
"from_name": "Your Name",
"from_email": "your.email@outlook.com",
"user_name": "your.email@outlook.com",
"password": "your_password",
"smtp_host": "smtp.office365.com",
"smtp_port": 587,
"imap_host": "outlook.office365.com",
"imap_port": 993,
"type": "OUTLOOK",
"warmup_enabled": true
}
```
```json theme={null}
{
"from_name": "Your Name",
"from_email": "you@yourdomain.com",
"user_name": "you@yourdomain.com",
"password": "your_password",
"smtp_host": "smtp.yourdomain.com",
"smtp_port": 587,
"imap_host": "imap.yourdomain.com",
"imap_port": 993,
"type": "SMTP",
"warmup_enabled": false
}
```
## Usage Notes
For Gmail accounts, you must use an [App Password](https://support.google.com/accounts/answer/185833) rather than your regular Gmail password. Enable 2-factor authentication first, then generate an app password.
SmartLead automatically validates SMTP and IMAP connections upon adding an account. If validation fails, the account is still created but marked with connection errors that you can fix later.
Enable warmup for new email accounts to gradually build sender reputation. Set `total_warmup_per_day` to start with 10-20 emails and use `daily_rampup` of 2-5 to increase daily volume gradually.
## Related Endpoints
* [Add OAuth Email Account](/api-reference/email-accounts/add-oauth) - For OAuth-based Gmail/Outlook
* [Get All Email Accounts](/api-reference/email-accounts/get-all)
* [Update Warmup Settings](/api-reference/email-accounts/warmup-settings)
# Delete Email Account
Source: https://api.smartlead.ai/api-reference/email-accounts/delete
DELETE https://server.smartlead.ai/api/v1/email-accounts/{email_account_id}
Delete an email account and remove it from all campaigns
Deleting an email account removes it from all campaigns and deactivates warmup. This action cannot be undone. Ensure no active campaigns rely on this account before deletion.
## Path Parameters
The email account ID to delete
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/email-accounts/123?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
account_id = 123
response = requests.delete(
f"https://server.smartlead.ai/api/v1/email-accounts/{account_id}",
params={"api_key": API_KEY}
)
result = response.json()
if result.get('ok'):
print(f"Email account {account_id} deleted successfully")
else:
print(f"Error: {result.get('message')}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const accountId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/${accountId}?api_key=${API_KEY}`,
{ method: 'DELETE' }
);
const result = await response.json();
if (result.ok) {
console.log(`Email account ${accountId} deleted successfully`);
} else {
console.log(`Error: ${result.message}`);
}
```
## Response Codes
Email account deleted successfully
Invalid or missing API key
Email account not found or you don't have access to it
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"message": "Email account deleted successfully!",
"emailAccountId": 123
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"ok": false,
"message": "Email account not found!",
"errorCode": "ACCOUNT_NOT_FOUND",
"emailAccountId": 123
}
```
## Deletion Behavior
When an email account is deleted:
* Removed from all campaign associations
* Warmup status set to `INACTIVE` with reason "Email account is deleted by user action"
* Smart sender domain mappings are deleted
* Account is soft-deleted (not permanently removed from database)
Before deleting an email account, ensure:
* No active campaigns depend solely on this account
* You have alternative email accounts configured
* All scheduled emails from this account have been sent or rescheduled
## Related Endpoints
* [Get All Email Accounts](/api-reference/email-accounts/get-all)
* [Suspend Email Account](/api-reference/email-accounts/suspend) - Temporarily disable without deleting
* [Add SMTP Email Account](/api-reference/email-accounts/add-smtp)
# Get All Email Accounts
Source: https://api.smartlead.ai/api-reference/email-accounts/get-all
GET https://server.smartlead.ai/api/v1/email-accounts/
Retrieve all email accounts with advanced filtering and pagination options
Returns email accounts with SMTP/IMAP credentials, warmup status, and campaign associations. Supports filtering by connection status, warmup state, email provider, and usage status.
## Query Parameters
Your SmartLead API key
Pagination offset (minimum: 0)
Number of accounts to return per page (minimum: 1, maximum: 100)
Filter by usage status. Valid values: `true` (used in campaigns), `false` (not used in campaigns)
Filter by warmup status. Valid values: `ACTIVE`, `INACTIVE`
Filter by SMTP connection status. Valid values: `true` (connected), `false` (failed)
Filter by warmup blocked status. Valid values: `true` (blocked), `false` (not blocked)
Filter by email service provider. Valid values: `GMAIL`, `OUTLOOK`, `SMTP`
Filter by email username (partial match supported)
Filter by client ID (for multi-tenant accounts)
If `true`, includes an array of campaign IDs for each email account. Returns a `campaign_ids` field on each account object.
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/email-accounts/?api_key=YOUR_KEY&limit=50&emailWarmupStatus=ACTIVE&isSmtpSuccess=true"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/email-accounts/",
params={
"api_key": API_KEY,
"limit": 50,
"offset": 0,
"emailWarmupStatus": "ACTIVE",
"isSmtpSuccess": "true",
"esp": "GMAIL"
}
)
accounts = response.json()
print(f"Total accounts: {len(accounts)}")
# Display account details
for account in accounts:
print(f"{account['from_email']} - Warmup: {account['warmup_details']['status'] if account['warmup_details'] else 'None'}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const params = new URLSearchParams({
api_key: API_KEY,
limit: 50,
offset: 0,
emailWarmupStatus: 'ACTIVE',
isSmtpSuccess: 'true',
esp: 'GMAIL'
});
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/?${params}`
);
const accounts = await response.json();
console.log(`Total accounts: ${accounts.length}`);
// Display account details
accounts.forEach(account => {
const warmupStatus = account.warmup_details?.status || 'None';
console.log(`${account.from_email} - Warmup: ${warmupStatus}`);
});
```
## Response Fields
The response is an array of email account objects, each containing:
Unique email account identifier
Display name for outgoing emails
Email address
Email account username
Account type: `GMAIL`, `OUTLOOK`, or `SMTP`
Associated client ID
Number of campaigns using this email account
When the account was added
When the account was last updated
SMTP server hostname
SMTP server port
SMTP port type (SSL/TLS/STARTTLS)
Whether SMTP connection is successful
SMTP connection error message if failed
IMAP server hostname
IMAP server port
IMAP port type (SSL/TLS)
IMAP username
Whether IMAP uses different credentials than SMTP
Whether IMAP connection is successful
IMAP connection error message if failed
Maximum messages allowed per day
Messages sent today
Email signature HTML
Custom domain for tracking links
BCC email address for all outgoing emails
Custom reply-to email address
Minimum time to wait between emails (in minutes)
Email warmup status and metrics
Warmup status: `ACTIVE`, `INACTIVE`, `PAUSED`
Total emails sent during warmup
Total emails marked as spam
Warmup reputation percentage (e.g., "95%")
Warmup service key identifier
When warmup was started
Warmup reply rate percentage
Reason if warmup is blocked
Tags assigned to this email account. Always included in the response.
Unique tag identifier
Tag display name
Tag color as a hex code (e.g., `#F5B1FC`)
Array of campaign IDs using this email account. Only included when `fetch_campaigns=true` is passed as a query parameter.
## Response Codes
Email accounts retrieved successfully
Invalid or missing API key
Invalid query parameters (check limit range and filter values)
Server error occurred
```json 200 - Success theme={null}
[
{
"id": 123,
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-11-26T08:00:00.000Z",
"user_id": 456,
"from_name": "John Doe",
"from_email": "john@example.com",
"minTimeToWaitInMins": 5,
"username": "john@example.com",
"password": "encrypted_password",
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"smtp_port_type": "TLS",
"message_per_day": 50,
"different_reply_to_address": null,
"is_different_imap_account": false,
"imap_username": "john@example.com",
"imap_password": "encrypted_password",
"imap_host": "imap.gmail.com",
"imap_port": 993,
"imap_port_type": "SSL",
"signature": "Best regards,
John
",
"custom_tracking_domain": null,
"bcc_email": null,
"is_smtp_success": true,
"is_imap_success": true,
"smtp_failure_error": null,
"imap_failure_error": null,
"type": "GMAIL",
"daily_sent_count": 25,
"client_id": null,
"campaign_count": 3,
"tags": [
{
"tag_id": 10,
"tag_name": "Winners",
"tag_color": "#B1FCCF"
},
{
"tag_id": 15,
"tag_name": "Webinar Emails",
"tag_color": "#F5B1FC"
}
],
"warmup_details": {
"status": "ACTIVE",
"total_sent_count": 450,
"total_spam_count": 2,
"warmup_reputation": "95%",
"warmup_key_id": 789,
"warmup_created_at": "2025-01-15T10:30:00.000Z",
"reply_rate": 15,
"blocked_reason": null
},
"campaign_ids": [101, 102, 103]
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "limit must be less than or equal to 100"
}
```
## Usage Notes
The `tags` array is always included in the response. The `campaign_ids` array is only included when `fetch_campaigns=true` is passed as a query parameter.
Passwords are base64 encoded in the response for security. Decode them before use in your SMTP/IMAP clients.
Use filters to find specific accounts:
* Filter by `isSmtpSuccess=false` to find accounts with connection issues
* Filter by `isInUse=false` to find unused accounts
* Filter by `emailWarmupStatus=ACTIVE` to find accounts currently warming up
## Related Endpoints
* [Get Email Account by ID](/api-reference/email-accounts/get-by-id)
* [Get All Tags](/api-reference/email-accounts/tags)
* [Add SMTP Email Account](/api-reference/email-accounts/add-smtp)
* [Update Email Account](/api-reference/email-accounts/update)
# Get Email Account by ID
Source: https://api.smartlead.ai/api-reference/email-accounts/get-by-id
GET https://server.smartlead.ai/api/v1/email-accounts/{email_account_id}/
Retrieve complete configuration, credentials, and warmup details for a specific email account
Returns detailed email account information including SMTP/IMAP credentials (with decoded passwords), warmup statistics, and optionally the list of campaigns using this account.
## Path Parameters
The email account ID to retrieve
## Query Parameters
Your SmartLead API key
If `true`, includes array of campaign IDs using this email account
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/email-accounts/123/?api_key=YOUR_KEY&fetch_campaigns=true"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
account_id = 123
response = requests.get(
f"https://server.smartlead.ai/api/v1/email-accounts/{account_id}/",
params={
"api_key": API_KEY,
"fetch_campaigns": True
}
)
account = response.json()
print(f"Account: {account['from_email']}")
print(f"SMTP Status: {'Connected' if account['is_smtp_success'] else 'Failed'}")
print(f"Warmup Status: {account['warmup_details']['status']}")
if 'campaign_ids' in account:
print(f"Used in {len(account['campaign_ids'])} campaigns")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const accountId = 123;
const params = new URLSearchParams({
api_key: API_KEY,
fetch_campaigns: true
});
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/${accountId}/?${params}`
);
const account = await response.json();
console.log(`Account: ${account.from_email}`);
console.log(`SMTP Status: ${account.is_smtp_success ? 'Connected' : 'Failed'}`);
console.log(`Warmup Status: ${account.warmup_details.status}`);
if (account.campaign_ids) {
console.log(`Used in ${account.campaign_ids.length} campaigns`);
}
```
## Response Fields
Response includes the same fields as Get All Email Accounts, plus detailed warmup configuration and optionally campaign IDs.
Comprehensive warmup details with additional fields
Warmup detail record ID
Warmup status: `ACTIVE`, `INACTIVE`, `PAUSED`
When warmup was initiated
Reply rate percentage for warmup emails
Warmup service key identifier
Reason if warmup is blocked
Total warmup emails sent
Total warmup emails marked as spam
Maximum warmup emails per day
Minimum warmup emails per day
Whether warmup is blocked
Maximum emails allowed per day (warmup + campaign)
Warmup reputation score (0-100)
Array of campaign IDs using this email account (only if `fetch_campaigns=true`)
## Response Codes
Email account retrieved successfully
Invalid or missing API key
Email account not found or you don't have access to it
Server error occurred
```json 200 - Success theme={null}
{
"id": 123,
"created_at": "2025-01-15T10:30:00.000Z",
"updated_at": "2025-11-26T08:00:00.000Z",
"user_id": 456,
"from_name": "John Doe",
"from_email": "john@example.com",
"username": "john@example.com",
"password": "decrypted_password",
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"smtp_port_type": "TLS",
"message_per_day": 50,
"is_smtp_success": true,
"is_imap_success": true,
"type": "GMAIL",
"daily_sent_count": 25,
"client_id": null,
"warmup_details": {
"id": 789,
"status": "ACTIVE",
"created_at": "2025-01-15T10:30:00.000Z",
"reply_rate": 15,
"warmup_key_id": 1001,
"blocked_reason": null,
"total_sent_count": 450,
"total_spam_count": 2,
"warmup_max_count": 30,
"warmup_min_count": 10,
"is_warmup_blocked": false,
"max_email_per_day": 50,
"warmup_reputation": 95
},
"campaign_ids": [101, 102, 103]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Email account not found"
}
```
## Usage Notes
This endpoint returns decoded passwords in plain text. Use HTTPS and secure storage when handling this sensitive data.
Use `fetch_campaigns=true` to see which campaigns are using this email account before making changes or deletions.
## Related Endpoints
* [Get All Email Accounts](/api-reference/email-accounts/get-all)
* [Update Email Account](/api-reference/email-accounts/update)
* [Update Warmup Settings](/api-reference/email-accounts/warmup-settings)
# Suspend Email Account
Source: https://api.smartlead.ai/api-reference/email-accounts/suspend
PUT https://server.smartlead.ai/api/v1/email-accounts/suspend/{email_account_id}
Temporarily suspend an email account from all sending activities including campaigns and warmup
Suspending an email account prevents it from sending any emails in campaigns or warmup while keeping the account configuration intact. This is useful for troubleshooting issues or temporarily pausing an account without deletion.
## Path Parameters
The email account ID to suspend
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X PUT "https://server.smartlead.ai/api/v1/email-accounts/suspend/123?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
account_id = 123
response = requests.put(
f"https://server.smartlead.ai/api/v1/email-accounts/suspend/{account_id}",
params={"api_key": API_KEY}
)
result = response.json()
if result.get('success'):
print(f"Email account {account_id} suspended successfully")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const accountId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/suspend/${accountId}?api_key=${API_KEY}`,
{ method: 'PUT' }
);
const result = await response.json();
if (result.success) {
console.log(`Email account ${accountId} suspended successfully`);
}
```
## Response Codes
Email account suspended successfully
Invalid account ID or account not found
Invalid or missing API key
Server error occurred
```json 200 - Success theme={null}
{
"success": true,
"message": "Email account suspended successfully",
"data": {
"accountId": 123,
"isSuspended": true
}
}
```
```json 400 - Account Not Found theme={null}
{
"success": false,
"message": "Email account not found or does not belong to you"
}
```
```json 400 - Invalid ID theme={null}
{
"success": false,
"message": "Valid account ID is required"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
## Suspension Behavior
When an email account is suspended:
* The `is_suspended` flag is set to `true`
* The account stops sending campaign emails immediately
* Warmup emails are also paused
* The account remains in campaign configurations but won't be used for sending
* All account data and configurations are preserved
Use suspension instead of deletion when you need to:
* Temporarily troubleshoot connection issues
* Pause an account during maintenance
* Test campaign performance without this account
* Investigate deliverability problems
## Related Endpoints
* [Unsuspend Email Account](/api-reference/email-accounts/unsuspend)
* [Delete Email Account](/api-reference/email-accounts/delete) - Permanent removal
* [Get Email Account by ID](/api-reference/email-accounts/get-by-id)
# Get All Tags
Source: https://api.smartlead.ai/api-reference/email-accounts/tags
GET https://server.smartlead.ai/api/v1/email-accounts/tags
Retrieve all inbox tags belonging to the authenticated user
Returns all tags created by the user, independent of which email accounts they are assigned to. Use this to get a master list of available tags for filtering or display purposes.
## Query Parameters
Your SmartLead API key for authentication
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/email-accounts/tags?api_key=YOUR_API_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/email-accounts/tags",
params={"api_key": API_KEY}
)
tags = response.json()
for tag in tags:
print(f"Tag: {tag['name']} (ID: {tag['id']}, Color: {tag['color']})")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/tags?api_key=${API_KEY}`
);
const tags = await response.json();
tags.forEach(tag => {
console.log(`Tag: ${tag.name} (ID: ${tag.id}, Color: ${tag.color})`);
});
```
## Response Fields
The response is an array of tag objects:
Unique tag identifier
Tag display name
Tag color as a hex code (e.g., `#B1FCCF`)
## Response Codes
Tags retrieved successfully
Invalid or missing API key
Server error occurred
```json 200 - Success theme={null}
[
{
"id": 10,
"name": "Winners",
"color": "#B1FCCF"
},
{
"id": 15,
"name": "Webinar Emails",
"color": "#F5B1FC"
},
{
"id": 22,
"name": "High Priority",
"color": "#FCB1B1"
}
]
```
```json 401 - Unauthorized theme={null}
{
"ok": false,
"message": "User authentication required."
}
```
```json 500 - Internal Server Error theme={null}
{
"error": "Failed to fetch email account tags."
}
```
## Related Endpoints
* [Get All Email Accounts](/api-reference/email-accounts/get-all)
* [Get Email Account by ID](/api-reference/email-accounts/get-by-id)
# Unsuspend Email Account
Source: https://api.smartlead.ai/api-reference/email-accounts/unsuspend
DELETE https://server.smartlead.ai/api/v1/email-accounts/unsuspend/{email_account_id}
Reactivate a suspended email account and restore sending capabilities
Unsuspending an email account restores it to active status, allowing it to be used for campaign emails and warmup. The account resumes participating in email rotations across all associated campaigns.
## Path Parameters
The email account ID to unsuspend
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/email-accounts/unsuspend/123?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
account_id = 123
response = requests.delete(
f"https://server.smartlead.ai/api/v1/email-accounts/unsuspend/{account_id}",
params={"api_key": API_KEY}
)
result = response.json()
if result.get('success'):
print(f"Email account {account_id} unsuspended and reactivated")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const accountId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/unsuspend/${accountId}?api_key=${API_KEY}`,
{ method: 'DELETE' }
);
const result = await response.json();
if (result.success) {
console.log(`Email account ${accountId} unsuspended and reactivated`);
}
```
## Response Codes
Email account unsuspended successfully
Invalid account ID or account not found
Invalid or missing API key
Server error occurred
```json 200 - Success theme={null}
{
"success": true,
"message": "Email account unsuspended successfully",
"data": {
"accountId": 123,
"isSuspended": false
}
}
```
```json 400 - Account Not Found theme={null}
{
"success": false,
"message": "Email account not found or does not belong to you"
}
```
```json 400 - Invalid ID theme={null}
{
"success": false,
"message": "Valid account ID is required"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
## Reactivation Behavior
When an email account is unsuspended:
* The `is_suspended` flag is set to `false`
* The account immediately becomes available for campaign email sending
* Warmup resumes if previously enabled
* The account rejoins email rotation in all associated campaigns
* Scheduled emails can be sent from this account
After unsuspending an account, verify:
* SMTP/IMAP connections are still valid
* Warmup settings are appropriate for resuming
* Daily sending limits are correctly configured
## Related Endpoints
* [Suspend Email Account](/api-reference/email-accounts/suspend)
* [Get Email Account by ID](/api-reference/email-accounts/get-by-id)
* [Update Email Account](/api-reference/email-accounts/update)
# Update Email Account
Source: https://api.smartlead.ai/api-reference/email-accounts/update
POST https://server.smartlead.ai/api/v1/email-accounts/{email_account_id}
Update email account settings including sending limits, tracking domain, signature, and client association
Updates specific email account settings without requiring re-authentication. Use this endpoint to modify daily limits, custom domains, signatures, and other non-credential settings.
## Path Parameters
The email account ID to update
## Query Parameters
Your SmartLead API key
## Request Body
Maximum emails allowed per day (including warmup and campaign emails)
Display name for outgoing emails
Custom domain for tracking links (e.g., "track.yourdomain.com")
BCC email address for all outgoing emails
Email signature HTML
Client ID to associate this email account with (for multi-tenant accounts)
Minimum time to wait between emails in minutes
Whether to suspend or unsuspend the account
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/123?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"max_email_per_day": 60,
"from_name": "John Doe - Sales",
"custom_tracking_url": "track.example.com",
"signature": "Best regards,
John Doe
Sales Manager
",
"time_to_wait_in_mins": 10
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
account_id = 123
payload = {
"max_email_per_day": 60,
"from_name": "John Doe - Sales",
"custom_tracking_url": "track.example.com",
"signature": "Best regards,
John Doe
Sales Manager
",
"time_to_wait_in_mins": 10
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/email-accounts/{account_id}",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
if result.get('ok'):
print(f"Email account {account_id} updated successfully")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const accountId = 123;
const payload = {
max_email_per_day: 60,
from_name: 'John Doe - Sales',
custom_tracking_url: 'track.example.com',
signature: 'Best regards,
John Doe
Sales Manager
',
time_to_wait_in_mins: 10
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/${accountId}?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
if (result.ok) {
console.log(`Email account ${accountId} updated successfully`);
}
```
## Response Codes
Email account updated successfully
Invalid or missing API key
Email account not found or you don't have access to it
Invalid field values
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"message": "Email account updated successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Email account not found"
}
```
## Usage Notes
All fields are optional - only include the fields you want to update. Omitted fields remain unchanged.
Use this endpoint to:
* Adjust daily sending limits as your account reputation improves
* Add or update email signatures
* Configure custom tracking domains
* Change BCC settings for compliance
To update SMTP/IMAP credentials or connection settings, use the Add SMTP Email Account endpoint with the account ID included to perform an update instead.
## Related Endpoints
* [Get Email Account by ID](/api-reference/email-accounts/get-by-id)
* [Add SMTP Email Account](/api-reference/email-accounts/add-smtp) - For credential updates
* [Suspend Email Account](/api-reference/email-accounts/suspend)
# Update Warmup Settings
Source: https://api.smartlead.ai/api-reference/email-accounts/warmup-settings
POST https://server.smartlead.ai/api/v1/email-accounts/{email_account_id}/warmup
Configure email warmup parameters to gradually build sender reputation
Email warmup helps establish sender reputation by gradually increasing daily email volume. Configure warmup to start with low volumes and progressively increase to avoid being flagged as spam.
## Path Parameters
The email account ID to configure warmup for
## Query Parameters
Your SmartLead API key
## Request Body
Whether to enable or disable warmup for this account
Number of warmup emails to send per day (minimum: 1, maximum: 50)
Daily increase in warmup email count (minimum: 5, maximum: 20)
Target reply rate percentage for warmup emails (minimum: 20, maximum: 100)
Warmup service key identifier
Whether to automatically adjust warmup volume based on performance
Whether to enable gradual rampup of warmup volume
```bash cURL theme={null}
# Enable warmup with configuration
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/123/warmup?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"warmup_enabled": true,
"total_warmup_per_day": 20,
"daily_rampup": 5,
"reply_rate_percentage": 30,
"auto_adjust_warmup": true,
"is_rampup_enabled": true
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
account_id = 123
# Enable warmup
payload = {
"warmup_enabled": True,
"total_warmup_per_day": 20,
"daily_rampup": 5,
"reply_rate_percentage": 30,
"auto_adjust_warmup": True,
"is_rampup_enabled": True
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/email-accounts/{account_id}/warmup",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
if result.get('ok'):
print(f"Warmup configured: {payload['total_warmup_per_day']} emails/day")
# Disable warmup
disable_payload = {"warmup_enabled": False}
response = requests.post(
f"https://server.smartlead.ai/api/v1/email-accounts/{account_id}/warmup",
params={"api_key": API_KEY},
json=disable_payload
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const accountId = 123;
// Enable warmup
const payload = {
warmup_enabled: true,
total_warmup_per_day: 20,
daily_rampup: 5,
reply_rate_percentage: 30,
auto_adjust_warmup: true,
is_rampup_enabled: true
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/${accountId}/warmup?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
if (result.ok) {
console.log(`Warmup configured: ${payload.total_warmup_per_day} emails/day`);
}
```
## Response Codes
Warmup settings updated successfully
Invalid or missing API key
Email account not found
Invalid parameter values (check min/max ranges)
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"message": "Warmup settings updated successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "total_warmup_per_day must be less than or equal to 50"
}
```
## Warmup Best Practices
**Recommended Settings for New Accounts:**
* Start with `total_warmup_per_day: 10-15`
* Set `daily_rampup: 5` to increase gradually
* Target `reply_rate_percentage: 25-30%`
* Enable `auto_adjust_warmup: true` for automatic optimization
**Warmup Timeline:**
* Week 1: 10-15 emails/day
* Week 2: 15-25 emails/day
* Week 3: 25-40 emails/day
* Week 4+: 40-50 emails/day
The `daily_rampup` automatically increases volume each day until reaching `total_warmup_per_day`.
Setting `total_warmup_per_day` too high for new accounts can trigger spam filters. Start conservatively and increase gradually based on warmup reputation scores.
## Related Endpoints
* [Get Warmup Stats](/api-reference/email-accounts/warmup-stats)
* [Get Email Account by ID](/api-reference/email-accounts/get-by-id)
* [Add SMTP Email Account](/api-reference/email-accounts/add-smtp)
# Get Warmup Statistics
Source: https://api.smartlead.ai/api-reference/email-accounts/warmup-stats
GET https://server.smartlead.ai/api/v1/email-accounts/{email_account_id}/warmup-stats
Retrieve daily warmup performance statistics for the past 7 days
Returns warmup email statistics for the last 7 days including emails sent, spam count, and daily performance metrics. Use this to monitor warmup progress and reputation building.
## Path Parameters
The email account ID to retrieve warmup stats for
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/email-accounts/123/warmup-stats?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
account_id = 123
response = requests.get(
f"https://server.smartlead.ai/api/v1/email-accounts/{account_id}/warmup-stats",
params={"api_key": API_KEY}
)
stats = response.json()
print(f"Total warmup emails sent: {stats.get('total_sent', 0)}")
print(f"Spam count: {stats.get('spam_count', 0)}")
print(f"Daily breakdown:")
for day in stats.get('daily_stats', []):
print(f" {day['date']}: {day['sent']} sent, {day['spam']} spam")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const accountId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/email-accounts/${accountId}/warmup-stats?api_key=${API_KEY}`
);
const stats = await response.json();
console.log(`Total warmup emails sent: ${stats.total_sent || 0}`);
console.log(`Spam count: ${stats.spam_count || 0}`);
// Display daily breakdown
if (stats.daily_stats) {
console.log('Daily breakdown:');
stats.daily_stats.forEach(day => {
console.log(` ${day.date}: ${day.sent} sent, ${day.spam} spam`);
});
}
```
## Response Codes
Warmup statistics retrieved successfully
Invalid or missing API key
Email account not found or you don't have access to it
Server error occurred or warmup service unavailable
```json 200 - Success theme={null}
{
"total_sent": 140,
"spam_count": 3,
"reputation_score": 95,
"daily_stats": [
{
"date": "2025-11-20",
"sent": 15,
"spam": 0,
"delivered": 15,
"opened": 12,
"replied": 4
},
{
"date": "2025-11-21",
"sent": 18,
"spam": 1,
"delivered": 17,
"opened": 14,
"replied": 5
},
{
"date": "2025-11-22",
"sent": 20,
"spam": 0,
"delivered": 20,
"opened": 16,
"replied": 6
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"message": "Email account not found",
"status": "error"
}
```
## Usage Notes
Statistics are automatically aggregated for the last 7 days from the current date. The endpoint provides a snapshot of recent warmup performance to help you assess sender reputation progress.
Monitor these key metrics:
* **Spam count** should remain very low (\< 2% of total sent)
* **Reputation score** should steadily increase toward 90-100
* **Reply count** indicates healthy engagement with warmup emails
If spam count is high or reputation is declining, consider:
* Reducing `total_warmup_per_day` temporarily
* Checking DNS records (SPF, DKIM, DMARC)
* Reviewing email content quality
* Contacting support if issues persist
## Related Endpoints
* [Update Warmup Settings](/api-reference/email-accounts/warmup-settings)
* [Get Email Account by ID](/api-reference/email-accounts/get-by-id)
* [Suspend Email Account](/api-reference/email-accounts/suspend)
# Block Email Domains
Source: https://api.smartlead.ai/api-reference/inbox/block-domains
POST https://server.smartlead.ai/api/v1/master-inbox/block-domains
Block one or more email domains to prevent future outreach
Prevent emails to specific domains. Essential for managing bounces, spam complaints, and invalid domains across all campaigns.
## Overview
Blocks one or more email domains system-wide to prevent future outreach. Useful for bounce management, spam complaint handling, and maintaining sender reputation.
**Block Effects:**
* No future emails sent to blocked domains
* Applies across ALL campaigns
* Existing leads marked appropriately
* Can be unblocked later via domain block list management
**Common Block Sources:**
* `manual`: User-initiated block
* `bounce`: Auto-block from hard bounces
* `complaint`: Spam complaints
* `invalid`: Email validation failures
## Query Parameters
Your SmartLead API key
## Request Body
Array of domain strings to block (minimum 1 domain)
Examples: `["spam.com", "invalid.com", "bounces.net"]`
Block source for tracking: `manual`, `bounce`, `complaint`, or `invalid`
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/block-domains?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"domains": ["spam.com", "invalid.com"],
"source": "manual"
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def block_domains(domains, source="manual"):
"""Block multiple domains at once"""
payload = {
"domains": domains,
"source": source
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/block-domains",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
print(f"✅ Blocked {len(domains)} domain(s)")
return response.json()
# Block spam domains
block_domains(["spam.com", "junk.net"], source="manual")
# Auto-block bounced domains
bounced_domains = ["bounced1.com", "bounced2.com"]
block_domains(bounced_domains, source="bounce")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function blockDomains(domains, source = 'manual') {
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/block-domains?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ domains, source })
}
);
return response.json();
}
// Block multiple domains
await blockDomains(['spam.com', 'invalid.com'], 'manual');
```
## Response Example
```json 200 - Success theme={null}
{
"success": true,
"message": "Domains blocked successfully",
"data": {
"blocked_domains": ["spam.com", "invalid.com"],
"source": "manual",
"blocked_at": "2025-01-20T15:30:00Z"
}
}
```
```json 422 - Validation Error theme={null}
{
"error": "domains array must contain at least 1 domain"
}
```
## Related Endpoints
* [Get Domain Block List](/api-reference/utilities/domain-block-list)
# Create Lead Note
Source: https://api.smartlead.ai/api-reference/inbox/create-note
POST https://server.smartlead.ai/api/v1/master-inbox/create-note
Add a note to a lead's record for team collaboration and context
Document important lead information and share context with your team. Essential for collaboration, call notes, and maintaining lead history.
## Overview
Adds a note to a lead's record for team collaboration and historical tracking.
**Use Cases:**
* Document call outcomes
* Record meeting notes
* Share lead insights with team
* Track qualification details
* Add context for handoffs
## Query Parameters
Your SmartLead API key
## Request Body
Lead-campaign mapping ID
Note content
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/create-note?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_lead_map_id": 2433664091,
"note_message": "Called lead - interested in Q2 2025 rollout. Follow up end of Jan."
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def create_note(lead_map_id, note):
payload = {
"email_lead_map_id": lead_map_id,
"note_message": note
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/create-note",
params={"api_key": API_KEY},
json=payload
)
return response.json()
# Add call notes
create_note(
2433664091,
"Spoke with decision maker. Budget approved $50k. Next step: demo."
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function createNote(leadMapId, note) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/create-note?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email_lead_map_id: leadMapId,
note_message: note
})
}
);
return response.json();
}
await createNote(2433664091, 'Meeting scheduled for Jan 25');
```
## Related Endpoints
* [Create Task](/api-reference/inbox/create-task)
* [Update Category](/api-reference/inbox/update-category)
# Create Lead Task
Source: https://api.smartlead.ai/api-reference/inbox/create-task
POST https://server.smartlead.ai/api/v1/master-inbox/create-task
Create a task associated with a lead for follow-up management
Create actionable tasks linked to leads. Essential for managing follow-ups, tracking action items, and team collaboration.
## Overview
Creates a task associated with a specific lead to track follow-up actions and ensure nothing falls through the cracks.
## Query Parameters
Your SmartLead API key
## Request Body
Lead-campaign mapping ID
Task title/name
Detailed task notes (optional)
Task priority: `LOW`, `MEDIUM`, or `HIGH`
Due date in ISO 8601 format (optional)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/create-task?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_lead_map_id": 2433664091,
"name": "Schedule demo call",
"description": "Lead interested in enterprise plan",
"priority": "HIGH",
"due_date": "2025-01-25T14:00:00Z"
}'
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
def create_task(lead_map_id, name, description="", priority="MEDIUM", due_date=None):
"""Create a task for lead follow-up"""
payload = {
"email_lead_map_id": lead_map_id,
"name": name,
"description": description,
"priority": priority,
"due_date": due_date
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/create-task",
params={"api_key": API_KEY},
json=payload
)
return response.json()
# Create high-priority task due tomorrow
tomorrow = (datetime.now() + timedelta(days=1)).replace(hour=14, minute=0).isoformat() + 'Z'
create_task(
lead_map_id=2433664091,
name="Schedule demo call",
description="Lead expressed interest in enterprise features",
priority="HIGH",
due_date=tomorrow
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function createTask(leadMapId, name, options = {}) {
const payload = {
email_lead_map_id: leadMapId,
name: name,
description: options.description || '',
priority: options.priority || 'MEDIUM',
due_date: options.dueDate || null
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/create-task?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
return response.json();
}
// Create task
await createTask(2433664091, 'Follow up on pricing', {
description: 'Lead requested custom pricing',
priority: 'HIGH',
dueDate: '2025-01-25T14:00:00Z'
});
```
## Response Example
```json 200 - Success theme={null}
{
"success": true,
"message": "Task created successfully",
"data": {
"task_id": 789,
"email_lead_map_id": 2433664091,
"name": "Schedule demo call",
"priority": "HIGH",
"due_date": "2025-01-25T14:00:00Z"
}
}
```
## Related Endpoints
* [Create Note](/api-reference/inbox/create-note)
* [Set Reminder](/api-reference/inbox/set-reminder)
# Forward Email
Source: https://api.smartlead.ai/api-reference/inbox/forward
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/forward-email
Forward an email to other recipients
Forward email threads to colleagues or external recipients. Maintains original context and thread history.
## Overview
Forwards an email to specified recipients. Useful for collaboration, escalation, and sharing important conversations.
**Use Cases:**
* Escalate to manager/supervisor
* Share with team members
* Forward to subject matter expert
* Loop in decision makers
* External referrals
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Message ID to forward
Email stats ID
Comma-separated recipient email addresses.
Custom HTML or plain-text body prepended above the auto-generated forwarded message chain. Mirrors the "compose" textbox in the Global Inbox UI when forwarding from the app. When omitted, only the auto-generated forwarded chain is sent.
Custom subject line for the forwarded email. Overrides the original campaign's subject when provided. When omitted, the original campaign subject is used.
Optional comma-separated CC recipient email addresses.
Optional comma-separated BCC recipient email addresses.
`forward_email_body`, `forward_email_subject`, `cc_emails`, and `bcc_emails` are optional. Existing integrations that send only `message_id`, `stats_id`, and `to_emails` are fully backwards-compatible — behaviour is unchanged when these fields are omitted.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/12345/forward-email?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"message_id": "msg-abc-123",
"stats_id": "stats-abc-123",
"to_emails": "manager@company.com,sales@company.com",
"cc_emails": "teamlead@company.com",
"bcc_emails": "audit@company.com",
"forward_email_subject": "FYI – please review",
"forward_email_body": "Sharing this thread for your visibility.
"
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def forward_email(
campaign_id,
message_id,
stats_id,
to_emails,
forward_email_body=None,
forward_email_subject=None,
cc_emails=None,
bcc_emails=None,
):
"""Forward an email to other recipients"""
payload = {
"message_id": message_id,
"stats_id": stats_id,
"to_emails": to_emails,
}
if forward_email_body is not None:
payload["forward_email_body"] = forward_email_body
if forward_email_subject is not None:
payload["forward_email_subject"] = forward_email_subject
if cc_emails is not None:
payload["cc_emails"] = cc_emails
if bcc_emails is not None:
payload["bcc_emails"] = bcc_emails
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/forward-email",
params={"api_key": API_KEY},
json=payload,
)
return response.json()
# Forward with default subject and body (backwards-compatible)
forward_email(
campaign_id=12345,
message_id="msg-abc-123",
stats_id="stats-abc-123",
to_emails="manager@company.com",
)
# Forward with custom subject and body
forward_email(
campaign_id=12345,
message_id="msg-abc-124",
stats_id="stats-abc-124",
to_emails="sales@company.com,support@company.com",
cc_emails="teamlead@company.com",
bcc_emails="audit@company.com",
forward_email_subject="FYI – please review",
forward_email_body="Sharing this thread for your visibility.
",
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function forwardEmail(campaignId, body) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/forward-email?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
}
);
return response.json();
}
// Forward with default subject and body (backwards-compatible)
await forwardEmail(12345, {
message_id: 'msg-abc-123',
stats_id: 'stats-abc-123',
to_emails: 'manager@company.com',
});
// Forward with custom subject and body
await forwardEmail(12345, {
message_id: 'msg-abc-124',
stats_id: 'stats-abc-124',
to_emails: 'sales@company.com,support@company.com',
cc_emails: 'teamlead@company.com',
bcc_emails: 'audit@company.com',
forward_email_subject: 'FYI – please review',
forward_email_body: 'Sharing this thread for your visibility.
',
});
```
## Response Example
```json 200 - Success theme={null}
{
"ok": true,
"messageId": "",
"status": "success"
}
```
```json 400 - Validation Error theme={null}
{
"statusCode": 400,
"error": "Bad Request",
"message": "\"forward_email_body\" must be a string"
}
```
```json 500 - Internal Server Error theme={null}
{
"ok": false,
"error": "Email account not found!",
"status": "error"
}
```
## Related Endpoints
* [Reply to Email](/api-reference/inbox/reply)
* [Get Inbox Messages](/api-reference/inbox/get-messages)
# Get Archived Emails
Source: https://api.smartlead.ai/api-reference/inbox/get-archived
POST https://server.smartlead.ai/api/v1/master-inbox/archived
Retrieve archived conversations removed from active inbox
Access archived emails for historical reference and reporting. Maintains clean inbox while preserving complete email history.
## Overview
Retrieves emails that have been archived. Archiving removes conversations from active inbox while maintaining searchable history.
**Archive Triggers:**
* Manual user archival
* Auto-archive after campaign completion
* Lead status change to closed/lost
* Bulk archive operations
## Query Parameters
Your SmartLead API key
Include full thread history
## Request Body
Pagination offset
Records per page (1-20)
Standard inbox filters - campaignId max 5, emailAccountId max 10
`REPLY_TIME_DESC` or `SENT_TIME_DESC`
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/archived?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"filters": {"campaignId": 12345}, "limit": 20}'
```
```python Python theme={null}
import requests
# Get archived emails from completed campaign
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/archived",
params={"api_key": "YOUR_API_KEY"},
json={"filters": {"campaignId": 12345, "emailStatus": "Replied"}}
)
archived = response.json()
print(f"Archived: {archived.get('total_count', 0)} emails")
```
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages)
# Get Assigned to Me
Source: https://api.smartlead.ai/api-reference/inbox/get-assigned
POST https://server.smartlead.ai/api/v1/master-inbox/assigned-me
Retrieve all emails and conversations assigned to the authenticated user
View your personalized inbox showing only leads and conversations assigned to you. Essential for team collaboration and individual accountability.
## Overview
Retrieves all emails assigned to the authenticated user across all campaigns. This endpoint provides a personalized view for team members to focus on their assigned leads.
**Key Features**:
* Personalized inbox view for individual team members
* Same comprehensive filtering as other inbox endpoints
* Track assigned lead performance and engagement
* Enable accountability in team-based campaigns
**Use Cases**:
* **Individual dashboards**: Show team members only their assigned work
* **Performance tracking**: Monitor individual team member metrics
* **Load balancing**: View current assignment distribution
* **Task management**: Track follow-ups on assigned leads
## Query Parameters
Your SmartLead API key
Include full email thread history. Set to `true` to get complete conversation context.
## Request Body
Number of records to skip for pagination. Must be non-negative.
Number of records to return per page. Must be between 1 and 20.
Advanced filtering options
Search term to filter emails by lead email, name, or content. Max 30 characters.
Filter by lead category assignment
Include leads without category assignment
Include leads with category assignment
Exclude specific category IDs (max 10 items)
Include only specific category IDs (max 10 items)
Filter by email engagement status. Valid values: `Opened`, `Clicked`, `Replied`, `Unsubscribed`, `Bounced`, `Accepted`, `Not Replied`
Filter by specific campaign ID (single value only for this endpoint)
Filter by specific email account ID (single value only)
Filter by specific team member ID (single value only)
Filter by campaign tag ID (single value only)
Filter by client ID (single value only)
Date range filter for reply times. Array of 2 ISO 8601 datetime strings: `["2025-01-01T00:00:00Z", "2025-01-31T23:59:59Z"]`
Sort order for results
* `REPLY_TIME_DESC`: Most recent replies first (default)
* `SENT_TIME_DESC`: Most recently sent emails first
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/assigned-me?api_key=YOUR_KEY&fetch_message_history=false" \
-H "Content-Type: application/json" \
-d '{
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"isAssigned": true,
"categoryIdsIn": [1]
},
"replyTimeBetween": ["2025-01-01T00:00:00Z", "2025-01-31T23:59:59Z"]
},
"sortBy": "REPLY_TIME_DESC"
}'
```
```python Python theme={null}
import requests
from datetime import datetime
API_KEY = "YOUR_API_KEY"
# Get my assigned leads that replied this month
payload = {
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"isAssigned": True,
"categoryIdsIn": [1] # Interested category
},
"replyTimeBetween": [
"2025-01-01T00:00:00Z",
"2025-01-31T23:59:59Z"
]
},
"sortBy": "REPLY_TIME_DESC"
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/assigned-me",
params={
"api_key": API_KEY,
"fetch_message_history": False
},
json=payload
)
result = response.json()
print(f"Found {result.get('total_count', 0)} assigned leads")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Get my assigned leads that replied this month
const payload = {
offset: 0,
limit: 20,
filters: {
emailStatus: 'Replied',
leadCategories: {
isAssigned: true,
categoryIdsIn: [1] // Interested category
},
replyTimeBetween: [
'2025-01-01T00:00:00Z',
'2025-01-31T23:59:59Z'
]
},
sortBy: 'REPLY_TIME_DESC'
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/assigned-me?api_key=${API_KEY}&fetch_message_history=false`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`Found ${result.total_count} assigned leads`);
```
## Response Codes
Request successful - assigned emails retrieved
Invalid or missing API key
Invalid request parameters (e.g., limit > 20, invalid date format)
Server error occurred
```json 200 - Success theme={null}
{
"messages": [
{
"id": "msg_123",
"campaign_lead_map_id": "2433664091",
"lead": {
"email": "john@company.com",
"first_name": "John",
"last_name": "Doe"
},
"campaign": {
"id": 12345,
"name": "Q1 2025 Outreach"
},
"last_message": {
"subject": "Re: Partnership Opportunity",
"body": "I'm interested in learning more...",
"received_at": "2025-01-15T14:30:00Z"
},
"email_status": "Replied",
"category": {
"id": 1,
"name": "Interested"
},
"assigned_to": {
"id": 456,
"name": "Jane Smith"
},
"is_read": false
}
],
"total_count": 1,
"offset": 0,
"limit": 20
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "limit must be between 1 and 20"
}
```
## Common Workflows
### Daily Task Check
```python theme={null}
# Get all my unread assigned leads
payload = {
"filters": {
"emailStatus": "Replied",
"leadCategories": {"isAssigned": True}
},
"limit": 20
}
response = get_assigned_me(payload)
```
### Hot Leads Follow-up
```python theme={null}
# Get interested leads assigned to me
payload = {
"filters": {
"leadCategories": {
"isAssigned": True,
"categoryIdsIn": [1] # Interested
}
},
"sortBy": "REPLY_TIME_DESC"
}
response = get_assigned_me(payload)
```
### Campaign-Specific View
```python theme={null}
# See my assigned leads in specific campaign
payload = {
"filters": {
"campaignId": 12345
},
"limit": 20
}
response = get_assigned_me(payload)
```
## Performance Tips
1. **Use pagination**: Default limit of 20 is optimal for response time
2. **Disable message history**: Set `fetch_message_history=false` for list views
3. **Filter smartly**: Combine filters to reduce result set
4. **Sort appropriately**: Use `REPLY_TIME_DESC` for action-oriented views
## Related Endpoints
* [Update Team Member](/api-reference/inbox/update-team-member) - Reassign leads
* [Get Inbox Messages](/api-reference/inbox/get-messages) - All inbox replies
* [Update Lead Category](/api-reference/inbox/update-category) - Categorize leads
# Get Inbox Item by ID
Source: https://api.smartlead.ai/api-reference/inbox/get-by-id
GET https://server.smartlead.ai/api/v1/master-inbox/{id}
Fetch a specific master inbox item by its unique identifier
Retrieve detailed information about a single email thread including all messages, lead data, and metadata. Essential for deep linking and detailed conversation views.
## Overview
Fetches a specific master inbox item by ID. Returns complete thread information without needing complex filters.
**Use Cases:**
* Direct navigation to specific conversation
* Deep linking from notifications/emails
* Conversation detail views
* Share specific threads with team
## Path Parameters
The unique identifier of the master inbox item. This is the `campaign_lead_map_id` from other inbox endpoints.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/master-inbox/2433664091?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
inbox_item_id = 2433664091
response = requests.get(
f"https://server.smartlead.ai/api/v1/master-inbox/{inbox_item_id}",
params={"api_key": API_KEY}
)
item = response.json()
print(f"Lead: {item['lead']['email']}")
print(f"Campaign: {item['campaign']['name']}")
print(f"Status: {item['email_status']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const inboxItemId = 2433664091;
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/${inboxItemId}?api_key=${API_KEY}`
);
const item = await response.json();
console.log(`Conversation with ${item.lead.email}`);
```
## Response Example
```json 200 - Success theme={null}
{
"id": "msg_abc123",
"campaign_lead_map_id": "2433664091",
"lead": {
"email": "john@company.com",
"first_name": "John",
"last_name": "Doe",
"company": "ACME Corp"
},
"campaign": {
"id": 12345,
"name": "Q1 Outreach"
},
"message_history": [
{
"subject": "Partnership Opportunity",
"direction": "outbound",
"sent_at": "2025-01-15T10:00:00Z"
},
{
"subject": "Re: Partnership Opportunity",
"direction": "inbound",
"received_at": "2025-01-20T14:00:00Z"
}
],
"email_status": "Replied",
"category": {"id": 1, "name": "Interested"}
}
```
```json 404 - Not Found theme={null}
{
"error": "Inbox item not found with ID 2433664091"
}
```
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages)
* [Reply to Message](/api-reference/inbox/reply)
# Get Important Emails
Source: https://api.smartlead.ai/api-reference/inbox/get-important
POST https://server.smartlead.ai/api/v1/master-inbox/important
Retrieve emails marked as important to prioritize high-value conversations
Access your starred/important emails in one view. Essential for prioritizing high-value leads and urgent conversations that need immediate attention.
## Overview
Retrieves all emails marked as important by users or automatically flagged by the system. This endpoint helps you focus on the most critical conversations and high-value leads.
**Key Features**:
* Quick access to flagged important conversations
* Same comprehensive filtering as other inbox endpoints
* Combine manual flags with automatic importance scoring
* Priority queue for urgent follow-ups
**Importance Criteria**:
* **Manual flags**: User-starred messages
* **High-value indicators**: Enterprise leads, large deal sizes
* **Urgent keywords**: "Urgent", "ASAP", "Budget approved"
* **VIP contacts**: Tagged as important accounts
* **Executive responses**: C-level replies
**Common Use Cases**:
* **VIP management**: Track high-value account communications
* **Urgent response queue**: Handle time-sensitive requests
* **Deal pipeline**: Monitor active opportunities
* **Executive visibility**: Surface C-level conversations
* **Team priorities**: Share important leads across team
## Query Parameters
Your SmartLead API key
Include full email thread history
* `false`: Only latest message (recommended for list views)
* `true`: Complete conversation thread
## Request Body
Number of records to skip for pagination
Number of records per page (1-20)
Advanced filtering options
Search term (max 30 characters)
Filter by lead category
Include uncategorized leads
Include categorized leads
Exclude categories (max 10)
Include only specific categories (max 10)
Email engagement status: `Opened`, `Clicked`, `Replied`, `Unsubscribed`, `Bounced`, `Accepted`, `Not Replied`
Campaign ID(s) - max 5 campaigns
Email account ID(s) - max 10 accounts
Team member ID(s) - max 10 members
Campaign tag ID(s) - max 10 tags
Client ID(s) - max 10 clients
Date range: `["start_datetime", "end_datetime"]` in ISO 8601 format
Sort order: `REPLY_TIME_DESC` or `SENT_TIME_DESC`
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/important?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"categoryIdsIn": [1, 2]
}
},
"sortBy": "REPLY_TIME_DESC"
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
# Get important interested leads that replied
payload = {
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"categoryIdsIn": [1, 2] # Interested, Meeting Request
},
"campaignTagId": 5 # VIP tag
},
"sortBy": "REPLY_TIME_DESC"
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/important",
params={"api_key": API_KEY, "fetch_message_history": False},
json=payload
)
result = response.json()
print(f"🌟 {result.get('total_count', 0)} important replies")
for msg in result.get('messages', []):
lead = msg['lead']
category = msg.get('category', {}).get('name', 'Uncategorized')
print(f" {lead['email']} - {category}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Get today's important replies
async function getTodayImportantReplies() {
const today = new Date();
today.setHours(0, 0, 0, 0);
const payload = {
filters: {
emailStatus: 'Replied',
replyTimeBetween: [
today.toISOString(),
new Date().toISOString()
]
},
sortBy: 'REPLY_TIME_DESC',
limit: 20
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/important?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`⭐ ${result.total_count} important replies today`);
return result;
}
```
## Response Example
```json 200 - Success theme={null}
{
"messages": [
{
"id": "msg_important_456",
"campaign_lead_map_id": "2433664091",
"lead": {
"email": "ceo@bigcorp.com",
"first_name": "Sarah",
"last_name": "Williams",
"title": "CEO",
"company": "BigCorp Inc"
},
"campaign": {
"id": 12345,
"name": "Enterprise Outreach"
},
"last_message": {
"subject": "Re: Strategic Partnership",
"body": "This looks very promising. Can we set up a call with my team?",
"received_at": "2025-01-20T10:30:00Z"
},
"email_status": "Replied",
"category": {
"id": 2,
"name": "Meeting Request"
},
"is_important": true,
"importance_score": 95,
"tags": ["enterprise", "c-level", "hot-lead"]
}
],
"total_count": 1
}
```
## Common Workflows
### VIP Daily Digest
```python theme={null}
def get_vip_daily_digest():
"""Generate daily digest of important VIP interactions"""
from datetime import datetime, timedelta
today_start = datetime.now().replace(hour=0, minute=0, second=0)
payload = {
"filters": {
"emailStatus": "Replied",
"campaignTagId": 5, # VIP tag
"replyTimeBetween": [
today_start.isoformat() + 'Z',
datetime.now().isoformat() + 'Z'
]
},
"sortBy": "REPLY_TIME_DESC"
}
response = get_important_emails(payload)
messages = response.get('messages', [])
print(f"📊 VIP Daily Digest - {len(messages)} interactions\n")
for msg in messages:
lead = msg['lead']
category = msg.get('category', {}).get('name', 'Uncategorized')
print(f"⭐ {lead.get('title', '')} at {lead.get('company', '')}")
print(f" {lead['email']} - {category}")
print(f" {msg['last_message']['subject']}\n")
return messages
```
### Executive Visibility Report
```python theme={null}
def generate_executive_report():
"""Create executive summary of important conversations"""
payload = {
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"categoryIdsIn": [1, 2] # Interested, Meeting Request
}
},
"limit": 20
}
response = get_important_emails(payload)
messages = response.get('messages', [])
# Categorize by type
meeting_requests = [m for m in messages
if m.get('category', {}).get('id') == 2]
interested_leads = [m for m in messages
if m.get('category', {}).get('id') == 1]
print("🎯 Executive Summary - Important Conversations")
print(f" Total: {len(messages)}")
print(f" Meeting Requests: {len(meeting_requests)}")
print(f" Interested Leads: {len(interested_leads)}")
# List top priorities
print("\n🔥 Top Priorities:")
for i, msg in enumerate(messages[:5], 1):
print(f" {i}. {msg['lead']['company']} - {msg['last_message']['subject']}")
```
### Importance Scoring
```python theme={null}
def score_and_flag_important(lead_map_id, criteria):
"""Auto-score and flag leads as important based on criteria"""
score = 0
reasons = []
# Scoring rules
if criteria.get('title') in ['CEO', 'CTO', 'VP', 'Director']:
score += 30
reasons.append("C-level/VP")
if criteria.get('company_size') == 'enterprise':
score += 25
reasons.append("Enterprise")
if criteria.get('deal_size', 0) > 50000:
score += 20
reasons.append("High deal value")
if criteria.get('response_time_hours', 999) < 4:
score += 15
reasons.append("Quick response")
if 'budget' in criteria.get('message_body', '').lower():
score += 10
reasons.append("Budget mentioned")
# Flag as important if score > 50
if score >= 50:
flag_as_important(lead_map_id)
print(f"⭐ Flagged as important (score: {score})")
print(f" Reasons: {', '.join(reasons)}")
return True
return False
```
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages) - All replies
* [Get Unread Replies](/api-reference/inbox/get-unread) - Unread messages
* [Get Assigned to Me](/api-reference/inbox/get-assigned) - Your assigned leads
# Get Inbox Replies
Source: https://api.smartlead.ai/api-reference/inbox/get-messages
POST https://server.smartlead.ai/api/v1/master-inbox/inbox-replies
Retrieve all lead replies across all campaigns in your unified inbox
Your central hub for all lead responses across campaigns. Essential for managing conversations, tracking engagement, and ensuring no reply goes unnoticed.
## Overview
Retrieves all replies from leads across all campaigns in your unified inbox. This is the primary endpoint for managing all incoming responses from your outreach efforts.
**Key Features**:
* Unified view of all replies across campaigns
* Optional full message history retrieval
* Comprehensive filtering by campaign, account, team, tags, clients
* Lead category filtering
* Date range and engagement status filtering
* Flexible sorting options
**Use Cases**:
* **Response management**: Central inbox for all campaign replies
* **Team collaboration**: Filter by assigned team members
* **Performance tracking**: Monitor reply rates and patterns
* **Lead qualification**: Filter by category and engagement
* **Client reporting**: Segment replies by client
* **Follow-up workflows**: Identify leads needing attention
## Query Parameters
Your SmartLead API key
Include full email thread history.
* `true`: Returns complete conversation thread (slower, more data)
* `false`: Returns only latest message (faster, recommended for list views)
**Performance tip**: Use `false` for list views, `true` only when viewing individual conversations.
## Request Body
Number of records to skip for pagination. Must be non-negative.
Number of records to return per page. Must be between 1 and 20.
Advanced filtering options
Search term to filter replies by lead email, name, or message content.
Maximum 30 characters.
Filter by lead category assignment
Include leads without category assignment
Include leads with category assignment
Exclude specific category IDs (max 10 items)
Include only specific category IDs (max 10 items)
Filter by email engagement status. Can be a single status or array.
Valid values: `Opened`, `Clicked`, `Replied`, `Unsubscribed`, `Bounced`, `Accepted`, `Not Replied`
Examples:
* Single: `"Replied"`
* Multiple: `["Replied", "Clicked"]`
Filter by campaign ID(s).
* Single: `12345`
* Multiple: `[12345, 12346, 12347]` (max 5 campaigns for this endpoint)
Filter by email account ID(s).
* Single: `789`
* Multiple: `[789, 790, 791, ...]` (max 20 accounts)
Filter by assigned team member(s).
* Single: `456`
* Multiple: `[456, 457, 458]` (max 10 members)
Filter by campaign tag(s).
* Single: `5`
* Multiple: `[5, 6, 7]` (max 10 tags)
Filter by client ID(s).
* Single: `100`
* Multiple: `[100, 101, 102]` (max 10 clients)
Filter by reply date range. Array of 2 ISO 8601 datetime strings.
Format: `["start_datetime", "end_datetime"]`
Example: `["2025-01-01T00:00:00Z", "2025-01-31T23:59:59Z"]`
Sort order for results
* `REPLY_TIME_DESC`: Most recent replies first (default)
* `SENT_TIME_DESC`: Most recently sent emails first
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/inbox-replies?api_key=YOUR_KEY&fetch_message_history=false" \
-H "Content-Type: application/json" \
-d '{
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"campaignId": [12345, 12346],
"leadCategories": {
"categoryIdsIn": [1]
}
},
"sortBy": "REPLY_TIME_DESC"
}'
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
# Example 1: Get today's replies from interested leads
today_start = datetime.now().replace(hour=0, minute=0, second=0).isoformat() + 'Z'
now = datetime.now().isoformat() + 'Z'
payload = {
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"categoryIdsIn": [1] # Interested category
},
"replyTimeBetween": [today_start, now]
},
"sortBy": "REPLY_TIME_DESC"
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/inbox-replies",
params={
"api_key": API_KEY,
"fetch_message_history": False # Fast list view
},
json=payload
)
result = response.json()
print(f"Today's interested replies: {result.get('total_count', 0)}")
# Process each reply
for message in result.get('messages', []):
lead = message['lead']
last_msg = message['last_message']
print(f"\n{lead['email']}: {last_msg['subject']}")
print(f"Replied at: {last_msg['received_at']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Example 2: Get unread replies with full message history
async function getUnreadReplies() {
const payload = {
offset: 0,
limit: 20,
filters: {
emailStatus: 'Replied',
// Add more filters as needed
},
sortBy: 'REPLY_TIME_DESC'
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/inbox-replies?api_key=${API_KEY}&fetch_message_history=true`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
// Process replies with full conversation context
for (const message of result.messages || []) {
console.log(`\n${message.lead.email}`);
if (message.message_history) {
console.log(` Thread length: ${message.message_history.length} messages`);
// Display full conversation
message.message_history.forEach((msg, idx) => {
console.log(` ${idx + 1}. [${msg.direction}] ${msg.subject}`);
});
}
}
return result;
}
getUnreadReplies();
```
```python Advanced: Multi-Campaign Comparison theme={null}
# Example 3: Compare reply rates across campaigns
campaigns_to_compare = [12345, 12346, 12347]
results_by_campaign = {}
for campaign_id in campaigns_to_compare:
payload = {
"filters": {
"campaignId": campaign_id,
"emailStatus": "Replied"
},
"limit": 20
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/inbox-replies",
params={"api_key": API_KEY, "fetch_message_history": False},
json=payload
)
data = response.json()
results_by_campaign[campaign_id] = {
'total_replies': data.get('total_count', 0),
'messages': data.get('messages', [])
}
# Analyze results
for campaign_id, data in results_by_campaign.items():
print(f"Campaign {campaign_id}: {data['total_replies']} replies")
```
## Response Codes
Request successful - inbox replies retrieved
Invalid or missing API key
Request validation failed. Common issues:
* `limit` > 20
* More than 5 campaign IDs
* More than 20 email account IDs
* More than 10 items in other array filters
* Invalid date format
Server error occurred
```json 200 - Success (without message history) theme={null}
{
"messages": [
{
"id": "msg_xyz789",
"campaign_lead_map_id": "2433664091",
"lead": {
"email": "sarah@startup.io",
"first_name": "Sarah",
"last_name": "Johnson",
"company": "Startup Inc",
"phone": "+1-555-0100"
},
"campaign": {
"id": 12345,
"name": "Q1 2025 SaaS Outreach"
},
"email_account": {
"id": 789,
"email": "sales@yourcompany.com",
"name": "Sales Team"
},
"last_message": {
"id": "email_abc123",
"subject": "Re: Partnership Opportunity",
"body": "Thanks for reaching out! I'm interested in learning more about your solution...",
"received_at": "2025-01-20T14:30:00Z",
"sent_from": "sarah@startup.io",
"sent_to": "sales@yourcompany.com"
},
"email_status": "Replied",
"category": {
"id": 1,
"name": "Interested"
},
"assigned_to": {
"id": 456,
"name": "Jane Smith",
"email": "jane@yourcompany.com"
},
"stats": {
"total_sent": 3,
"total_opened": 2,
"total_clicked": 1,
"total_replied": 1,
"last_activity": "2025-01-20T14:30:00Z"
},
"is_read": false,
"is_important": false,
"is_archived": false,
"tags": ["hot-lead", "enterprise"]
}
],
"total_count": 1,
"offset": 0,
"limit": 20
}
```
```json 200 - Success (with message history) theme={null}
{
"messages": [
{
"id": "msg_xyz789",
"campaign_lead_map_id": "2433664091",
"lead": {...},
"last_message": {...},
"message_history": [
{
"id": "msg_1",
"subject": "Partnership Opportunity",
"body": "Hi Sarah, I noticed your company...",
"direction": "outbound",
"sent_at": "2025-01-15T10:00:00Z",
"opened_at": "2025-01-15T10:30:00Z"
},
{
"id": "msg_2",
"subject": "Re: Partnership Opportunity",
"body": "Thanks for reaching out! I'm interested...",
"direction": "inbound",
"received_at": "2025-01-20T14:30:00Z"
}
],
"email_status": "Replied",
"...": "..."
}
],
"total_count": 1
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "campaignId array cannot exceed 5 items",
"field": "filters.campaignId",
"provided_count": 10,
"max_allowed": 5
}
```
## Common Workflows
### Daily Inbox Check
```python theme={null}
def check_daily_inbox():
"""Get all unread replies from today"""
today_start = datetime.now().replace(hour=0, minute=0, second=0).isoformat() + 'Z'
now = datetime.now().isoformat() + 'Z'
payload = {
"filters": {
"emailStatus": "Replied",
"replyTimeBetween": [today_start, now]
},
"sortBy": "REPLY_TIME_DESC",
"limit": 20
}
response = get_inbox_replies(payload, fetch_history=False)
unread = [msg for msg in response['messages'] if not msg['is_read']]
print(f"{len(unread)} unread replies today")
return unread
```
### Priority Lead Follow-up
```python theme={null}
def get_hot_leads():
"""Get interested leads that replied recently"""
three_days_ago = (datetime.now() - timedelta(days=3)).isoformat() + 'Z'
payload = {
"filters": {
"leadCategories": {
"categoryIdsIn": [1, 2] # Interested, Meeting Request
},
"replyTimeBetween": [three_days_ago, datetime.now().isoformat() + 'Z']
},
"sortBy": "REPLY_TIME_DESC"
}
return get_inbox_replies(payload)
```
### Team Workload Distribution
```python theme={null}
def get_team_workload(team_member_ids):
"""Check reply counts for each team member"""
workload = {}
for member_id in team_member_ids:
payload = {
"filters": {
"campaignTeamMemberId": member_id,
"emailStatus": "Replied"
},
"limit": 1 # Just need count
}
response = get_inbox_replies(payload)
workload[member_id] = response.get('total_count', 0)
return workload
```
### Campaign Performance Monitor
```python theme={null}
def monitor_campaign_replies(campaign_ids, start_date, end_date):
"""Track reply metrics across campaigns"""
payload = {
"filters": {
"campaignId": campaign_ids[:5], # Max 5
"replyTimeBetween": [start_date, end_date]
},
"limit": 20
}
response = get_inbox_replies(payload)
messages = response.get('messages', [])
# Calculate metrics
metrics = {
'total_replies': len(messages),
'interested': len([m for m in messages
if m.get('category', {}).get('id') == 1]),
'by_campaign': {}
}
for msg in messages:
campaign_id = msg['campaign']['id']
if campaign_id not in metrics['by_campaign']:
metrics['by_campaign'][campaign_id] = 0
metrics['by_campaign'][campaign_id] += 1
return metrics
```
## Message History vs List View
### When to Use `fetch_message_history=false` (Recommended)
* ✅ **List views**: Displaying inbox overview
* ✅ **Counting replies**: Just need totals
* ✅ **Quick filtering**: Finding specific leads
* ✅ **Dashboard displays**: Overview metrics
* ✅ **Mobile apps**: Faster loading
* ✅ **Pagination**: Browsing multiple pages
**Performance**: \~10x faster, \~90% less data transferred
### When to Use `fetch_message_history=true`
* ✅ **Conversation view**: Displaying full thread
* ✅ **Reply context**: Need full conversation history
* ✅ **AI analysis**: Processing full threads
* ✅ **Detailed reporting**: Complete interaction data
* ✅ **CRM sync**: Syncing full conversation history
**Trade-off**: Slower response, much more data, but complete context
```python theme={null}
# Fast list view
list_view_response = get_inbox_replies(
payload,
fetch_history=False # Fast
)
# Then fetch details only when user clicks
def view_conversation(message_id):
detailed_response = get_inbox_replies(
{"filters": {"messageId": message_id}},
fetch_history=True # Full context
)
return detailed_response
```
## Filtering Best Practices
### 1. Use Appropriate Array Limits
```python theme={null}
# ✅ GOOD: Within limits
filters = {
"campaignId": [12345, 12346, 12347], # Max 5 OK
"emailAccountId": [1, 2, 3, ..., 20], # Max 20 OK
"campaignTeamMemberId": [10, 11, 12] # Max 10 OK
}
# ❌ BAD: Exceeds limits
filters = {
"campaignId": [1, 2, 3, 4, 5, 6, 7], # ERROR: Max 5
}
```
### 2. Combine Category Filters
```python theme={null}
# Get engaged leads, exclude uninterested
filters = {
"leadCategories": {
"isAssigned": True, # Has a category
"categoryIdsNotIn": [3, 4] # Exclude "Not Interested", "Do Not Contact"
}
}
```
### 3. Smart Date Ranges
```python theme={null}
# Rolling windows for consistent monitoring
def get_recent_replies(days=7):
end = datetime.now()
start = end - timedelta(days=days)
return {
"replyTimeBetween": [
start.isoformat() + 'Z',
end.isoformat() + 'Z'
]
}
```
### 4. Progressive Filtering
```python theme={null}
# Start broad, narrow down based on results
def find_replies_progressive():
# Step 1: Get all replies
payload1 = {"filters": {"emailStatus": "Replied"}}
result1 = get_inbox_replies(payload1)
if result1['total_count'] > 100:
# Step 2: Add time filter
payload2 = {
"filters": {
"emailStatus": "Replied",
"replyTimeBetween": get_recent_replies(7)
}
}
result2 = get_inbox_replies(payload2)
if result2['total_count'] > 50:
# Step 3: Add category filter
payload3 = payload2.copy()
payload3["filters"]["leadCategories"] = {"categoryIdsIn": [1]}
return get_inbox_replies(payload3)
return result2
return result1
```
## Performance Optimization
1. **Disable message history for lists**: 10x faster
2. **Use pagination properly**: Limit=20 is optimal
3. **Filter by campaign/account**: Reduces query scope
4. **Cache frequently accessed data**: Store client-side
5. **Batch similar requests**: Group by filter criteria
6. **Use appropriate sort orders**: Match your use case
## Error Handling
```python theme={null}
def safe_get_inbox_replies(payload, fetch_history=False):
"""Get inbox replies with error handling"""
try:
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/inbox-replies",
params={
"api_key": API_KEY,
"fetch_message_history": fetch_history
},
json=payload,
timeout=30 # 30 second timeout
)
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
if e.response.status_code == 422:
print(f"Validation error: {e.response.json()}")
# Adjust payload and retry
elif e.response.status_code == 429:
print("Rate limited - waiting 60 seconds")
time.sleep(60)
return safe_get_inbox_replies(payload, fetch_history)
else:
print(f"HTTP error: {e}")
except requests.exceptions.Timeout:
print("Request timed out - try with smaller limit or disable message history")
except Exception as e:
print(f"Unexpected error: {e}")
return None
```
## Related Endpoints
* [Get Sent Emails](/api-reference/inbox/get-sent) - All sent emails
* [Get Unread Replies](/api-reference/inbox/get-unread) - Only unread replies
* [Get Assigned to Me](/api-reference/inbox/get-assigned) - My assigned replies
* [Get Important](/api-reference/inbox/get-important) - Flagged replies
* [Mark Read](/api-reference/inbox/mark-read) - Update read status
* [Update Category](/api-reference/inbox/update-category) - Categorize leads
* [Reply to Message](/api-reference/inbox/reply) - Send reply
# Get Reminder Emails
Source: https://api.smartlead.ai/api-reference/inbox/get-reminders
POST https://server.smartlead.ai/api/v1/master-inbox/reminders
Retrieve emails with active reminders sorted by reminder time
Track all emails with reminders set. Essential for follow-up management and ensuring timely responses to important leads.
## Overview
Retrieves emails with active reminders. Unique sorting by reminder time (ascending/descending) helps prioritize upcoming vs overdue reminders.
**Reminder Sorting (Unique to this endpoint):**
* `REMINDER_TIME_DESC`: Most recent/future reminders first
* `REMINDER_TIME_ASC`: Earliest/overdue reminders first (recommended for daily review)
## Query Parameters
Your SmartLead API key
**Note**: This endpoint does NOT support `fetch_message_history` parameter (unlike other inbox endpoints)
## Request Body
Pagination offset
Records per page (1-20)
Filter object with the following optional fields: `search` (string), `campaignId` (number or array, max 5), `emailAccountId` (number or array, max 10), `emailStatus` (string or array — valid values: `Opened`, `Clicked`, `Replied`, `Unsubscribed`, `Bounced`, `Accepted`, `Not Replied`), `leadCategories` (object with `categoryIdsIn`, `categoryIdsNotIn`, `unassigned`, `isAssigned`), `campaignTeamMemberId` (number or array, max 10), `campaignTagId` (number or array, max 10), `campaignClientId` (number or array, max 10), `replyTimeBetween` (array of 2 date strings).
**Unique Sort Options:**
* `REMINDER_TIME_ASC`: Earliest reminders first (overdue → upcoming)
* `REMINDER_TIME_DESC`: Latest reminders first (upcoming → overdue)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/reminders?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"sortBy": "REMINDER_TIME_ASC", "limit": 20}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
# Get overdue reminders first
payload = {
"sortBy": "REMINDER_TIME_ASC", # Oldest first
"limit": 20
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/reminders",
params={"api_key": API_KEY},
json=payload
)
reminders = response.json()
for msg in reminders.get('messages', []):
print(f"⏰ {msg['lead']['email']} - Reminder: {msg['reminder_time']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Get today's due reminders
const payload = {
sortBy: 'REMINDER_TIME_ASC',
limit: 20
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/reminders?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`${result.total_count} reminders`);
```
## Response Example
```json 200 - Success theme={null}
{
"messages": [{
"campaign_lead_map_id": "2433664091",
"lead": {"email": "john@company.com"},
"reminder_time": "2025-01-20T14:00:00Z",
"reminder_message": "Follow up on pricing question",
"is_overdue": false
}],
"total_count": 1
}
```
## Related Endpoints
* [Set Reminder](/api-reference/inbox/set-reminder)
* [Create Task](/api-reference/inbox/create-task)
# Get Scheduled Emails
Source: https://api.smartlead.ai/api-reference/inbox/get-scheduled
POST https://server.smartlead.ai/api/v1/master-inbox/scheduled
Retrieve emails queued for future sending with schedule time sorting
View and manage your scheduled email queue. Essential for reviewing upcoming sends and optimizing send times.
## Overview
Retrieves scheduled emails queued to be sent at a future time. Unique sorting by scheduled time helps manage your outreach pipeline.
**Scheduled Sorting (Unique to this endpoint):**
* `SCHEDULED_TIME_ASC`: Earliest scheduled sends first (next to send)
* `SCHEDULED_TIME_DESC`: Latest scheduled sends first
## Query Parameters
Your SmartLead API key
Include full thread history
## Request Body
Pagination offset
Records per page (1-20)
Standard inbox filters - campaignId max 5, emailAccountId max 10
**Unique Options**: `SCHEDULED_TIME_ASC` or `SCHEDULED_TIME_DESC`
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/scheduled?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"sortBy": "SCHEDULED_TIME_ASC", "limit": 20}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
# Get next scheduled emails
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/scheduled",
params={"api_key": API_KEY},
json={"sortBy": "SCHEDULED_TIME_ASC", "limit": 20}
)
scheduled = response.json()
print(f"Next {len(scheduled.get('messages', []))} scheduled emails")
```
```javascript JavaScript theme={null}
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/scheduled?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({sortBy: 'SCHEDULED_TIME_ASC', limit: 20})
}
);
```
## Response Example
```json 200 theme={null}
{
"messages": [{
"campaign_lead_map_id": "2433664091",
"scheduled_time": "2025-01-21T09:00:00Z",
"email_status": "Scheduled"
}],
"total_count": 1
}
```
## Related Endpoints
* [Get Sent Emails](/api-reference/inbox/get-sent)
* [Get Inbox Messages](/api-reference/inbox/get-messages)
# Get Sent Emails
Source: https://api.smartlead.ai/api-reference/inbox/get-sent
POST https://server.smartlead.ai/api/v1/master-inbox/sent
Retrieve all sent emails across campaigns with comprehensive filtering and pagination
Track all sent emails across your campaigns. Monitor delivery, opens, clicks, and replies. Essential for campaign performance tracking and follow-up management.
## Overview
Retrieves all sent emails from your account with comprehensive filtering options. This endpoint provides a unified view of all outreach activity across campaigns.
**Key Features**:
* Unified view of all sent emails across campaigns
* Track email engagement (opens, clicks, replies)
* Filter by campaign, email account, team member, tags, clients
* Advanced lead category filtering
* Date range filtering for reply tracking
* Pagination and custom sorting
**Common Use Cases**:
* **Performance monitoring**: Track which emails receive replies
* **Follow-up management**: Find emails that haven't received responses
* **Campaign analysis**: Compare performance across campaigns
* **Team reporting**: Filter by team member to track individual activity
* **Client reporting**: Segment by client for account-specific insights
## Query Parameters
Your SmartLead API key
## Request Body
Number of records to skip for pagination. Must be non-negative.
Number of records to return per page. Must be between 1 and 20.
Advanced filtering options to segment your sent emails
Search term to filter emails. Searches across:
* Lead email addresses
* Lead names
* Email content
Maximum 30 characters.
Filter by lead category assignment status and specific categories
Include leads without category assignment. Set to `true` to include uncategorized leads.
Include leads with category assignment. Set to `true` to include categorized leads.
Exclude specific category IDs. Array of numbers, maximum 10 items.
Example: `[3, 4]` to exclude "Not Interested" and "Do Not Contact"
Include only specific category IDs. Array of numbers, maximum 10 items.
Example: `[1, 2]` to show only "Interested" and "Meeting Request"
Filter by email engagement status. Can be a single status or array of statuses.
**Valid statuses**:
* `Opened`: Email was opened by recipient
* `Clicked`: Recipient clicked a link in the email
* `Replied`: Recipient sent a reply
* `Unsubscribed`: Recipient unsubscribed
* `Bounced`: Email bounced (hard or soft)
* `Accepted`: Email was accepted by server
* `Not Replied`: Email was opened but no reply received
**Examples**:
* Single: `"Replied"`
* Multiple: `["Opened", "Clicked", "Replied"]`
Filter by campaign ID(s). Can be a single campaign or array of campaigns.
* Single campaign: `12345`
* Multiple campaigns: `[12345, 12346, 12347]` (max 15 campaigns)
Filter by email account ID(s). Can be a single account or array of accounts.
* Single account: `789`
* Multiple accounts: `[789, 790, 791]` (no limit on array size)
Filter by team member assignment. Can be a single member or array of members.
* Single member: `456`
* Multiple members: `[456, 457, 458]` (no limit on array size)
Filter by campaign tag. Can be a single tag or array of tags.
* Single tag: `5`
* Multiple tags: `[5, 6, 7]` (no limit on array size)
Filter by client ID. Can be a single client or array of clients.
* Single client: `100`
* Multiple clients: `[100, 101, 102]` (no limit on array size)
Filter by reply time date range. Array of 2 ISO 8601 datetime strings.
Format: `["start_datetime", "end_datetime"]`
Example: `["2025-01-01T00:00:00Z", "2025-01-31T23:59:59Z"]`
Sort order for results
* `REPLY_TIME_DESC`: Most recent replies first (default, best for active conversations)
* `SENT_TIME_DESC`: Most recently sent emails first (best for tracking recent outreach)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/sent?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": ["Replied", "Opened"],
"campaignId": [12345, 12346],
"leadCategories": {
"categoryIdsIn": [1]
},
"replyTimeBetween": ["2025-01-01T00:00:00Z", "2025-01-31T23:59:59Z"]
},
"sortBy": "REPLY_TIME_DESC"
}'
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
# Example 1: Get replied emails from last 7 days
seven_days_ago = (datetime.now() - timedelta(days=7)).isoformat() + 'Z'
now = datetime.now().isoformat() + 'Z'
payload = {
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"replyTimeBetween": [seven_days_ago, now],
"leadCategories": {
"categoryIdsIn": [1] # Interested leads only
}
},
"sortBy": "REPLY_TIME_DESC"
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/sent",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(f"Found {result.get('total_count', 0)} interested replies in last 7 days")
for msg in result.get('messages', []):
print(f"- {msg['lead']['email']}: {msg['email_status']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Example 2: Get opened but not replied emails from specific campaign
const payload = {
offset: 0,
limit: 20,
filters: {
emailStatus: ['Opened', 'Clicked'], // Engaged but not replied
campaignId: 12345,
leadCategories: {
unassigned: true // Not yet categorized
}
},
sortBy: 'SENT_TIME_DESC'
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/sent?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`${result.total_count} engaged leads need follow-up`);
```
```python Advanced Filtering Example theme={null}
# Example 3: Multi-campaign performance comparison
payload = {
"filters": {
"campaignId": [12345, 12346, 12347], # Multiple campaigns
"emailStatus": ["Replied", "Opened", "Clicked"],
"campaignTeamMemberId": 456, # Specific team member
"campaignTagId": 5 # VIP tag
},
"limit": 20
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/sent",
params={"api_key": API_KEY},
json=payload
)
# Group by campaign for comparison
results_by_campaign = {}
for msg in response.json().get('messages', []):
campaign_id = msg['campaign']['id']
if campaign_id not in results_by_campaign:
results_by_campaign[campaign_id] = []
results_by_campaign[campaign_id].append(msg)
for campaign_id, messages in results_by_campaign.items():
print(f"Campaign {campaign_id}: {len(messages)} engaged leads")
```
## Response Codes
Request successful - sent emails retrieved
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Request validation failed. Common issues:
* `limit` > 20
* Invalid `emailStatus` value
* Array exceeds maximum length
* Invalid date format in `replyTimeBetween`
Server error occurred. Please try again or contact support if the issue persists.
```json 200 - Success theme={null}
{
"messages": [
{
"id": "msg_abc123",
"campaign_lead_map_id": "2433664091",
"lead": {
"email": "john@company.com",
"first_name": "John",
"last_name": "Doe",
"company": "ACME Corp"
},
"campaign": {
"id": 12345,
"name": "Q1 2025 Outreach"
},
"email_account": {
"id": 789,
"email": "sales@yourcompany.com"
},
"last_message": {
"subject": "Partnership Opportunity",
"sent_at": "2025-01-15T10:00:00Z",
"opened_at": "2025-01-15T10:30:00Z",
"replied_at": "2025-01-15T14:00:00Z"
},
"email_status": "Replied",
"category": {
"id": 1,
"name": "Interested"
},
"assigned_to": {
"id": 456,
"name": "Jane Smith"
},
"stats": {
"opens": 2,
"clicks": 1,
"replies": 1
}
}
],
"total_count": 1,
"offset": 0,
"limit": 20
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "limit must be between 1 and 20",
"field": "limit",
"provided_value": 50
}
```
## Common Workflows
### Daily Reply Check
```python theme={null}
# Get all replies received today
from datetime import datetime
today_start = datetime.now().replace(hour=0, minute=0, second=0).isoformat() + 'Z'
now = datetime.now().isoformat() + 'Z'
payload = {
"filters": {
"emailStatus": "Replied",
"replyTimeBetween": [today_start, now]
},
"sortBy": "REPLY_TIME_DESC"
}
```
### Find Follow-up Opportunities
```python theme={null}
# Emails opened but not replied in last 3 days
three_days_ago = (datetime.now() - timedelta(days=3)).isoformat() + 'Z'
payload = {
"filters": {
"emailStatus": ["Opened", "Clicked"],
"replyTimeBetween": [three_days_ago, now],
"leadCategories": {
"unassigned": True # Not yet categorized
}
}
}
```
### Campaign Performance Audit
```python theme={null}
# Get all campaign activity with engagement metrics
payload = {
"filters": {
"campaignId": [12345, 12346],
"emailStatus": ["Replied", "Opened", "Clicked"]
},
"limit": 20
}
response = get_sent_emails(payload)
# Calculate metrics
total = response['total_count']
replied = len([m for m in response['messages']
if m['email_status'] == 'Replied'])
reply_rate = (replied / total * 100) if total > 0 else 0
print(f"Reply rate: {reply_rate:.2f}%")
```
### Team Member Activity
```python theme={null}
# Track individual team member performance
def get_member_sent_stats(member_id, start_date, end_date):
payload = {
"filters": {
"campaignTeamMemberId": member_id,
"replyTimeBetween": [start_date, end_date]
},
"limit": 20
}
response = get_sent_emails(payload)
messages = response.get('messages', [])
return {
'total_sent': len(messages),
'replied': len([m for m in messages if m['email_status'] == 'Replied']),
'opened': len([m for m in messages if m['email_status'] in ['Opened', 'Clicked']])
}
```
## Filtering Best Practices
### 1. Start Broad, Then Narrow
```python theme={null}
# Step 1: Get all sent emails in campaign
basic_filter = {"campaignId": 12345}
# Step 2: Add engagement filter
engagement_filter = {
"campaignId": 12345,
"emailStatus": ["Replied", "Opened"]
}
# Step 3: Add category filter
interested_filter = {
"campaignId": 12345,
"emailStatus": ["Replied", "Opened"],
"leadCategories": {"categoryIdsIn": [1]}
}
```
### 2. Combine Inclusion and Exclusion
```python theme={null}
# Get engaged leads, excluding "Do Not Contact"
filters = {
"emailStatus": ["Replied", "Opened", "Clicked"],
"leadCategories": {
"categoryIdsNotIn": [4] # Exclude Do Not Contact
}
}
```
### 3. Use Date Ranges Effectively
```python theme={null}
# Rolling 30-day window
end_date = datetime.now()
start_date = end_date - timedelta(days=30)
filters = {
"replyTimeBetween": [
start_date.isoformat() + 'Z',
end_date.isoformat() + 'Z'
]
}
```
### 4. Paginate Large Results
```python theme={null}
def get_all_sent_emails(filters):
"""Fetch all results across multiple pages"""
all_messages = []
offset = 0
limit = 20
while True:
payload = {
"filters": filters,
"offset": offset,
"limit": limit
}
response = get_sent_emails(payload)
messages = response.get('messages', [])
if not messages:
break
all_messages.extend(messages)
offset += limit
# Stop if we've fetched all records
if offset >= response.get('total_count', 0):
break
return all_messages
```
## Performance Optimization
1. **Use appropriate limits**: Default of 20 balances speed and data volume
2. **Filter strategically**: More specific filters = faster queries
3. **Avoid very large date ranges**: Break into smaller chunks
4. **Cache results**: Store frequently accessed data client-side
5. **Use specific campaign/account filters**: Reduces query scope
## Email Status Reference
| Status | Meaning | Follow-up Action |
| -------------- | ------------------------ | ---------------------------- |
| `Accepted` | Email accepted by server | Wait for open/reply |
| `Opened` | Recipient opened email | Consider follow-up |
| `Clicked` | Clicked link in email | High engagement - prioritize |
| `Replied` | Sent a response | Take action immediately |
| `Not Replied` | Opened but no reply | Schedule follow-up |
| `Bounced` | Email failed to deliver | Verify/remove address |
| `Unsubscribed` | Opted out | Do not contact |
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages) - All replies across campaigns
* [Get Unread Replies](/api-reference/inbox/get-unread) - Unread responses
* [Update Lead Category](/api-reference/inbox/update-category) - Categorize leads
* [Create Task](/api-reference/inbox/create-task) - Create follow-up tasks
* [Get Campaign Statistics](/api-reference/campaigns/statistics) - Aggregate metrics
# Get Snoozed Emails
Source: https://api.smartlead.ai/api-reference/inbox/get-snoozed
POST https://server.smartlead.ai/api/v1/master-inbox/snoozed
Retrieve emails temporarily snoozed for later follow-up
Manage inbox overflow by retrieving emails snoozed until a specific time. Helps prioritize immediate tasks while ensuring important conversations resurface automatically.
## Overview
Retrieves snoozed emails that are scheduled to reappear at a later time. Snoozing helps manage inbox load by temporarily hiding emails that don't require immediate attention.
**Key Features:**
* View all snoozed conversations
* Same filtering as other inbox endpoints (max 5 campaigns, max 10 accounts)
* Automatically reappear when snooze expires
* Bulk snooze management
**Use Cases:**
* Waiting for information before responding
* Follow-up after specific event/date
* Reduce immediate inbox clutter
* Schedule review of low-priority leads
## Query Parameters
Your SmartLead API key
Include full email thread history
## Request Body
Pagination offset
Records per page (1-20)
Filter object with the following optional fields: `search` (string), `campaignId` (number or array, max 5), `emailAccountId` (number or array, max 10), `emailStatus` (string or array — valid values: `Opened`, `Clicked`, `Replied`, `Unsubscribed`, `Bounced`, `Accepted`, `Not Replied`), `leadCategories` (object with `categoryIdsIn`, `categoryIdsNotIn`, `unassigned`, `isAssigned`), `campaignTeamMemberId` (number or array, max 10), `campaignTagId` (number or array, max 10), `campaignClientId` (number or array, max 10), `replyTimeBetween` (array of 2 date strings).
`REPLY_TIME_DESC` or `SENT_TIME_DESC`
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/snoozed?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"offset": 0,
"limit": 20,
"filters": {
"campaignId": 12345,
"leadCategories": {"categoryIdsIn": [1]}
}
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
# Get all snoozed emails
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/snoozed",
params={"api_key": API_KEY, "fetch_message_history": False},
json={"offset": 0, "limit": 20, "filters": {}}
)
result = response.json()
print(f"Snoozed emails: {result.get('total_count', 0)}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/snoozed?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({limit: 20, filters: {}})
}
);
const result = await response.json();
console.log(`Snoozed: ${result.total_count}`);
```
## Response Example
```json 200 - Success theme={null}
{
"messages": [{
"campaign_lead_map_id": "2433664091",
"lead": {"email": "john@company.com"},
"snoozed_until": "2025-01-25T09:00:00Z",
"email_status": "Replied"
}],
"total_count": 1
}
```
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages)
* [Get Reminders](/api-reference/inbox/get-reminders)
# Get Unread Replies
Source: https://api.smartlead.ai/api-reference/inbox/get-unread
POST https://server.smartlead.ai/api/v1/master-inbox/unread-replies
Retrieve all unread replies from leads to ensure no important responses are missed
Critical for inbox management - get all unread replies in one view. Essential for ensuring timely responses to leads and preventing missed opportunities.
## Overview
Retrieves all unread replies from leads across all campaigns. This endpoint is essential for maintaining inbox zero and ensuring no lead response goes unnoticed.
**Key Features**:
* Unified view of all unread responses
* Same comprehensive filtering as other inbox endpoints
* Real-time unread count tracking
* Optional full message history
* Priority handling for urgent responses
**Common Use Cases**:
* **Daily inbox review**: Start your day with unread replies
* **Team notifications**: Alert team members of unread messages
* **SLA monitoring**: Track response times on unread messages
* **Priority routing**: Identify high-value unread leads
* **Dashboard metrics**: Display unread count badges
## Query Parameters
Your SmartLead API key
Include full email thread history
* `false`: Only latest message (recommended for list views)
* `true`: Complete conversation thread (use for detail views)
## Request Body
Number of records to skip for pagination. Must be non-negative.
Number of records to return per page. Must be between 1 and 20.
Advanced filtering options to segment unread replies
Search term to filter by lead email, name, or message content. Maximum 30 characters.
Filter by lead category assignment
Include leads without category assignment
Include leads with category assignment
Exclude specific category IDs (max 10 items)
Include only specific category IDs (max 10 items)
Filter by email engagement status. Can be a single status or array.
Valid values: `Opened`, `Clicked`, `Replied`, `Unsubscribed`, `Bounced`, `Accepted`, `Not Replied`
**Note**: For unread endpoint, typically use `Replied` status
Filter by campaign ID(s)
* Single: `12345`
* Multiple: `[12345, 12346, 12347]` (max 5 campaigns)
Filter by email account ID(s)
* Single: `789`
* Multiple: `[789, 790, 791, ...]` (max 10 accounts)
Filter by assigned team member(s)
* Single: `456`
* Multiple: `[456, 457, 458]` (max 10 members)
Filter by campaign tag(s)
* Single: `5`
* Multiple: `[5, 6, 7]` (max 10 tags)
Filter by client ID(s)
* Single: `100`
* Multiple: `[100, 101, 102]` (max 10 clients)
Filter by reply date range. Array of 2 ISO 8601 datetime strings.
Format: `["start_datetime", "end_datetime"]`
Example: `["2025-01-01T00:00:00Z", "2025-01-31T23:59:59Z"]`
Sort order for results
* `REPLY_TIME_DESC`: Most recent replies first (default, recommended)
* `SENT_TIME_DESC`: Most recently sent emails first
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/unread-replies?api_key=YOUR_KEY&fetch_message_history=false" \
-H "Content-Type: application/json" \
-d '{
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"campaignId": [12345, 12346],
"leadCategories": {
"categoryIdsIn": [1]
}
},
"sortBy": "REPLY_TIME_DESC"
}'
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
# Example 1: Get all unread replies from today
today_start = datetime.now().replace(hour=0, minute=0, second=0).isoformat() + 'Z'
now = datetime.now().isoformat() + 'Z'
payload = {
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"replyTimeBetween": [today_start, now]
},
"sortBy": "REPLY_TIME_DESC"
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/unread-replies",
params={
"api_key": API_KEY,
"fetch_message_history": False
},
json=payload
)
result = response.json()
print(f"Unread replies today: {result.get('total_count', 0)}")
# Process each unread reply
for message in result.get('messages', []):
lead = message['lead']
last_msg = message['last_message']
category = message.get('category', {}).get('name', 'Uncategorized')
print(f"\n📧 {lead['email']} ({category})")
print(f" Subject: {last_msg['subject']}")
print(f" Replied: {last_msg['received_at']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Example 2: Get unread high-priority replies
async function getUnreadPriorityReplies() {
const payload = {
offset: 0,
limit: 20,
filters: {
emailStatus: 'Replied',
leadCategories: {
categoryIdsIn: [1, 2] // Interested, Meeting Request
},
campaignTagId: 5 // VIP tag
},
sortBy: 'REPLY_TIME_DESC'
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/unread-replies?api_key=${API_KEY}&fetch_message_history=false`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`🔥 ${result.total_count} high-priority unread replies`);
// Display with urgency indicator
for (const message of result.messages || []) {
const hoursAgo = (Date.now() - new Date(message.last_message.received_at)) / (1000 * 60 * 60);
const urgency = hoursAgo > 24 ? '🚨 URGENT' : hoursAgo > 12 ? '⚠️ HIGH' : '✅ NORMAL';
console.log(`${urgency} - ${message.lead.email}`);
}
return result;
}
getUnreadPriorityReplies();
```
```python Advanced: Team Unread Distribution theme={null}
# Example 3: Check unread count per team member
team_members = [456, 457, 458, 459, 460]
def get_team_unread_distribution(member_ids):
"""Get unread count for each team member"""
distribution = {}
for member_id in member_ids:
payload = {
"filters": {
"campaignTeamMemberId": member_id,
"emailStatus": "Replied"
},
"limit": 1 # Just need count
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/unread-replies",
params={"api_key": API_KEY, "fetch_message_history": False},
json=payload
)
data = response.json()
distribution[member_id] = data.get('total_count', 0)
return distribution
# Get distribution
unread_by_member = get_team_unread_distribution(team_members)
# Display results
print("Team Unread Distribution:")
for member_id, count in sorted(unread_by_member.items(), key=lambda x: x[1], reverse=True):
print(f" Member {member_id}: {count} unread replies")
# Alert if anyone has >20 unread
for member_id, count in unread_by_member.items():
if count > 20:
print(f"⚠️ Alert: Member {member_id} has {count} unread (>20 threshold)")
```
## Response Codes
Request successful - unread replies retrieved
Invalid or missing API key
Request validation failed. Common issues:
* `limit` > 20
* More than 5 campaign IDs
* More than 10 items in other array filters
* Invalid date format
Server error occurred
```json 200 - Success theme={null}
{
"messages": [
{
"id": "msg_unread_123",
"campaign_lead_map_id": "2433664091",
"lead": {
"email": "john@enterprise.com",
"first_name": "John",
"last_name": "Smith",
"company": "Enterprise Corp"
},
"campaign": {
"id": 12345,
"name": "Q1 Enterprise Outreach"
},
"email_account": {
"id": 789,
"email": "sales@yourcompany.com"
},
"last_message": {
"id": "email_abc789",
"subject": "Re: Demo Request",
"body": "Hi, thanks for reaching out. I'd like to schedule a demo for next week...",
"received_at": "2025-01-20T09:15:00Z",
"sent_from": "john@enterprise.com",
"sent_to": "sales@yourcompany.com"
},
"email_status": "Replied",
"category": {
"id": 2,
"name": "Meeting Request"
},
"assigned_to": {
"id": 456,
"name": "Jane Smith"
},
"is_read": false,
"is_important": true,
"tags": ["enterprise", "demo-request"],
"reply_age_hours": 2.5
}
],
"total_count": 1,
"offset": 0,
"limit": 20
}
```
```json 422 - Validation Error theme={null}
{
"error": "campaignId array cannot exceed 5 items",
"field": "filters.campaignId",
"provided_count": 7,
"max_allowed": 5
}
```
## Common Workflows
### Morning Inbox Zero Routine
```python theme={null}
def morning_inbox_check():
"""Start the day by processing unread replies"""
# Get all unread replies
payload = {
"filters": {"emailStatus": "Replied"},
"sortBy": "REPLY_TIME_DESC",
"limit": 20
}
response = get_unread_replies(payload)
unread = response.get('messages', [])
print(f"📬 Good morning! You have {len(unread)} unread replies\n")
# Categorize by priority
high_priority = [m for m in unread if m.get('is_important')]
interested = [m for m in unread
if m.get('category', {}).get('id') == 1]
print(f"🔥 {len(high_priority)} high-priority")
print(f"👍 {len(interested)} interested leads")
print(f"📋 {len(unread) - len(high_priority) - len(interested)} general")
return unread
```
### Real-time Unread Counter
```python theme={null}
def get_unread_count(filters=None):
"""Quick unread count (no message content)"""
payload = {
"filters": filters or {"emailStatus": "Replied"},
"limit": 1 # Minimal data transfer
}
response = get_unread_replies(payload)
return response.get('total_count', 0)
# Usage for dashboard badge
total_unread = get_unread_count()
print(f"Unread badge: {total_unread}")
# By campaign
campaign_unread = get_unread_count({"campaignId": 12345})
print(f"Campaign 12345: {campaign_unread} unread")
```
### Unread SLA Monitor
```python theme={null}
def monitor_unread_sla(sla_hours=24):
"""Alert on unread replies exceeding SLA"""
from datetime import datetime, timedelta
sla_threshold = (datetime.now() - timedelta(hours=sla_hours)).isoformat() + 'Z'
payload = {
"filters": {
"emailStatus": "Replied",
"replyTimeBetween": [
"2000-01-01T00:00:00Z", # Beginning of time
sla_threshold
]
},
"sortBy": "REPLY_TIME_DESC",
"limit": 20
}
response = get_unread_replies(payload)
overdue = response.get('messages', [])
if overdue:
print(f"⚠️ SLA BREACH: {len(overdue)} unread replies over {sla_hours}h old")
for msg in overdue:
hours_old = (datetime.now() -
datetime.fromisoformat(msg['last_message']['received_at'].replace('Z', '+00:00'))).total_seconds() / 3600
print(f" - {msg['lead']['email']}: {hours_old:.1f}h old")
else:
print(f"✅ All unread replies within {sla_hours}h SLA")
return overdue
```
### Priority Triage System
```python theme={null}
def triage_unread_replies():
"""Auto-categorize unread replies by urgency"""
payload = {
"filters": {"emailStatus": "Replied"},
"limit": 20
}
response = get_unread_replies(payload)
messages = response.get('messages', [])
triage = {
'urgent': [], # >24h old, important, or meeting request
'high': [], # Interested category or >12h old
'normal': [], # Everything else
'low': [] # Already categorized as not interested
}
from datetime import datetime
now = datetime.now()
for msg in messages:
hours_old = (now - datetime.fromisoformat(
msg['last_message']['received_at'].replace('Z', '+00:00')
)).total_seconds() / 3600
category_id = msg.get('category', {}).get('id')
is_important = msg.get('is_important', False)
if hours_old > 24 or is_important or category_id == 2:
triage['urgent'].append(msg)
elif category_id == 1 or hours_old > 12:
triage['high'].append(msg)
elif category_id == 3:
triage['low'].append(msg)
else:
triage['normal'].append(msg)
# Display triage results
print("\n📊 Unread Triage Report:")
print(f"🚨 Urgent: {len(triage['urgent'])} - Respond immediately")
print(f"⚠️ High: {len(triage['high'])} - Respond today")
print(f"📋 Normal: {len(triage['normal'])} - Respond within 24h")
print(f"⬇️ Low: {len(triage['low'])} - Can wait")
return triage
```
### Batch Mark as Read
```python theme={null}
def batch_review_unread(limit=10):
"""Review and mark multiple unread as read"""
payload = {
"filters": {"emailStatus": "Replied"},
"sortBy": "REPLY_TIME_DESC",
"limit": limit
}
response = get_unread_replies(payload, fetch_history=True)
messages = response.get('messages', [])
for i, msg in enumerate(messages, 1):
print(f"\n[{i}/{len(messages)}] {msg['lead']['email']}")
print(f"Subject: {msg['last_message']['subject']}")
print(f"Preview: {msg['last_message']['body'][:100]}...")
# Show full thread if available
if msg.get('message_history'):
print(f"Thread: {len(msg['message_history'])} messages")
# Prompt for action (in real app, this would be UI)
action = input("Action [r]ead / [c]ategorize / [s]kip: ")
if action == 'r':
# Mark as read using change-read-status endpoint
mark_as_read(msg['campaign_lead_map_id'])
print("✅ Marked as read")
elif action == 'c':
category = input("Category ID: ")
update_category(msg['campaign_lead_map_id'], int(category))
mark_as_read(msg['campaign_lead_map_id'])
print("✅ Categorized and marked as read")
```
## Filtering Best Practices
### 1. Prioritize by Time
```python theme={null}
# Today's unread (highest priority)
today_unread = {
"filters": {
"emailStatus": "Replied",
"replyTimeBetween": [
datetime.now().replace(hour=0, minute=0).isoformat() + 'Z',
datetime.now().isoformat() + 'Z'
]
}
}
# This week's unread
week_start = (datetime.now() - timedelta(days=7)).isoformat() + 'Z'
week_unread = {
"filters": {
"emailStatus": "Replied",
"replyTimeBetween": [week_start, datetime.now().isoformat() + 'Z']
}
}
```
### 2. Combine Category Filters
```python theme={null}
# Hot unread leads (interested or meeting requests)
hot_unread = {
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"categoryIdsIn": [1, 2] # Interested, Meeting Request
}
}
}
# Unread but not junk
quality_unread = {
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"categoryIdsNotIn": [3, 4] # Exclude Not Interested, Do Not Contact
}
}
}
```
### 3. Team-specific Views
```python theme={null}
# My team's unread
my_team_ids = [456, 457, 458]
team_unread = {
"filters": {
"emailStatus": "Replied",
"campaignTeamMemberId": my_team_ids
}
}
# Unassigned unread (needs triage)
unassigned_unread = {
"filters": {
"emailStatus": "Replied",
"leadCategories": {"unassigned": True}
}
}
```
### 4. Campaign-specific Monitoring
```python theme={null}
# High-value campaign unread
important_campaign_unread = {
"filters": {
"emailStatus": "Replied",
"campaignId": [12345, 12346], # Enterprise campaigns
"campaignTagId": 5 # VIP tag
}
}
```
## Performance Tips
1. **Disable message history for counts**: 10x faster
2. **Use limit=1 for counters**: Minimal data transfer
3. **Filter by campaign**: Reduces query scope
4. **Cache unread count**: Update every 5-10 minutes
5. **Paginate large results**: Limit=20 is optimal
## Real-time Monitoring
```python theme={null}
import time
def monitor_unread_realtime(interval=60):
"""Monitor unread count in real-time"""
previous_count = 0
while True:
current_count = get_unread_count()
if current_count != previous_count:
if current_count > previous_count:
new_replies = current_count - previous_count
print(f"🔔 {new_replies} new unread reply(ies)! Total: {current_count}")
# Fetch the new ones
payload = {
"filters": {"emailStatus": "Replied"},
"limit": new_replies
}
new_messages = get_unread_replies(payload)
# Notify team
for msg in new_messages.get('messages', []):
send_notification(f"New reply from {msg['lead']['email']}")
else:
print(f"✅ Unread count decreased to {current_count}")
previous_count = current_count
time.sleep(interval) # Check every minute
```
## Integration Examples
### Slack Notifications
```python theme={null}
def send_unread_to_slack(webhook_url):
"""Send unread summary to Slack"""
unread = get_unread_count()
if unread > 0:
# Get details
payload = {"filters": {"emailStatus": "Replied"}, "limit": 5}
messages = get_unread_replies(payload).get('messages', [])
slack_message = {
"text": f"📬 You have {unread} unread replies",
"blocks": [
{
"type": "section",
"text": {"type": "mrkdwn", "text": f"*{unread} Unread Replies*"}
}
]
}
# Add top 5
for msg in messages:
slack_message["blocks"].append({
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"• *{msg['lead']['email']}*\n _{msg['last_message']['subject']}_"
}
})
requests.post(webhook_url, json=slack_message)
```
### Dashboard Widget
```python theme={null}
def get_unread_dashboard_data():
"""Get unread data for dashboard display"""
total = get_unread_count()
# Get breakdown by category
interested = get_unread_count({"leadCategories": {"categoryIdsIn": [1]}})
meeting = get_unread_count({"leadCategories": {"categoryIdsIn": [2]}})
uncategorized = get_unread_count({"leadCategories": {"unassigned": True}})
# Get age breakdown
today = get_unread_count({
"replyTimeBetween": [
datetime.now().replace(hour=0, minute=0).isoformat() + 'Z',
datetime.now().isoformat() + 'Z'
]
})
return {
"total": total,
"by_category": {
"interested": interested,
"meeting_request": meeting,
"uncategorized": uncategorized
},
"by_age": {
"today": today,
"older": total - today
}
}
```
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages) - All replies (read + unread)
* [Mark Read Status](/api-reference/inbox/mark-read) - Mark as read/unread
* [Get Important](/api-reference/inbox/get-important) - Flagged messages
* [Get Assigned to Me](/api-reference/inbox/get-assigned) - Your assigned replies
* [Update Category](/api-reference/inbox/update-category) - Categorize leads
* [Reply to Message](/api-reference/inbox/reply) - Send reply
# Get Untracked Replies
Source: https://api.smartlead.ai/api-reference/inbox/get-untracked
GET https://server.smartlead.ai/api/v1/master-inbox/untracked-replies
Retrieve replies not tracked by SmartLead campaigns
Discover email replies not associated with your SmartLead campaigns. Essential for finding manual outreach responses, forwarded conversations, and historical emails.
## Overview
Retrieves untracked email replies - messages received in connected email accounts that aren't linked to active campaigns.
**Untracked Reply Sources:**
* Manual emails sent outside SmartLead
* Forwarded conversations
* Replies to emails sent before tracking started
* Non-campaign communications
## Query Parameters
Your SmartLead API key
Results per page (1-100)
Pagination offset
Include attachment metadata. **Performance tip**: Keep false for list views
Include full email body. **Performance tip**: Keep false for list views
Filter by sender email address
Filter by recipient email address
Filter by email subject line (partial match)
```bash cURL theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/master-inbox/untracked-replies?api_key=YOUR_KEY&limit=20&fetchBody=false"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
# Get untracked replies with minimal data
params = {
"api_key": API_KEY,
"limit": 20,
"offset": 0,
"fetchAttachments": False,
"fetchBody": False
}
response = requests.get(
"https://server.smartlead.ai/api/v1/master-inbox/untracked-replies",
params=params
)
untracked = response.json()
print(f"Untracked replies: {untracked.get('total_count', 0)}")
# Get details for specific email
params_detailed = {
"api_key": API_KEY,
"from_email": "john@company.com",
"fetchBody": True,
"fetchAttachments": True
}
detailed = requests.get(
"https://server.smartlead.ai/api/v1/master-inbox/untracked-replies",
params=params_detailed
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Fast list view (no body/attachments)
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/untracked-replies?` +
`api_key=${API_KEY}&limit=20&fetchBody=false&fetchAttachments=false`
);
const result = await response.json();
console.log(`${result.total_count} untracked replies`);
```
## Response Example
```json 200 - Success theme={null}
{
"untracked_replies": [
{
"id": "untracked_abc123",
"from_email": "john@company.com",
"to_email": "sales@yourcompany.com",
"subject": "Re: Your Product",
"received_at": "2025-01-20T10:30:00Z",
"has_attachments": true,
"body": "(included if fetchBody=true)",
"attachments": "(included if fetchAttachments=true)"
}
],
"total_count": 1
}
```
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages)
# Get Custom View Emails
Source: https://api.smartlead.ai/api-reference/inbox/get-views
POST https://server.smartlead.ai/api/v1/master-inbox/views
Retrieve emails based on saved custom filter views
Access emails using your custom saved views/filters. Create complex filter combinations and save them for quick access to specific inbox segments.
## Overview
Retrieves emails based on custom saved views. This endpoint allows you to create and access sophisticated filter combinations for segmenting your inbox.
**Key Features**:
* Save complex filter combinations as reusable views
* Quick access to frequently used inbox segments
* Additional subsequence filtering capability
* All standard inbox filtering options available
**Common Custom Views**:
* **"Hot Leads"**: Replied + High Priority + Assigned to Me
* **"Follow-up Needed"**: Not Replied + Sent > 3 days ago
* **"Campaign X VIPs"**: Specific campaign + Important flag
* **"Subsequence Tracking"**: Leads in specific subsequence
## Query Parameters
Your SmartLead API key
Include full email thread history
## Request Body
Number of records to skip for pagination
Number of records per page (1-20)
Custom view filter configuration
Search term (max 30 characters)
Lead category filters
Include uncategorized leads
Include categorized leads
Exclude specific category IDs (max 10)
Include only specific category IDs (max 10)
Email engagement status: `Opened`, `Clicked`, `Replied`, `Unsubscribed`, `Bounced`, `Accepted`, `Not Replied`
Filter by campaign ID (single value only for views)
Filter by email account ID (single value)
Filter by team member assignment (single value)
Filter by campaign tag (single value)
Filter by client ID (single value)
**Unique to views**: Filter by subsequence ID to track leads in specific child campaigns
Date range for reply times: `["start_date", "end_date"]` in ISO 8601 format
Sort order: `REPLY_TIME_DESC` or `SENT_TIME_DESC`
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/views?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"offset": 0,
"limit": 20,
"filters": {
"emailStatus": "Replied",
"campaignId": 12345,
"leadCategories": {
"categoryIdsIn": [1]
},
"subSequenceId": 789
},
"sortBy": "REPLY_TIME_DESC"
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
# Example: "Hot Leads in Subsequence" view
hot_leads_view = {
"filters": {
"emailStatus": "Replied",
"campaignId": 12345,
"leadCategories": {
"categoryIdsIn": [1] # Interested
},
"subSequenceId": 789 # Pricing discussion subsequence
},
"sortBy": "REPLY_TIME_DESC",
"limit": 20
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/views",
params={"api_key": API_KEY},
json=hot_leads_view
)
leads = response.json()
print(f"Hot leads in subsequence: {leads.get('total_count', 0)}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Example: "Needs Follow-up" view
const needsFollowupView = {
filters: {
emailStatus: 'Not Replied',
replyTimeBetween: [
new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(),
new Date().toISOString()
]
},
sortBy: 'SENT_TIME_DESC',
limit: 20
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/views?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(needsFollowupView)
}
);
const result = await response.json();
console.log(`Leads needing follow-up: ${result.total_count}`);
```
## Response Codes
Custom view emails retrieved successfully
Invalid API key
Invalid filter parameters
Server error
```json 200 - Success theme={null}
{
"messages": [
{
"id": "msg_456",
"campaign_lead_map_id": "9876543210",
"lead": {
"email": "sarah@startup.io",
"first_name": "Sarah",
"last_name": "Johnson"
},
"campaign": {
"id": 12345,
"name": "SaaS Outreach"
},
"subsequence": {
"id": 789,
"name": "Pricing Discussion"
},
"last_message": {
"subject": "Re: Pricing Question",
"body": "Thanks for the detailed pricing...",
"received_at": "2025-01-20T10:15:00Z"
},
"email_status": "Replied",
"category": {
"id": 1,
"name": "Interested"
}
}
],
"total_count": 1,
"offset": 0,
"limit": 20
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid subSequenceId"
}
```
## Predefined View Examples
### Hot Leads View
```python theme={null}
{
"filters": {
"emailStatus": "Replied",
"leadCategories": {
"categoryIdsIn": [1] # Interested
},
"campaignTeamMemberId": current_user_id
},
"sortBy": "REPLY_TIME_DESC"
}
```
### Needs Follow-up View
```python theme={null}
{
"filters": {
"emailStatus": "Not Replied",
"replyTimeBetween": [
three_days_ago,
now
]
},
"sortBy": "SENT_TIME_DESC"
}
```
### Subsequence Performance View
```python theme={null}
{
"filters": {
"subSequenceId": 789,
"emailStatus": "Replied"
},
"sortBy": "REPLY_TIME_DESC"
}
```
### VIP Campaign View
```python theme={null}
{
"filters": {
"campaignId": 12345,
"campaignTagId": 5, # VIP tag
"leadCategories": {
"isAssigned": True
}
}
}
```
## Subsequence Filtering
The `subSequenceId` filter is unique to this endpoint and allows tracking leads that have been pushed to child campaigns:
```python theme={null}
# Track leads in demo request subsequence
demo_requests = {
"filters": {
"campaignId": main_campaign_id,
"subSequenceId": demo_subsequence_id,
"emailStatus": "Replied"
}
}
# Compare parent vs subsequence performance
parent_responses = get_views({"filters": {"campaignId": main_campaign_id}})
subseq_responses = get_views({"filters": {"subSequenceId": demo_subsequence_id}})
```
## Building Effective Views
### 1. Start Specific, Then Broaden
```python theme={null}
# Start narrow
specific_view = {
"filters": {
"campaignId": 123,
"emailStatus": "Replied",
"leadCategories": {"categoryIdsIn": [1]}
}
}
# If no results, remove constraints
broader_view = {
"filters": {
"campaignId": 123,
"emailStatus": "Replied"
}
}
```
### 2. Combine Time and Status
```python theme={null}
recent_inactive = {
"filters": {
"emailStatus": "Opened", # Opened but not replied
"replyTimeBetween": [last_week, today]
}
}
```
### 3. Multi-Dimension Filtering
```python theme={null}
high_value_prospects = {
"filters": {
"leadCategories": {"categoryIdsIn": [1]}, # Interested
"campaignTagId": vip_tag_id,
"campaignTeamMemberId": senior_rep_id,
"subSequenceId": pricing_discussion_id
}
}
```
## Performance Optimization
1. **Single values preferred**: Use single IDs instead of arrays when possible
2. **Limit subsequence queries**: Subsequence filtering is more intensive
3. **Paginate properly**: Use offset/limit for large result sets
4. **Cache views**: Save frequently used filter combinations client-side
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages) - All replies
* [Push to Subsequence](/api-reference/inbox/push-to-subsequence) - Add leads to subsequence
* [Get By Campaign](/api-reference/leads/get-by-campaign) - Campaign-specific leads
# Change Read Status
Source: https://api.smartlead.ai/api-reference/inbox/mark-read
PATCH https://server.smartlead.ai/api/v1/master-inbox/change-read-status
Mark emails as read or unread
**Deprecated Endpoint**: The old endpoint `PATCH /v1/master-inbox/mark-unread` is deprecated after August 14, 2025. Use this endpoint (`change-read-status`) instead with `read_status: false`.
Manage read/unread status of lead conversations. Essential for inbox organization and tracking which emails need attention.
## Overview
Changes the read/unread status of a lead conversation. Replaces the deprecated `/mark-unread` endpoint with more flexible boolean control.
**Migration from /mark-unread:**
```python theme={null}
# OLD (deprecated after Aug 14, 2025)
PATCH /v1/master-inbox/mark-unread
Body: {"email_lead_map_id": 123}
# NEW (use this)
PATCH /v1/master-inbox/change-read-status
Body: {"email_lead_map_id": 123, "read_status": false}
```
## Query Parameters
Your SmartLead API key
## Request Body
The ID of the lead-campaign mapping. This is the `campaign_lead_map_id` from inbox endpoints.
Target read status:
* `true`: Mark as read
* `false`: Mark as unread
```bash cURL theme={null}
# Mark as read
curl -X PATCH "https://server.smartlead.ai/api/v1/master-inbox/change-read-status?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email_lead_map_id": 2433664091, "read_status": true}'
# Mark as unread
curl -X PATCH "https://server.smartlead.ai/api/v1/master-inbox/change-read-status?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email_lead_map_id": 2433664091, "read_status": false}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def mark_as_read(lead_map_id):
"""Mark email as read"""
payload = {
"email_lead_map_id": lead_map_id,
"read_status": True
}
response = requests.patch(
"https://server.smartlead.ai/api/v1/master-inbox/change-read-status",
params={"api_key": API_KEY},
json=payload
)
return response.json()
def mark_as_unread(lead_map_id):
"""Mark email as unread for later follow-up"""
payload = {
"email_lead_map_id": lead_map_id,
"read_status": False
}
response = requests.patch(
"https://server.smartlead.ai/api/v1/master-inbox/change-read-status",
params={"api_key": API_KEY},
json=payload
)
return response.json()
# Mark as read after reviewing
mark_as_read(2433664091)
# Mark as unread for later
mark_as_unread(2433664092)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function changeReadStatus(leadMapId, isRead) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/change-read-status?api_key=${API_KEY}`,
{
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email_lead_map_id: leadMapId,
read_status: isRead
})
}
);
return response.json();
}
// Mark as read
await changeReadStatus(2433664091, true);
// Mark as unread
await changeReadStatus(2433664092, false);
```
## Response Example
```json 200 - Success theme={null}
{
"success": true,
"message": "Read status updated",
"data": {
"email_lead_map_id": 2433664091,
"is_read": true,
"updated_at": "2025-01-20T15:30:00Z"
}
}
```
```json 422 - Validation Error theme={null}
{
"error": "read_status must be a boolean value"
}
```
## Common Workflows
### Bulk Mark as Read
```python theme={null}
def bulk_mark_as_read(lead_map_ids):
"""Mark multiple emails as read"""
results = []
for lead_id in lead_map_ids:
result = mark_as_read(lead_id)
results.append(result)
return results
# Mark all unread as read
unread = get_unread_replies({})
lead_ids = [msg['campaign_lead_map_id'] for msg in unread['messages']]
bulk_mark_as_read(lead_ids)
```
## Related Endpoints
* [Get Unread Replies](/api-reference/inbox/get-unread)
* [Get Inbox Messages](/api-reference/inbox/get-messages)
# Push Lead to Subsequence
Source: https://api.smartlead.ai/api-reference/inbox/push-to-subsequence
POST https://server.smartlead.ai/api/v1/master-inbox/push-to-subsequence
Move a lead to a subsequence (child campaign) for targeted follow-up
Branch lead into targeted follow-up sequences based on behavior or interest. Essential for sophisticated campaign logic and personalized nurturing.
## Overview
Moves a lead from a parent campaign to a subsequence (child campaign) for specialized follow-up. Enables branching campaign logic based on lead behavior and interests.
**Subsequence Concept:**
* Parent campaign identifies lead interest/behavior
* Lead pushed to specialized subsequence
* Subsequence delivers targeted messaging
* Optional: Stop subsequence if lead replies to parent
**Use Cases:**
1. **Interest-based routing**: Clicked pricing link → Push to "Pricing Discussion" subsequence
2. **Re-engagement**: No reply after 30 days → Push to "Re-engagement" subsequence
3. **Product-specific**: Asked about Feature X → Push to "Feature X Demo" subsequence
4. **Qualification**: High engagement → Push to "Enterprise Sales" subsequence
## Query Parameters
Your SmartLead API key
## Request Body
Lead-campaign mapping ID from parent campaign
Target subsequence (child campaign) ID
Delay in seconds before starting subsequence (min 0, default: immediate)
If `true`, stop subsequence if lead replies to parent campaign
```bash cURL theme={null}
# Push to subsequence with 2-day delay
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/push-to-subsequence?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_lead_map_id": 2433664091,
"sub_sequence_id": 789,
"sub_sequence_delay_time": 172800,
"stop_lead_on_parent_campaign_reply": true
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def push_to_subsequence(lead_map_id, subseq_id, delay_days=0, stop_on_parent_reply=False):
"""Push lead to subsequence with optional delay"""
delay_seconds = delay_days * 24 * 60 * 60
payload = {
"email_lead_map_id": lead_map_id,
"sub_sequence_id": subseq_id,
"sub_sequence_delay_time": delay_seconds,
"stop_lead_on_parent_campaign_reply": stop_on_parent_reply
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/push-to-subsequence",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
print(f"✅ Lead pushed to subsequence {subseq_id}")
if delay_days > 0:
print(f" Will start in {delay_days} days")
return response.json()
# Example: Push to pricing discussion after 2 days
push_to_subsequence(
lead_map_id=2433664091,
subseq_id=789, # Pricing discussion subsequence
delay_days=2,
stop_on_parent_reply=True # Stop if they reply to main campaign
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function pushToSubsequence(leadMapId, subseqId, options = {}) {
const delayDays = options.delayDays || 0;
const delaySeconds = delayDays * 24 * 60 * 60;
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/push-to-subsequence?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email_lead_map_id: leadMapId,
sub_sequence_id: subseqId,
sub_sequence_delay_time: delaySeconds,
stop_lead_on_parent_campaign_reply: options.stopOnParentReply || false
})
}
);
return response.json();
}
// Push to demo request subsequence
await pushToSubsequence(2433664091, 789, {
delayDays: 3,
stopOnParentReply: true
});
```
## Response Example
```json 200 - Success theme={null}
{
"success": true,
"message": "Lead pushed to subsequence successfully",
"data": {
"email_lead_map_id": 2433664091,
"parent_campaign_id": 12345,
"sub_sequence_id": 789,
"will_start_at": "2025-01-22T00:00:00Z",
"stop_on_parent_reply": true
}
}
```
## Subsequence Workflows
### Interest-Based Routing
```python theme={null}
# Lead clicked pricing link
if lead_clicked_pricing:
push_to_subsequence(
lead_map_id,
pricing_discussion_subseq_id,
delay_days=1,
stop_on_parent_reply=True
)
```
### Re-engagement Campaign
```python theme={null}
# No reply after 30 days
if days_since_last_send > 30 and not replied:
push_to_subsequence(
lead_map_id,
reengagement_subseq_id,
delay_days=0,
stop_on_parent_reply=True
)
```
## Related Endpoints
* [Get Custom Views](/api-reference/inbox/get-views) - Filter by subsequence
* [Resume Lead](/api-reference/inbox/resume-lead)
# Reply to Email
Source: https://api.smartlead.ai/api-reference/inbox/reply
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/reply-email-thread
Send a reply to a lead in an email thread
Send replies to leads directly from the inbox. Maintains thread continuity and tracks all responses.
## Overview
Sends a reply email to a lead, maintaining the email thread. Can send immediately or schedule for later.
**Key Features:**
* Thread continuity maintained
* Optional scheduling
* CC/BCC support
* Attachments support
* Signature inclusion
* Reply tracking in conversation history
## Path Parameters
Campaign ID
## Query Parameters
Your SmartLead API key
## Request Body
Email stats ID for the message to reply to
Reply email body content
Recipient email (optional, defaults to lead email)
Recipient first name (optional)
Recipient last name (optional)
Schedule send time (ISO 8601 format)
Message ID being replied to
Original email body being replied to
Original email timestamp
CC recipients (comma-separated)
BCC recipients (comma-separated)
Scheduling condition (optional)
Include email signature
Sequence type (optional)
File attachments array
File name
File URL (required)
MIME type
File size in bytes
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/12345/reply-email-thread?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_stats_id": "abc-123",
"email_body": "Thanks for your interest! Let me know if you have any questions.",
"add_signature": true
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
CAMPAIGN_ID = 12345
def send_reply(campaign_id, email_stats_id, body, schedule_time=None, add_signature=True):
payload = {
"email_stats_id": email_stats_id,
"email_body": body,
"add_signature": add_signature
}
if schedule_time:
payload["scheduled_time"] = schedule_time
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/reply-email-thread",
params={"api_key": API_KEY},
json=payload
)
return response.json()
# Send immediate reply
send_reply(CAMPAIGN_ID, "abc-123", "Thanks for your interest!")
# Schedule reply for tomorrow 9 AM
from datetime import datetime, timedelta
tomorrow_9am = (datetime.now() + timedelta(days=1)).replace(hour=9, minute=0).isoformat() + 'Z'
send_reply(CAMPAIGN_ID, "abc-124", "Following up on our previous conversation", schedule_time=tomorrow_9am)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const CAMPAIGN_ID = 12345;
async function sendReply(campaignId, emailStatsId, body, options = {}) {
const payload = {
email_stats_id: emailStatsId,
email_body: body,
add_signature: options.add_signature !== false,
...options
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/reply-email-thread?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
return response.json();
}
// Send reply
await sendReply(CAMPAIGN_ID, 'abc-123', 'Happy to help!');
```
## Related Endpoints
* [Forward Email](/api-reference/inbox/forward)
* [Get Inbox Messages](/api-reference/inbox/get-messages)
# Get Reply Status
Source: https://api.smartlead.ai/api-reference/inbox/reply-status
GET https://server.smartlead.ai/api/v1/master-inbox/reply-status
Check the delivery status of a sent reply from the unified inbox
Track whether your reply was successfully delivered. Use this to confirm email delivery status and troubleshoot sending issues.
## Overview
Returns the delivery status of a specific reply sent from the master inbox. Use the `message_id` from the email headers to look up the current status of the reply.
**Use Cases**:
* **Delivery confirmation**: Verify that a reply was successfully sent
* **Troubleshooting**: Diagnose delivery failures or delays
* **Automation workflows**: Poll status after sending a reply via API
* **Audit trails**: Track when replies were actually delivered
## Query Parameters
Your SmartLead API key
The email Message-ID header value of the reply you want to check.
This is the RFC 5322 Message-ID assigned to the email, typically in angle bracket format: ``
Example: `<4d9ff292-b7a4-45a1-80aa-e1ac2c925404-133jc7w@dealversego.co>`
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/master-inbox/reply-status?api_key=YOUR_KEY&message_id=%3C4d9ff292-b7a4-45a1-80aa-e1ac2c925404-133jc7w%40dealversego.co%3E"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
MESSAGE_ID = "<4d9ff292-b7a4-45a1-80aa-e1ac2c925404-133jc7w@dealversego.co>"
response = requests.get(
"https://server.smartlead.ai/api/v1/master-inbox/reply-status",
params={
"api_key": API_KEY,
"message_id": MESSAGE_ID
}
)
result = response.json()
if result["ok"]:
data = result["data"]
print(f"Status: {data['status']}")
print(f"Message: {data['status_message']}")
print(f"Delivered at: {data['event_time']}")
else:
print("Failed to retrieve status")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const MESSAGE_ID = '<4d9ff292-b7a4-45a1-80aa-e1ac2c925404-133jc7w@dealversego.co>';
const params = new URLSearchParams({
api_key: API_KEY,
message_id: MESSAGE_ID
});
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/reply-status?${params}`
);
const result = await response.json();
if (result.ok) {
console.log(`Status: ${result.data.status}`);
console.log(`Message: ${result.data.status_message}`);
console.log(`Event time: ${result.data.event_time}`);
}
```
## Response Fields
Whether the request was successful
Reply status details
The email Message-ID that was queried
Delivery status of the reply (e.g., `COMPLETED` when the email was successfully delivered)
Human-readable description of the current status (e.g., `"Email sent successfully!"`)
ISO 8601 timestamp of when the status event occurred (e.g., when the email was delivered)
ISO 8601 timestamp of when the email is scheduled to be sent. `null` if the email was sent immediately.
Internal SmartLead identifier for the email statistics record. Can be used to correlate with other analytics data.
## Response Codes
Request successful — reply status retrieved
Invalid or missing API key
No reply found for the given message\_id
Missing or invalid `message_id` parameter
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"message_id": "<4d9ff292-b7a4-45a1-80aa-e1ac2c925404-133jc7w@dealversego.co>",
"status": "COMPLETED",
"status_message": "Email sent successfully!",
"event_time": "2026-03-12T11:29:05.173Z",
"scheduled_time": null,
"email_stats_id": "4d9ff292-b7a4-45a1-80aa-e1ac2c925404"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"ok": false,
"error": "No reply found for the given message_id"
}
```
## Related Endpoints
* [Reply to Message](/api-reference/inbox/reply) — Send a reply from the inbox
* [Get Inbox Replies](/api-reference/inbox/get-messages) — Get all inbox replies
* [Get Sent Emails](/api-reference/inbox/get-sent) — View all sent emails
# Resume Paused Lead
Source: https://api.smartlead.ai/api-reference/inbox/resume-lead
PATCH https://server.smartlead.ai/api/v1/master-inbox/resume-lead
Resume a paused lead in a campaign with optional delay
Re-engage paused or stopped leads in your campaigns. Optionally add a delay before resuming the email sequence.
## Overview
Resumes a paused lead in a campaign sequence, optionally adding a delay before restarting.
**Use Cases:**
* Lead requested follow-up later
* Re-engage cold leads
* Resume after temporary pause
* Add to nurture sequence after delay
## Query Parameters
Your SmartLead API key
## Request Body
Campaign ID to resume lead in
Lead-campaign mapping ID
Optional delay in days before resuming (min 0, default immediate)
```bash cURL theme={null}
# Resume immediately
curl -X PATCH "https://server.smartlead.ai/api/v1/master-inbox/resume-lead?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaign_id": 12345,
"email_lead_map_id": 2433664091,
"resume_delay_days": 0
}'
# Resume after 7 days
curl -X PATCH "https://server.smartlead.ai/api/v1/master-inbox/resume-lead?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaign_id": 12345,
"email_lead_map_id": 2433664091,
"resume_delay_days": 7
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def resume_lead(campaign_id, lead_map_id, delay_days=0):
"""Resume paused lead with optional delay"""
payload = {
"campaign_id": campaign_id,
"email_lead_map_id": lead_map_id,
"resume_delay_days": delay_days
}
response = requests.patch(
"https://server.smartlead.ai/api/v1/master-inbox/resume-lead",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
if delay_days > 0:
print(f"✅ Lead will resume in {delay_days} days")
else:
print("✅ Lead resumed immediately")
return response.json()
# Resume immediately
resume_lead(12345, 2433664091, delay_days=0)
# Resume after 30-day pause
resume_lead(12345, 2433664092, delay_days=30)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function resumeLead(campaignId, leadMapId, delayDays = 0) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/resume-lead?api_key=${API_KEY}`,
{
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
campaign_id: campaignId,
email_lead_map_id: leadMapId,
resume_delay_days: delayDays
})
}
);
return response.json();
}
// Resume after 7 days
await resumeLead(12345, 2433664091, 7);
```
## Response Example
```json 200 - Success theme={null}
{
"success": true,
"message": "Lead resumed successfully",
"data": {
"campaign_id": 12345,
"email_lead_map_id": 2433664091,
"resume_delay_days": 7,
"will_resume_at": "2025-01-27T00:00:00Z"
}
}
```
## Related Endpoints
* [Pause Lead](/api-reference/leads/pause)
* [Push to Subsequence](/api-reference/inbox/push-to-subsequence)
# Set Lead Reminder
Source: https://api.smartlead.ai/api-reference/inbox/set-reminder
POST https://server.smartlead.ai/api/v1/master-inbox/set-reminder
Set a reminder for a specific lead conversation
Schedule reminders for lead follow-ups. Ensures timely responses and prevents leads from going cold.
## Overview
Sets a reminder for a specific lead conversation. Reminders trigger email/push notifications at the specified time.
**Features:**
* Email/push notifications at reminder time
* Appears in reminders inbox view
* Multiple reminders per lead supported
* Edit or cancel before trigger
## Query Parameters
Your SmartLead API key
## Request Body
Lead-campaign mapping ID
Specific email/message ID to set reminder for
Reminder note/description
Reminder timestamp in ISO 8601 format
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/set-reminder?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_lead_map_id": 2433664091,
"email_stats_id": "abc-def-123",
"message": "Follow up on pricing question",
"reminder_time": "2025-01-27T14:00:00Z"
}'
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
def set_reminder(lead_map_id, email_stats_id, message, days_from_now):
"""Set reminder X days from now"""
reminder_time = (datetime.now() + timedelta(days=days_from_now)).isoformat() + 'Z'
payload = {
"email_lead_map_id": lead_map_id,
"email_stats_id": email_stats_id,
"message": message,
"reminder_time": reminder_time
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/set-reminder",
params={"api_key": API_KEY},
json=payload
)
return response.json()
# Remind me in 3 days
set_reminder(
2433664091,
"abc-def-123",
"Follow up on demo feedback",
days_from_now=3
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function setReminder(leadMapId, emailStatsId, message, daysFromNow) {
const reminderDate = new Date();
reminderDate.setDate(reminderDate.getDate() + daysFromNow);
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/set-reminder?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email_lead_map_id: leadMapId,
email_stats_id: emailStatsId,
message: message,
reminder_time: reminderDate.toISOString()
})
}
);
return response.json();
}
await setReminder(2433664091, 'abc-def-123', 'Check if interested', 7);
```
## Response Example
```json 200 - Success theme={null}
{
"success": true,
"message": "Reminder set successfully",
"data": {
"reminder_id": 789,
"email_lead_map_id": 2433664091,
"reminder_time": "2025-01-27T14:00:00Z",
"message": "Follow up on pricing question"
}
}
```
## Related Endpoints
* [Get Reminder Emails](/api-reference/inbox/get-reminders)
* [Create Task](/api-reference/inbox/create-task)
# Update Lead Category
Source: https://api.smartlead.ai/api-reference/inbox/update-category
PATCH https://server.smartlead.ai/api/v1/master-inbox/update-category
Assign or change the category for a lead (Interested, Not Interested, etc.)
Categories help organize leads by response type. Common categories: Interested, Not Interested, Meeting Request, Do Not Contact. Get category IDs from the categories endpoint.
## Query Parameters
Your SmartLead API key
## Request Body
The ID of the lead-campaign mapping to update. This is the `campaign_lead_map_id` from inbox or campaign leads endpoints.
The category ID to assign. Use `null` to remove category assignment.
**Common Categories**:
* `1` - Interested
* `2` - Meeting Request
* `3` - Not Interested
* `4` - Do Not Contact
* `5` - Information Request
* Custom categories (your defined IDs)
```bash cURL theme={null}
curl -X PATCH "https://server.smartlead.ai/api/v1/master-inbox/update-category?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_lead_map_id": 2433664091,
"category_id": 1
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
# Mark lead as interested
payload = {
"email_lead_map_id": 2433664091,
"category_id": 1 # Interested
}
response = requests.patch(
"https://server.smartlead.ai/api/v1/master-inbox/update-category",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
print("Lead categorized as Interested")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Mark lead as interested
const payload = {
email_lead_map_id: 2433664091,
category_id: 1 // Interested
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/update-category?api_key=${API_KEY}`,
{
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
console.log('Lead categorized');
```
## Response Codes
Category updated successfully
Invalid API key
Lead mapping not found
Invalid category\_id or email\_lead\_map\_id
```json 200 - Success theme={null}
{
"success": true,
"message": "Lead category updated successfully"
}
```
```json 404 - Not Found theme={null}
{
"error": "Lead mapping not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "category_id must be a valid number or null"
}
```
## Common Use Cases
### Mark as Interested
```python theme={null}
update_category(lead_map_id, category_id=1) # Interested
```
### Mark as Not Interested
```python theme={null}
update_category(lead_map_id, category_id=3) # Not Interested
```
### Mark as Meeting Request
```python theme={null}
update_category(lead_map_id, category_id=2) # Meeting Request
```
### Remove Category
```python theme={null}
update_category(lead_map_id, category_id=None) # Unassign
```
## Getting email\_lead\_map\_id
The `email_lead_map_id` is returned as `campaign_lead_map_id` from inbox endpoints:
```json From inbox response theme={null}
{
"campaign_lead_map_id": "2433664091", // Use this as email_lead_map_id
"lead": {...}
}
```
## Related Endpoints
* [Get Lead Categories](/api-reference/leads/categories)
* [Get Inbox Messages](/api-reference/inbox/get-messages)
* [Get Unread Replies](/api-reference/inbox/get-unread)
# Update Lead Revenue
Source: https://api.smartlead.ai/api-reference/inbox/update-revenue
PATCH https://server.smartlead.ai/api/v1/master-inbox/update-revenue
Update the revenue value associated with a lead for ROI tracking
Track deal values and revenue per lead. Essential for calculating campaign ROI and measuring sales performance.
## Overview
Updates the revenue value for a lead. Critical for ROI calculations, performance tracking, and determining high-value leads.
## Query Parameters
Your SmartLead API key
## Request Body
Lead-campaign mapping ID
Revenue amount (must be non-negative). Currency based on account settings.
```bash cURL theme={null}
curl -X PATCH "https://server.smartlead.ai/api/v1/master-inbox/update-revenue?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"email_lead_map_id": 2433664091, "revenue": 50000}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def update_lead_revenue(lead_map_id, revenue_amount):
"""Update revenue for a lead"""
payload = {
"email_lead_map_id": lead_map_id,
"revenue": revenue_amount
}
response = requests.patch(
"https://server.smartlead.ai/api/v1/master-inbox/update-revenue",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
print(f"✅ Revenue updated: ${revenue_amount:,.2f}")
return response.json()
# Record $50k deal
update_lead_revenue(2433664091, 50000)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function updateRevenue(leadMapId, revenue) {
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/update-revenue?api_key=${API_KEY}`,
{
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email_lead_map_id: leadMapId,
revenue: revenue
})
}
);
return response.json();
}
// Update to $50k
await updateRevenue(2433664091, 50000);
```
## Response Example
```json 200 - Success theme={null}
{
"success": true,
"message": "Revenue updated successfully",
"data": {
"email_lead_map_id": 2433664091,
"revenue": 50000,
"updated_at": "2025-01-20T15:30:00Z"
}
}
```
```json 422 - Validation Error theme={null}
{
"error": "revenue must be non-negative",
"field": "revenue",
"provided_value": -1000
}
```
## Related Endpoints
* [Get Inbox Messages](/api-reference/inbox/get-messages)
* [Update Category](/api-reference/inbox/update-category)
# Assign Team Member
Source: https://api.smartlead.ai/api-reference/inbox/update-team-member
POST https://server.smartlead.ai/api/v1/master-inbox/update-team-member
Assign or reassign a lead to a specific team member
Assign leads to team members for personalized follow-up and workload distribution. Essential for team collaboration and performance tracking.
## Overview
Assigns a lead to a specific team member. This endpoint enables lead distribution across your team, reassignment between members, and tracking of individual performance.
**Key Benefits**:
* **Load balancing**: Distribute leads evenly across team
* **Expertise matching**: Assign leads based on team member specialization
* **Accountability**: Track which team member is responsible for each lead
* **Performance metrics**: Measure individual team member results
**Common Use Cases**:
* Round-robin lead assignment
* Geographic territory management
* Industry expertise routing
* Workload rebalancing
* Manager reassignment
## Query Parameters
Your SmartLead API key
## Request Body
The ID of the lead-campaign mapping to update. This is the `campaign_lead_map_id` from inbox or campaign leads endpoints.
The ID of the team member to assign this lead to. Get team member IDs from your team management settings.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/update-team-member?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_lead_map_id": 2433664091,
"team_member_id": 456
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
def assign_lead_to_member(lead_map_id, member_id):
"""Assign a lead to a specific team member"""
payload = {
"email_lead_map_id": lead_map_id,
"team_member_id": member_id
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/update-team-member",
params={"api_key": API_KEY},
json=payload
)
if response.status_code == 200:
print(f"Lead {lead_map_id} assigned to member {member_id}")
return response.json()
else:
print(f"Error: {response.json()}")
return None
# Assign lead to Jane (ID: 456)
assign_lead_to_member(2433664091, 456)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
async function assignLeadToMember(leadMapId, memberId) {
const payload = {
email_lead_map_id: leadMapId,
team_member_id: memberId
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/master-inbox/update-team-member?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`Lead assigned to member ${memberId}`);
return result;
}
// Assign lead to Jane (ID: 456)
assignLeadToMember(2433664091, 456);
```
## Response Codes
Team member assignment updated successfully
Invalid API key
Lead mapping or team member not found
Invalid email\_lead\_map\_id or team\_member\_id
```json 200 - Success theme={null}
{
"success": true,
"message": "Team member assigned successfully",
"data": {
"email_lead_map_id": 2433664091,
"team_member_id": 456,
"assigned_at": "2025-01-20T15:30:00Z"
}
}
```
```json 404 - Not Found theme={null}
{
"error": "Team member not found with ID 456"
}
```
```json 422 - Validation Error theme={null}
{
"error": "email_lead_map_id must be a valid number"
}
```
## Assignment Strategies
### Round-Robin Assignment
```python theme={null}
team_members = [101, 102, 103, 104, 105]
current_index = 0
def assign_next_lead(lead_map_id):
global current_index
member_id = team_members[current_index]
assign_lead_to_member(lead_map_id, member_id)
current_index = (current_index + 1) % len(team_members)
# Distribute leads evenly
for lead in new_leads:
assign_next_lead(lead['campaign_lead_map_id'])
```
### Territory-Based Assignment
```python theme={null}
territory_map = {
'US-WEST': 101,
'US-EAST': 102,
'EUROPE': 103,
'ASIA': 104
}
def assign_by_territory(lead_map_id, lead_territory):
member_id = territory_map.get(lead_territory)
if member_id:
assign_lead_to_member(lead_map_id, member_id)
else:
print(f"No member assigned for territory: {lead_territory}")
```
### Expertise-Based Routing
```python theme={null}
expertise_routing = {
'SaaS': 101,
'E-commerce': 102,
'Healthcare': 103,
'Finance': 104
}
def assign_by_industry(lead_map_id, industry):
member_id = expertise_routing.get(industry, 101) # Default to 101
assign_lead_to_member(lead_map_id, member_id)
```
### Workload Balancing
```python theme={null}
def get_member_workload(member_id):
"""Get current number of assigned leads"""
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/assigned-me",
params={"api_key": API_KEY},
json={"filters": {"campaignTeamMemberId": member_id}}
)
return response.json().get('total_count', 0)
def assign_to_least_busy(lead_map_id, team_members):
"""Assign to team member with fewest current leads"""
workloads = {m: get_member_workload(m) for m in team_members}
least_busy = min(workloads, key=workloads.get)
assign_lead_to_member(lead_map_id, least_busy)
```
## Bulk Assignment
```python theme={null}
def bulk_assign_leads(lead_map_ids, team_member_id):
"""Assign multiple leads to the same team member"""
results = []
for lead_map_id in lead_map_ids:
try:
result = assign_lead_to_member(lead_map_id, team_member_id)
results.append({
'lead_map_id': lead_map_id,
'status': 'success',
'result': result
})
except Exception as e:
results.append({
'lead_map_id': lead_map_id,
'status': 'error',
'error': str(e)
})
return results
# Assign 10 leads to Jane
new_leads = [2433664091, 2433664092, 2433664093, ...]
bulk_assign_leads(new_leads, 456)
```
## Reassignment Workflows
### Manager Reassignment
```python theme={null}
def reassign_from_to(from_member_id, to_member_id, filters=None):
"""Reassign all leads from one member to another"""
# Get all leads assigned to from_member
payload = {
"filters": {
"campaignTeamMemberId": from_member_id
},
"limit": 20
}
if filters:
payload["filters"].update(filters)
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/assigned-me",
params={"api_key": API_KEY},
json=payload
)
leads = response.json().get('messages', [])
# Reassign each lead
for lead in leads:
assign_lead_to_member(
lead['campaign_lead_map_id'],
to_member_id
)
return len(leads)
# Transfer all of John's hot leads to Jane
count = reassign_from_to(
from_member_id=123,
to_member_id=456,
filters={"leadCategories": {"categoryIdsIn": [1]}} # Interested only
)
print(f"Reassigned {count} leads")
```
### Vacation Coverage
```python theme={null}
def setup_vacation_coverage(away_member_id, covering_member_id, start_date, end_date):
"""Temporarily reassign leads during vacation"""
# Get active leads
payload = {
"filters": {
"campaignTeamMemberId": away_member_id,
"emailStatus": "Replied" # Only active conversations
}
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/assigned-me",
params={"api_key": API_KEY},
json=payload
)
active_leads = response.json().get('messages', [])
# Reassign to covering member
for lead in active_leads:
assign_lead_to_member(
lead['campaign_lead_map_id'],
covering_member_id
)
# Add note about temporary reassignment
create_note(
lead['campaign_lead_map_id'],
f"Temporarily assigned to covering member during vacation from {start_date} to {end_date}"
)
```
## Getting email\_lead\_map\_id
The `email_lead_map_id` is returned as `campaign_lead_map_id` from inbox endpoints:
```json From inbox response theme={null}
{
"messages": [{
"campaign_lead_map_id": "2433664091", // Use this value
"lead": {...},
"assigned_to": {
"id": 123,
"name": "John Doe"
}
}]
}
```
## Team Member Notifications
After assignment, the team member typically receives:
* Email notification of new assignment
* In-app notification
* Addition to their "Assigned to Me" inbox view
Configure notification preferences in team settings.
## Best Practices
1. **Document assignment logic**: Keep records of why leads were assigned
2. **Add notes on assignment**: Use create-note endpoint to explain context
3. **Monitor workload distribution**: Regularly check assignment balance
4. **Set up SLAs**: Define expected response times for assigned leads
5. **Review periodically**: Reassess assignments based on performance
6. **Handle edge cases**: Plan for invalid IDs, missing members, etc.
## Performance Tracking
```python theme={null}
def get_member_performance(member_id, start_date, end_date):
"""Get performance metrics for assigned leads"""
payload = {
"filters": {
"campaignTeamMemberId": member_id,
"replyTimeBetween": [start_date, end_date]
}
}
response = requests.post(
"https://server.smartlead.ai/api/v1/master-inbox/assigned-me",
params={"api_key": API_KEY},
json=payload
)
messages = response.json().get('messages', [])
# Calculate metrics
total = len(messages)
replied = len([m for m in messages if m['email_status'] == 'Replied'])
interested = len([m for m in messages
if m.get('category', {}).get('id') == 1])
return {
'member_id': member_id,
'total_assigned': total,
'reply_rate': (replied / total * 100) if total > 0 else 0,
'interest_rate': (interested / total * 100) if total > 0 else 0
}
```
## Related Endpoints
* [Get Assigned to Me](/api-reference/inbox/get-assigned) - View assigned leads
* [Get Inbox Messages](/api-reference/inbox/get-messages) - All inbox replies
* [Create Note](/api-reference/inbox/create-note) - Add assignment context
* [Update Lead Category](/api-reference/inbox/update-category) - Categorize assigned leads
# Assign Tags to Lead Lists
Source: https://api.smartlead.ai/api-reference/lead-lists/assign-tags
POST https://server.smartlead.ai/api/v1/lead-list/assign-tags
Add or remove tags from one or more lead lists
## Query Parameters
Your SmartLead API key
## Request Body
Array of lead list IDs to tag. 1-10 lists allowed.
Array of tag IDs to assign. 1-10 tags allowed.
Array of tag IDs to remove. 1-10 tags allowed.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/lead-list/assign-tags?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"listIds": [500, 501], "tagIds": [1, 2], "removeTagIds": [3]}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"message": "Tags updated successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Create Lead List
Source: https://api.smartlead.ai/api-reference/lead-lists/create
POST https://server.smartlead.ai/api/v1/lead-list/
Create a new lead list for organizing and segmenting your leads
Lead lists help you organize leads into logical groups before pushing them to campaigns. Create lists for different segments, sources, or campaigns.
## Query Parameters
Your SmartLead API key
## Request Body
Name for the new lead list
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/lead-list/?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"listName": "Q1 2025 Enterprise Prospects"}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 500,
"name": "Q1 2025 Enterprise Prospects",
"created_at": "2025-12-01T10:00:00.000Z"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Delete Lead List
Source: https://api.smartlead.ai/api-reference/lead-lists/delete
DELETE https://server.smartlead.ai/api/v1/lead-list/{id}
Delete a lead list by its ID
## Path Parameters
The unique ID of the lead list to delete
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/lead-list/500?api_key=YOUR_KEY"
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"message": "Lead list deleted successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get All Lead Lists
Source: https://api.smartlead.ai/api-reference/lead-lists/get-all
GET https://server.smartlead.ai/api/v1/lead-list/
Retrieve all lead lists with optional filtering and pagination
## Query Parameters
Your SmartLead API key
Filter by list name (partial match)
Comma-separated tag IDs to filter by (e.g., `1,2,3`)
Number of lists to return. Range: 1-1000. Default: 10
Number of records to skip for pagination. Minimum: 0. Default: 0
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/lead-list/?api_key=YOUR_KEY&limit=20&offset=0"
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"id": 500,
"name": "Q1 2025 Enterprise Prospects",
"lead_count": 1250,
"created_at": "2025-12-01T10:00:00.000Z"
},
{
"id": 501,
"name": "SMB Tech Companies",
"lead_count": 850,
"created_at": "2025-12-05T14:00:00.000Z"
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get Lead List by ID
Source: https://api.smartlead.ai/api-reference/lead-lists/get-by-id
GET https://server.smartlead.ai/api/v1/lead-list/{id}
Retrieve details of a specific lead list by its ID
## Path Parameters
The unique ID of the lead list
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/lead-list/500?api_key=YOUR_KEY"
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 500,
"name": "Q1 2025 Enterprise Prospects",
"lead_count": 1250,
"created_at": "2025-12-01T10:00:00.000Z",
"updated_at": "2025-12-10T16:30:00.000Z"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Import Leads to List
Source: https://api.smartlead.ai/api-reference/lead-lists/import-leads
POST https://server.smartlead.ai/api/v1/lead-list/{id}/import
Import leads into a specific lead list
Bulk import leads into a list. Each lead object should contain at least an email field. Custom fields and CSV settings can be configured.
## Path Parameters
The ID of the lead list to import into
## Query Parameters
Your SmartLead API key
## Request Body
Array of lead objects to import. Each lead should contain at minimum an email field, plus any additional fields like first\_name, last\_name, company, etc.
A name to identify this import batch (e.g., the source CSV filename)
Mapping of email fields in your data
Custom field definitions for your lead data
Import settings including `ignoreGlobalBlockList` (boolean) to skip blocked domain checking
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/lead-list/500/import?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"leadList": [
{"email": "john@company.com", "first_name": "John", "last_name": "Doe", "company": "ACME Corp"},
{"email": "jane@startup.io", "first_name": "Jane", "last_name": "Smith", "company": "Startup Inc"}
],
"fileName": "enterprise-prospects-jan2025.csv",
"csvSettings": {
"ignoreGlobalBlockList": false
}
}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"total_leads": 2,
"imported": 2,
"duplicates": 0,
"blocked": 0
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Move Leads Between Lists
Source: https://api.smartlead.ai/api-reference/lead-lists/push-between-lists
POST https://server.smartlead.ai/api/v1/leads/leads/push-between-lists
Copy or move leads from one list to another
## Request Body
Operation type: `copy` or `move`
Specific lead IDs to transfer. Array of numbers, 1-10,000 items. Provide either `leadIds` or `fromListId`.
Source list ID to transfer all leads from. Provide either `leadIds` or `fromListId`.
Destination list ID to transfer leads to
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/leads/leads/push-between-lists?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"action": "move",
"fromListId": 500,
"toListId": 501
}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"total_leads_moved": 1250
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Push Leads to Campaign
Source: https://api.smartlead.ai/api-reference/lead-lists/push-to-campaign
POST https://server.smartlead.ai/api/v1/leads/push-to-campaign
Push leads from a list or by IDs to a campaign
Move or copy leads into a campaign for outreach. You can push specific leads by ID, all leads from a list, or all leads in your account.
## Query Parameters
Your SmartLead API key
## Request Body
Target campaign ID. Either `campaignId` or `campaignName` must be provided.
Target campaign name. If campaign doesn't exist, a new one is created.
Whether to `copy` or `move` leads. Move removes them from the source.
Lead selection criteria
Source list ID to push leads from
Specific lead IDs to push. Array of numbers, 1-10,000 items.
Set to `true` to push all leads. When true, `listId` and `leadIds` should not be provided.
Import settings for the campaign (e.g., block list handling)
Additional filters to apply when selecting leads
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/leads/push-to-campaign?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaignId": 12345,
"action": "copy",
"leadList": {
"listId": 500
}
}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"total_leads": 1250,
"pushed": 1200,
"duplicates": 50
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Update Lead List
Source: https://api.smartlead.ai/api-reference/lead-lists/update
PUT https://server.smartlead.ai/api/v1/lead-list/{id}
Update the name of an existing lead list
## Path Parameters
The unique ID of the lead list to update
## Request Body
New name for the lead list
```bash cURL theme={null}
curl -X PUT "https://server.smartlead.ai/api/v1/lead-list/500?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"listName": "Q1 2025 Enterprise Prospects - Updated"}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 500,
"name": "Q1 2025 Enterprise Prospects - Updated"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Create Lead Note
Source: https://api.smartlead.ai/api-reference/lead-notes/create
POST https://server.smartlead.ai/api/v1/master-inbox/create-note
Create a note for a specific lead in a campaign
Add notes to leads to track interactions, observations, and follow-up reminders. Notes are visible to all team members with access to the campaign.
## Query Parameters
Your SmartLead API key
## Request Body
The campaign-lead mapping ID. This links the note to a specific lead within a specific campaign.
The content of the note
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/create-note?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_lead_map_id": 2433664091,
"note_message": "Spoke with lead, interested in enterprise plan. Follow up next week."
}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 456,
"email_lead_map_id": 2433664091,
"note_message": "Spoke with lead, interested in enterprise plan. Follow up next week.",
"created_at": "2025-12-01T10:30:00.000Z"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get Lead Notes
Source: https://api.smartlead.ai/api-reference/lead-notes/get-all
GET https://server.smartlead.ai/api/v1/crm/leads/notes/{id}
Retrieve all notes for a specific lead
## Path Parameters
The lead ID to retrieve notes for
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/crm/leads/notes/123?api_key=YOUR_KEY"
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"id": 456,
"lead_id": 123,
"note_message": "Spoke with lead, interested in enterprise plan",
"created_by": "John Doe",
"created_at": "2025-12-01T10:30:00.000Z"
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Add Tags to Lead
Source: https://api.smartlead.ai/api-reference/lead-tags/add-to-lead
POST https://server.smartlead.ai/api/v1/crm/leads/tags
Assign one or more tags to a specific lead
## Request Body
The lead ID to add tags to
Array of tag IDs to assign to the lead
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/crm/leads/tags?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"leadId": 123, "tagIds": [1, 2, 3]}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"message": "Tags added to lead successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Create Tag
Source: https://api.smartlead.ai/api-reference/lead-tags/create
POST https://server.smartlead.ai/api/v1/email-accounts/tag-manager
Create a new tag that can be used across email accounts and leads
Tags are created at the account level and can be used to organize both email accounts and leads. This is the same endpoint used for email account tag creation.
## Query Parameters
Your SmartLead API key
## Request Body
Tag ID. Use an existing ID to update.
Tag name
Hex color code (e.g., `#FF5733`)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/tag-manager?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"id": 1, "name": "VIP", "color": "#FF5733"}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 1,
"name": "VIP",
"color": "#FF5733"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get Lead Tags
Source: https://api.smartlead.ai/api-reference/lead-tags/get-all
GET https://server.smartlead.ai/api/v1/crm/leads/tags
Get tags associated with a specific lead
## Query Parameters
The lead ID to retrieve tags for. If omitted, returns all available tags.
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/crm/leads/tags?api_key=YOUR_KEY&leadId=123"
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"id": 1,
"tag_mapping_id": 789,
"name": "VIP",
"color": "#FF5733"
},
{
"id": 2,
"tag_mapping_id": 790,
"name": "Enterprise",
"color": "#4CAF50"
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Remove Tag from Lead
Source: https://api.smartlead.ai/api-reference/lead-tags/remove-from-lead
DELETE https://server.smartlead.ai/api/v1/crm/leads/tags/{tagMappingId}
Remove a specific tag mapping from a lead
## Path Parameters
The tag mapping ID (not the tag ID). Get this from the Get Lead Tags response.
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/crm/leads/tags/789?api_key=YOUR_KEY"
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"message": "Tag removed from lead successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Create Lead Task
Source: https://api.smartlead.ai/api-reference/lead-tasks/create
POST https://server.smartlead.ai/api/v1/master-inbox/create-task
Create a task for a specific lead in a campaign
Create follow-up tasks for leads with priorities and due dates. Tasks appear in the master inbox for easy tracking.
## Query Parameters
Your SmartLead API key
## Request Body
The campaign-lead mapping ID
Task name/title
Detailed task description
Task priority level. Values: `LOW`, `MEDIUM`, `HIGH`. Default: `MEDIUM`
Due date in ISO 8601 format (e.g., `2025-12-15T09:00:00Z`)
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/master-inbox/create-task?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email_lead_map_id": 2433664091,
"name": "Follow up on enterprise proposal",
"description": "Send pricing breakdown for 50-seat plan",
"priority": "HIGH",
"due_date": "2025-12-15T09:00:00Z"
}'
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 789,
"email_lead_map_id": 2433664091,
"name": "Follow up on enterprise proposal",
"description": "Send pricing breakdown for 50-seat plan",
"priority": "HIGH",
"due_date": "2025-12-15T09:00:00Z",
"created_at": "2025-12-01T10:00:00.000Z"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get Lead Tasks
Source: https://api.smartlead.ai/api-reference/lead-tasks/get-all
GET https://server.smartlead.ai/api/v1/crm/leads/tasks/{id}
Retrieve all tasks for a specific lead
## Path Parameters
The lead ID to retrieve tasks for
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/crm/leads/tasks/123?api_key=YOUR_KEY"
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key
Request validation failed. Check parameter types and constraints.
```json 200 - Success theme={null}
{
"ok": true,
"data": [
{
"id": 789,
"lead_id": 123,
"name": "Follow up on enterprise proposal",
"description": "Send pricing breakdown for 50-seat plan",
"priority": "HIGH",
"due_date": "2025-12-15T09:00:00Z",
"status": "pending",
"created_at": "2025-12-01T10:00:00.000Z"
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get All Leads Activities
Source: https://api.smartlead.ai/api-reference/leads/activities
GET https://server.smartlead.ai/api/v1/campaigns/all-leads-activities
Retrieve comprehensive activity timeline for all leads across all campaigns with email interactions
Returns detailed activity data including sent emails, opens, clicks, replies, and thread conversations for leads across all campaigns. Useful for building activity feeds and tracking engagement.
## Query Parameters
Your SmartLead API key
Pagination offset (minimum: 0)
Number of lead activities to return (minimum: 1, maximum: 1000)
Filter activities from this date/time. Accepts ISO 8601 format (e.g., `2025-11-25T00:00:00.000Z`) or `YYYY-MM-DD` format
Filter activities until this date/time. Accepts ISO 8601 format or `YYYY-MM-DD` format. Must be used with `event_time_from`
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/all-leads-activities?api_key=YOUR_KEY&limit=50&event_time_from=2025-11-01&event_time_to=2025-11-30"
```
```python Python theme={null}
import requests
from datetime import datetime, timedelta
API_KEY = "YOUR_API_KEY"
# Get activities from the last 7 days
event_time_from = (datetime.now() - timedelta(days=7)).isoformat()
event_time_to = datetime.now().isoformat()
response = requests.get(
"https://server.smartlead.ai/api/v1/campaigns/all-leads-activities",
params={
"api_key": API_KEY,
"limit": 50,
"offset": 0,
"event_time_from": event_time_from,
"event_time_to": event_time_to
}
)
result = response.json()
print(f"Total activities: {len(result['data'])}")
print(f"Has more: {result['hasMore']}")
# Process activities
for activity in result['data']:
print(f"Lead {activity['lead_id']} in campaign {activity['campaign_name']}")
print(f" Activities: {len(activity['activities'])}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
// Get activities from the last 7 days
const eventTimeFrom = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
const eventTimeTo = new Date().toISOString();
const params = new URLSearchParams({
api_key: API_KEY,
limit: 50,
offset: 0,
event_time_from: eventTimeFrom,
event_time_to: eventTimeTo
});
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/all-leads-activities?${params}`
);
const result = await response.json();
console.log(`Total activities: ${result.data.length}`);
console.log(`Has more: ${result.hasMore}`);
// Process activities
result.data.forEach(activity => {
console.log(`Lead ${activity.lead_id} in campaign ${activity.campaign_name}`);
console.log(` Activities: ${activity.activities.length}`);
});
```
## Response Fields
Array of lead activity objects
Unique lead identifier
Campaign-lead mapping identifier
Campaign ID
Campaign name
Campaign status
Lead status in the campaign
Current sequence number for the lead
When the lead was added to the campaign
Array of email activity objects
Email statistics ID
Email message ID
Email subject line
Email body content
When the email was sent
Sender email address
Recipient email address
Sequence number of the email
Number of times the email was opened
Number of times links were clicked
Details about link clicks
Reply information if the lead replied
When the reply was received
Reply email content
Reply message ID
Array of thread replies (back-and-forth conversation)
Whether there are more results available for pagination
## Response Codes
Activities retrieved successfully
Invalid date format for event\_time\_from or event\_time\_to
Invalid or missing API key
Invalid query parameters (check limit and offset ranges)
Server error occurred
```json 200 - Success theme={null}
{
"data": [
{
"lead_id": 2995276770,
"email_lead_map_id": 2433664091,
"campaign_id": 123,
"campaign_name": "Q4 Outreach",
"campaign_status": "ACTIVE",
"status": "INPROGRESS",
"current_seq_num": 2,
"created_at": "2025-11-25T12:54:54.000Z",
"activities": [
{
"stats_id": 12345,
"message_id": "",
"subject": "Quick question about your workflow",
"email_body": "Hi John, I wanted to reach out...",
"sent_time": "2025-11-26T10:00:00.000Z",
"from_email": "sender@company.com",
"to_email": "john@example.com",
"email_seq_number": 1,
"open_count": 3,
"click_count": 1,
"click_details": {},
"reply_details": {
"time": "2025-11-26T14:30:00.000Z",
"reply_email_body": "Thanks for reaching out...",
"message_id": ""
},
"thread_replies": []
}
]
}
],
"hasMore": true
}
```
```json 400 - Bad Request theme={null}
{
"error": "Invalid event_time_from format. Use YYYY-MM-DD or ISO 8601 format.",
"status": "error"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
## Usage Notes
This endpoint is optimized for retrieving activity timelines. Use the `event_time_from` and `event_time_to` parameters to filter by date range for better performance.
The `hasMore` field indicates if there are additional results. Use the `offset` parameter to paginate through results.
## Related Endpoints
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
* [Get Lead by Email](/api-reference/leads/get-by-email)
* [Export Campaign Leads](/api-reference/leads/export)
# Add Leads to Campaign
Source: https://api.smartlead.ai/api-reference/leads/add-to-campaign
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads
Add new leads to a campaign with validation and deduplication
Max 400 leads per request. Validates against block lists and duplicates. Returns added/skipped counts with reasons.
## Path Parameters
The ID of the campaign to add leads to
## Query Parameters
Your SmartLead API key
## Request Body
Array of lead objects to add (maximum 400 leads per request)
Lead's email address
Lead's first name
Lead's last name
Lead's phone number
Company name
Company website
Lead's location
LinkedIn profile URL
Company URL
Custom fields for personalization (maximum 200 key-value pairs per lead)
Lead import settings
Skip global block list validation
Include previously unsubscribed leads
Allow same lead in multiple campaigns
Skip community bounce list check
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"lead_list": [
{
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "Acme Corp",
"custom_fields": {
"job_title": "CEO"
}
}
]
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
payload = {
"lead_list": [
{
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "Acme Corp",
"custom_fields": {
"job_title": "CEO"
}
}
]
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(f"Added: {result.get('added_count', 0)}, Skipped: {result.get('skipped_count', 0)}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const payload = {
lead_list: [
{
email: 'john@example.com',
first_name: 'John',
last_name: 'Doe',
company_name: 'Acme Corp',
custom_fields: {
job_title: 'CEO'
}
}
]
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`Added: ${result.added_count}, Skipped: ${result.skipped_count}`);
```
## Response Codes
Leads added successfully
Invalid request parameters or malformed request body
Invalid or missing API key
Campaign not found or no access
Lead validation failed - check email format, required fields
Too many requests
Server error occurred
```json 200 - Success theme={null}
{
"success": true,
"message": "Leads added successfully",
"added_count": 1,
"skipped_count": 0,
"skipped_leads": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid email format for john@invalid"
}
```
## Related Endpoints
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
* [Update Lead](/api-reference/leads/update)
* [Delete Lead](/api-reference/leads/delete)
# Get Lead Categories
Source: https://api.smartlead.ai/api-reference/leads/categories
GET https://server.smartlead.ai/api/v1/leads/fetch-categories
Retrieve all available lead categories including global and user-specific categories
Returns both global categories (available to all users) and categories you've created. Categories are used to organize and filter leads based on their engagement or status.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/leads/fetch-categories?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/leads/fetch-categories",
params={"api_key": API_KEY}
)
categories = response.json()
print(f"Total categories: {len(categories)}")
# Filter by sentiment
positive_categories = [c for c in categories if c['sentiment_type'] == 'positive']
print(f"Positive sentiment categories: {len(positive_categories)}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/leads/fetch-categories?api_key=${API_KEY}`
);
const categories = await response.json();
console.log(`Total categories: ${categories.length}`);
// Filter by sentiment
const positiveCategories = categories.filter(c => c.sentiment_type === 'positive');
console.log(`Positive sentiment categories: ${positiveCategories.length}`);
```
## Response Fields
The response is an array of category objects, each containing:
Unique category identifier
Category name (e.g., "Interested", "Not Interested", "Meeting Booked")
Sentiment classification of the category. Values: `positive`, `negative`, `neutral`
ISO 8601 timestamp of when the category was created
## Response Codes
Categories retrieved successfully
Invalid or missing API key
Server error occurred
```json 200 - Success theme={null}
[
{
"id": 1,
"name": "Interested",
"sentiment_type": "positive",
"created_at": "2024-01-15T10:30:00.000Z"
},
{
"id": 2,
"name": "Not Interested",
"sentiment_type": "negative",
"created_at": "2024-01-15T10:30:00.000Z"
},
{
"id": 3,
"name": "Meeting Booked",
"sentiment_type": "positive",
"created_at": "2024-01-15T10:30:00.000Z"
},
{
"id": 789,
"name": "Follow Up Later",
"sentiment_type": "neutral",
"created_at": "2025-11-20T14:22:00.000Z"
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
## Usage Notes
Categories are sorted by ID in ascending order. Global categories (available to all users) have lower IDs, while user-created categories have higher IDs.
Use the category ID when updating a lead's category via the Update Lead Category endpoint. The sentiment type helps you filter leads for reporting and analytics.
## Related Endpoints
* [Get Campaign Leads](/api-reference/leads/get-by-campaign) - Filter leads by category
* [Get Lead by Email](/api-reference/leads/get-by-email) - View lead's assigned category
# Delete Lead from Campaign
Source: https://api.smartlead.ai/api-reference/leads/delete
DELETE https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}
Remove a lead from a campaign and optionally from your account if not used elsewhere
If the lead is not associated with any other campaign, it will be permanently deleted from your account. This action cannot be undone.
## Path Parameters
The campaign ID to remove the lead from
The lead ID to delete
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/campaigns/123/leads/456?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
lead_id = 456
response = requests.delete(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}",
params={"api_key": API_KEY}
)
result = response.json()
if result.get('ok'):
print(f"Lead {lead_id} deleted from campaign {campaign_id}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const leadId = 456;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}?api_key=${API_KEY}`,
{ method: 'DELETE' }
);
const result = await response.json();
if (result.ok) {
console.log(`Lead ${leadId} deleted from campaign ${campaignId}`);
}
```
## Response Codes
Lead deleted successfully from campaign
Invalid or missing API key
Campaign not found or you don't have access to it
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"message": "success"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Campaign not found - Invalid campaign_id."
}
```
## Behavior Notes
The lead will only be permanently deleted from your account if it's not associated with any other campaigns. If the lead exists in other campaigns, only the campaign association is removed.
## Related Endpoints
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
* [Add Leads to Campaign](/api-reference/leads/add-to-campaign)
* [Pause Lead](/api-reference/leads/pause)
# Export Campaign Leads
Source: https://api.smartlead.ai/api-reference/leads/export
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads-export
Export all leads from a campaign as a CSV file with complete engagement metrics
Returns a CSV file containing all leads in the campaign with their contact information, status, category, and engagement metrics (opens, clicks, replies). The file is named `sl_campaign_{campaign_id}_leads.csv`.
## Path Parameters
The campaign ID to export leads from
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
# Download CSV file
curl "https://server.smartlead.ai/api/v1/campaigns/123/leads-export?api_key=YOUR_KEY" \
-o campaign_123_leads.csv
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads-export",
params={"api_key": API_KEY}
)
# Save CSV file
if response.status_code == 200:
with open(f'campaign_{campaign_id}_leads.csv', 'wb') as f:
f.write(response.content)
print(f"Exported {campaign_id} leads to CSV")
else:
print(f"Error: {response.status_code}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads-export?api_key=${API_KEY}`
);
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `campaign_${campaignId}_leads.csv`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
console.log('CSV downloaded');
} else {
console.error('Export failed:', response.status);
}
```
## CSV File Columns
The exported CSV file contains the following columns:
* `id` - Lead ID
* `campaign_lead_map_id` - Campaign-lead mapping ID
* `first_name` - Lead's first name
* `last_name` - Lead's last name
* `email` - Lead's email address
* `phone_number` - Lead's phone number
* `company_name` - Company name
* `website` - Company website
* `location` - Lead's location
* `linkedin_profile` - LinkedIn profile URL
* `company_url` - Company URL
* `custom_fields` - Custom fields as JSON object
* `status` - Lead status (STARTED, INPROGRESS, COMPLETED, PAUSED, STOPPED)
* `category` - Category name
* `is_interested` - Boolean indicating positive sentiment category
* `created_at` - When lead was added to campaign
* `last_email_sequence_sent` - Last sequence number sent
* `open_count` - Total number of opens
* `click_count` - Total number of clicks
* `reply_count` - Total number of replies
* `is_unsubscribed` - Whether lead is globally unsubscribed
* `unsubscribed_client_id_map` - Client-specific unsubscribe data
## Response Codes
CSV file generated and returned successfully
Invalid or missing API key
Campaign not found or you don't have access to it
Server error occurred
```csv 200 - Success (CSV Content) theme={null}
id,campaign_lead_map_id,status,category,is_interested,created_at,first_name,last_name,email,phone_number,company_name,website,location,custom_fields,linkedin_profile,company_url,is_unsubscribed,unsubscribed_client_id_map,last_email_sequence_sent,open_count,click_count,reply_count
2995276770,2433664091,INPROGRESS,Interested,true,2025-11-25T12:54:54.000Z,John,Doe,john@example.com,+1234567890,Acme Corp,https://acme.com,San Francisco,"{""job_title"":""CEO""}",https://linkedin.com/in/johndoe,https://acme.com,false,,2,3,1,1
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Campaign not found - Invalid campaign_id."
}
```
## Response Headers
The response includes the following headers:
* `Content-Type: text/csv`
* `Content-Disposition: attachment; filename=sl_campaign_{campaign_id}_leads.csv`
## Usage Notes
This endpoint is ideal for:
* Backing up campaign leads
* Importing leads into CRM systems
* Analyzing engagement metrics in spreadsheet tools
* Generating reports for stakeholders
Large campaigns may take longer to export. The export includes all leads regardless of status.
## Related Endpoints
* [Get Campaign Leads](/api-reference/leads/get-by-campaign) - Paginated API access to leads
* [Get Lead by Email](/api-reference/leads/get-by-email) - Get individual lead details
* [Get All Leads Activities](/api-reference/leads/activities) - Activity timeline for all leads
# Get Campaign Leads
Source: https://api.smartlead.ai/api-reference/leads/get-by-campaign
GET https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads
Retrieve paginated list of leads in a campaign with advanced filtering options
Supports filtering by status, category, email engagement, and date ranges. Returns lead details with custom fields. Maximum 100 leads per page.
## Path Parameters
The campaign ID to retrieve leads from
## Query Parameters
Your SmartLead API key
Pagination offset (minimum: 0)
Number of leads to return per page (minimum: 1, maximum: 100)
Filter by lead status. Valid values: `STARTED`, `INPROGRESS`, `COMPLETED`, `PAUSED`, `STOPPED`
Filter by category ID (must be a positive integer)
Filter by email engagement status. Valid values: `is_opened`, `is_clicked`, `is_replied`, `is_bounced`, `is_unsubscribed`, `is_spam`, `is_accepted`, `not_replied`, `is_sender_bounced`
Filter leads created after this ISO 8601 date (e.g., `2025-11-25T00:00:00.000Z`)
Filter leads with last email sent after this ISO 8601 date
Filter leads with any activity (sent or reply) after this ISO 8601 date
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/campaigns/123/leads?api_key=YOUR_KEY&limit=50&status=INPROGRESS&emailStatus=is_opened"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
response = requests.get(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads",
params={
"api_key": API_KEY,
"limit": 50,
"offset": 0,
"status": "INPROGRESS",
"emailStatus": "is_opened"
}
)
result = response.json()
print(f"Total leads: {result['total_leads']}")
print(f"Returned: {len(result['data'])} leads")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const params = new URLSearchParams({
api_key: API_KEY,
limit: 50,
offset: 0,
status: 'INPROGRESS',
emailStatus: 'is_opened'
});
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads?${params}`
);
const result = await response.json();
console.log(`Total leads: ${result.total_leads}`);
console.log(`Returned: ${result.data.length} leads`);
```
## Response Fields
Total count of leads matching the filter criteria
The offset used in the request
The limit used in the request
Array of lead objects
Unique identifier for the lead-campaign mapping
Category ID assigned to this lead, or null if uncategorized
Current status of the lead in this campaign. Values: `STARTED`, `INPROGRESS`, `COMPLETED`, `PAUSED`, `STOPPED`
ISO 8601 timestamp when the lead was added to the campaign
Lead contact information
Unique lead identifier
Lead's email address
Lead's first name
Lead's last name
Lead's phone number
Company name
Company website
Lead's location
LinkedIn profile URL
Company URL
Custom fields object containing personalization data
Whether the lead is globally unsubscribed
Map of client IDs where lead is unsubscribed
## Response Codes
Leads retrieved successfully
Invalid or missing API key
Campaign not found or you don't have access to it
Invalid query parameters (check offset, limit ranges and status values)
Server error occurred
```json 200 - Success theme={null}
{
"total_leads": "42",
"offset": 0,
"limit": 50,
"data": [
{
"campaign_lead_map_id": 2433664091,
"lead_category_id": null,
"status": "INPROGRESS",
"created_at": "2025-11-25T12:54:54.000Z",
"lead": {
"id": 2995276770,
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"phone_number": "+1234567890",
"company_name": "Acme Corp",
"website": "https://acme.com",
"location": "San Francisco, CA",
"linkedin_profile": "https://linkedin.com/in/johndoe",
"company_url": "https://acme.com",
"custom_fields": {
"job_title": "CEO",
"industry": "Technology"
},
"is_unsubscribed": false,
"unsubscribed_client_id_map": null
}
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Campaign not found - Invalid campaign_id."
}
```
## Related Endpoints
* [Add Leads to Campaign](/api-reference/leads/add-to-campaign)
* [Update Lead](/api-reference/leads/update)
* [Delete Lead](/api-reference/leads/delete)
* [Get Lead by Email](/api-reference/leads/get-by-email)
# Get Lead by Email
Source: https://api.smartlead.ai/api-reference/leads/get-by-email
GET https://server.smartlead.ai/api/v1/leads/
Search for a lead by email address and retrieve all associated campaign data
Returns lead details including personal information, custom fields, and all campaigns the lead is enrolled in. Returns empty object if lead not found.
## Query Parameters
Your SmartLead API key
The email address to search for
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/leads/?api_key=YOUR_KEY&email=john@example.com"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
email = "john@example.com"
response = requests.get(
"https://server.smartlead.ai/api/v1/leads/",
params={
"api_key": API_KEY,
"email": email
}
)
result = response.json()
if result:
print(f"Found lead: {result['first_name']} {result['last_name']}")
print(f"Enrolled in {len(result['lead_campaign_data'])} campaigns")
else:
print("Lead not found")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const email = 'john@example.com';
const response = await fetch(
`https://server.smartlead.ai/api/v1/leads/?api_key=${API_KEY}&email=${encodeURIComponent(email)}`
);
const result = await response.json();
if (Object.keys(result).length > 0) {
console.log(`Found lead: ${result.first_name} ${result.last_name}`);
console.log(`Enrolled in ${result.lead_campaign_data.length} campaigns`);
} else {
console.log('Lead not found');
}
```
## Response Fields
Unique lead identifier
Lead's email address
Lead's first name
Lead's last name
Lead's phone number
Company name
Company website
Lead's location
LinkedIn profile URL
Company URL
Custom fields object containing personalization data
Whether the lead is globally unsubscribed
Map of client IDs where lead is unsubscribed
ISO 8601 timestamp of when the lead was created
Array of campaigns this lead is enrolled in
Unique identifier for the lead-campaign mapping
Campaign ID
Campaign name
Client ID who owns the campaign
Email of the client who owns the campaign
Category ID assigned to this lead in the campaign
## Response Codes
Lead retrieved successfully (returns empty object if not found)
Invalid or missing API key
Missing or invalid email parameter
Server error occurred
```json 200 - Success theme={null}
{
"id": 2995276770,
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"phone_number": "+1234567890",
"company_name": "Acme Corp",
"website": "https://acme.com",
"location": "San Francisco, CA",
"linkedin_profile": "https://linkedin.com/in/johndoe",
"company_url": "https://acme.com",
"custom_fields": {
"job_title": "CEO",
"industry": "Technology"
},
"is_unsubscribed": false,
"unsubscribed_client_id_map": null,
"created_at": "2025-11-25T12:54:54.000Z",
"lead_campaign_data": [
{
"campaign_lead_map_id": 2433664091,
"campaign_id": 123,
"campaign_name": "Q4 Outreach",
"client_id": 456,
"client_email": "user@company.com",
"lead_category_id": 789
}
]
}
```
```json 200 - Lead Not Found theme={null}
{}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "email is required"
}
```
## Related Endpoints
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
* [Add Leads to Campaign](/api-reference/leads/add-to-campaign)
* [Unsubscribe Lead](/api-reference/leads/unsubscribe)
# Pause Lead
Source: https://api.smartlead.ai/api-reference/leads/pause
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/pause
Temporarily pause email sending for a specific lead in a campaign
Pausing a lead stops all scheduled emails. The lead status changes to `PAUSED` and any drafted emails are marked as `STOPPED`.
## Path Parameters
The campaign ID containing the lead
The lead ID to pause
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/456/pause?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
lead_id = 456
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/pause",
params={"api_key": API_KEY}
)
result = response.json()
if result.get('ok'):
print(f"Lead {lead_id} paused successfully")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const leadId = 456;
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}/pause?api_key=${API_KEY}`,
{ method: 'POST' }
);
const result = await response.json();
if (result.ok) {
console.log(`Lead ${leadId} paused successfully`);
}
```
## Response Codes
Lead paused successfully
Invalid or missing API key
Campaign not found or you don't have access to it
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"data": "success"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Campaign not found - Invalid campaign_id."
}
```
## Behavior Notes
When a lead is paused:
* Lead status changes to `PAUSED`
* The `next_timestamp_to_reach` is cleared
* All drafted emails for this lead are marked as `STOPPED`
* No new emails will be scheduled until the lead is resumed
## Related Endpoints
* [Resume Lead](/api-reference/leads/resume)
* [Delete Lead](/api-reference/leads/delete)
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
# Resume Lead
Source: https://api.smartlead.ai/api-reference/leads/resume
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/resume
Resume email sending for a paused lead with optional custom delay
Resuming a lead changes its status to `INPROGRESS` and schedules the next email based on the delay specified. If no delay is provided, the sequence's default delay is used.
## Path Parameters
The campaign ID containing the lead
The lead ID to resume
## Query Parameters
Your SmartLead API key
## Request Body
Number of days to wait before sending the next email. If not provided, uses the default delay from the sequence configuration. The next email timestamp is calculated as `last_sent_time + delay_days`.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/456/resume?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"resume_lead_with_delay_days": 3}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
lead_id = 456
# Resume with custom delay
payload = {
"resume_lead_with_delay_days": 3
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/resume",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
if result.get('ok'):
print(f"Lead {lead_id} resumed with {payload['resume_lead_with_delay_days']} day delay")
# Or resume with default delay
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/resume",
params={"api_key": API_KEY},
json={}
)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const leadId = 456;
// Resume with custom delay
const payload = {
resume_lead_with_delay_days: 3
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}/resume?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
if (result.ok) {
console.log(`Lead ${leadId} resumed with ${payload.resume_lead_with_delay_days} day delay`);
}
```
## Response Codes
Lead resumed successfully
Invalid or missing API key
Campaign not found or you don't have access to it
Server error occurred (e.g., lead is at the last sequence and cannot be resumed)
```json 200 - Success theme={null}
{
"ok": true,
"data": "success"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Campaign not found - Invalid campaign_id."
}
```
```json 500 - Last Sequence Error theme={null}
{
"error": "This is the last sequence. You cannot resume this lead."
}
```
```json 500 - Invalid Lead theme={null}
{
"error": "Invalid lead id"
}
```
## Behavior Notes
When a lead is resumed:
* Lead status changes from `PAUSED` to `INPROGRESS`
* The next sequence is determined automatically
* The `next_timestamp_to_reach` is calculated based on:
* If `resume_lead_with_delay_days` is provided: `last_sent_time + specified_days`
* If not provided: Uses the default delay from the sequence configuration
* If no `last_sent_time` exists: Scheduled immediately (NOW)
* Drafted emails are marked as `DRAFTED` and ready to send
You cannot resume a lead that is already on the last sequence of the campaign. Attempting to do so will return an error.
## Related Endpoints
* [Pause Lead](/api-reference/leads/pause)
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
* [Delete Lead](/api-reference/leads/delete)
# Unsubscribe Lead Globally
Source: https://api.smartlead.ai/api-reference/leads/unsubscribe
POST https://server.smartlead.ai/api/v1/leads/{lead_id}/unsubscribe
Globally unsubscribe a lead from all current and future campaigns
This action unsubscribes the lead globally across all campaigns in your account. The lead will not receive any future emails from any campaign. This action cannot be undone via API.
## Path Parameters
The lead ID to unsubscribe globally
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/leads/456/unsubscribe?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
lead_id = 456
response = requests.post(
f"https://server.smartlead.ai/api/v1/leads/{lead_id}/unsubscribe",
params={"api_key": API_KEY}
)
result = response.json()
if result.get('ok'):
print(f"Lead {lead_id} unsubscribed globally")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const leadId = 456;
const response = await fetch(
`https://server.smartlead.ai/api/v1/leads/${leadId}/unsubscribe?api_key=${API_KEY}`,
{ method: 'POST' }
);
const result = await response.json();
if (result.ok) {
console.log(`Lead ${leadId} unsubscribed globally`);
}
```
## Response Codes
Lead unsubscribed successfully
Invalid or missing API key
Lead not found or you don't have access to it
Server error occurred
```json 200 - Success theme={null}
{
"ok": true
}
```
```json 200 - No Update theme={null}
{
"ok": false
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Lead not found - Invalid lead_id."
}
```
## Behavior Notes
When a lead is globally unsubscribed:
* The `is_unsubscribed` flag is set to `true` on the lead record
* The lead will not receive emails from any campaign
* The lead remains in all campaigns but will not be contacted
* This action affects all current and future campaigns
To unsubscribe a lead from a specific campaign only (not globally), use the campaign-specific unsubscribe endpoint: `POST /api/v1/campaigns/{campaign_id}/leads/{lead_id}/unsubscribe`
## Related Endpoints
* [Get Lead by Email](/api-reference/leads/get-by-email)
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
* [Delete Lead](/api-reference/leads/delete)
# Update Lead
Source: https://api.smartlead.ai/api-reference/leads/update
POST https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}/
Update lead contact information and custom fields. Changes apply globally across all campaigns.
Updating a lead modifies the lead record globally across all campaigns. The `email` field is required even if not being changed.
## Path Parameters
The campaign ID (used for validation and audit logging)
The lead ID to update
## Query Parameters
Your SmartLead API key
## Request Body
Lead's email address (required field, even if not being changed)
Lead's first name
Lead's last name
Lead's phone number
Company name
Company website
Lead's location
LinkedIn profile URL
Company URL
Custom fields object (maximum 200 key-value pairs). Custom fields are merged with existing fields, not replaced.
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/123/leads/456?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "Acme Corp",
"custom_fields": {
"job_title": "CTO",
"department": "Engineering"
}
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
campaign_id = 123
lead_id = 456
payload = {
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "Acme Corp",
"custom_fields": {
"job_title": "CTO",
"department": "Engineering"
}
}
response = requests.post(
f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads/{lead_id}",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
if result.get('ok'):
print("Lead updated successfully")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const campaignId = 123;
const leadId = 456;
const payload = {
email: 'john@example.com',
first_name: 'John',
last_name: 'Doe',
company_name: 'Acme Corp',
custom_fields: {
job_title: 'CTO',
department: 'Engineering'
}
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/campaigns/${campaignId}/leads/${leadId}?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
if (result.ok) {
console.log('Lead updated successfully');
}
```
## Response Codes
Lead updated successfully
Invalid or missing API key
Campaign or lead not found, or you don't have access
Missing required email field or invalid custom\_fields object size
Server error occurred
```json 200 - Success theme={null}
{
"ok": true
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"ok": false,
"error": "Invalid request!"
}
```
```json 404 - Campaign Not Found theme={null}
{
"error": "Campaign not found - Invalid campaign_id."
}
```
```json 422 - Validation Error theme={null}
{
"error": "email is required"
}
```
## Related Endpoints
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
* [Add Leads to Campaign](/api-reference/leads/add-to-campaign)
* [Delete Lead](/api-reference/leads/delete)
# IP Blacklist Check
Source: https://api.smartlead.ai/api-reference/smart-delivery/blacklists
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/blacklist
Check if sending IPs are listed on major email blacklists
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/blacklist?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/blacklist",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/blacklist?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"reply_id": "reply_001",
"reply": {
"from_email": "campaigns@example.com"
},
"to_email": "seed1@gmail.com",
"domain": "gmail.com",
"blacklist_type_value": "spamhaus",
"total_blacklist": 0,
"rdns": "mail.example.com",
"ip": "192.168.1.100",
"details": "IP not listed on Spamhaus"
},
{
"reply_id": "reply_002",
"reply": {
"from_email": "support@example.com"
},
"to_email": "seed3@yahoo.com",
"domain": "yahoo.com",
"blacklist_type_value": "barracuda",
"total_blacklist": 1,
"rdns": "mail2.example.com",
"ip": "192.168.1.101",
"details": "IP listed on Barracuda Block List"
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Create Automated Placement Test
Source: https://api.smartlead.ai/api-reference/smart-delivery/create-automated-test
POST https://smartdelivery.smartlead.ai/api/v1/spam-test/schedule
Create automated recurring spam test with scheduled monitoring
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://smartdelivery.smartlead.ai/api/v1/spam-test/schedule?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/schedule",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/schedule?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"created_at": "2026-03-15T14:30:00Z",
"updated_at": "2026-03-15T14:30:00Z",
"id": "test_888888",
"test_name": "Automated Recurring Test",
"description": "Weekly automated deliverability monitoring",
"spam_filters": true,
"link_checker": true,
"campaign_id": "camp_234567",
"sequence_mapping_id": "seq_890123",
"all_email_sent_without_time_gap": true,
"min_time_btwn_emails": 60,
"min_time_unit": "minutes",
"is_warmup": false,
"test_with_sl_account": true,
"has_seed_mapping": true,
"status": "active",
"user_id": "user_567890",
"test_type": "automated",
"email_track_id": "track_432109",
"provider_id": "outlook_eu",
"schedule_start_time": "2026-03-15T10:00:00Z",
"test_end_date": "2026-06-15T10:00:00Z",
"every_days": 7,
"scheduler_cron_value": "0 10 * * 0"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Create Folder
Source: https://api.smartlead.ai/api-reference/smart-delivery/create-folder
POST https://smartdelivery.smartlead.ai/api/v1/spam-test/folder
Create new folder for organizing spam tests
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://smartdelivery.smartlead.ai/api/v1/spam-test/folder?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"folderName": "My Folder"}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/folder",
params={"api_key": API_KEY},
json={"folderName": "My Folder"}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/folder?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ folderName: 'My Folder' })
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"id": "folder_003",
"name": "My Folder",
"user_id": "user_001",
"client_id": "client_001",
"created_at": "2026-03-15T14:30:00Z",
"updated_at": "2026-03-15T14:30:00Z"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Create Manual Placement Test
Source: https://api.smartlead.ai/api-reference/smart-delivery/create-manual-test
POST https://smartdelivery.smartlead.ai/api/v1/spam-test/manual
Create manual spam test where you send email to SmartLead test inboxes
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://smartdelivery.smartlead.ai/api/v1/spam-test/manual?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/manual",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/manual?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"created_at": "2026-03-15T14:30:00Z",
"updated_at": "2026-03-15T14:30:00Z",
"id": "test_999999",
"test_name": "Manual Placement Test",
"description": "Testing email deliverability across regions",
"spam_filters": true,
"link_checker": true,
"campaign_id": "camp_123456",
"sequence_mapping_id": "seq_789012",
"all_email_sent_without_time_gap": false,
"min_time_btwn_emails": 30,
"min_time_unit": "minutes",
"is_warmup": false,
"test_with_sl_account": false,
"has_seed_mapping": true,
"status": "active",
"user_id": "user_456789",
"test_type": "manual",
"email_track_id": "track_321098",
"provider_id": "gmail_na"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Delete Folder
Source: https://api.smartlead.ai/api-reference/smart-delivery/delete-folder
DELETE https://smartdelivery.smartlead.ai/api/v1/spam-test/folder/{folderId}
Delete an empty test folder
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X DELETE "https://smartdelivery.smartlead.ai/api/v1/spam-test/folder/{folderId}?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.delete(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/folder/{folderId}",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/folder/{folderId}?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"message": "Folder deleted successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Delete Tests in Bulk
Source: https://api.smartlead.ai/api-reference/smart-delivery/delete-tests-bulk
POST https://smartdelivery.smartlead.ai/api/v1/spam-test/delete
Delete multiple spam tests at once by test IDs
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://smartdelivery.smartlead.ai/api/v1/spam-test/delete?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/delete",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/delete?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"message": "Tests deleted successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# DKIM Details
Source: https://api.smartlead.ai/api-reference/smart-delivery/dkim-details
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/dkim-details
Check DKIM configuration status for sender domain authentication
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/dkim-details?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/dkim-details",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/dkim-details?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"from_email": "campaigns@example.com",
"seed_accounts": [
{
"id": "seed_001",
"email": "seed1@gmail.com",
"esp": "Gmail",
"dkim_verified": true
},
{
"id": "seed_002",
"email": "seed2@outlook.com",
"esp": "Outlook",
"dkim_verified": true
}
]
},
{
"from_email": "support@example.com",
"seed_accounts": [
{
"id": "seed_003",
"email": "seed3@yahoo.com",
"esp": "Yahoo",
"dkim_verified": false
}
]
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Domain Blacklist
Source: https://api.smartlead.ai/api-reference/smart-delivery/domain-blacklist
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/domain-blacklist
Check if sending domain is blacklisted
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/domain-blacklist?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/domain-blacklist",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/domain-blacklist?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"from_email": "campaigns@example.com",
"seed_accounts": [
{
"id": "seed_001",
"email": "seed1@gmail.com",
"esp": "Gmail",
"domain_blacklisted": false
},
{
"id": "seed_002",
"email": "seed2@outlook.com",
"esp": "Outlook",
"domain_blacklisted": false
}
]
},
{
"from_email": "support@example.com",
"seed_accounts": [
{
"id": "seed_003",
"email": "seed3@yahoo.com",
"esp": "Yahoo",
"domain_blacklisted": false
}
]
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Geo-wise Report
Source: https://api.smartlead.ai/api-reference/smart-delivery/geo-report
POST https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/groupwise
Analyze deliverability by geographic region
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/groupwise?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/groupwise",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/groupwise?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"overallTotalCount": 780,
"status": "completed",
"result": [
{
"region": "North America",
"inbox_rate": 92.5,
"spam_rate": 5.2,
"bounce_rate": 2.3,
"mailbox_count": 300
},
{
"region": "Europe",
"inbox_rate": 88.9,
"spam_rate": 8.1,
"bounce_rate": 3.0,
"mailbox_count": 280
},
{
"region": "Asia Pacific",
"inbox_rate": 85.3,
"spam_rate": 10.2,
"bounce_rate": 4.5,
"mailbox_count": 200
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Get Folder by ID
Source: https://api.smartlead.ai/api-reference/smart-delivery/get-folder-by-id
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/folder/{folderId}
Get details for a specific test folder
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/folder/{folderId}?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/folder/{folderId}",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/folder/{folderId}?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"id": "folder_001",
"name": "Q1 2026 Tests",
"user_id": "user_001",
"client_id": "client_001",
"created_at": "2026-01-01T10:00:00Z",
"updated_at": "2026-03-15T14:30:00Z"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Get All Folders
Source: https://api.smartlead.ai/api-reference/smart-delivery/get-folders
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/folder
List organizational folders for spam tests
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/folder?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/folder",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/folder?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"id": "folder_001",
"name": "Q1 2026 Tests",
"user_id": "user_001",
"client_id": "client_001",
"created_at": "2026-01-01T10:00:00Z",
"updated_at": "2026-03-15T14:30:00Z"
},
{
"id": "folder_002",
"name": "Q4 2025 Archive",
"user_id": "user_001",
"client_id": "client_001",
"created_at": "2025-10-01T10:00:00Z",
"updated_at": "2025-12-31T23:59:59Z"
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# IP Blacklist Count
Source: https://api.smartlead.ai/api-reference/smart-delivery/ip-blacklist-count
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/blacklist
Get count of blacklists your IP appears on for quick health check
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/blacklist?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/blacklist",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/blacklist?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"total_blacklist": 0
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# IP Details
Source: https://api.smartlead.ai/api-reference/smart-delivery/ip-details
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/ip-analytics
Get comprehensive information about sending IP addresses
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/ip-analytics?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/ip-analytics",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/ip-analytics?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"ip": "192.168.1.100",
"blacklisted": false,
"summary": "IP reputation is excellent with no blacklist listings",
"whois_data": {
"isp": "Example ISP",
"location": "United States",
"reverse_dns": "mail1.example.com",
"organization": "Example Organization"
},
"created_at": "2025-03-01T10:00:00Z"
},
{
"ip": "192.168.1.101",
"blacklisted": false,
"summary": "IP reputation is good with no blacklist listings",
"whois_data": {
"isp": "Example ISP",
"location": "United States",
"reverse_dns": "mail2.example.com",
"organization": "Example Organization"
},
"created_at": "2025-09-01T10:00:00Z"
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# List All Tests
Source: https://api.smartlead.ai/api-reference/smart-delivery/list-tests
POST https://smartdelivery.smartlead.ai/api/v1/spam-test/report
List all spam tests with filtering by date, type, and status
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://smartdelivery.smartlead.ai/api/v1/spam-test/report?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"spam_test_id": "test_001",
"test_name": "Gmail Inbox Placement Test",
"test_type": "automated",
"status": "active",
"schedule_start_time": "2026-03-10T09:00:00Z",
"test_end_date": "2026-06-10T09:00:00Z",
"every_days": 7,
"current_test_run_no": 8
},
{
"spam_test_id": "test_002",
"test_name": "Outlook Spam Filter Test",
"test_type": "manual",
"status": "completed",
"schedule_start_time": "2026-03-14T14:00:00Z",
"test_end_date": "2026-03-20T14:00:00Z",
"every_days": null,
"current_test_run_no": 1
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Mailbox Count
Source: https://api.smartlead.ai/api-reference/smart-delivery/mailbox-count
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/mailboxes-count
Get count of test mailboxes by provider
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/mailboxes-count?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/mailboxes-count",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/mailboxes-count?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"inbox_count": 264,
"spam_count": 12,
"tab_count": 24,
"failed_count": 0,
"total_email_count": 300
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Mailbox Summary
Source: https://api.smartlead.ai/api-reference/smart-delivery/mailbox-summary
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/mailboxes-summary
Get high-level summary of all test mailboxes
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/mailboxes-summary?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/mailboxes-summary",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/mailboxes-summary?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"id": "mb_001",
"from_email": "campaigns@example.com",
"esp": "Gmail",
"total_email_count": 100,
"inbox_count": 91,
"tab_count": 6,
"spam_count": 3,
"failed_count": 0,
"placement_score": 91.0
},
{
"id": "mb_002",
"from_email": "campaigns@example.com",
"esp": "Outlook",
"total_email_count": 100,
"inbox_count": 88,
"tab_count": 8,
"spam_count": 4,
"failed_count": 0,
"placement_score": 88.0
},
{
"id": "mb_003",
"from_email": "support@example.com",
"esp": "Yahoo",
"total_email_count": 100,
"inbox_count": 85,
"tab_count": 10,
"spam_count": 5,
"failed_count": 0,
"placement_score": 85.0
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Get Provider IDs
Source: https://api.smartlead.ai/api-reference/smart-delivery/provider-ids
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/seed/providers
Get region-wise email provider IDs for spam testing configuration
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/seed/providers?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/seed/providers",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/seed/providers?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"region_id": "na-1",
"region_name": "North America",
"groups": [
{
"group_id": "gmail_na",
"group_name": "Gmail",
"provider_count": 150
},
{
"group_id": "outlook_na",
"group_name": "Outlook",
"provider_count": 120
},
{
"group_id": "yahoo_na",
"group_name": "Yahoo",
"provider_count": 130
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Provider-wise Report
Source: https://api.smartlead.ai/api-reference/smart-delivery/provider-report
POST https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/providerwise
Get deliverability report by email provider (Gmail, Outlook, Yahoo)
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X POST "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/providerwise?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.post(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/providerwise",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/providerwise?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"overallTotalCount": 900,
"status": "completed",
"result": [
{
"provider": "Gmail",
"inbox_rate": 94.2,
"spam_rate": 3.8,
"bounce_rate": 2.0,
"mailbox_count": 350,
"avg_delivery_time_seconds": 45
},
{
"provider": "Outlook",
"inbox_rate": 88.5,
"spam_rate": 8.2,
"bounce_rate": 3.3,
"mailbox_count": 310,
"avg_delivery_time_seconds": 52
},
{
"provider": "Yahoo",
"inbox_rate": 89.1,
"spam_rate": 7.5,
"bounce_rate": 3.4,
"mailbox_count": 240,
"avg_delivery_time_seconds": 48
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# rDNS Report
Source: https://api.smartlead.ai/api-reference/smart-delivery/rdns-report
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/rdns-details
Check reverse DNS configuration for sending IP addresses
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/rdns-details?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/rdns-details",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/rdns-details?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"from_email": "campaigns@example.com",
"seed_accounts": [
{
"id": "seed_001",
"email": "seed1@gmail.com",
"esp": "Gmail",
"rdns_verified": true
},
{
"id": "seed_002",
"email": "seed2@outlook.com",
"esp": "Outlook",
"rdns_verified": true
}
]
},
{
"from_email": "support@example.com",
"seed_accounts": [
{
"id": "seed_003",
"email": "seed3@yahoo.com",
"esp": "Yahoo",
"rdns_verified": false
}
]
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Email Reply Headers
Source: https://api.smartlead.ai/api-reference/smart-delivery/reply-headers
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-account-wise/{replyId}/email-headers
Analyze email headers from test replies for advanced diagnostics
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-account-wise/{replyId}/email-headers?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-account-wise/{replyId}/email-headers",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-account-wise/{replyId}/email-headers?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"Return-Path": "",
"Received": "from mail.example.com ([192.168.1.100]) by mx.gmail.com with SMTP id abc123; Sat, 15 Mar 2026 15:30:00 +0000",
"Reveived-Spf": "pass (google.com: domain of campaigns@example.com designates 192.168.1.100 as permitted sender) client-ip=192.168.1.100;",
"Authentication-Results": "mx.gmail.com; dkim=pass (valid signature) header.d=example.com; spf=pass (google.com: domain of campaigns@example.com designates 192.168.1.100 as permitted sender) smtp.mailfrom=campaigns@example.com; dmarc=pass (p=quarantine dis=none) header.from=example.com"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Schedule History
Source: https://api.smartlead.ai/api-reference/smart-delivery/schedule-history
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/schedule-history
Get send history for automated tests with execution log
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/schedule-history?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/schedule-history",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/schedule-history?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"spam_test_id": "test_001",
"test_run_no": 15,
"status": "completed",
"inbox_count": 184,
"tab_count": 12,
"spam_count": 4,
"reply_hour_interval_start": 0,
"reply_hour_interval_end": 24,
"adjusted_total_email_count": 200
},
{
"spam_test_id": "test_001",
"test_run_no": 14,
"status": "completed",
"inbox_count": 181,
"tab_count": 14,
"spam_count": 5,
"reply_hour_interval_start": 0,
"reply_hour_interval_end": 24,
"adjusted_total_email_count": 200
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Sender Account List
Source: https://api.smartlead.ai/api-reference/smart-delivery/sender-list
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-accounts
List all sender accounts available for spam testing
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-accounts?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-accounts",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-accounts?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"id": "sender_001",
"spam_test_id": "test_101",
"from_email": "campaigns@example.com",
"created_at": "2026-02-01T10:00:00Z",
"updated_at": "2026-03-15T14:30:00Z",
"client_id": "client_001",
"user_id": "user_001"
},
{
"id": "sender_002",
"spam_test_id": "test_101",
"from_email": "support@example.com",
"created_at": "2026-02-15T10:00:00Z",
"updated_at": "2026-03-15T14:30:00Z",
"client_id": "client_001",
"user_id": "user_001"
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Sender Account Report
Source: https://api.smartlead.ai/api-reference/smart-delivery/sender-report
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-account-wise
Get performance report by sender email account
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-account-wise?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-account-wise",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/sender-account-wise?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"email": "campaigns@example.com",
"details": {
"sender_name": "Example Campaigns",
"tests_count": 12,
"avg_inbox_rate": 92.5,
"avg_spam_rate": 5.2,
"avg_bounce_rate": 2.3,
"reputation_score": 8.7,
"last_test_date": "2026-03-15T14:30:00Z"
}
},
{
"email": "support@example.com",
"details": {
"sender_name": "Example Support",
"tests_count": 8,
"avg_inbox_rate": 88.1,
"avg_spam_rate": 8.5,
"avg_bounce_rate": 3.4,
"reputation_score": 8.2,
"last_test_date": "2026-03-14T10:15:00Z"
}
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Spam Filter Report
Source: https://api.smartlead.ai/api-reference/smart-delivery/spam-filter-report
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/spam-filter-details
Detailed analysis of which spam filters triggered and why
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/spam-filter-details?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/spam-filter-details",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/spam-filter-details?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"from_email": "campaigns@example.com",
"spam_filter_details": [
{
"filter": "SpamAssassin",
"triggered_count": 5,
"trigger_percentage": 5.0,
"reasons": ["High spam score", "Missing DKIM signature"]
},
{
"filter": "Gmail Spam Filter",
"triggered_count": 3,
"trigger_percentage": 3.0,
"reasons": ["Suspicious sender reputation"]
}
]
},
{
"from_email": "support@example.com",
"spam_filter_details": [
{
"filter": "Outlook Junk Filter",
"triggered_count": 2,
"trigger_percentage": 2.0,
"reasons": ["Low reputation score"]
}
]
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# SPF Details
Source: https://api.smartlead.ai/api-reference/smart-delivery/spf-details
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/spf-details
Verify SPF record configuration for sender authorization
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/spf-details?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/spf-details",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/spf-details?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"from_email": "campaigns@example.com",
"seed_accounts": [
{
"id": "seed_001",
"email": "seed1@gmail.com",
"esp": "Gmail",
"spf_verified": true
},
{
"id": "seed_002",
"email": "seed2@outlook.com",
"esp": "Outlook",
"spf_verified": true
}
]
},
{
"from_email": "support@example.com",
"seed_accounts": [
{
"id": "seed_003",
"email": "seed3@yahoo.com",
"esp": "Yahoo",
"spf_verified": false
}
]
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Stop Automated Test
Source: https://api.smartlead.ai/api-reference/smart-delivery/stop-automated-test
PUT https://smartdelivery.smartlead.ai/api/v1/spam-test/{spamTestId}/stop
Stop a running automated spam test, preserves results
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl -X PUT "https://smartdelivery.smartlead.ai/api/v1/spam-test/{spamTestId}/stop?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.put(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/{spamTestId}/stop",
params={"api_key": API_KEY},
json={}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/{spamTestId}/stop?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"message": "Test stopped successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Get Spam Test Details
Source: https://api.smartlead.ai/api-reference/smart-delivery/test-details
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/{spamTestId}
Get complete spam test results including inbox placement and scores
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/{spamTestId}?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/{spamTestId}",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/{spamTestId}?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"id": "test_67890abcdef",
"test_name": "Q1 Campaign Spam Test",
"test_type": "manual",
"description": "Testing deliverability across major providers",
"folder_id": "folder_12345",
"link_checker": true,
"test_with_sl_account": false,
"campaign_id": "camp_345678",
"sequence_mapping_id": "seq_901234",
"provider_id": "gmail_na",
"client_id": "client_111111",
"user_id": "user_678901",
"created_at": "2026-03-15T14:30:00Z",
"updated_at": "2026-03-15T15:45:00Z"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Test Email Content
Source: https://api.smartlead.ai/api-reference/smart-delivery/test-email-content
GET https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/email-content
Get actual email content from a specific spam test
**Smart Delivery API**: This is part of SmartLead's deliverability testing suite. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access and API details.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/email-content?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/email-content",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smartdelivery.smartlead.ai/api/v1/spam-test/report/{spamTestId}/email-content?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"spamTest": "test_001",
"subject": "Special Q1 Offer - Limited Time",
"text": "Get 30% off your next purchase. Claim your offer at https://example.com/offer",
"html": "Q1 OfferSpecial Q1 Offer
Get 30% off your next purchase
Claim Offer",
"rawEmailContent": "From: campaigns@example.com\nSubject: Special Q1 Offer - Limited Time\nContent-Type: text/html\n\nSpecial Q1 Offer
"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
# Cities API
Source: https://api.smartlead.ai/api-reference/smart-prospect/cities
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/cities
List cities for the authenticated user - GET /cities
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of cities to return (1–100). Pattern: ^\[1-9]\[0-9]\*\$ or 100. Default: "10".
Number of cities to skip for pagination (≥ 0). Pattern: ^\[0-9]+\$. Default: "0".
Search string to match city names starting with this value (1–255 characters).
Filter by state name(s). Comma-separated values (e.g. california,texas,florida). 1–255 chars.
Filter by country name(s). Comma-separated values (e.g. usa,canada). Requires state. 1–255 chars.
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/cities?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "id": 1, "city_name": "Austin" },
{ "id": 2, "city_name": "Houston" }
],
"pagination": {
"limit": 10,
"offset": 0,
"page": 1,
"count": 2
},
"search": null
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Company API
Source: https://api.smartlead.ai/api-reference/smart-prospect/company
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/company
List companies for the authenticated user - GET /company
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of companies to return (optional). Default: 100.
Number of companies to skip for pagination (optional). Default: 0.
Search string to filter companies by name (optional).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/company?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "company_name": "Acme Corp" },
{ "company_name": "Tech Inc" }
]
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Countries API
Source: https://api.smartlead.ai/api-reference/smart-prospect/countries
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/countries
List countries for the authenticated user - GET /countries
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of countries to return (1–100). Pattern: ^\[1-9]\[0-9]\*\$ or 100. Default: "10".
Number of countries to skip for pagination (≥ 0). Pattern: ^\[0-9]+\$. Default: "0".
Search string to match country names starting with this value (1–255 characters).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/countries?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "id": 1, "country_name": "United States" },
{ "id": 2, "country_name": "United Kingdom" }
],
"pagination": {
"limit": 10,
"offset": 0,
"page": 1,
"count": 2
},
"search": null
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Departments API
Source: https://api.smartlead.ai/api-reference/smart-prospect/departments
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/departments
List departments for the authenticated user - GET /departments
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of departments to return (1–100). Pattern: ^\[1-9]\[0-9]\*\$ or 100. Default: "10".
Number of departments to skip for pagination (≥ 0). Pattern: ^\[0-9]+\$. Default: "0".
Search string to match department names starting with this value (1–255 characters).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/departments?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "id": 1, "department_name": "Engineering" },
{ "id": 2, "department_name": "Sales" }
],
"pagination": {
"limit": 10,
"offset": 0,
"page": 1,
"count": 2
},
"search": null
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Domain API
Source: https://api.smartlead.ai/api-reference/smart-prospect/domain
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/domain
List domains for the authenticated user - GET /domain
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of domains to return (optional). Default: 100.
Number of domains to skip for pagination (optional). Default: 0.
Search string to filter domains by name (optional).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/domain?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "domain_name": "acme.com" },
{ "domain_name": "techinc.com" }
]
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Fetch Contacts API
Source: https://api.smartlead.ai/api-reference/smart-prospect/fetch-contacts
POST https://prospect-api.smartlead.ai/api/v1/search-email-leads/fetch-contacts
Fetch contact emails by filter or by IDs - POST /fetch-contacts
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
## Request Body
The request body must be JSON. **`filter_id` is required.** You must provide either **`id`** (array of adapt IDs) with `filter_id`, or **`limit`** with `filter_id`. When using `limit`, it must be between 1 and 10000 (or 30000 for some users). Limit and credit checks apply when using `limit`; failures return **200** with `success: false` and an error message.
Filter ID (positive number).
Adapt IDs to fetch (use with filter\_id; no limit check). Required when not using limit.
Number of contacts to fetch for the filter (1–10000 or 1–30000 for some users). Required when not using id.
Page size for visual pagination (1–1000, default 10).
Offset for visual pagination (≥ 0, default 0).
```bash cURL theme={null}
curl -X POST "https://prospect-api.smartlead.ai/api/v1/search-email-leads/fetch-contacts?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filter_id": 327105, "limit": 10, "visual_limit": 10, "visual_offset": 0}'
```
## Response Codes
Request successful
Bad Request
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": {
"list": [
{
"id": "5f22b0c8cff47e0001616f81",
"firstName": "Orhan",
"lastName": "Demiri",
"fullName": "Orhan Demiri",
"title": "Director",
"company": { "name": "Example Corp", "website": "example.com" },
"email": "orhan@example.com",
"status": "completed"
}
],
"total_count": 1,
"visual_limit": 10,
"visual_offset": 0,
"metrics": {
"totalContacts": 1,
"totalEmails": 1,
"noEmailFound": 0,
"invalidEmails": 0,
"catchAllEmails": 0,
"verifiedEmails": 1,
"completed": 1
}
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Fetched Searches API
Source: https://api.smartlead.ai/api-reference/smart-prospect/fetched-searches
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/fetched-searches
Retrieve fetched leads (search filters with fetch data) for the authenticated user - GET /search-filters/fetched-searches
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of fetched searches to return (positive integer string). Pattern: ^\[1-9]\[0-9]\*\$. Default: "10".
Number of fetched searches to skip for pagination (non-negative integer string). Pattern: ^\[0-9]+\$. Default: "0".
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/fetched-searches?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": {
"fetchedLeads": [
{
"id": 327107,
"user_id": 2568,
"search_string": "Director in United States",
"filter_details": {
"title": ["Director"],
"country": ["United States"],
"limit": 100
},
"type": "saved",
"include_owned": false,
"is_saved": true,
"is_fetched": true,
"fetch_details": {
"metrics": {
"totalContacts": 500,
"totalEmails": 480,
"noEmailFound": 20,
"invalidEmails": 10,
"catchAllEmails": 5,
"verifiedEmails": 465,
"completed": 480
},
"leads_found": 500,
"email_fetched": 480
},
"created_at": "2025-01-15T10:00:00.000Z",
"updated_at": "2025-01-20T14:30:00.000Z"
}
],
"totalCount": 1
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Find Emails API
Source: https://api.smartlead.ai/api-reference/smart-prospect/find-emails
POST https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-contacts/find-emails
Find email addresses for up to 10 contacts - POST /search-contacts/find-emails
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
## Request Body
The request body must be JSON. **`contacts` is required** and must be a non-empty array with **at most 10 items**. Each contact must have **firstName**, **lastName**, and **companyDomain**.
Array of contacts (max 10 items)
First name of the contact
Last name of the contact
Company domain (e.g. example.com)
```bash cURL theme={null}
curl -X POST "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-contacts/find-emails?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{
"firstName": "John",
"lastName": "Doe",
"companyDomain": "example.com"
}
]
}'
```
## Response Codes
Request successful
Bad Request
Unauthorized
Payment Required
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Find emails completed",
"data": [
{
"firstName": "John",
"lastName": "Doe",
"companyDomain": "example.com",
"email_id": "john.doe@example.com",
"status": "Found",
"verification_status": "Valid"
},
{
"firstName": "Jane",
"lastName": "Smith",
"companyDomain": "acme.io",
"email_id": "",
"status": "Not Found",
"verification_status": null
}
]
}
```
```json 401 - Unauthorized theme={null}
{
"success": false,
"message": "User not authenticated",
"data": null
}
```
# Get Contacts API
Source: https://api.smartlead.ai/api-reference/smart-prospect/get-contacts
POST https://prospect-api.smartlead.ai/api/v1/search-email-leads/get-contacts
Retrieve saved contacts by filter or by adapt IDs - POST /get-contacts
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
## Request Body
The request body must be JSON. **Provide either `id` (array of adapt\_ids, max 200) or `filter_id` (number). Do not provide both (XOR).** When using `filter_id`, you may optionally include `limit`, `offset`, `search`, `verification_status`, and `catch_all_status`.
Array of adapt\_ids (max 200). Required when not using filter\_id.
Filter ID to get data for. Required when not using id.
Number of records to return (1–1000, optional when using filter\_id).
Number of records to skip (≥ 0, optional when using filter\_id).
Search string to filter by first\_name, last\_name, or full\_name.
Filter by email verification status: valid, catch\_all, or invalid.
Filter by catch-all status: catch\_all\_verified, catch\_all\_soft\_bounced, catch\_all\_hard\_bounced, catch\_all\_unknown, catch\_all\_bounced.
```bash cURL theme={null}
curl -X POST "https://prospect-api.smartlead.ai/api/v1/search-email-leads/get-contacts?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filter_id": 327105, "limit": 50, "offset": 0}'
```
## Response Codes
Request successful
Bad Request
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": {
"list": [
{
"id": "5f22b0c8cff47e0001616f81",
"firstName": "Orhan",
"lastName": "Demiri",
"fullName": "Orhan Demiri",
"title": "Director",
"company": { "name": "Example Corp", "website": "example.com" },
"email": "orhan@example.com",
"verificationStatus": "valid",
"status": "completed"
}
],
"pagination": {
"filterId": 327105,
"limit": 50,
"offset": 0,
"total": 100,
"hasMore": true
},
"totalCount": 100
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Head Counts API
Source: https://api.smartlead.ai/api-reference/smart-prospect/head-counts
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/head-counts
List head counts (company size ranges) for the authenticated user - GET /head-counts
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of head counts to return (1–100). Pattern: ^\[1-9]\[0-9]\*\$ or 100. Default: "10".
Number of head counts to skip for pagination (≥ 0). Pattern: ^\[0-9]+\$. Default: "0".
Search string to match head count values starting with this value (1–255 characters).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/head-counts?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "id": 1, "head_count": "1-10" },
{ "id": 2, "head_count": "11-50" }
],
"pagination": {
"limit": 10,
"offset": 0,
"page": 1,
"count": 2
},
"search": null
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Industries API
Source: https://api.smartlead.ai/api-reference/smart-prospect/industries
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/industries
List industries for the authenticated user - GET /industries
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of industries to return (1–100). Pattern: ^\[1-9]\[0-9]\*\$ or 100. Default: "10".
Number of industries to skip for pagination (≥ 0). Pattern: ^\[0-9]+\$. Default: "0".
Search string to match industry names starting with this value (1–255 characters).
Include sub-industries for each industry. Values: true or false.
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/industries?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{
"id": 1,
"industry_name": "Technology",
"sub_industry_list": [
{ "sub_industry_name": "Software" },
{ "sub_industry_name": "Hardware" }
]
},
{
"id": 2,
"industry_name": "Healthcare",
"sub_industry_list": []
}
],
"pagination": {
"limit": 10,
"offset": 0,
"page": 1,
"count": 2
},
"search": null
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Job Title API
Source: https://api.smartlead.ai/api-reference/smart-prospect/job-title
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/job-title
List job titles for the authenticated user - GET /job-title
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of job titles to return (optional). Default: 100.
Number of job titles to skip for pagination (optional). Default: 0.
Search string to filter job titles by name (optional).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/job-title?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "job_title": "Software Engineer" },
{ "job_title": "Product Manager" }
]
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Keywords API
Source: https://api.smartlead.ai/api-reference/smart-prospect/keywords
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/keywords
List keywords for the authenticated user - GET /keywords
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of keywords to return (optional). Default: 100.
Number of keywords to skip for pagination (optional). Default: 0.
Search string to filter keywords by name (optional).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/keywords?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Keywords retrieved successfully",
"data": [
{ "keyword": "marketing" },
{ "keyword": "sales" }
]
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Levels API
Source: https://api.smartlead.ai/api-reference/smart-prospect/levels
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/levels
List levels (job/seniority levels) for the authenticated user - GET /levels
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of levels to return (1–100). Pattern: ^\[1-9]\[0-9]\*\$ or 100. Default: "10".
Number of levels to skip for pagination (≥ 0). Pattern: ^\[0-9]+\$. Default: "0".
Search string to match level names starting with this value (1–255 characters).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/levels?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "id": 1, "level_name": "Entry" },
{ "id": 2, "level_name": "Senior" }
],
"pagination": {
"limit": 10,
"offset": 0,
"page": 1,
"count": 2
},
"search": null
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Recent Searches API
Source: https://api.smartlead.ai/api-reference/smart-prospect/recent-searches
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/recent-searches
Retrieve recent searches (search filters) for the authenticated user - GET /search-filters/recent-searches
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of recent searches to return (positive integer string). Pattern: ^\[1-9]\[0-9]\*\$. Default: "10".
Number of recent searches to skip for pagination (non-negative integer string). Pattern: ^\[0-9]+\$. Default: "0".
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/recent-searches?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": {
"recentSearches": [
{
"id": 327106,
"search_string": "Director in United States",
"filter_details": {
"title": ["Director"],
"country": ["United States"],
"limit": 100
},
"created_at": "2025-01-15T10:00:00.000Z",
"updated_at": "2025-01-20T14:30:00.000Z"
}
],
"totalCount": 1
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Reply Analytics API
Source: https://api.smartlead.ai/api-reference/smart-prospect/reply-analytics
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/reply-analytics
Retrieve reply analytics (replied count, trend) for the authenticated user - GET /reply-analytics
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/reply-analytics?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": {
"currentMonth": { "replied": 150 },
"previousMonth": { "replied": 120 },
"percentage_change": "+25%",
"trend": "increase"
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Revenue API
Source: https://api.smartlead.ai/api-reference/smart-prospect/revenue
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/revenue
List active revenue options for the authenticated user - GET /revenue
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/revenue?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "id": 1, "revenue": "$1M-$10M" },
{ "id": 2, "revenue": "$10M-$50M" }
]
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Review Contacts API
Source: https://api.smartlead.ai/api-reference/smart-prospect/review-contacts
PATCH https://prospect-api.smartlead.ai/api/v1/search-email-leads/review-contacts/{filter_id}
Review/update contacts for a filter (sync metrics and status) - PATCH /review-contacts/:filter_id
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Path Parameters
Filter ID to review contacts for (positive integer string, e.g. 327105). Pattern: ^\[0-9]+\$.
## Query Parameters
Your SmartLead API key for authentication
```bash cURL theme={null}
curl -X PATCH "https://prospect-api.smartlead.ai/api/v1/search-email-leads/review-contacts/327105?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Bad Request
Unauthorized
Not Found
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Contacts reviewed successfully",
"data": {
"filter_id": 327105,
"records_updated": 150,
"fetch_details": {
"metrics": {
"totalContacts": 200,
"totalEmails": 180,
"noEmailFound": 20,
"invalidEmails": 10,
"catchAllEmails": 5,
"verifiedEmails": 165,
"completed": 180
},
"leads_found": 200,
"email_fetched": 180,
"catch_all_status_list": ["catch_all_verified", "catch_all_unknown"],
"verification_status_list": ["valid", "invalid"]
}
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Save Search API
Source: https://api.smartlead.ai/api-reference/smart-prospect/save-search
POST https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/save-search
Save a search filter for the authenticated user - POST /search-filters/save-search
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
## Request Body
The request body must be JSON. **`search_string` is required** (human-readable name for the saved search). All other fields are optional search criteria.
Human-readable name for the saved search (min length 1).
Full name(s) to search.
First name(s).
Last name(s).
Job title(s).
Titles to exclude.
Titles to include.
Companies to exclude.
Company domains to exclude.
Companies to include.
Company domains to include.
Department(s).
Seniority level(s).
Company name(s).
Company domain(s).
Company keyword(s).
Company headcount(s).
Company revenue range(s).
Industry(ies).
Sub-industry(ies).
City(ies).
State(s).
Country(ies).
Whether to hide owned contacts.
Result limit (1–10000).
Match title exactly.
Match company exactly.
Match company domain exactly.
```bash cURL theme={null}
curl -X POST "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/save-search?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"search_string": "Directors in United States"}'
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Search saved successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Saved Searches API
Source: https://api.smartlead.ai/api-reference/smart-prospect/saved-searches
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/saved-searches
Retrieve saved searches (search filters) for the authenticated user - GET /search-filters/saved-searches
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of saved searches to return (positive integer string). Pattern: ^\[1-9]\[0-9]\*\$. Default: "10".
Number of saved searches to skip for pagination (non-negative integer string). Pattern: ^\[0-9]+\$. Default: "0".
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/saved-searches?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": {
"savedSearches": [
{
"id": 327105,
"search_string": "Director in United States",
"filter_details": {
"title": ["Director"],
"country": ["United States"],
"limit": 100
},
"created_at": "2025-01-15T10:00:00.000Z",
"updated_at": "2025-01-20T14:30:00.000Z"
}
],
"totalCount": 1
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Search Analytics API
Source: https://api.smartlead.ai/api-reference/smart-prospect/search-analytics
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-analytics
Retrieve search analytics (leads found, emails fetched, credits) for the authenticated user - GET /search-analytics
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Optional filter ID to get analytics for a specific filter (leads found, emails fetched for that filter). Pattern: ^\[0-9]+\$.
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-analytics?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": {
"leadsFound": {
"current": 1200,
"previousMonth": 1000,
"percentageChange": 20,
"percentageChangeText": "+20%",
"trend": "increase",
"total": 5000
},
"emailsFetched": {
"current": 1100,
"previousMonth": 950,
"percentageChange": 15.79,
"percentageChangeText": "+15.79%",
"trend": "increase",
"total": 4500
},
"availableCredits": {
"available": 500,
"total": 1000,
"used": 500
},
"leadsFoundToday": 50,
"filterData": {
"leadsFound": 200,
"emailsFetched": 180
},
"maxDailyFetchLimit": 1000,
"maxSingleFetchLimit": 500
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Search Contacts API
Source: https://api.smartlead.ai/api-reference/smart-prospect/search-contacts
POST https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-contacts
Search for contacts with filters - POST /search-contacts
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
## Request Body
The request body must be JSON. **`limit` is required** and must be between 1 and 500. **All array parameters have a maximum of 2000 items** each.
Number of contacts to return (1–500)
Filter by full name (max 2000 items)
Filter by first name (max 2000 items)
Filter by last name (max 2000 items)
Filter by job title (max 2000 items)
Exclude contacts with these titles (max 2000 items)
Exclude these companies (max 2000 items)
Exclude these company domains (max 2000 items)
Include only these titles (max 2000 items)
Include only these companies (max 2000 items)
Include only these company domains (max 2000 items)
Filter by department (max 2000 items)
Filter by seniority level (max 2000 items)
Filter by company name (max 2000 items)
Filter by company domain (max 2000 items)
Filter by company keyword (max 2000 items)
Filter by company headcount range (max 2000 items)
Filter by company revenue (max 2000 items)
Filter by industry (max 2000 items)
Filter by sub-industry (max 2000 items)
Filter by city (max 2000 items)
Filter by state (max 2000 items)
Filter by country (max 2000 items)
Exclude contacts already owned
Pagination scroll ID for next page
Match title exactly
Match company exactly
Match company domain exactly
```bash cURL theme={null}
curl -X POST "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-contacts?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"limit": 10}'
```
## Response Codes
Request successful
Bad Request
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Contacts searched successfully",
"data": {
"list": [
{
"id": "5f22b0e8cff47e0001616f81",
"firstName": "Orhan",
"lastName": "Demiri",
"fullName": "Orhan Demiri",
"title": "Generalagentur Agenturleiter",
"company": {
"name": "Gothaer",
"website": "gothaer.de"
},
"department": ["Sales"],
"level": "Staff",
"industry": "Financial Services",
"subIndustry": "",
"companyHeadCount": "1K - 10K",
"companyRevenue": "> $1B",
"country": "Germany",
"state": "",
"city": "",
"email": "random@example.com",
"linkedin": "linkedin.com/random_data",
"emailDeliverability": 0.95,
"address": "Germany"
},
{
"id": "5f22b1a0cff47e000161b01f",
"firstName": "Tim",
"lastName": "Ziegler",
"fullName": "Tim Ziegler",
"title": "Director of Sales and Business Development",
"company": {
"name": "soluzione Script GmbH",
"website": "soluzione.de"
},
"department": ["Sales"],
"level": "Director-Level",
"industry": "Education",
"subIndustry": "E-Learning",
"companyHeadCount": "25 - 100",
"companyRevenue": "$1 - 10M",
"country": "Germany",
"state": "Bavaria",
"city": "Bavaria",
"email": "random@example.com",
"linkedin": "linkedin.com/random_data",
"emailDeliverability": 0.95,
"address": "Bavaria"
}
],
"scroll_id": "FGluY2x1ZGVfY29udGV4dF91dWlkDXF1ZXJ5QW5kRmV0Y2gBFkh5d0FSVjZaUXlpbzdWYWkxRV9DNGcAAAAAADUQGhZlT2V0Z0ptSVNyYWQwbk9kYTFsRXhB",
"filter_id": 327105,
"total_count": 16064669
}
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "API key is required"
}
```
# States API
Source: https://api.smartlead.ai/api-reference/smart-prospect/states
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/states
List states for the authenticated user - GET /states
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of states to return (1–100). Pattern: ^\[1-9]\[0-9]\*\$ or 100. Default: "10".
Number of states to skip for pagination (≥ 0). Pattern: ^\[0-9]+\$. Default: "0".
Search string to match state names starting with this value (1–255 characters).
Filter by country name(s). Comma-separated values (e.g. india,usa,canada). 1–255 chars.
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/states?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "id": 1, "state_name": "Texas" },
{ "id": 2, "state_name": "California" }
],
"pagination": {
"limit": 10,
"offset": 0,
"page": 1,
"count": 2
},
"search": null
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Sub-Industries API
Source: https://api.smartlead.ai/api-reference/smart-prospect/sub-industries
GET https://prospect-api.smartlead.ai/api/v1/search-email-leads/sub-industries
List sub-industries for the authenticated user - GET /sub-industries
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Query Parameters
Your SmartLead API key for authentication
Number of sub-industries to return (1–100). Pattern: ^\[1-9]\[0-9]\*\$ or 100. Default: "10".
Number of sub-industries to skip for pagination (≥ 0). Pattern: ^\[0-9]+\$. Default: "0".
Search string to match sub-industry names starting with this value (1–255 characters).
Filter by industry ID (positive integer string).
```bash cURL theme={null}
curl -X GET "https://prospect-api.smartlead.ai/api/v1/search-email-leads/sub-industries?api_key=YOUR_API_KEY"
```
## Response Codes
Request successful
Unauthorized
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Data retrieved successfully",
"data": [
{ "id": 1, "sub_industry_name": "Software", "industry_id": 1 },
{ "id": 2, "sub_industry_name": "Hardware", "industry_id": 1 }
],
"pagination": {
"limit": 10,
"offset": 0,
"page": 1,
"count": 2
},
"search": null,
"industry_id": null
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Update Fetched Lead API
Source: https://api.smartlead.ai/api-reference/smart-prospect/update-fetched-lead
PUT https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/fetched-searches/{id}
Update a fetched lead (search string/name) by ID - PUT /search-filters/fetched-searches/:id
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Path Parameters
The ID of the fetched lead to update (positive integer string, e.g. 327107). Pattern: ^\[1-9]\[0-9]\*\$.
## Query Parameters
Your SmartLead API key for authentication
## Request Body
The request body must be JSON. **`search_string` is required** (the new name for the fetched lead).
The new search string/name for the fetched lead (1–255 characters).
```bash cURL theme={null}
curl -X PUT "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/fetched-searches/327107?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"search_string": "Directors and VPs in United States"}'
```
## Response Codes
Request successful
Bad Request
Unauthorized
Forbidden
Not Found
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Fetched lead updated successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Update Saved Search API
Source: https://api.smartlead.ai/api-reference/smart-prospect/update-saved-search
PUT https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/save-search/{id}
Update a saved search (search string/name) by ID - PUT /search-filters/save-search/:id
This endpoint requires authentication via API key passed as a query parameter (`api_key`).
## Path Parameters
The ID of the saved search to update (positive integer string, e.g. 327105). Pattern: ^\[1-9]\[0-9]\*\$.
## Query Parameters
Your SmartLead API key for authentication
## Request Body
The request body must be JSON. **`search_string` is required** (the new name for the saved search).
The new search string/name for the saved search (1–255 characters).
```bash cURL theme={null}
curl -X PUT "https://prospect-api.smartlead.ai/api/v1/search-email-leads/search-filters/save-search/327105?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"search_string": "Directors and VPs in United States"}'
```
## Response Codes
Request successful
Bad Request
Unauthorized
Not Found
Internal Server Error
```json 200 - Success theme={null}
{
"success": true,
"message": "Saved search updated successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"statusCode": 401,
"success": false,
"message": "Unauthorized",
"error": "User not authenticated"
}
```
# Auto Generate Mailboxes
Source: https://api.smartlead.ai/api-reference/smart-senders/auto-generate
POST https://smart-senders.smartlead.ai/api/v1/smart-senders/auto-generate-mailboxes
Auto-generate professional mailbox email addresses for one or more domains
**Smart Senders API**: Mailbox marketplace feature. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access.
## Query Parameters
API key used to authenticate and authorize the request.
## Body Parameters
Unique identifier of the vendor whose mailbox generation logic will be used.
List of domains for which mailboxes need to be generated.
## Headers
Must be `application/json`
```bash cURL theme={null}
curl -X POST "https://smart-senders.smartlead.ai/api/v1/smart-senders/auto-generate-mailboxes?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"vendor_id": "1",
"domains": {
"example.com": {
"count": 3
}
}
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
payload = {
"vendor_id": "1",
"domains": {
"example.com": {
"count": 3
}
}
}
response = requests.post(
"https://smart-senders.smartlead.ai/api/v1/smart-senders/auto-generate-mailboxes",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const payload = {
vendor_id: '1',
domains: {
'example.com': {
count: 3
}
}
};
const response = await fetch(
`https://smart-senders.smartlead.ai/api/v1/smart-senders/auto-generate-mailboxes?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Returns auto-generated mailbox email addresses for the requested domains.
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Server error occurred. Please try again or contact support if the issue persists.
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get Purchased Domain List
Source: https://api.smartlead.ai/api-reference/smart-senders/domain-list
GET https://smart-senders.smartlead.ai/api/v1/smart-senders/get-domain-list
Get the list of domains purchased through Smart Senders
**Smart Senders API**: Mailbox marketplace feature. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access.
## Query Parameters
API key used to authenticate and authorise the request.
## Headers
`application/json` (not required for GET, but safe to include)
```bash cURL theme={null}
curl "https://smart-senders.smartlead.ai/api/v1/smart-senders/get-domain-list?api_key=YOUR_API_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smart-senders.smartlead.ai/api/v1/smart-senders/get-domain-list",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smart-senders.smartlead.ai/api/v1/smart-senders/get-domain-list?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Returns the list of domains purchased through Smart Senders.
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Server error occurred. Please try again or contact support if the issue persists.
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get OTP for Admin Mailbox
Source: https://api.smartlead.ai/api-reference/smart-senders/get-otp
GET https://smart-senders.smartlead.ai/api/v1/smart-senders/auth-secret
Fetch a one-time password for an admin mailbox
**Smart Senders API**: Mailbox marketplace feature. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access.
## Query Parameters
API key used to authenticate and authorize the request.
The email address for which the OTP should be generated.
```bash cURL theme={null}
curl "https://smart-senders.smartlead.ai/api/v1/smart-senders/auth-secret?api_key=YOUR_API_KEY&email_account=admin@example.com"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smart-senders.smartlead.ai/api/v1/smart-senders/auth-secret",
params={
"api_key": API_KEY,
"email_account": "admin@example.com"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const params = new URLSearchParams({
api_key: API_KEY,
email_account: 'admin@example.com'
});
const response = await fetch(
`https://smart-senders.smartlead.ai/api/v1/smart-senders/auth-secret?${params}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Returns the one-time password for the specified admin mailbox.
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Server error occurred. Please try again or contact support if the issue persists.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"otp": "847192",
"expires_in": 300
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get Vendors
Source: https://api.smartlead.ai/api-reference/smart-senders/get-vendors
GET https://smart-senders.smartlead.ai/api/v1/smart-senders/get-vendors
Get list of active mailbox vendors with pricing and service details
**Smart Senders API**: Mailbox marketplace feature. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access.
## Query Parameters
Your SmartLead API key
```bash cURL theme={null}
curl "https://smart-senders.smartlead.ai/api/v1/smart-senders/get-vendors?api_key=YOUR_API_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smart-senders.smartlead.ai/api/v1/smart-senders/get-vendors",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://smart-senders.smartlead.ai/api/v1/smart-senders/get-vendors?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Returns all active vendors with their corresponding IDs and details.
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Server error occurred. Please try again or contact support if the issue persists.
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Get Order Details
Source: https://api.smartlead.ai/api-reference/smart-senders/order-details
GET https://smart-senders.smartlead.ai/api/v1/smart-senders/order-details
Retrieve the status and details of a specific order placed through Smart Senders
**Smart Senders API**: Mailbox marketplace feature. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access.
## Query Parameters
API key used to authenticate and authorize the request.
Unique order reference ID for which details are being requested.
```bash cURL theme={null}
curl "https://smart-senders.smartlead.ai/api/v1/smart-senders/order-details?api_key=YOUR_API_KEY&order_id=ORD_12345"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smart-senders.smartlead.ai/api/v1/smart-senders/order-details",
params={
"api_key": API_KEY,
"order_id": "ORD_12345"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const params = new URLSearchParams({
api_key: API_KEY,
order_id: 'ORD_12345'
});
const response = await fetch(
`https://smart-senders.smartlead.ai/api/v1/smart-senders/order-details?${params}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Returns the order status, payment details, and related messages.
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Server error occurred. Please try again or contact support if the issue persists.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"order_id": "ORD_12345",
"status": "completed",
"domain": "sales-outreach.com",
"email_accounts": [
{
"email": "john.smith@sales-outreach.com",
"password": "encrypted_password_hash"
},
{
"email": "alice.johnson@sales-outreach.com",
"password": "encrypted_password_hash"
}
],
"created_at": "2026-02-10T14:22:00Z",
"expires_at": "2026-03-10T14:22:00Z"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Place Order
Source: https://api.smartlead.ai/api-reference/smart-senders/place-order
POST https://smart-senders.smartlead.ai/api/v1/smart-senders/place-order
Place an order to purchase domains and provision mailboxes through a Smart Senders vendor
**Smart Senders API**: Mailbox marketplace feature. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access.
## Query Parameters
API key used to authenticate and authorise the request.
## Body Parameters
Unique identifier of the vendor with whom the order will be placed.
Domain to which purchased domains will be configured to forward (e.g., `example.com` or customer's tracking domain).
Customer billing/contact details required by the vendor for domain purchase and provisioning. Fields include:
* `email` (string) — Contact email
* `firstName` (string) — First name
* `lastName` (string) — Last name
* `company` (string) — Company name
* `country` (string) — Country
* `city` (string) — City
* `addressLineOne` (string) — Primary address
* `addressLineTwo` (string) — Secondary address (optional)
* `postalCode` (string) — Postal/ZIP code
* `state` (string) — State/province
* `phoneCc` (string) — Phone country code (e.g., `+91`)
* `phone` (string) — Phone number
* `languagePreference` (string) — Language preference (e.g., `en`)
Array of domain objects. Each object contains:
* `domain_name` (string) — The domain to purchase
* `mailbox_details` (array) — Array of mailbox objects, each containing:
* `mailbox` (string, required) — Full email address for the mailbox
* `first_name` (string, required) — First name for the mailbox
* `last_name` (string, required) — Last name for the mailbox
* `profile_pic` (string) — Profile picture filename
* `parent_account_id` (number) — ID of the parent email account to link to (optional)
## Headers
Must be `application/json`
```bash cURL theme={null}
curl -X POST "https://smart-senders.smartlead.ai/api/v1/smart-senders/place-order?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"vendor_id": 2,
"forwarding_domain": "example.com",
"user_details": {
"email": "manjit@example.com",
"firstName": "Manjit",
"lastName": "Singh",
"company": "Smartlead",
"country": "India",
"city": "Bangalore",
"addressLineOne": "123 MG Road",
"addressLineTwo": "",
"postalCode": "560001",
"state": "Karnataka",
"phoneCc": "+91",
"phone": "9876543210",
"languagePreference": "en"
},
"domains": [
{
"domain_name": "example.com",
"mailbox_details": [
{
"mailbox": "manjit.singh@example.com",
"first_name": "Manjit",
"last_name": "Singh",
"profile_pic": "profile1.jpg",
"parent_account_id": 123
},
{
"mailbox": "singh@example.com",
"first_name": "Manjit",
"last_name": "Singh",
"profile_pic": "profile2.jpg"
}
]
},
{
"domain_name": "testdomain.com",
"mailbox_details": [
{
"mailbox": "john.doe@testdomain.com",
"first_name": "John",
"last_name": "Doe",
"profile_pic": "profile3.jpg"
}
]
}
]
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
payload = {
"vendor_id": 2,
"forwarding_domain": "example.com",
"user_details": {
"email": "manjit@example.com",
"firstName": "Manjit",
"lastName": "Singh",
"company": "Smartlead",
"country": "India",
"city": "Bangalore",
"addressLineOne": "123 MG Road",
"addressLineTwo": "",
"postalCode": "560001",
"state": "Karnataka",
"phoneCc": "+91",
"phone": "9876543210",
"languagePreference": "en"
},
"domains": [
{
"domain_name": "example.com",
"mailbox_details": [
{
"mailbox": "manjit.singh@example.com",
"first_name": "Manjit",
"last_name": "Singh",
"profile_pic": "profile1.jpg",
"parent_account_id": 123
},
{
"mailbox": "singh@example.com",
"first_name": "Manjit",
"last_name": "Singh",
"profile_pic": "profile2.jpg"
}
]
},
{
"domain_name": "testdomain.com",
"mailbox_details": [
{
"mailbox": "john.doe@testdomain.com",
"first_name": "John",
"last_name": "Doe",
"profile_pic": "profile3.jpg"
}
]
}
]
}
response = requests.post(
"https://smart-senders.smartlead.ai/api/v1/smart-senders/place-order",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const payload = {
vendor_id: 2,
forwarding_domain: 'example.com',
user_details: {
email: 'manjit@example.com',
firstName: 'Manjit',
lastName: 'Singh',
company: 'Smartlead',
country: 'India',
city: 'Bangalore',
addressLineOne: '123 MG Road',
addressLineTwo: '',
postalCode: '560001',
state: 'Karnataka',
phoneCc: '+91',
phone: '9876543210',
languagePreference: 'en'
},
domains: [
{
domain_name: 'example.com',
mailbox_details: [
{
mailbox: 'manjit.singh@example.com',
first_name: 'Manjit',
last_name: 'Singh',
profile_pic: 'profile1.jpg',
parent_account_id: 123
},
{
mailbox: 'singh@example.com',
first_name: 'Manjit',
last_name: 'Singh',
profile_pic: 'profile2.jpg'
}
]
},
{
domain_name: 'testdomain.com',
mailbox_details: [
{
mailbox: 'john.doe@testdomain.com',
first_name: 'John',
last_name: 'Doe',
profile_pic: 'profile3.jpg'
}
]
}
]
};
const response = await fetch(
`https://smart-senders.smartlead.ai/api/v1/smart-senders/place-order?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Order placed successfully. Returns order confirmation details.
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Server error occurred. Please try again or contact support if the issue persists.
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Search Domain
Source: https://api.smartlead.ai/api-reference/smart-senders/search-domain
GET https://smart-senders.smartlead.ai/api/v1/smart-senders/search-domain
Search for available domains in Smart Senders marketplace
**Smart Senders API**: Mailbox marketplace feature. Contact [support@smartlead.ai](mailto:support@smartlead.ai) for access.
## Query Parameters
The authentication key used to verify and authorise the API request from the client.
The domain name for which availability or related operations are being requested.
The unique identifier of the vendor whose service will be used to process the domain request.
```bash cURL theme={null}
curl "https://smart-senders.smartlead.ai/api/v1/smart-senders/search-domain?api_key=YOUR_API_KEY&vendor_id=1&domain_name=techbuilddemo"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://smart-senders.smartlead.ai/api/v1/smart-senders/search-domain",
params={
"api_key": API_KEY,
"vendor_id": 1,
"domain_name": "techbuilddemo"
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const params = new URLSearchParams({
api_key: API_KEY,
vendor_id: '1',
domain_name: 'techbuilddemo'
});
const response = await fetch(
`https://smart-senders.smartlead.ai/api/v1/smart-senders/search-domain?${params}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Returns available domains matching the search criteria. Domains are priced at \$15 or less.
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
Server error occurred. Please try again or contact support if the issue persists.
```json 200 - Success theme={null}
{
"ok": true,
"data": []
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
# Domain Block List Management
Source: https://api.smartlead.ai/api-reference/utilities/domain-block-list
Comprehensive domain and email block list management.
Comprehensive domain and email block list management GET retrieves paginated block list with filtering by client assignment and search terms
## Overview
Comprehensive domain and email block list management
**Key Features**:
* Returns blocked entries with: email/domain, source (manual/bounce/spam), creation date, client association
## Get Domain Block List
### GET /v1/leads/get-domain-block-list
Retrieves entries from your domain block list with pagination.
**Query Parameters**:
* `api_key` (required): Your API key
* `offset` (optional, default: 0): Pagination offset
* `limit` (optional, default: 100, max: 1000): Number of records
* `filter_client_id` (optional): Filter by client ID
* `filter_email_or_domain` (optional): Search by email or domain name
* `filter_email_with_domain` (optional): Search by email with domain
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/leads/get-domain-block-list?api_key=YOUR_KEY&offset=0&limit=100&filter_client_id=1&filter_email_or_domain=example.com"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/leads/get-domain-block-list",
params={
"api_key": API_KEY,
"offset": 0,
"limit": 100,
"filter_client_id": 1,
"filter_email_or_domain": "example.com"
}
)
block_list = response.json()
print(f"Found {len(block_list)} blocked entries")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/leads/get-domain-block-list?api_key=${API_KEY}&offset=0&limit=100&filter_client_id=1&filter_email_or_domain=example.com`
);
const blockList = await response.json();
console.log(`Found ${blockList.length} blocked entries`);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
[
{
"id": 228361167,
"email_or_domain": "competitor.com",
"created_at": "2025-11-25T12:38:45.193Z",
"source": "Smartlead.ai Bounce Detection",
"client_id": null
}
]
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Limit must be between 1 and 1000"
}
```
***
## Add to Block List
### POST /v1/leads/add-domain-block-list
Adds domains or email addresses to the global block list.
**Query Parameters**:
* `api_key` (required): Your API key
**Request Body**:
* `domain_block_list` (required): Array of domains/emails to block
* `client_id` (optional): Associate with specific client
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/leads/add-domain-block-list?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain_block_list": ["competitor.com", "spam@example.com"],
"client_id": null
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
payload = {
"domain_block_list": ["competitor.com", "spam@example.com"],
"client_id": None
}
response = requests.post(
"https://server.smartlead.ai/api/v1/leads/add-domain-block-list",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(f"Added {len(payload['domain_block_list'])} entries to block list")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const payload = {
domain_block_list: ['competitor.com', 'spam@example.com'],
client_id: null
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/leads/add-domain-block-list?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log('Block list updated');
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"message": "3 entries added to block list"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "domain_block_list must be an array"
}
```
***
## Delete from Block List
### DELETE /v1/leads/delete-domain-block-list
Removes an entry from the block list.
**Query Parameters**:
* `api_key` (required): Your API key
* `id` (required): ID of the block list entry to delete
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/leads/delete-domain-block-list?api_key=YOUR_KEY&id=123"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
block_list_id = 123
response = requests.delete(
"https://server.smartlead.ai/api/v1/leads/delete-domain-block-list",
params={
"api_key": API_KEY,
"id": block_list_id
}
)
if response.status_code == 200:
print("Entry removed from block list")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const blockListId = 123;
const response = await fetch(
`https://server.smartlead.ai/api/v1/leads/delete-domain-block-list?api_key=${API_KEY}&id=${blockListId}`,
{ method: 'DELETE' }
);
console.log('Entry removed from block list');
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"message": "Entry deleted successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Block list entry not found"
}
```
# Send Single Email
Source: https://api.smartlead.ai/api-reference/utilities/send-single-email
POST https://server.smartlead.ai/api/v1/send-email/initiate
Send one-off transactional email outside of campaigns with attachments
## Path Parameters
No path parameters
## Query Parameters
Your SmartLead API key
## Request Body
Recipient email address
Email subject line
Email body content (HTML or plain text)
Sender email address. Either `fromEmail` or `fromEmailId` is required
ID of the sender email account. Either `fromEmail` or `fromEmailId` is required
Display name for the sender (optional)
Reply-to email address (optional)
Array of attachment objects (optional). Each attachment requires:
* `filename` (string): Name of the file
* `content` (string): Base64-encoded file content
* `mimeType` (string): MIME type of the file (e.g., "application/pdf")
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/send-email/initiate?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "recipient@example.com",
"subject": "Welcome to SmartLead",
"body": "Hello!
This is your welcome email.
",
"fromEmail": "sender@example.com",
"fromName": "SmartLead Team",
"replyTo": "support@example.com",
"attachments": []
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
payload = {
"to": "recipient@example.com",
"subject": "Welcome to SmartLead",
"body": "Hello!
This is your welcome email.
",
"fromEmail": "sender@example.com",
"fromName": "SmartLead Team",
"replyTo": "support@example.com",
"attachments": []
}
response = requests.post(
"https://server.smartlead.ai/api/v1/send-email/initiate",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const payload = {
to: 'recipient@example.com',
subject: 'Welcome to SmartLead',
body: 'Hello!
This is your welcome email.
',
fromEmail: 'sender@example.com',
fromName: 'SmartLead Team',
replyTo: 'support@example.com',
attachments: []
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/send-email/initiate?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"success": true,
"data": {
"message": "Email sent successfully",
"message_id": "msg_67890abcde"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Related Endpoints
* [Related endpoint](#)
# Create Webhook
Source: https://api.smartlead.ai/api-reference/webhooks/create
POST https://server.smartlead.ai/api/v1/webhook/create
Create webhook to receive real-time notifications for campaign events like opens, clicks, and replies
Webhooks allow you to receive real-time HTTP POST notifications when specific events occur in your campaigns. Configure webhooks at user, client, or campaign level.
## Query Parameters
Your SmartLead API key
## Request Body
The URL where webhook notifications will be sent via HTTP POST
Scope of the webhook. Valid values:
* `user` - User level (all campaigns)
* `client` - Client level (all campaigns for a client)
* `campaign` - Campaign level (single campaign)
Campaign ID (required when association\_type=3)
Webhook name for identification
Map of events to subscribe to. Set each event key to `true` to enable. Available events:
* `EMAIL_SENT` - Email sent
* `FIRST_EMAIL_SENT` - First email of sequence sent
* `EMAIL_OPEN` - Email opened
* `EMAIL_LINK_CLICK` - Link clicked
* `EMAIL_REPLY` - Lead replied
* `EMAIL_BOUNCE` - Email bounced
* `LEAD_UNSUBSCRIBED` - Lead unsubscribed
* `LEAD_CATEGORY_UPDATED` - Lead category changed
* `CAMPAIGN_STATUS_CHANGED` - Campaign status changed
* `UNTRACKED_REPLIES` - Untracked reply received
* `MANUAL_STEP_REACHED` - Manual step reached in sequence
Map of category IDs to filter events by lead category
Client ID (required when association\_type=2)
Specific event type to subscribe to
Specific lead category ID to filter events by
Webhook type identifier
Force creation even if a similar webhook exists
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/webhook/create?api_key=YOUR_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,
"EMAIL_OPEN": true
}
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
payload = {
"name": "Reply Notifications",
"webhook_url": "https://your-domain.com/webhook",
"email_campaign_id": 123,
"association_type": "campaign",
"event_type_map": {
"EMAIL_REPLY": True,
"EMAIL_OPEN": True
}
}
response = requests.post(
"https://server.smartlead.ai/api/v1/webhook/create",
params={"api_key": API_KEY},
json=payload
)
result = response.json()
print(f"Webhook created with ID: {result['id']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const payload = {
name: 'Reply Notifications',
webhook_url: 'https://your-domain.com/webhook',
email_campaign_id: 123,
association_type: 'campaign',
event_type_map: {
EMAIL_REPLY: true,
EMAIL_OPEN: true
}
};
const response = await fetch(
`https://server.smartlead.ai/api/v1/webhook/create?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}
);
const result = await response.json();
console.log(`Webhook created with ID: ${result.id}`);
```
## Webhook Payload
When an event occurs, SmartLead sends a POST request to your `webhook_url`. The payload structure varies by event type. Here's an example for `EMAIL_REPLY`:
```json theme={null}
{
"event_type": "EMAIL_REPLY",
"from_email": "sender@yourcompany.com",
"subject": "Re: Quick question about Acme Corp",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_replied": "2025-01-15T11:00:00Z",
"reply_body": "Thanks for reaching out...",
"preview_text": "Thanks for reaching out...",
"campaign_name": "Q1 Outreach",
"campaign_id": 123,
"client_id": 456,
"sequence_number": 1
}
```
See [Webhook Events](/api-reference/webhooks/events) for all event payloads.
## Association Types
Receives events from all campaigns owned by the user. Use when you want centralized notifications. If a User-level webhook exists, it takes priority over Client and Campaign-level webhooks.
Receives events from all campaigns for a specific client. Useful for agency/white-label setups. Requires `client_id` in the request body.
Receives events only from a specific campaign. Most common use case for per-campaign tracking. Requires `email_campaign_id` in the request body.
## Response Codes
Webhook created successfully
Invalid or missing API key
Missing required fields or invalid association\_type
Server error occurred
```json 200 - Success theme={null}
{
"ok": true,
"id": 456,
"webhook_url": "https://your-domain.com/webhook"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 422 - Validation Error theme={null}
{
"error": "webhook_url is required"
}
```
## Related Endpoints
* [Get Webhook](/api-reference/webhooks/get)
* [Update Webhook](/api-reference/webhooks/update)
* [Delete Webhook](/api-reference/webhooks/delete)
* [Webhook Events](/api-reference/webhooks/events)
# Delete Campaign Webhook
Source: https://api.smartlead.ai/api-reference/webhooks/delete
DELETE https://server.smartlead.ai/api/v1/webhook/delete
Permanently delete a campaign webhook and stop all event notifications
## Query Parameters
Your SmartLead API key
## Request Body
The webhook ID to delete
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/webhook/delete?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": 12345
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.delete(
"https://server.smartlead.ai/api/v1/webhook/delete",
params={"api_key": API_KEY},
json={"id": 12345}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/webhook/delete?api_key=${API_KEY}`,
{
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id: 12345 })
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Related Endpoints
* [Related endpoint](#)
# Webhook Events Reference
Source: https://api.smartlead.ai/api-reference/webhooks/events
Complete reference of all webhook event types and their payload structures
This is a reference page, not an API endpoint. Use these event types when creating webhooks via the [Create Webhook](/api-reference/webhooks/create) endpoint.
## Available Events
### EMAIL\_SENT
Triggered when an email is successfully sent to a lead.
**When**: Immediately after email delivery confirmation\
**Use For**: Tracking send volume, updating CRM status, logging
**Payload Example**:
```json theme={null}
{
"event_type": "EMAIL_SENT",
"from_email": "sender@yourcompany.com",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_sent": "2025-01-15T09:00:00Z",
"campaign_name": "Q1 Outreach",
"campaign_id": 123,
"sequence_number": 1,
"custom_subject": "Quick question about Acme Corp",
"custom_email_message": "Email body content...",
"message_id": "abc123def456"
}
```
***
### FIRST\_EMAIL\_SENT
Triggered only when the first email in a sequence is sent to a lead. Use this instead of `EMAIL_SENT` if you only want to track initial outreach.
**When**: When sequence step 1 is sent\
**Use For**: Tracking new outreach starts, CRM contact creation
**Payload Example**: Same structure as `EMAIL_SENT`, but only fires for `sequence_number: 1`.
***
### EMAIL\_OPEN
Triggered when a lead opens your email (tracking pixel loads).
**When**: When recipient's email client loads the tracking pixel\
**Use For**: Lead scoring, engagement tracking, trigger follow-up actions
**Payload Example**:
```json theme={null}
{
"event_type": "EMAIL_OPEN",
"from_email": "sender@yourcompany.com",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_opened": "2025-01-15T10:30:00Z",
"campaign_name": "Q1 Outreach",
"campaign_id": 123,
"sequence_number": 1
}
```
***
### EMAIL\_LINK\_CLICK
Triggered when a lead clicks a tracked link in your email.
**When**: Immediately when link is clicked\
**Use For**: High intent signals, lead scoring, conversion tracking
**Payload Example**:
```json theme={null}
{
"event_type": "EMAIL_LINK_CLICK",
"from_email": "sender@yourcompany.com",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_clicked": "2025-01-15T10:45:00Z",
"link_clicked": ["https://example.com/demo"],
"campaign_name": "Q1 Outreach",
"campaign_id": 123,
"sequence_number": 1
}
```
***
### EMAIL\_REPLY
Triggered when a lead replies to your email.
**When**: When reply is received and processed\
**Use For**: Hot lead alerts, CRM updates, sales notifications
**Payload Example**:
```json theme={null}
{
"event_type": "EMAIL_REPLY",
"from_email": "sender@yourcompany.com",
"subject": "Re: Quick question about Acme Corp",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_replied": "2025-01-15T11:00:00Z",
"reply_body": "Thanks for reaching out. I'm interested...",
"preview_text": "Thanks for reaching out. I'm interested...",
"campaign_name": "Q1 Outreach",
"campaign_id": 123,
"client_id": 456,
"sequence_number": 1
}
```
***
### EMAIL\_BOUNCE
Triggered when an email bounces (delivery fails).
**When**: When email server returns bounce notification\
**Use For**: List cleaning, deliverability monitoring, account health
***
### LEAD\_UNSUBSCRIBED
Triggered when a lead clicks the unsubscribe link.
**When**: Immediately when unsubscribe link is clicked\
**Use For**: Compliance, list management, CRM suppression
**Payload Example**:
```json theme={null}
{
"event_type": "LEAD_UNSUBSCRIBED",
"lead_email": "lead@example.com",
"lead_name": "John Doe",
"campaign_name": "Q1 Outreach",
"campaign_id": 123,
"unsubscribed_client_id_map": {}
}
```
***
### LEAD\_CATEGORY\_UPDATED
Triggered when a lead's category changes (manual or auto-categorization).
**When**: When lead category is updated\
**Use For**: CRM sync, sales routing, workflow automation
**Payload Example**:
```json theme={null}
{
"event_type": "LEAD_CATEGORY_UPDATED",
"lead_id": 789,
"lead_email": "lead@example.com",
"lead_name": "John",
"lead_data": {
"email": "lead@example.com",
"first_name": "John",
"last_name": "Doe",
"phone_number": "+1234567890",
"company_name": "Acme Corp",
"website": "https://acmecorp.com",
"location": "San Francisco, CA",
"custom_fields": {},
"linkedin_profile": "https://linkedin.com/in/johndoe",
"company_url": "https://acmecorp.com",
"category": {
"name": "Interested",
"sentiment_type": "positive"
}
},
"category": "Interested",
"lead_category_id": 5,
"campaign_name": "Q1 Outreach",
"campaign_id": 123,
"from": "sender@yourcompany.com",
"to": "lead@example.com",
"history": [
{
"type": "SENT",
"time": "2025-01-15T09:00:00Z",
"email_body": "...",
"subject": "Quick question"
},
{
"type": "REPLY",
"time": "2025-01-15T11:00:00Z",
"email_body": "Thanks for reaching out..."
}
],
"lastReply": {
"type": "REPLY",
"time": "2025-01-15T11:00:00Z",
"email_body": "Thanks for reaching out..."
}
}
```
The `LEAD_CATEGORY_UPDATED` event includes the full conversation history between the sending account and the lead, including all sent emails, replies, and threaded replies.
***
### CAMPAIGN\_STATUS\_CHANGED
Triggered when a campaign's status changes (e.g., started, paused, completed).
**When**: When campaign status is updated\
**Use For**: Workflow automation, status dashboards, notifications
***
### UNTRACKED\_REPLIES
Triggered when an untracked reply is received — a reply that doesn't match a known lead in the campaign.
**When**: When an untracked reply is detected\
**Use For**: Catch-all inbox monitoring, forwarded replies
***
### MANUAL\_STEP\_REACHED
Triggered when a lead reaches a manual step in the email sequence (e.g., a step that requires human action like a phone call or LinkedIn message).
**When**: When the sequence advances a lead to a manual step\
**Use For**: Task creation, sales team notifications, CRM task assignment
***
### EMAIL\_ACCOUNT\_DISCONNECTED
Triggered when a sending email account is disconnected (SMTP/IMAP failure).
**When**: When an email account connection fails\
**Use For**: Account health monitoring, alerting
This event uses a separate per-user webhook configuration (`notify_on_disconnect.webhookUrl` in user settings), not the standard campaign webhook system.
***
### LINKEDIN\_DISCONNECTED
Triggered when a LinkedIn cookie becomes invalid.
**When**: When LinkedIn cookie validation fails\
**Use For**: Account health monitoring, alerting
This event uses a separate per-user webhook configuration, not the standard campaign webhook system.
***
## Webhook Configuration
When creating a webhook, specify which events you want to receive using the `event_type_map` object:
```json Webhook Config Example theme={null}
{
"webhook_url": "https://your-server.com/webhook",
"association_type": "campaign",
"email_campaign_id": 123,
"event_type_map": {
"EMAIL_SENT": true,
"EMAIL_OPEN": true,
"EMAIL_LINK_CLICK": true,
"EMAIL_REPLY": true,
"EMAIL_BOUNCE": true,
"LEAD_UNSUBSCRIBED": true,
"LEAD_CATEGORY_UPDATED": true,
"CAMPAIGN_STATUS_CHANGED": false,
"UNTRACKED_REPLIES": false,
"MANUAL_STEP_REACHED": false
}
}
```
For `LEAD_CATEGORY_UPDATED`, you can also specify which categories to listen to via the `category_id_map`:
```json Category Filter Example theme={null}
{
"event_type_map": {
"LEAD_CATEGORY_UPDATED": true
},
"category_id_map": {
"5": true,
"6": true
}
}
```
## Handling Webhooks
### Example Handler (Python/Flask)
```python theme={null}
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def handle_webhook():
data = request.json
event = data['event_type']
if event == 'EMAIL_REPLY':
# High priority - lead replied!
send_slack_notification(
f"New reply from {data['to_email']}"
)
update_crm(data['to_email'], status='Engaged')
elif event == 'EMAIL_OPEN':
# Medium priority - lead is interested
increment_lead_score(data['to_email'])
elif event == 'EMAIL_BOUNCE':
# Clean up - remove from lists
remove_from_all_campaigns(data.get('to_email'))
elif event == 'LEAD_CATEGORY_UPDATED':
# Sync category to CRM
update_crm_category(data['lead_email'], data['category'])
return {'status': 'received'}, 200
```
### Example Handler (JavaScript/Express)
```javascript theme={null}
app.post('/webhook', express.json(), (req, res) => {
const event = req.body;
// Acknowledge receipt immediately
res.status(200).json({ status: 'received' });
// Process asynchronously
switch(event.event_type) {
case 'EMAIL_REPLY':
console.log(`Reply from ${event.to_email}: ${event.preview_text}`);
// Send to CRM, trigger workflows, etc.
break;
case 'EMAIL_OPEN':
console.log(`${event.to_email} opened email`);
// Update lead score
break;
case 'LEAD_CATEGORY_UPDATED':
console.log(`${event.lead_email} categorized as ${event.category}`);
// Sync to CRM
break;
}
});
```
## Best Practices
**Return 200 Quickly**: Process webhooks asynchronously to avoid timeouts. SmartLead will retry if your server doesn't respond with 200 in time.
**Implement Idempotency**: Use event fields like `campaign_id` + `to_email` + `event_type` + timestamp to handle duplicate deliveries.
**Webhook Level Priority**: If a User-level webhook exists, it will override Client and Campaign-level webhooks for the same event type.
## Related Endpoints
* [Create Webhook](/api-reference/webhooks/create)
* [Get Webhook](/api-reference/webhooks/get)
* [Update Webhook](/api-reference/webhooks/update)
* [Delete Webhook](/api-reference/webhooks/delete)
# Get Webhook
Source: https://api.smartlead.ai/api-reference/webhooks/get
GET https://server.smartlead.ai/api/v1/webhook/{webhook_id}
Get configuration details for a specific webhook by ID
## Path Parameters
The webhook id
## Query Parameters
Your SmartLead API key
## Request Body
No request body required
```bash cURL theme={null}
curl "https://server.smartlead.ai/api/v1/webhook/{webhook_id}?api_key=YOUR_KEY"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
response = requests.get(
"https://server.smartlead.ai/api/v1/webhook/{webhook_id}",
params={"api_key": API_KEY}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const response = await fetch(
`https://server.smartlead.ai/api/v1/webhook/${webhook_id}?api_key=${API_KEY}`
);
const result = await response.json();
console.log(result);
```
## Response Codes
Request successful
Invalid request parameters or malformed request body
Invalid or missing API key. Check your authentication.
The requested resource (campaign, lead, email account, etc.) does not exist or you don't have access to it
Request validation failed. Check parameter types, required fields, and value constraints.
Too many requests. Please slow down and retry after the rate limit resets.
Server error occurred. Please try again or contact support if the issue persists.
API is temporarily unavailable or under maintenance. Please try again later.
```json 200 - Success theme={null}
{
"ok": true,
"data": {
"id": 456,
"email_campaign_id": 123,
"name": "Campaign Analytics Webhook",
"webhook_url": "https://your-server.com/webhooks/smartlead",
"event_type_map": {
"EMAIL_SENT": true,
"EMAIL_OPEN": true,
"EMAIL_LINK_CLICK": true,
"EMAIL_REPLY": true
},
"category_id_map": {},
"created_at": "2026-03-15T10:30:00Z",
"updated_at": "2026-03-20T14:22:00Z"
}
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
```json 404 - Not Found theme={null}
{
"error": "Resource not found"
}
```
```json 422 - Validation Error theme={null}
{
"error": "Invalid parameters provided"
}
```
## Related Endpoints
* [Create Webhook](/api-reference/webhooks/create)
* [Update Webhook](/api-reference/webhooks/update)
* [Delete Webhook](/api-reference/webhooks/delete)
* [Webhook Events](/api-reference/webhooks/events)
# Update Webhook
Source: https://api.smartlead.ai/api-reference/webhooks/update
PUT https://server.smartlead.ai/api/v1/webhook/update/:webhook_id
Update the configuration of an existing webhook
Use this endpoint to update the configuration of an existing webhook.
## Path Parameters
The webhook ID to update
## Query Parameters
Your SmartLead API key
## Request Body
A descriptive name for the webhook
The URL to receive webhook events
Array of event types to subscribe to (e.g. `EMAIL_SENT`, `EMAIL_OPENED`, `EMAIL_REPLIED`, `EMAIL_CLICKED`, `LEAD_UNSUBSCRIBED`, `EMAIL_BOUNCED`)
Array of lead categories to filter events by
```bash cURL theme={null}
curl -X PUT "https://server.smartlead.ai/api/v1/webhook/update/12345?api_key=YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My Updated Webhook",
"webhook_url": "https://example.com/webhook",
"event_types": ["EMAIL_SENT", "EMAIL_REPLIED", "EMAIL_BOUNCED"],
"categories": []
}'
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
WEBHOOK_ID = 12345
response = requests.put(
f"https://server.smartlead.ai/api/v1/webhook/update/{WEBHOOK_ID}",
params={"api_key": API_KEY},
json={
"name": "My Updated Webhook",
"webhook_url": "https://example.com/webhook",
"event_types": ["EMAIL_SENT", "EMAIL_REPLIED", "EMAIL_BOUNCED"],
"categories": []
}
)
result = response.json()
print(result)
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const WEBHOOK_ID = 12345;
const response = await fetch(
`https://server.smartlead.ai/api/v1/webhook/update/${WEBHOOK_ID}?api_key=${API_KEY}`,
{
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'My Updated Webhook',
webhook_url: 'https://example.com/webhook',
event_types: ['EMAIL_SENT', 'EMAIL_REPLIED', 'EMAIL_BOUNCED'],
categories: []
})
}
);
const result = await response.json();
console.log(result);
```
## Response Codes
Webhook added/updated successfully
Invalid request parameters
Invalid or missing API key
Campaign not found
```json 200 - Success theme={null}
{
"ok": true,
"id": 12345,
"message": "Webhook saved successfully"
}
```
```json 401 - Unauthorized theme={null}
{
"message": "Invalid API Key"
}
```
## Related Endpoints
* [Get Campaign Webhooks](/api-reference/webhooks/get)
* [Delete Campaign Webhook](/api-reference/webhooks/delete)
# Authentication
Source: https://api.smartlead.ai/authentication
Learn how to authenticate with the SmartLead API
## Overview
SmartLead API uses API keys for authentication. Your API key carries many privileges, so be sure to keep it secure!
## Getting Your API Key
Visit [app.smartlead.ai](https://app.smartlead.ai) and log in to your account
Click on your profile icon and select "Settings" → "API Keys"
Click "Generate New API Key" button
Copy the generated API key and store it securely. This key will not be shown again.
API keys are equivalent to your password. Never commit them to version control, share them publicly, or expose them in client-side code.
## Using Your API Key
### Query Parameter Method (Recommended)
Pass your API key as a query parameter in the URL:
```bash theme={null}
GET https://server.smartlead.ai/api/v1/campaigns/?api_key=YOUR_API_KEY
```
### Request Body Method
For POST/PATCH requests, you can also include the API key in the request body:
```json theme={null}
{
"api_key": "YOUR_API_KEY",
"name": "My Campaign"
}
```
## Example Requests
```bash cURL theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/campaigns/?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json"
```
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://server.smartlead.ai/api/v1"
# Using query parameter
response = requests.get(
f"{BASE_URL}/campaigns/",
params={"api_key": API_KEY}
)
campaigns = response.json()
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://server.smartlead.ai/api/v1';
async function fetchCampaigns() {
const response = await fetch(
`${BASE_URL}/campaigns/?api_key=${API_KEY}`,
{
headers: {
'Content-Type': 'application/json',
},
}
);
const data = await response.json();
return data.campaigns;
}
```
```php PHP theme={null}
```
## Authentication Errors
If your API key is invalid or missing, you'll receive a 401 Unauthorized response:
```json theme={null}
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or missing API key"
}
}
```
## Best Practices
* Use environment variables or secure key management systems
* Never hardcode API keys in your source code
* Rotate your API keys periodically
```bash theme={null}
# .env file
SMARTLEAD_API_KEY=your_api_key_here
```
```python theme={null}
import os
API_KEY = os.getenv('SMARTLEAD_API_KEY')
```
Always check for authentication errors and handle them appropriately in your application.
## Rate Limiting
Your API key is subject to rate limiting based on your subscription plan. See [Rate Limits](/guides/rate-limits) for more information.
## Multiple API Keys
You can generate multiple API keys for different applications or environments:
* **Production Key**: For your live application
* **Development Key**: For testing and development
* **Integration Keys**: For specific third-party integrations
Generate separate API keys for different environments to better manage access and track usage.
## Regenerating API Keys
If you suspect your API key has been compromised:
1. Log in to your dashboard
2. Navigate to Settings → API Keys
3. Click "Regenerate" next to the compromised key
4. Update your application with the new key
Regenerating an API key will immediately invalidate the old key. Make sure to update all applications using the old key.
## What's Next?
Learn how to create your first campaign via API
Set up your sending email accounts
# Understanding Campaigns
Source: https://api.smartlead.ai/core/campaigns
Learn about email campaigns and how they work in SmartLead
## What is a Campaign?
A campaign in SmartLead is a complete cold email outreach sequence that includes:
* **Email Sequences**: Multiple follow-up emails with automated timing
* **Lead List**: Your target prospects with custom fields for personalization
* **Email Accounts**: Rotating sender accounts for better deliverability
* **Schedule**: When and how often to send emails
* **Tracking**: Open, click, and reply monitoring
* **Settings**: Advanced options for delivery and behavior
## Campaign Lifecycle
Start with a name and basic settings
Create your initial email and follow-ups
Add sender accounts for rotation
Upload your prospect list
Set sending hours and timezone
Start sending emails
## Campaign Status
| Status | Description | Can Send? |
| ------------- | ----------------------------- | --------- |
| **DRAFT** | Newly created, not configured | No |
| **ACTIVE** | Currently sending emails | Yes |
| **PAUSED** | Temporarily stopped | No |
| **STOPPED** | Permanently stopped | No |
| **ARCHIVED** | Hidden from active list | No |
| **COMPLETED** | All leads processed | No |
## Key Features
### Multi-Sequence Campaigns
Create sophisticated email sequences:
```
Day 0: Initial outreach
Day 3: First follow-up
Day 7: Second follow-up
Day 14: Final follow-up
```
### Personalization Variables
Use these in your email templates:
* `{{first_name}}` - Lead's first name
* `{{last_name}}` - Lead's last name
* `{{company_name}}` - Company name
* `{{job_title}}` - Custom field: job title
* Any custom field you define
**Example Email**:
```
Hi {{first_name}},
I noticed {{company_name}} is in the {{industry}} space...
Best,
Your Name
```
### Account Rotation
SmartLead automatically rotates between your connected email accounts to:
* Distribute sending load
* Improve deliverability
* Build sender reputation
* Avoid ESP limits
### AI ESP Matching
When enabled, SmartLead intelligently matches leads with appropriate sender accounts based on:
* Lead's email provider
* Account deliverability scores
* Sending patterns
* Historical performance
## Campaign Settings Explained
### Track Settings
Control what gets tracked:
* **Email Opens**: Track when leads open your emails
* **Link Clicks**: Track when leads click links
* **Privacy Mode**: Disable tracking for privacy-focused outreach
### Scheduler Settings
Configure sending times:
```json theme={null}
{
"timezone": "America/New_York",
"days": [1,2,3,4,5], // Monday-Friday
"start_hour": "09:00",
"end_hour": "17:00"
}
```
### Sending Limits
* **Max Leads Per Day**: Daily sending cap
* **Min Time Between Emails**: Delay between consecutive sends
* **Follow-up Percentage**: What % of leads get follow-ups
### Stop Lead Settings
Configure when to stop emailing a lead:
* `REPLY_TO_AN_EMAIL`: Stop on any reply
* `OPENED_EMAIL`: Stop after opens
* `CLICKED_LINK`: Stop after link click
* `NEVER`: Complete full sequence
## Best Practices
### Campaign Structure
* Focus each campaign on a specific objective
* Don't mix different audiences in one campaign
* Keep messaging consistent
* Create separate campaigns for different personas
* Personalize based on industry, role, or company size
* Use custom fields for deep personalization
* Start with smaller test campaigns
* Monitor open and reply rates
* Adjust messaging based on results
* A/B test subject lines
### Email Sequence Design
1. **First Email (Day 0)**
* Keep it short and value-focused
* Clear call-to-action
* Personalize with custom fields
2. **Follow-up 1 (Day 3-5)**
* Reference previous email
* Add additional value
* Different angle/benefit
3. **Follow-up 2 (Day 7-10)**
* Case study or social proof
* Address potential objections
* Softer CTA
4. **Final Follow-up (Day 14-21)**
* Permission-based ("Should I stop emailing?")
* Last chance offer
* Easy opt-out
### Deliverability Tips
* Warm up new email accounts before adding to campaigns
* Keep daily sending under 50 emails per account
* Rotate multiple accounts
* Monitor bounce rates
* Use custom tracking domains
## Campaign Analytics
Monitor these key metrics:
* **Open Rate**: % of leads who opened your email
* **Click Rate**: % of leads who clicked links
* **Reply Rate**: % of leads who replied (most important)
* **Bounce Rate**: % of undeliverable emails
* **Unsubscribe Rate**: % who opted out
### Good Benchmarks
| Metric | Good | Great | Excellent |
| ----------- | -------------- | -------------- | ---------------- |
| Open Rate | 30-40% | 40-50% | 50%+ |
| Click Rate | 5-10% | 10-15% | 15%+ |
| Reply Rate | 2-5% | 5-10% | 10%+ |
| Bounce Rate | lesser than 2% | lesser than 1% | lesser than 0.5% |
## Common Campaign Types
### 1. Basic Cold Outreach
* 3-4 email sequence
* General value proposition
* Broad targeting
### 2. Warm Introduction
* 2-3 email sequence
* Reference to mutual connection
* Relationship-based
### 3. Content/Value First
* Lead with free resource
* Educational approach
* Longer sequence (5-7 emails)
### 4. Event Invitation
* Short sequence (1-2 emails)
* Time-sensitive
* Clear event details
## API Integration Examples
### Create and Launch Campaign
```python Python theme={null}
import requests
API_KEY = "YOUR_API_KEY"
BASE_URL = "https://server.smartlead.ai/api/v1"
# 1. Create campaign
campaign_response = requests.post(
f"{BASE_URL}/campaigns/new",
params={"api_key": API_KEY},
json={"name": "Q1 2024 Outreach"}
)
campaign_id = campaign_response.json()['campaign']['id']
# 2. Add sequences
sequences_response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/sequences",
params={"api_key": API_KEY},
json={
"sequences": [
{
"seq_number": 1,
"subject": "Quick question",
"email_body": "Hi {{first_name}},...",
"seq_delay_details": {"delay_in_days": 0}
}
]
}
)
# 3. Add email accounts
accounts_response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/email-accounts",
params={"api_key": API_KEY},
json={"email_account_ids": [456, 457]}
)
# 4. Add leads
leads_response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY},
json={
"lead_list": [
{
"email": "prospect@example.com",
"first_name": "John",
"company_name": "Acme Corp"
}
]
}
)
# 5. Start campaign
start_response = requests.patch(
f"{BASE_URL}/campaigns/{campaign_id}/status",
params={"api_key": API_KEY},
json={"status": "ACTIVE"}
)
print(f"Campaign {campaign_id} is now ACTIVE!")
```
## Troubleshooting
### Campaign Not Sending
Check:
1. Campaign status is ACTIVE
2. At least one email account connected
3. Leads are in STARTED or INPROGRESS status
4. Schedule allows sending at current time
5. Email accounts have remaining daily quota
### Low Reply Rates
Common fixes:
1. Improve subject lines
2. Shorten email copy
3. Better personalization
4. Clear call-to-action
5. Check deliverability (opens/spam)
### High Bounce Rate
Actions:
1. Verify emails before adding
2. Remove invalid emails
3. Check email account configuration
4. Review sending patterns
5. Warm up accounts properly
## Related Resources
* [Create Campaign API](/api-reference/campaigns/create)
* [Add Leads API](/api-reference/leads/add-to-campaign)
* [Campaign Settings API](/api-reference/campaigns/update-settings)
* [Campaign Analytics](/api-reference/analytics/campaign-performance)
# Email Accounts
Source: https://api.smartlead.ai/core/email-accounts
Understanding email account management and warmup
## What are Email Accounts?
Email accounts in SmartLead are the sender accounts used to deliver your campaigns. SmartLead supports:
* **SMTP Accounts**: Custom email servers
* **Gmail Accounts**: OAuth-connected Gmail
* **Outlook Accounts**: OAuth-connected Microsoft 365
## Account Rotation
SmartLead automatically rotates between multiple accounts to:
* **Distribute Load**: Spread emails across accounts
* **Improve Deliverability**: Avoid ESP sending limits
* **Build Reputation**: Warm up multiple accounts simultaneously
* **Increase Volume**: Send more emails per day
## Email Warmup
### What is Warmup?
Warmup gradually increases your sending volume to build sender reputation with email providers.
### Why Warmup?
* **New Accounts**: Build credibility
* **Better Deliverability**: Land in inbox, not spam
* **Higher Limits**: Increase daily sending capacity
* **Account Health**: Maintain good reputation
### Warmup Settings
```json theme={null}
{
"warmup_enabled": true,
"max_email_per_day": 20,
"daily_rampup": 2,
"reply_rate_percentage": 30,
"warmup_min_count": 5,
"warmup_max_count": 20
}
```
### Warmup Schedule Example
| Day | Emails Sent | Warmup | Campaign | Reply Rate |
| --- | ----------- | ------ | -------- | ---------- |
| 1 | 5 | 5 | 0 | 30% |
| 2 | 7 | 7 | 0 | 30% |
| 3 | 9 | 9 | 0 | 30% |
| 5 | 15 | 10 | 5 | 30% |
| 10 | 30 | 15 | 15 | 30% |
| 20 | 50 | 20 | 30 | 30% |
## Account Types
### SMTP Account
Custom email server with SMTP/IMAP configuration.
**Required**:
* SMTP host and port
* IMAP host and port
* Username and password
**Use For**: Maximum control, custom domains
### Gmail Account
OAuth-connected Google Workspace or Gmail.
**Required**:
* OAuth tokens (via Google Sign-In)
**Use For**: Easy setup, reliable delivery
### Outlook Account
OAuth-connected Microsoft 365 or Outlook.com.
**Required**:
* OAuth tokens (via Microsoft Sign-In)
**Use For**: Business accounts, Exchange servers
## Daily Sending Limits
Recommended limits per account type:
| Account Type | Daily Limit | Notes |
| --------------- | ----------- | ----------------------------- |
| **New SMTP** | 20-30 | Start low, increase gradually |
| **Warmed SMTP** | 50-100 | After 30 days warmup |
| **Gmail** | 50 | Google's recommended limit |
| **Outlook** | 50 | Microsoft's recommended limit |
| **Enterprise** | 100+ | With proper warmup |
## Best Practices
Rotate 5-10 accounts for better deliverability and higher volume
Never skip warmup for new accounts - it's critical for deliverability
Use custom domains for tracking links to improve trust
Check warmup reputation regularly - pause if it drops below 80%
## Related Endpoints
* [Add SMTP Account](/api-reference/email-accounts/add-smtp)
* [Add OAuth Account](/api-reference/email-accounts/add-oauth)
* [Get All Email Accounts](/api-reference/email-accounts/get-all)
* [Update Warmup Settings](/api-reference/email-accounts/warmup-settings)
* [Get Warmup Stats](/api-reference/email-accounts/warmup-stats)
# Understanding Leads
Source: https://api.smartlead.ai/core/leads
Learn about lead management in SmartLead
## What is a Lead?
A lead in SmartLead is a prospect you want to reach via email. Each lead has:
* **Contact Information**: Email, name, company details
* **Custom Fields**: Unlimited personalization data
* **Status**: Current state in campaign (STARTED, INPROGRESS, COMPLETED)
* **Category**: User-defined labels (Interested, Not Interested, etc.)
* **Activity History**: All interactions tracked
## Lead Lifecycle
Lead is imported to a campaign
Sequences are sent according to schedule
Opens, clicks, replies recorded
Responses categorized (Interested, etc.)
Campaign completes or lead is paused
## Lead Status
| Status | Description |
| -------------- | --------------------------- |
| **STARTED** | Lead added, waiting to send |
| **INPROGRESS** | Actively receiving emails |
| **COMPLETED** | All sequences sent |
| **PAUSED** | Temporarily stopped |
| **STOPPED** | Permanently stopped |
| **BLOCKED** | In block list |
## Lead Categories
Default categories:
* **Interested**: Positive response
* **Meeting Request**: Wants to meet
* **Not Interested**: Negative response
* **Do Not Contact**: Hard opt-out
* **Information Request**: Needs more info
* **Custom Categories**: Create your own
## Custom Fields
Add unlimited personalization data:
```json theme={null}
{
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"custom_fields": {
"job_title": "CEO",
"industry": "Technology",
"company_size": "50-100",
"pain_point": "Lead generation",
"annual_revenue": "$5M-$10M",
"linkedin": "https://linkedin.com/in/johndoe"
}
}
```
Use in emails: `{{job_title}}`, `{{industry}}`, etc.
## Best Practices
Use the email verification API before adding leads to improve deliverability
Add 5-10 custom fields for better personalization and higher reply rates
Create separate campaigns for different personas or industries
Track opens, clicks, replies to identify hot leads
## Related Endpoints
* [Add Leads to Campaign](/api-reference/leads/add-to-campaign)
* [Get Campaign Leads](/api-reference/leads/get-by-campaign)
* [Get Lead Categories](/api-reference/leads/categories)
* [Update Lead](/api-reference/leads/update)
# Email Sequences
Source: https://api.smartlead.ai/core/sequences
Understanding email sequences and follow-ups
## What are Sequences?
Sequences are automated follow-up emails that are sent based on time delays and conditions. A typical sequence might look like:
Initial outreach email
First follow-up if no reply
Second follow-up if no reply
Final follow-up
## Sequence Structure
Each sequence has:
* **Sequence Number**: 1, 2, 3, etc.
* **Subject Line**: Email subject (can use variables)
* **Email Body**: Message content (supports HTML and plain text)
* **Delay**: Days to wait before sending
* **Conditions**: When to send (optional)
## Example Sequence
```json theme={null}
{
"seq_number": 1,
"subject": "Quick question about {{company_name}}",
"email_body": "Hi {{first_name}},\n\nI noticed {{company_name}} is in the {{industry}} space...",
"seq_delay_details": {
"delay_in_days": 0
}
}
```
## Personalization Variables
Use these in subject and body:
### Standard Fields
* `{{first_name}}` - Lead's first name
* `{{last_name}}` - Lead's last name
* `{{email}}` - Lead's email
* `{{company_name}}` - Company name
* `{{website}}` - Company website
* `{{location}}` - Lead's location
### Custom Fields
Any custom field you add:
* `{{job_title}}`
* `{{industry}}`
* `{{company_size}}`
* `{{pain_point}}`
* Any other custom field
### Usage Example
```
Subject: {{first_name}}, question about {{company_name}}'s {{industry}} strategy
Hi {{first_name}},
I noticed {{company_name}} is based in {{location}} and works in the {{industry}} space.
As a {{job_title}}, you might be interested in...
Best regards,
Your Name
```
## Sequence Delays
Configure delays between emails:
```json theme={null}
{
"seq_delay_details": {
"delay_in_days": 3
}
}
```
**Recommended Delays**:
* Email 1 → Email 2: 2-4 days
* Email 2 → Email 3: 3-5 days
* Email 3 → Email 4: 5-7 days
* Email 4 → Email 5: 7-14 days
## Sequence Variants (A/B Testing)
Test multiple versions of the same sequence:
```json theme={null}
{
"seq_number": 1,
"seq_variants": [
{
"variant_id": "A",
"subject": "Quick question",
"email_body": "Version A...",
"distribution": 50
},
{
"variant_id": "B",
"subject": "Thoughts on your process?",
"email_body": "Version B...",
"distribution": 50
}
]
}
```
## Stop Conditions
Configure when to stop sending:
* **Reply to Email**: Stop on any reply (recommended)
* **Email Opened**: Stop after they open
* **Link Clicked**: Stop after click
* **Never**: Send full sequence regardless
## Best Practices
First email: 50-125 words for best response rates
Lead with value, not your product. What's in it for them?
One clear call-to-action per email
A/B test subject lines and messaging
Don't be too aggressive - 3-5 days between emails
## Sequence Types
### 1. Standard Sequence
```
Email 1: Initial outreach
Email 2: Value add / case study
Email 3: Different angle
Email 4: Permission to close
```
### 2. Value Sequence
```
Email 1: Free resource offer
Email 2: Additional resources
Email 3: Soft pitch
Email 4: Hard pitch
```
### 3. Problem-Solution
```
Email 1: Identify problem
Email 2: Your solution
Email 3: Case study / proof
Email 4: Call to action
```
## Related Endpoints
* [Get Campaign Sequences](/api-reference/campaigns/get-sequences)
* [Update Campaign Sequences](/api-reference/campaigns/update-sequences)
* [Create Campaign](/api-reference/campaigns/create)
# Webhooks
Source: https://api.smartlead.ai/core/webhooks
Set up real-time notifications for campaign events
## What are Webhooks?
Webhooks allow you to receive real-time notifications when events occur in your SmartLead campaigns. Instead of polling the API, SmartLead will send HTTP POST requests to your server when events happen.
## Use Cases
Update your CRM when leads reply or book meetings
Score leads based on engagement (opens, clicks)
Get Slack/Email alerts for important replies
Send data to your analytics platform
## Available Events
| Event | Description | When Triggered |
| -------------------- | --------------------- | ----------------------------- |
| `EMAIL_SENT` | Email sent to lead | After successful delivery |
| `EMAIL_OPENED` | Lead opened email | When tracking pixel loads |
| `EMAIL_CLICKED` | Lead clicked link | When tracked link is clicked |
| `EMAIL_REPLIED` | Lead replied to email | When reply is received |
| `EMAIL_BOUNCED` | Email bounced | When email fails to deliver |
| `EMAIL_UNSUBSCRIBED` | Lead unsubscribed | When unsubscribe link clicked |
## Webhook Payload Format
All webhook events follow this structure:
```json theme={null}
{
"event": "EMAIL_REPLIED",
"timestamp": "2024-01-15T10:30:00Z",
"campaign_id": 123,
"campaign_name": "Cold Outreach Q1",
"lead_id": 789,
"email_account_id": 456,
"lead": {
"email": "lead@example.com",
"first_name": "Jane",
"last_name": "Doe",
"company_name": "Acme Corp",
"custom_fields": {
"job_title": "CEO"
}
},
"sequence_number": 1,
"email": {
"subject": "Quick question",
"message_id": "abc123@smartlead.ai"
},
"reply": {
"subject": "Re: Quick question",
"body": "Thanks for reaching out...",
"received_at": "2024-01-15T10:30:00Z"
}
}
```
## Setting Up Webhooks
Set up an HTTPS endpoint on your server that accepts POST requests
```python Python theme={null}
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def handle_webhook():
data = request.json
event = data['event']
if event == 'EMAIL_REPLIED':
# Handle reply
lead_email = data['lead']['email']
reply_body = data['reply']['body']
# Your logic here
return {'status': 'success'}, 200
```
Use the API to register your webhook URL
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/webhook/create?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "CRM Integration",
"webhook_url": "https://your-server.com/webhook",
"email_campaign_id": 123,
"association_type": 3,
"event_type_map": {
"EMAIL_REPLIED": true,
"EMAIL_OPENED": true
}
}'
```
SmartLead will send test events when you save the webhook
Activate your campaign and start receiving events
## Webhook Association Types
Webhooks can be associated with:
* **User Level** (association\_type: 1): Receive events from all campaigns
* **Client Level** (association\_type: 2): Events for specific client's campaigns
* **Campaign Level** (association\_type: 3): Events from a single campaign
## Event Examples
### EMAIL\_SENT
```json theme={null}
{
"event": "EMAIL_SENT",
"timestamp": "2024-01-15T09:00:00Z",
"campaign_id": 123,
"lead_id": 789,
"email_account_id": 456,
"sequence_number": 1,
"lead": {
"email": "lead@example.com",
"first_name": "Jane"
}
}
```
### EMAIL\_OPENED
```json theme={null}
{
"event": "EMAIL_OPENED",
"timestamp": "2024-01-15T10:30:00Z",
"campaign_id": 123,
"lead_id": 789,
"sequence_number": 1,
"opened_count": 3,
"first_opened_at": "2024-01-15T10:30:00Z",
"last_opened_at": "2024-01-15T14:20:00Z"
}
```
### EMAIL\_REPLIED
```json theme={null}
{
"event": "EMAIL_REPLIED",
"timestamp": "2024-01-15T11:00:00Z",
"campaign_id": 123,
"lead_id": 789,
"email_account_id": 456,
"sequence_number": 1,
"reply": {
"subject": "Re: Quick question",
"body": "Thanks for reaching out. I'm interested...",
"received_at": "2024-01-15T11:00:00Z",
"message_id": "reply-abc123"
},
"lead": {
"email": "lead@example.com",
"first_name": "Jane",
"last_name": "Doe"
}
}
```
### EMAIL\_CLICKED
```json theme={null}
{
"event": "EMAIL_CLICKED",
"timestamp": "2024-01-15T10:45:00Z",
"campaign_id": 123,
"lead_id": 789,
"sequence_number": 1,
"link": {
"url": "https://example.com/demo",
"clicked_at": "2024-01-15T10:45:00Z"
}
}
```
## Webhook Security
### Verify Webhook Origin
Always verify webhooks come from SmartLead:
```python Python theme={null}
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
"""Verify webhook signature"""
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
```
Always use HTTPS for your webhook endpoint to ensure data is encrypted in transit.
### Best Practices
1. **Return 200 Quickly**: Process webhooks asynchronously
2. **Implement Retry Logic**: Handle temporary failures
3. **Validate Payload**: Check all required fields exist
4. **Log Everything**: Keep webhook logs for debugging
5. **Use Idempotency**: Handle duplicate events gracefully
## Example Implementations
### Node.js/Express
```javascript theme={null}
const express = require('express');
const app = express();
app.post('/webhook', express.json(), (req, res) => {
const { event, lead, reply } = req.body;
// Quickly acknowledge receipt
res.status(200).json({ status: 'received' });
// Process asynchronously
process.nextTick(() => {
switch(event) {
case 'EMAIL_REPLIED':
console.log(`Reply from ${lead.email}: ${reply.body}`);
// Update your CRM, send notifications, etc.
break;
case 'EMAIL_OPENED':
console.log(`${lead.email} opened email`);
break;
}
});
});
app.listen(3000);
```
### Python/Flask
```python theme={null}
from flask import Flask, request
import logging
app = Flask(__name__)
logger = logging.getLogger(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
data = request.json
# Log the event
logger.info(f"Received {data['event']} event")
# Quick response
response = {'status': 'received'}
# Process asynchronously (use Celery, etc.)
process_webhook_async(data)
return response, 200
def process_webhook_async(data):
event = data['event']
if event == 'EMAIL_REPLIED':
# Update CRM
update_crm_contact(
email=data['lead']['email'],
status='Replied'
)
# Send Slack notification
send_slack_notification(
f"New reply from {data['lead']['first_name']}!"
)
```
## Webhook Management
### Create Webhook
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/webhook/create?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My Webhook",
"webhook_url": "https://your-server.com/webhook",
"email_campaign_id": 123,
"association_type": 3,
"event_type_map": {
"EMAIL_SENT": true,
"EMAIL_OPENED": true,
"EMAIL_CLICKED": true,
"EMAIL_REPLIED": true,
"EMAIL_BOUNCED": true
}
}'
```
### Get Webhook Details
```bash cURL theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/webhook/123?api_key=YOUR_API_KEY"
```
### Delete Webhook
```bash cURL theme={null}
curl -X DELETE "https://server.smartlead.ai/api/v1/webhook/delete/123?api_key=YOUR_API_KEY"
```
## Retry Logic
SmartLead will retry failed webhook deliveries:
* **1st retry**: After 1 minute
* **2nd retry**: After 5 minutes
* **3rd retry**: After 15 minutes
* **4th retry**: After 1 hour
* **5th retry**: After 6 hours
After 5 failed attempts, the webhook will be disabled.
## Debugging Webhooks
### Common Issues
**Check**:
* URL is publicly accessible
* HTTPS is properly configured
* Firewall allows SmartLead IPs
* Server is returning 200 status code
**Solution**: Use the `timestamp` field to order events, not arrival time
**Solution**: Use idempotency keys (lead\_id + event + timestamp)
**Reason**: Too many failures (5+ consecutive errors)
**Solution**: Fix your endpoint and re-enable webhook
### Test Your Webhook
Use a webhook testing service:
* [webhook.site](https://webhook.site)
* [requestbin.com](https://requestbin.com)
* Postman's webhook collection feature
## Integration Examples
### Update HubSpot
```python theme={null}
def handle_reply_webhook(data):
"""Update HubSpot when lead replies"""
if data['event'] == 'EMAIL_REPLIED':
hubspot_contact_id = find_contact_by_email(
data['lead']['email']
)
if hubspot_contact_id:
update_hubspot_contact(
contact_id=hubspot_contact_id,
properties={
'lead_status': 'Engaged',
'last_activity': data['timestamp'],
'reply_text': data['reply']['body']
}
)
```
### Send Slack Notification
```python theme={null}
import requests
def send_slack_notification(data):
"""Send Slack alert for replies"""
if data['event'] == 'EMAIL_REPLIED':
slack_webhook_url = 'YOUR_SLACK_WEBHOOK_URL'
message = {
'text': f"🎉 New reply from {data['lead']['first_name']}!",
'attachments': [{
'color': 'good',
'fields': [
{
'title': 'Lead',
'value': data['lead']['email'],
'short': True
},
{
'title': 'Campaign',
'value': data['campaign_name'],
'short': True
},
{
'title': 'Reply',
'value': data['reply']['body'][:100] + '...',
'short': False
}
]
}]
}
requests.post(slack_webhook_url, json=message)
```
## Rate Limiting
Webhook deliveries are not subject to API rate limits. However, ensure your server can handle:
* **Burst traffic**: Many events arriving simultaneously
* **Sustained load**: Continuous event stream during active campaigns
Use a queue system (Redis, RabbitMQ) to handle webhook events asynchronously.
## Related Endpoints
* [Create Webhook](/api-reference/webhooks/create)
* [Get Webhook](/api-reference/webhooks/get)
* [Delete Webhook](/api-reference/webhooks/delete)
* [Webhook Events Reference](/api-reference/webhooks/events)
# FAQ
Source: https://api.smartlead.ai/faq
Frequently asked questions about the SmartLead API
The SmartLead API is a RESTful interface that lets developers programmatically control the entire SmartLead cold email platform — creating and managing campaigns, importing leads, rotating email accounts, triggering sequences, and pulling analytics data. It uses API key authentication and supports both a recommended V1 endpoint (`/api/v1/...`) and a legacy endpoint for backward compatibility. Agencies and sales teams use it to embed cold email automation directly into their own CRMs, dashboards, or outbound stacks without manual platform interaction.
Authentication is handled via API keys. You generate your key from the SmartLead dashboard under **Settings**, then append it as a query parameter to every request:
```
GET https://server.smartlead.ai/api/v1/campaigns/?api_key=YOUR_API_KEY
```
There is no OAuth flow required. All requests go to the base URL `https://server.smartlead.ai/api`, with V1 endpoints prefixed at `/api/v1/`.
Rate limits on the SmartLead API are tied to your subscription plan — they are not fixed across all tiers. If a request exceeds your limit, the API returns a `429 Too Many Requests` HTTP status code. The recommended handling strategy is **exponential backoff**: wait progressively longer intervals before retrying. For exact rate limit values tied to your plan, contact SmartLead support or consult your account dashboard.
Through the API, you can connect multiple sending accounts (Gmail, Outlook, or custom SMTP) and SmartLead automatically distributes outgoing campaign volume across them. This rotation reduces the per-account send load, lowers the risk of any single mailbox being flagged for spam, and extends your overall daily sending capacity. The API lets you programmatically add, update, or remove email accounts and assign them to specific campaigns.
Yes. SmartLead's AI-powered warmup system is accessible via the API and gradually ramps up sending volume from new or dormant accounts to build sender reputation before a full campaign launch. Warmup settings — including sending pace and duration — can be configured programmatically. This means you can integrate warmup scheduling into your own onboarding or provisioning workflows without manual dashboard intervention.
SmartLead integrates natively with HubSpot, Salesforce, Pipedrive, Clay, Listkit, and more. Beyond native integrations, the API and webhook infrastructure allow connection to virtually any tool via Zapier, Make (formerly Integromat), and n8n. Common use cases include syncing lead status to a CRM when a reply is received, triggering Slack notifications on campaign events, and pushing enriched contact data from Clay directly into an active SmartLead sequence.
SmartLead offers two API versions. The **V1 API** (`/api/v1/...`) is the current recommended version and includes all modern features, better performance, and improved response formats. The **legacy API** (`/api/...`) is maintained for backward compatibility only — existing integrations that rely on it will continue to work, but it will not receive new feature updates. All new integrations should be built on V1.
SmartLead webhooks send real-time HTTP POST notifications to a URL you specify whenever a campaign event occurs — such as an email being opened, a reply received, a lead being categorized, or a bounce happening. This is useful when you want your external systems (CRM, Slack, database) to react instantly to outreach activity without polling the API repeatedly. You configure webhooks either through the dashboard or programmatically via the API, assigning them to specific campaigns or account-level events.
Yes, the SmartLead API is well-suited for agency use cases. One SmartLead account can serve an entire team, and the API supports programmatic campaign creation, lead management, and inbox access across multiple client workspaces. Agencies can use the API to build white-labeled dashboards, automate client onboarding workflows, and pull per-client performance data. The platform's volume-based (non-per-seat) pricing model makes API-driven, multi-client deployments significantly more cost-effective than per-user alternatives.
Yes. When a reply is detected, SmartLead can automatically pause or stop follow-up sequences for that lead to prevent over-sending. The API lets you retrieve reply data, update lead status (e.g., Interested, Not Interested, Meeting Booked), and trigger webhook events that push the updated record to your CRM or workflow automation tool. You can set conditions for replies, pauses, or lead updates without manual input, enabling a fully automated reply-handling pipeline that escalates hot leads in real time.
# Best Practices Guide
Source: https://api.smartlead.ai/guides/best-practices
Production-ready patterns for SmartLead API integrations — covering deliverability, personalization, campaign architecture, scaling, and security
## Overview
This guide covers the patterns and strategies that high-performing SmartLead integrations use in production. Whether you're building a custom outreach tool, syncing with your CRM, or automating campaign management, these best practices will help you get better results and avoid common pitfalls.
## Deliverability Best Practices
Deliverability is the foundation of cold email. If your emails land in spam, nothing else matters.
### Warm Up Every Account
Never send campaign emails from an account that hasn't been warmed up for at least 14 days. For new domains, allow 21–30 days.
```python Python theme={null}
# When creating an account, always enable warmup
account_payload = {
"from_name": "Sarah Johnson",
"from_email": "sarah@yourcompany.com",
"smtp_host": "smtp.yourprovider.com",
"smtp_port": 587,
"imap_host": "imap.yourprovider.com",
"imap_port": 993,
"max_email_per_day": 40,
"warmup_enabled": True,
"total_warmup_per_day": 25,
"daily_rampup": 2,
"reply_rate_percentage": 30
}
```
### Configure DNS Records
Before sending any emails, ensure these DNS records are properly set up for every sending domain:
| Record | What It Does | Priority |
| -------------------------- | ----------------------------------------------------------- | ----------- |
| **SPF** | Authorizes which servers can send email from your domain | Required |
| **DKIM** | Adds a cryptographic signature to verify email authenticity | Required |
| **DMARC** | Defines how receivers handle SPF/DKIM failures | Required |
| **Custom Tracking Domain** | Uses your domain for open/click tracking links | Recommended |
Missing DNS records is the most common cause of deliverability issues. Set these up before enabling warmup — warming up an account with bad DNS records can actively harm your domain reputation.
### Rotate Multiple Accounts
Use 3–5 email accounts per campaign to distribute sending volume and reduce the risk of any single account being flagged:
```python Python theme={null}
# Link multiple accounts to a campaign
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/email-accounts",
params={"api_key": API_KEY},
json={"email_account_ids": [101, 102, 103, 104, 105]}
)
```
### Monitor Bounce Rates
Set up automated monitoring and pause campaigns if bounce rates spike:
```python Python theme={null}
def check_campaign_health(campaign_id):
"""Monitor campaign health and alert on issues."""
response = requests.get(
f"{BASE_URL}/campaigns/{campaign_id}/analytics",
params={"api_key": API_KEY}
)
analytics = response.json()
total_sent = analytics.get("total_sent", 0)
total_bounced = analytics.get("total_bounced", 0)
if total_sent > 0:
bounce_rate = total_bounced / total_sent
if bounce_rate > 0.05: # 5% threshold
print(f"WARNING: Bounce rate {bounce_rate:.1%} — consider pausing campaign")
# Optionally auto-pause
requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/status",
params={"api_key": API_KEY},
json={"status": "PAUSED"}
)
```
## Personalization Best Practices
### Use Custom Fields Extensively
Generic cold emails get ignored. Use custom fields to make every email feel hand-written:
```python Python theme={null}
lead = {
"email": "alex@company.com",
"first_name": "Alex",
"company_name": "Acme Corp",
"custom_fields": {
"job_title": "VP of Sales",
"industry": "B2B SaaS",
"pain_point": "low reply rates on outbound",
"mutual_connection": "Jordan at YC",
"recent_news": "Series B announcement",
"team_size": "50"
}
}
```
Then reference them in your sequences:
```
Hi {{first_name}},
Congrats on {{recent_news}} — exciting times at {{company_name}}.
Given your role as {{job_title}}, I imagine {{pain_point}} is something you're thinking about.
{{mutual_connection}} mentioned you might be open to exploring new approaches...
```
### Validate Personalization Data
Always validate custom fields before import to prevent sending emails with empty placeholders:
```python Python theme={null}
def validate_lead_personalization(lead, required_fields):
"""Ensure all required personalization fields are present."""
missing = []
for field in required_fields:
if field in ["first_name", "last_name", "email", "company_name"]:
if not lead.get(field):
missing.append(field)
else:
if not lead.get("custom_fields", {}).get(field):
missing.append(field)
return missing
# Check before import
required = ["first_name", "company_name", "job_title", "industry"]
for lead in lead_list:
missing = validate_lead_personalization(lead, required)
if missing:
print(f"Lead {lead['email']} missing: {', '.join(missing)}")
```
If a custom field might be empty for some leads, write your email copy to handle it gracefully. Instead of "I noticed is hiring," use "I noticed your team is growing" as a fallback.
## Campaign Architecture
### Structure Campaigns by Segment
Create separate campaigns for each ICP segment rather than one massive campaign:
```
Campaign: Q1 SaaS — VP Sales — US (50-200 employees)
Campaign: Q1 SaaS — VP Sales — US (200-500 employees)
Campaign: Q1 SaaS — Head of Growth — US
Campaign: Q1 Fintech — VP Sales — US
```
This lets you tailor sequences, measure performance by segment, and adjust strategy independently.
### Sequence Design
Follow these guidelines for high-performing sequences:
| Step | Timing | Purpose | Length |
| ------- | ------ | --------------------------------- | ----------- |
| Email 1 | Day 0 | Hook — introduce your value prop | 50-80 words |
| Email 2 | Day 3 | Social proof — share a case study | 40-70 words |
| Email 3 | Day 7 | New angle — different pain point | 40-60 words |
| Email 4 | Day 14 | Break-up — final follow-up | 30-50 words |
```python Python theme={null}
sequences = {
"sequences": [
{"seq_number": 1, "seq_delay_details": {"delay_in_days": 0}, ...},
{"seq_number": 2, "seq_delay_details": {"delay_in_days": 3}, ...},
{"seq_number": 3, "seq_delay_details": {"delay_in_days": 4}, ...},
{"seq_number": 4, "seq_delay_details": {"delay_in_days": 7}, ...}
]
}
```
### A/B Test Systematically
Test one variable at a time and run tests until you have statistical significance:
```python Python theme={null}
# Test subject lines on step 1
sequence_step = {
"seq_number": 1,
"subject": "Quick question about {{company_name}}",
"email_body": "...",
"variants": [
{
"subject": "{{first_name}}, thought on {{company_name}}'s outbound",
"email_body": "...", # Same body to isolate subject impact
"variant_distribution": 50
}
]
}
```
Wait for at least 200 sends per variant before drawing conclusions. Small sample sizes produce unreliable results.
## Scaling Best Practices
### Batch All Operations
Always use batch endpoints when working with multiple items:
```python Python theme={null}
# Import leads in batches of 400
batch_size = 400
for i in range(0, len(all_leads), batch_size):
batch = all_leads[i:i + batch_size]
result = make_request("POST", f"campaigns/{campaign_id}/leads", {
"lead_list": batch,
"settings": {
"ignore_global_block_list": False,
"ignore_unsubscribe_list": False,
"ignore_duplicate_leads_in_other_campaign": False
}
})
time.sleep(1) # Brief pause between batches
```
### Use Webhooks for Real-Time Data
Don't poll the API for updates. Set up webhooks and react to events:
```python Python theme={null}
# Register webhook once
make_request("POST", "webhooks", {
"webhook_url": "https://yourapp.com/hooks/smartlead",
"event_types": ["EMAIL_REPLIED", "EMAIL_BOUNCED", "LEAD_UNSUBSCRIBED"],
"is_active": True
})
```
### Cache Static Data
Cache data that rarely changes to minimize API calls:
```python Python theme={null}
# Cache campaign list (changes infrequently)
campaigns = cached_request("campaigns/", ttl_seconds=300)
# Cache email accounts (changes infrequently)
accounts = cached_request("email-accounts", ttl_seconds=600)
# Don't cache analytics (changes with every send)
analytics = make_request("GET", f"campaigns/{cid}/analytics")
```
## Security Best Practices
### Protect Your API Key
```python Python theme={null}
# Good: Environment variable
API_KEY = os.getenv("SMARTLEAD_API_KEY")
# Bad: Hardcoded in source
API_KEY = "sl_abc123..." # Never do this
```
Never commit API keys to version control, include them in client-side code, or share them in Slack messages. Use environment variables or a secrets manager like AWS Secrets Manager, HashiCorp Vault, or Doppler.
### Validate Webhook Sources
Verify that incoming webhooks actually come from SmartLead:
```python Python theme={null}
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
"""Verify webhook signature to prevent spoofing."""
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected, signature)
@app.route('/webhooks/smartlead', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Smartlead-Signature', '')
if not verify_webhook(request.data.decode(), signature, WEBHOOK_SECRET):
return jsonify({'error': 'Invalid signature'}), 401
# Process webhook...
```
### Use Least-Privilege Access
If you have multiple integrations, create separate API keys for each with appropriate access scopes. Rotate keys periodically and revoke unused keys.
## Production Checklist
Before going live, verify:
SPF, DKIM, and DMARC are set up for all sending domains.
All email accounts have been warming for 14+ days with good inbox placement.
Your integration handles 400, 401, 404, 429, and 500 errors gracefully with retries.
Client-side rate limiting prevents 429 errors. Webhooks replace polling where possible.
Bounce rates, reply rates, and campaign health are monitored with alerts.
Keys stored in environment variables or secrets manager. Never in source code.
Webhook handler processes all event types, returns 200, and handles duplicates.
All leads are email-verified and personalization fields are validated before import.
## What's Next?
Build your first campaign from scratch
Explore all available endpoints
Comprehensive error handling patterns
Optimize your request patterns
# Campaign Setup Guide
Source: https://api.smartlead.ai/guides/campaign-setup
Learn how to create, configure, and optimize email campaigns — from sequences and A/B testing to scheduling, email account rotation, and advanced settings
## Overview
A SmartLead campaign is the core unit of outbound email. It ties together your email accounts, sequences, leads, and sending schedule into a single automated workflow. This guide covers everything you need to configure a campaign programmatically.
## Campaign Architecture
Every campaign has four building blocks:
1. **Email Accounts** — The sending addresses that rotate automatically
2. **Sequences** — The emails and follow-ups your leads receive
3. **Leads** — The prospects imported into the campaign
4. **Schedule** — When and how fast emails are sent
```
Campaign
├── Email Accounts (1+)
├── Sequences
│ ├── Step 1 (Initial email)
│ │ ├── Variant A
│ │ └── Variant B (optional A/B test)
│ ├── Step 2 (Follow-up, +3 days)
│ └── Step 3 (Break-up, +5 days)
├── Leads (up to 400 per import)
└── Schedule (timezone, days, hours)
```
## Creating a Campaign
```python Python theme={null}
import requests
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
BASE_URL = "https://server.smartlead.ai/api/v1"
campaign_payload = {
"name": "Q1 SaaS Outreach — VP Sales",
"track_settings": {
"track_open": True,
"track_click": True
}
}
response = requests.post(
f"{BASE_URL}/campaigns/create",
params={"api_key": API_KEY},
json=campaign_payload
)
campaign = response.json()
campaign_id = campaign["campaign"]["id"]
print(f"Campaign created: ID {campaign_id}")
```
```javascript JavaScript theme={null}
const API_KEY = process.env.SMARTLEAD_API_KEY;
const BASE_URL = 'https://server.smartlead.ai/api/v1';
const response = await fetch(`${BASE_URL}/campaigns/create?api_key=${API_KEY}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Q1 SaaS Outreach — VP Sales',
track_settings: {
track_open: true,
track_click: true
}
})
});
const campaign = await response.json();
const campaignId = campaign.campaign.id;
console.log(`Campaign created: ID ${campaignId}`);
```
Use descriptive campaign names that include the quarter, ICP, and persona. This makes it easier to filter and compare performance later. Example: `Q1 SaaS Outreach — VP Sales — US`.
## Building Sequences
Sequences define the emails your leads receive and the timing between them. Each step can optionally include A/B test variants.
### Basic Sequence
```python Python theme={null}
sequences_payload = {
"sequences": [
{
"seq_number": 1,
"subject": "Quick question about {{company_name}}",
"email_body": """Hi {{first_name}},
I noticed {{company_name}} is scaling its outbound — are you exploring ways to improve reply rates?
We help {{industry}} companies like yours book 3x more meetings through automated cold email.
Worth a 15-minute call this week?
Best,
Sarah""",
"seq_delay_details": {"delay_in_days": 0}
},
{
"seq_number": 2,
"subject": "Re: Quick question about {{company_name}}",
"email_body": """Hi {{first_name}},
Following up — I wanted to share a case study from a {{industry}} company that went from 2% to 14% reply rates in 30 days.
Happy to walk through what they did if you have 10 minutes.
Sarah""",
"seq_delay_details": {"delay_in_days": 3}
},
{
"seq_number": 3,
"subject": "Re: Quick question about {{company_name}}",
"email_body": """Hi {{first_name}},
Don't want to be a pest — just checking if improving outbound pipeline is a priority for {{company_name}} right now.
If the timing isn't right, no worries. Happy to reconnect next quarter.
Best,
Sarah""",
"seq_delay_details": {"delay_in_days": 5}
}
]
}
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/sequences",
params={"api_key": API_KEY},
json=sequences_payload
)
print("Sequences created!")
```
### Personalization Variables
Use double curly braces to insert lead-specific data into your emails:
| Variable | Description | Source |
| ----------------------- | -------------------- | ------------------------- |
| `{{first_name}}` | Lead's first name | Lead import |
| `{{last_name}}` | Lead's last name | Lead import |
| `{{email}}` | Lead's email address | Lead import |
| `{{company_name}}` | Company name | Lead import |
| `{{location}}` | Lead's location | Lead import |
| `{{custom_field_name}}` | Any custom field | `custom_fields` on import |
If a personalization variable is missing for a lead, SmartLead will leave the placeholder blank. Use fallback values in your copy to handle this gracefully — for example, write "your team" as a fallback for `{{company_name}}`.
### A/B Testing Variants
Test different subject lines or email bodies to optimize performance:
```python Python theme={null}
sequences_with_variants = {
"sequences": [
{
"seq_number": 1,
"subject": "Quick question about {{company_name}}",
"email_body": "Hi {{first_name}},\n\nI noticed {{company_name}} is scaling...",
"seq_delay_details": {"delay_in_days": 0},
"variants": [
{
"subject": "{{first_name}}, quick thought on {{company_name}}",
"email_body": "Hey {{first_name}},\n\nSaw that {{company_name}} is growing fast...",
"variant_distribution": 50
}
]
}
]
}
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/sequences",
params={"api_key": API_KEY},
json=sequences_with_variants
)
```
SmartLead automatically splits traffic between variants and tracks open/reply rates for each.
Test one variable at a time (subject line OR body, not both) so you can isolate what drives performance. Run tests for at least 200 sends before drawing conclusions.
## Linking Email Accounts
Connect one or more email accounts to your campaign. SmartLead rotates between them automatically to maximize deliverability.
```python Python theme={null}
# Link existing email accounts by their IDs
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/email-accounts",
params={"api_key": API_KEY},
json={"email_account_ids": [101, 102, 103]}
)
print("Email accounts linked!")
```
### Fetching Available Accounts
```python Python theme={null}
# List all email accounts
response = requests.get(
f"{BASE_URL}/email-accounts",
params={"api_key": API_KEY}
)
accounts = response.json()
for account in accounts:
print(f"ID: {account['id']} | {account['from_email']} | Warmup: {account['warmup_enabled']}")
```
Only link accounts that have been warmed up for at least 14 days. Sending cold emails from a fresh account will hurt your deliverability and sender reputation. See the [Email Warmup Guide](/guides/email-warmup) for details.
## Configuring the Schedule
Control when emails are sent and how many go out per day:
```python Python theme={null}
schedule_payload = {
"timezone": "America/New_York",
"days_of_the_week": [1, 2, 3, 4, 5], # Monday-Friday
"start_hour": "09:00",
"end_hour": "17:00",
"min_time_btw_emails": 8, # Minutes between emails
"max_new_leads_per_day": 30 # New leads contacted per day
}
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/schedule",
params={"api_key": API_KEY},
json=schedule_payload
)
print("Schedule configured!")
```
| Parameter | Description | Recommended |
| ----------------------- | ----------------------------- | -------------------------- |
| `timezone` | IANA timezone for send window | Match your leads' timezone |
| `days_of_the_week` | 1=Mon through 7=Sun | `[1,2,3,4,5]` (weekdays) |
| `start_hour` | Earliest send time | `"08:00"` - `"10:00"` |
| `end_hour` | Latest send time | `"16:00"` - `"18:00"` |
| `min_time_btw_emails` | Gap between sends (minutes) | `5` - `12` |
| `max_new_leads_per_day` | Daily new lead cap | `20` - `50` per account |
## Campaign Settings
### Track Settings
```python Python theme={null}
# Update tracking settings
response = requests.patch(
f"{BASE_URL}/campaigns/{campaign_id}/settings",
params={"api_key": API_KEY},
json={
"track_settings": {
"track_open": True,
"track_click": True
}
}
)
```
### Stop Conditions
Automatically stop emailing a lead when certain events occur:
```python Python theme={null}
settings_payload = {
"stop_lead_settings": {
"stop_on_reply": True,
"stop_on_auto_reply": False,
"stop_on_click": False
}
}
response = requests.patch(
f"{BASE_URL}/campaigns/{campaign_id}/settings",
params={"api_key": API_KEY},
json=settings_payload
)
```
Always enable `stop_on_reply`. Continuing to send follow-ups after someone replies creates a poor experience and can increase spam complaints.
## Activating the Campaign
Once everything is configured, set the campaign status to `ACTIVE`:
```python Python theme={null}
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/status",
params={"api_key": API_KEY},
json={"status": "ACTIVE"}
)
print("Campaign is now ACTIVE!")
```
### Campaign Statuses
| Status | Description |
| ----------- | ------------------------------------------------- |
| `DRAFTED` | Campaign created but not yet active |
| `ACTIVE` | Currently sending emails on schedule |
| `PAUSED` | Temporarily stopped; can be resumed |
| `COMPLETED` | All leads have received all sequences |
| `STOPPED` | Manually stopped; leads won't receive more emails |
```python Python theme={null}
# Pause a campaign
requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/status",
params={"api_key": API_KEY},
json={"status": "PAUSED"}
)
```
## Monitoring Campaign Performance
Track your campaign's performance with the analytics endpoints:
```python Python theme={null}
# Get campaign analytics
response = requests.get(
f"{BASE_URL}/campaigns/{campaign_id}/analytics",
params={"api_key": API_KEY}
)
analytics = response.json()
print(f"Sent: {analytics.get('total_sent', 0)}")
print(f"Opened: {analytics.get('total_opened', 0)}")
print(f"Replied: {analytics.get('total_replied', 0)}")
print(f"Bounced: {analytics.get('total_bounced', 0)}")
```
### Key Metrics to Watch
| Metric | Good | Warning | Action Needed |
| ---------------- | ------- | ------- | -------------------------------------------- |
| Open Rate | > 50% | 30–50% | \< 30% — fix subject lines or deliverability |
| Reply Rate | > 5% | 2–5% | \< 2% — improve copy or targeting |
| Bounce Rate | \< 3% | 3–5% | > 5% — verify email list quality |
| Unsubscribe Rate | \< 0.5% | 0.5–1% | > 1% — review targeting and frequency |
## Troubleshooting
Check these in order: (1) Email accounts are linked and warmed up, (2) the schedule window includes the current day and time, (3) leads have been imported and are in "Not Contacted" status, (4) email accounts haven't hit their daily sending limit.
Verify your lead list quality. Use an email verification service before importing leads. Check that your email accounts' DNS records (SPF, DKIM, DMARC) are properly configured. Consider reducing your daily sending volume.
Test different subject lines with A/B testing. Check your sender reputation using tools like mail-tester.com. Ensure your email accounts are properly warmed up. Avoid spam trigger words in subject lines.
Verify that the delay days are set correctly between steps. Check if `stop_on_reply` or other stop conditions are triggering. Ensure the campaign status is still ACTIVE.
## What's Next?
Warm up accounts before adding them to campaigns
Import, segment, and manage leads at scale
Optimize deliverability, copy, and campaign structure
Get real-time notifications for campaign events
# Email Warmup Guide
Source: https://api.smartlead.ai/guides/email-warmup
Understand and configure email warmup to build sender reputation, improve deliverability, and avoid the spam folder before launching campaigns
## Overview
Email warmup is the process of gradually building a sending reputation for a new email account. SmartLead automates this by exchanging emails between accounts in its warmup pool — opening, replying, and marking messages as important to signal to email providers that your account is legitimate.
Skipping warmup is the number one reason cold emails land in spam. This guide covers how to configure warmup via the API and when your accounts are ready for live campaigns.
## How Warmup Works
SmartLead's warmup pool consists of thousands of email accounts. When you enable warmup on an account:
1. **SmartLead sends emails** from your account to other pool members
2. **Pool members open and reply** to your emails automatically
3. **Positive engagement signals** (opens, replies, moving from spam to inbox) train email providers to trust your account
4. **Volume increases gradually** based on your `daily_rampup` setting
```
Day 1: ████░░░░░░░░░░ (5 warmup emails)
Day 7: ████████░░░░░░ (19 warmup emails)
Day 14: ██████████████ (33+ warmup emails)
└── Ready for campaigns
```
## Configuring Warmup on a New Account
When creating an email account, include warmup settings in the payload:
```python Python theme={null}
import requests
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
BASE_URL = "https://server.smartlead.ai/api/v1"
email_account_payload = {
"from_name": "Sarah Johnson",
"from_email": "sarah@yourcompany.com",
"user_name": "sarah@yourcompany.com",
"password": "your_app_password",
"smtp_host": "smtp.yourprovider.com",
"smtp_port": 587,
"imap_host": "imap.yourprovider.com",
"imap_port": 993,
"max_email_per_day": 40,
"warmup_enabled": True,
"total_warmup_per_day": 20,
"daily_rampup": 2,
"reply_rate_percentage": 30
}
response = requests.post(
f"{BASE_URL}/email-accounts/save",
params={"api_key": API_KEY},
json=email_account_payload
)
account = response.json()
print(f"Account created with warmup enabled: {account['email_account']['id']}")
```
### Warmup Parameters Explained
| Parameter | Description | Recommended |
| ----------------------- | -------------------------------------------- | --------------------------- |
| `warmup_enabled` | Turn warmup on/off | `True` for all new accounts |
| `total_warmup_per_day` | Max warmup emails per day | `20` – `40` |
| `daily_rampup` | Additional warmup emails added per day | `2` – `3` |
| `reply_rate_percentage` | Percentage of warmup emails that get a reply | `30` – `40` |
Do not set `total_warmup_per_day` above 40 for new accounts. Sending too many warmup emails too fast can trigger spam filters — the opposite of what you want.
## Enabling Warmup on Existing Accounts
```python Python theme={null}
# Enable warmup on an existing account
email_account_id = 12345
response = requests.patch(
f"{BASE_URL}/email-accounts/{email_account_id}",
params={"api_key": API_KEY},
json={
"warmup_enabled": True,
"total_warmup_per_day": 25,
"daily_rampup": 2,
"reply_rate_percentage": 30
}
)
print("Warmup enabled!")
```
## Warmup Timeline
Here's what a typical warmup schedule looks like:
| Phase | Days | Daily Volume | What's Happening |
| --------------- | ------- | ------------ | ------------------------------------------- |
| **Ramp-up** | 1–7 | 5 → 19 | Building initial reputation |
| **Growth** | 8–14 | 20 → 33 | Establishing consistent engagement |
| **Stable** | 14+ | 33–40 | Reputation established, ready for campaigns |
| **Maintenance** | Ongoing | 15–25 | Keep warmup running alongside campaigns |
Keep warmup enabled even after you start sending campaigns. SmartLead automatically coordinates warmup and campaign sends to stay within your daily limits. Warmup volume will decrease as campaign sends increase.
## Checking Warmup Status
Monitor your account's warmup progress:
```python Python theme={null}
# Get email account details including warmup stats
response = requests.get(
f"{BASE_URL}/email-accounts/{email_account_id}",
params={"api_key": API_KEY}
)
account = response.json()
print(f"Warmup enabled: {account.get('warmup_enabled')}")
print(f"Daily warmup limit: {account.get('total_warmup_per_day')}")
print(f"Current rampup: {account.get('daily_rampup')}")
```
## When to Start Campaigns
Your account is ready for live campaigns when:
* **Warmup has been running for 14+ days** without interruption
* **Inbox placement is above 90%** (check your email deliverability score)
* **No spam folder issues** have been flagged
* **Daily warmup volume** has reached a stable level
Confirm the account has been warming up for at least 14 days. Newer domains may need 21–30 days.
Send a test email to a personal account and verify it lands in the primary inbox, not spam or promotions.
Begin your campaign with `max_new_leads_per_day` set to 10–15. Monitor bounce rates and spam complaints for the first few days.
Increase sending volume by 5–10 leads per day every few days, as long as deliverability metrics remain healthy.
## Managing Daily Limits
SmartLead coordinates warmup and campaign sends within your `max_email_per_day` limit:
```
max_email_per_day = 40
├── Warmup emails: 15 (auto-adjusted)
└── Campaign emails: 25 (remaining capacity)
```
As campaign volume increases, warmup volume automatically decreases. If campaign volume drops, warmup ramps back up.
```python Python theme={null}
# Update daily email limit
response = requests.patch(
f"{BASE_URL}/email-accounts/{email_account_id}",
params={"api_key": API_KEY},
json={
"max_email_per_day": 50,
"total_warmup_per_day": 20
}
)
```
## DNS Requirements
Proper DNS configuration is critical for deliverability. Ensure these records are set up for your sending domain:
| Record | Purpose | Priority |
| -------------------------- | ------------------------------------------------------------- | ----------- |
| **SPF** | Authorizes your mail servers to send on behalf of your domain | Required |
| **DKIM** | Cryptographically signs emails to verify authenticity | Required |
| **DMARC** | Tells receiving servers how to handle SPF/DKIM failures | Required |
| **Custom Tracking Domain** | Branded tracking links instead of generic ones | Recommended |
Missing or misconfigured DNS records will tank your deliverability regardless of how well your account is warmed up. Set up SPF, DKIM, and DMARC before enabling warmup.
## Troubleshooting
Check your DNS records (SPF, DKIM, DMARC). Reduce `total_warmup_per_day` to 10 and rebuild gradually. Ensure your sending domain isn't on any blacklists — check with tools like MXToolbox.
Verify `daily_rampup` is set to 2 or higher. Check that the email account credentials (SMTP/IMAP) are still valid and the account isn't locked. Ensure `max_email_per_day` is high enough to allow warmup growth.
Reduce campaign volume immediately. Check bounce rates — if above 5%, your lead list needs better verification. Ensure warmup is still enabled alongside campaigns. Consider pausing campaigns for 3–5 days while warmup rebuilds reputation.
Verify your IMAP credentials and host/port settings. For Gmail, ensure "Less secure app access" is enabled or use an App Password. For Outlook, check that IMAP is enabled in account settings. Ensure 2FA app passwords are being used where required.
## What's Next?
Configure campaigns once your accounts are warmed up
Deliverability tips and sending strategies
# Error Handling Guide
Source: https://api.smartlead.ai/guides/error-handling
Handle SmartLead API errors gracefully — understand HTTP status codes, parse error responses, implement retry logic, and debug common issues
## Overview
The SmartLead API uses standard HTTP status codes and structured error responses to communicate what went wrong. This guide covers how to interpret errors, implement robust retry logic, and debug the most common issues.
## HTTP Status Codes
| Code | Meaning | Action |
| ----- | --------------------- | -------------------------------------------------------------- |
| `200` | Success | Request completed successfully |
| `201` | Created | Resource created successfully |
| `400` | Bad Request | Fix the request payload — check required fields and data types |
| `401` | Unauthorized | Check your API key |
| `403` | Forbidden | You don't have access to this resource |
| `404` | Not Found | The resource (campaign, lead, etc.) doesn't exist |
| `409` | Conflict | Duplicate resource — the lead or campaign already exists |
| `422` | Unprocessable Entity | Validation failed — check field values |
| `429` | Too Many Requests | Rate limited — slow down and retry after the delay |
| `500` | Internal Server Error | SmartLead server issue — retry with exponential backoff |
| `503` | Service Unavailable | Temporary outage — retry after a short delay |
## Error Response Format
Error responses follow a consistent JSON structure:
```json theme={null}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "email field is required for all leads in lead_list",
"details": {
"field": "lead_list[2].email",
"constraint": "required"
}
}
}
```
## Implementing Error Handling
### Basic Error Handler
```python Python theme={null}
import requests
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
BASE_URL = "https://server.smartlead.ai/api/v1"
def make_request(method, endpoint, payload=None):
"""Make an API request with comprehensive error handling."""
url = f"{BASE_URL}/{endpoint}"
params = {"api_key": API_KEY}
try:
if method == "GET":
response = requests.get(url, params=params, timeout=30)
elif method == "POST":
response = requests.post(url, params=params, json=payload, timeout=30)
elif method == "PATCH":
response = requests.patch(url, params=params, json=payload, timeout=30)
elif method == "DELETE":
response = requests.delete(url, params=params, timeout=30)
# Raise for HTTP errors
response.raise_for_status()
return response.json()
except requests.exceptions.HTTPError as e:
status = e.response.status_code
error_body = e.response.json() if e.response.content else {}
if status == 400:
print(f"Bad request: {error_body.get('error', {}).get('message', 'Unknown')}")
elif status == 401:
print("Invalid API key. Check your SMARTLEAD_API_KEY.")
elif status == 404:
print(f"Resource not found: {endpoint}")
elif status == 429:
print("Rate limited. Retry after a delay.")
elif status >= 500:
print(f"Server error ({status}). Retry later.")
else:
print(f"HTTP {status}: {error_body}")
raise
except requests.exceptions.ConnectionError:
print("Connection failed. Check your network.")
raise
except requests.exceptions.Timeout:
print("Request timed out. Try again.")
raise
```
```javascript JavaScript theme={null}
const API_KEY = process.env.SMARTLEAD_API_KEY;
const BASE_URL = 'https://server.smartlead.ai/api/v1';
async function makeRequest(method, endpoint, payload = null) {
const url = `${BASE_URL}/${endpoint}?api_key=${API_KEY}`;
const options = {
method,
headers: { 'Content-Type': 'application/json' }
};
if (payload && ['POST', 'PATCH', 'PUT'].includes(method)) {
options.body = JSON.stringify(payload);
}
const response = await fetch(url, options);
if (!response.ok) {
const errorBody = await response.json().catch(() => ({}));
const message = errorBody?.error?.message || response.statusText;
switch (response.status) {
case 400:
throw new Error(`Bad request: ${message}`);
case 401:
throw new Error('Invalid API key');
case 404:
throw new Error(`Not found: ${endpoint}`);
case 429:
throw new Error('Rate limited — retry after delay');
default:
throw new Error(`HTTP ${response.status}: ${message}`);
}
}
return response.json();
}
```
### Retry with Exponential Backoff
For transient errors (429, 500, 503), implement automatic retries:
```python Python theme={null}
import time
import random
def make_request_with_retry(method, endpoint, payload=None, max_retries=3):
"""Make an API request with exponential backoff retry."""
for attempt in range(max_retries + 1):
try:
return make_request(method, endpoint, payload)
except requests.exceptions.HTTPError as e:
status = e.response.status_code
# Only retry on transient errors
if status not in [429, 500, 502, 503]:
raise
if attempt == max_retries:
print(f"Failed after {max_retries} retries")
raise
# Exponential backoff with jitter
delay = (2 ** attempt) + random.uniform(0, 1)
# Respect Retry-After header if present
retry_after = e.response.headers.get("Retry-After")
if retry_after:
delay = max(delay, float(retry_after))
print(f"Retry {attempt + 1}/{max_retries} in {delay:.1f}s...")
time.sleep(delay)
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
if attempt == max_retries:
raise
delay = (2 ** attempt) + random.uniform(0, 1)
print(f"Connection issue. Retry {attempt + 1}/{max_retries} in {delay:.1f}s...")
time.sleep(delay)
```
Always add random jitter to your backoff delay. Without jitter, multiple clients retrying at the same intervals will create "thundering herd" problems that amplify the load on the server.
## Common Errors and Solutions
**Cause:** The `api_key` parameter is missing, expired, or incorrect.
**Fix:** Verify your API key in SmartLead Settings → API Keys. Regenerate if needed. Ensure the key is passed as a query parameter: `?api_key=YOUR_KEY`.
**Cause:** One or more leads in your `lead_list` are missing the `email` field.
**Fix:** Validate your data before sending. Every lead object must have an `email` field with a valid email address.
```python theme={null}
# Validate before import
valid_leads = [lead for lead in leads if lead.get("email")]
invalid_leads = [lead for lead in leads if not lead.get("email")]
if invalid_leads:
print(f"Skipping {len(invalid_leads)} leads without email")
```
**Cause:** You're trying to import more than 400 leads in a single request.
**Fix:** Batch your imports into groups of 400 or fewer. See the [Lead Management Guide](/guides/lead-management) for a batching example.
**Cause:** The campaign ID doesn't exist or belongs to a different account.
**Fix:** Verify the campaign ID by listing your campaigns first:
```python theme={null}
campaigns = make_request("GET", "campaigns/")
for c in campaigns.get("campaigns", []):
print(f"ID: {c['id']} — {c['name']}")
```
**Cause:** A lead with the same email address is already in this campaign.
**Fix:** This isn't necessarily an error — SmartLead prevents duplicate sends. Check the `skipped_leads` array in the import response for details.
**Cause:** Too many requests in a short time period.
**Fix:** Implement exponential backoff (see above). Check the `Retry-After` header for the recommended wait time. See the [Rate Limits Guide](/guides/rate-limits) for details.
**Cause:** An unexpected error on SmartLead's servers.
**Fix:** Retry with exponential backoff. If the error persists, check the [SmartLead status page](https://status.smartlead.ai) and contact support with the request details.
## Debugging Tips
### Log Every Request and Response
```python Python theme={null}
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("smartlead")
def make_request_debug(method, endpoint, payload=None):
url = f"{BASE_URL}/{endpoint}"
logger.debug(f"Request: {method} {url}")
if payload:
logger.debug(f"Payload: {payload}")
response = requests.request(
method, url,
params={"api_key": API_KEY},
json=payload,
timeout=30
)
logger.debug(f"Response: {response.status_code}")
logger.debug(f"Body: {response.text[:500]}")
response.raise_for_status()
return response.json()
```
### Validate Data Before Sending
```python Python theme={null}
def validate_lead(lead):
"""Validate a lead object before import."""
errors = []
if not lead.get("email"):
errors.append("Missing email")
elif "@" not in lead["email"]:
errors.append(f"Invalid email format: {lead['email']}")
if not lead.get("first_name"):
errors.append("Missing first_name (will affect personalization)")
return errors
# Validate batch before import
for i, lead in enumerate(lead_list):
errors = validate_lead(lead)
if errors:
print(f"Lead {i}: {', '.join(errors)}")
```
## What's Next?
Understand rate limits and optimize request patterns
Build reliable integrations with production-grade patterns
# Getting Started Guide
Source: https://api.smartlead.ai/guides/getting-started
Set up your SmartLead API integration from scratch — generate keys, make your first calls, and launch a campaign programmatically
## Overview
This guide walks you through everything you need to go from zero to a live email campaign using the SmartLead API. By the end, you'll have created a campaign, added email accounts, imported leads, configured sequences, and started sending — all through code.
## Prerequisites
Before you begin, make sure you have:
* A SmartLead account ([sign up here](https://app.smartlead.ai/signup))
* At least one email account ready (Gmail, Outlook, or SMTP credentials)
* Basic familiarity with REST APIs and HTTP requests
* A tool for making API calls (cURL, Postman, or any HTTP client library)
## Step 1: Get Your API Key
Go to [app.smartlead.ai](https://app.smartlead.ai) and sign in with your credentials.
Navigate to **Settings** → **API Keys** from the left sidebar.
Click **Generate New API Key**, give it a descriptive name (e.g., "Production API" or "Dev Testing"), and copy the key immediately.
Your API key is shown only once. Store it in a secure location like an environment variable or secrets manager. Never hardcode it in source files or commit it to version control.
### Store Your Key Securely
```bash .env theme={null}
SMARTLEAD_API_KEY=your_api_key_here
```
```python Python theme={null}
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
BASE_URL = "https://server.smartlead.ai/api/v1"
```
```javascript JavaScript theme={null}
const API_KEY = process.env.SMARTLEAD_API_KEY;
const BASE_URL = 'https://server.smartlead.ai/api/v1';
```
## Step 2: Verify Your Connection
Test that your API key works by fetching your campaigns:
```bash cURL theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/campaigns/?api_key=$SMARTLEAD_API_KEY"
```
```python Python theme={null}
import requests
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
BASE_URL = "https://server.smartlead.ai/api/v1"
response = requests.get(f"{BASE_URL}/campaigns/", params={"api_key": API_KEY})
if response.status_code == 200:
data = response.json()
print(f"Connected! Found {len(data.get('campaigns', []))} campaigns.")
else:
print(f"Error {response.status_code}: {response.text}")
```
```javascript JavaScript theme={null}
const API_KEY = process.env.SMARTLEAD_API_KEY;
const BASE_URL = 'https://server.smartlead.ai/api/v1';
const response = await fetch(`${BASE_URL}/campaigns/?api_key=${API_KEY}`);
const data = await response.json();
if (response.ok) {
console.log(`Connected! Found ${data.campaigns.length} campaigns.`);
} else {
console.error(`Error ${response.status}: ${JSON.stringify(data)}`);
}
```
A successful response looks like:
```json theme={null}
{
"campaigns": [],
"total_count": 0
}
```
## Step 3: Create a Campaign
Now create your first campaign:
```python Python theme={null}
campaign_payload = {
"name": "Q1 2025 SaaS Outreach",
"track_settings": {
"track_open": True,
"track_click": True
}
}
response = requests.post(
f"{BASE_URL}/campaigns/create",
params={"api_key": API_KEY},
json=campaign_payload
)
campaign = response.json()
campaign_id = campaign["campaign"]["id"]
print(f"Campaign created: ID {campaign_id}")
```
```javascript JavaScript theme={null}
const campaignPayload = {
name: 'Q1 2025 SaaS Outreach',
track_settings: {
track_open: true,
track_click: true
}
};
const response = await fetch(`${BASE_URL}/campaigns/create?api_key=${API_KEY}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(campaignPayload)
});
const campaign = await response.json();
const campaignId = campaign.campaign.id;
console.log(`Campaign created: ID ${campaignId}`);
```
## Step 4: Add an Email Account
You need at least one sending account. Here's how to add an SMTP account:
```python Python theme={null}
email_account_payload = {
"from_name": "Sarah Johnson",
"from_email": "sarah@yourcompany.com",
"user_name": "sarah@yourcompany.com",
"password": "your_app_password",
"smtp_host": "smtp.yourprovider.com",
"smtp_port": 587,
"imap_host": "imap.yourprovider.com",
"imap_port": 993,
"max_email_per_day": 40,
"warmup_enabled": True,
"total_warmup_per_day": 20,
"daily_rampup": 2,
"reply_rate_percentage": 30
}
response = requests.post(
f"{BASE_URL}/email-accounts/save",
params={"api_key": API_KEY},
json=email_account_payload
)
account = response.json()
email_account_id = account["email_account"]["id"]
print(f"Email account added: ID {email_account_id}")
```
Then connect it to your campaign:
```python Python theme={null}
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/email-accounts",
params={"api_key": API_KEY},
json={"email_account_ids": [email_account_id]}
)
print("Email account linked to campaign!")
```
For best deliverability, warm up new email accounts for at least 14 days before adding them to active campaigns. See the [Email Warmup Guide](/guides/email-warmup) for details.
## Step 5: Create Email Sequences
Add your outreach emails and follow-ups:
```python Python theme={null}
sequences_payload = {
"sequences": [
{
"seq_number": 1,
"subject": "Quick question about {{company_name}}",
"email_body": """Hi {{first_name}},
I came across {{company_name}} and noticed you're in the {{industry}} space.
We help companies like yours increase outbound pipeline by 3x through automated cold email. Companies like [relevant reference] saw results within the first month.
Would it make sense to chat for 15 minutes this week?
Best,
Sarah""",
"seq_delay_details": {"delay_in_days": 0}
},
{
"seq_number": 2,
"subject": "Re: Quick question about {{company_name}}",
"email_body": """Hi {{first_name}},
Following up on my note — I wanted to share a quick case study that might be relevant.
[Case study company] in {{industry}} increased their reply rates from 2% to 12% after switching to our approach.
Worth a quick call?
Sarah""",
"seq_delay_details": {"delay_in_days": 3}
},
{
"seq_number": 3,
"subject": "Re: Quick question about {{company_name}}",
"email_body": """Hi {{first_name}},
I don't want to be a pest — just wanted to check if this is something {{company_name}} is thinking about right now.
If the timing isn't right, no worries at all. Happy to reconnect later.
Best,
Sarah""",
"seq_delay_details": {"delay_in_days": 5}
}
]
}
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/sequences",
params={"api_key": API_KEY},
json=sequences_payload
)
print("Sequences created!")
```
## Step 6: Import Leads
Add prospects to your campaign (max 400 per request):
```python Python theme={null}
leads_payload = {
"lead_list": [
{
"email": "alex@acmecorp.com",
"first_name": "Alex",
"last_name": "Chen",
"company_name": "Acme Corp",
"custom_fields": {
"job_title": "VP of Sales",
"industry": "B2B SaaS",
"company_size": "50-200"
}
},
{
"email": "maria@techstartup.io",
"first_name": "Maria",
"last_name": "Garcia",
"company_name": "TechStartup",
"custom_fields": {
"job_title": "Head of Growth",
"industry": "Fintech",
"company_size": "20-50"
}
}
],
"settings": {
"ignore_global_block_list": False,
"ignore_unsubscribe_list": False,
"ignore_duplicate_leads_in_other_campaign": False
}
}
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY},
json=leads_payload
)
result = response.json()
print(f"Added: {result['added_count']}, Skipped: {result['skipped_count']}")
```
SmartLead automatically validates emails against block lists and checks for duplicates. Skipped leads will include a reason in the response.
## Step 7: Configure Schedule & Start
Set your sending schedule, then activate:
```python Python theme={null}
# Set schedule (Monday-Friday, 9am-5pm EST)
schedule_payload = {
"timezone": "America/New_York",
"days_of_the_week": [1, 2, 3, 4, 5],
"start_hour": "09:00",
"end_hour": "17:00",
"min_time_btw_emails": 8,
"max_new_leads_per_day": 30
}
requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/schedule",
params={"api_key": API_KEY},
json=schedule_payload
)
# Activate the campaign
requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/status",
params={"api_key": API_KEY},
json={"status": "ACTIVE"}
)
print("Campaign is now ACTIVE and sending!")
```
Your first campaign is live! SmartLead will now send emails according to your schedule, rotating between connected email accounts.
## Complete Working Example
Here's the full script combining all steps:
```python Python theme={null}
import requests
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
BASE_URL = "https://server.smartlead.ai/api/v1"
def make_request(method, endpoint, payload=None):
"""Helper to make API requests with error handling."""
url = f"{BASE_URL}/{endpoint}"
params = {"api_key": API_KEY}
if method == "GET":
response = requests.get(url, params=params)
elif method == "POST":
response = requests.post(url, params=params, json=payload)
elif method == "PATCH":
response = requests.patch(url, params=params, json=payload)
if response.status_code not in [200, 201]:
raise Exception(f"API error {response.status_code}: {response.text}")
return response.json()
# 1. Create campaign
campaign = make_request("POST", "campaigns/create", {
"name": "Q1 2025 SaaS Outreach"
})
campaign_id = campaign["campaign"]["id"]
print(f"✓ Campaign created: {campaign_id}")
# 2. Add sequences
make_request("POST", f"campaigns/{campaign_id}/sequences", {
"sequences": [
{
"seq_number": 1,
"subject": "Quick question about {{company_name}}",
"email_body": "Hi {{first_name}},\n\nI came across {{company_name}}...",
"seq_delay_details": {"delay_in_days": 0}
},
{
"seq_number": 2,
"subject": "Re: Quick question about {{company_name}}",
"email_body": "Hi {{first_name}},\n\nFollowing up...",
"seq_delay_details": {"delay_in_days": 3}
}
]
})
print("✓ Sequences added")
# 3. Link email accounts (use your existing account IDs)
make_request("POST", f"campaigns/{campaign_id}/email-accounts", {
"email_account_ids": [YOUR_EMAIL_ACCOUNT_ID]
})
print("✓ Email accounts linked")
# 4. Import leads
result = make_request("POST", f"campaigns/{campaign_id}/leads", {
"lead_list": [
{
"email": "prospect@example.com",
"first_name": "Alex",
"company_name": "Acme Corp",
"custom_fields": {"job_title": "VP Sales"}
}
]
})
print(f"✓ Leads added: {result['added_count']}")
# 5. Set schedule and activate
make_request("POST", f"campaigns/{campaign_id}/schedule", {
"timezone": "America/New_York",
"days_of_the_week": [1, 2, 3, 4, 5],
"start_hour": "09:00",
"end_hour": "17:00"
})
make_request("POST", f"campaigns/{campaign_id}/status", {
"status": "ACTIVE"
})
print("✓ Campaign is ACTIVE!")
```
## What's Next?
Advanced campaign configuration and optimization
Warm up accounts for maximum deliverability
Import, segment, and manage leads at scale
Connect SmartLead to your CRM and tools
# Lead Management Guide
Source: https://api.smartlead.ai/guides/lead-management
Import, segment, and manage leads at scale — including custom fields, bulk operations, deduplication, and lead lifecycle management
## Overview
Leads are the contacts who receive your campaign emails. SmartLead provides APIs for importing leads in bulk, enriching them with custom fields, tracking their status through the outreach lifecycle, and managing them across campaigns. This guide covers the full lead management workflow.
## Importing Leads
Add leads to a campaign using the lead import endpoint. You can send up to **400 leads per request**.
```python Python theme={null}
import requests
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
BASE_URL = "https://server.smartlead.ai/api/v1"
campaign_id = 12345
leads_payload = {
"lead_list": [
{
"email": "alex@acmecorp.com",
"first_name": "Alex",
"last_name": "Chen",
"company_name": "Acme Corp",
"location": "San Francisco, CA",
"custom_fields": {
"job_title": "VP of Sales",
"industry": "B2B SaaS",
"company_size": "50-200",
"linkedin_url": "https://linkedin.com/in/alexchen"
}
},
{
"email": "maria@techstartup.io",
"first_name": "Maria",
"last_name": "Garcia",
"company_name": "TechStartup",
"location": "Austin, TX",
"custom_fields": {
"job_title": "Head of Growth",
"industry": "Fintech",
"company_size": "20-50"
}
}
],
"settings": {
"ignore_global_block_list": False,
"ignore_unsubscribe_list": False,
"ignore_duplicate_leads_in_other_campaign": False
}
}
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY},
json=leads_payload
)
result = response.json()
print(f"Added: {result['added_count']}")
print(f"Skipped: {result['skipped_count']}")
```
```javascript JavaScript theme={null}
const API_KEY = process.env.SMARTLEAD_API_KEY;
const BASE_URL = 'https://server.smartlead.ai/api/v1';
const campaignId = 12345;
const response = await fetch(
`${BASE_URL}/campaigns/${campaignId}/leads?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
lead_list: [
{
email: 'alex@acmecorp.com',
first_name: 'Alex',
last_name: 'Chen',
company_name: 'Acme Corp',
custom_fields: {
job_title: 'VP of Sales',
industry: 'B2B SaaS'
}
}
],
settings: {
ignore_global_block_list: false,
ignore_unsubscribe_list: false,
ignore_duplicate_leads_in_other_campaign: false
}
})
}
);
const result = await response.json();
console.log(`Added: ${result.added_count}, Skipped: ${result.skipped_count}`);
```
### Import Settings
| Setting | Default | Description |
| ------------------------------------------ | ------- | -------------------------------------------- |
| `ignore_global_block_list` | `false` | Skip checking against your global block list |
| `ignore_unsubscribe_list` | `false` | Skip checking against unsubscribed leads |
| `ignore_duplicate_leads_in_other_campaign` | `false` | Allow leads already in other campaigns |
Keep all three settings as `false` unless you have a specific reason to override them. Block lists and unsubscribe lists exist to protect your sender reputation and ensure compliance with email regulations.
### Bulk Import (Large Lists)
For lists larger than 400 leads, batch your imports:
```python Python theme={null}
import time
all_leads = [...] # Your full lead list
batch_size = 400
for i in range(0, len(all_leads), batch_size):
batch = all_leads[i:i + batch_size]
response = requests.post(
f"{BASE_URL}/campaigns/{campaign_id}/leads",
params={"api_key": API_KEY},
json={
"lead_list": batch,
"settings": {
"ignore_global_block_list": False,
"ignore_unsubscribe_list": False,
"ignore_duplicate_leads_in_other_campaign": False
}
}
)
result = response.json()
print(f"Batch {i // batch_size + 1}: Added {result['added_count']}, Skipped {result['skipped_count']}")
# Small delay between batches
time.sleep(1)
```
## Custom Fields
Custom fields let you store any additional data on a lead and use it for personalization in your email sequences.
### Adding Custom Fields on Import
Include custom fields in the `custom_fields` object when importing leads:
```python Python theme={null}
lead = {
"email": "prospect@company.com",
"first_name": "Jordan",
"company_name": "TechCo",
"custom_fields": {
"job_title": "CTO",
"industry": "Healthcare",
"pain_point": "manual outreach processes",
"mutual_connection": "Sarah from YC",
"funding_round": "Series B"
}
}
```
### Using Custom Fields in Sequences
Reference any custom field in your email templates using `{{field_name}}`:
```
Hi {{first_name}},
I heard {{company_name}} just closed its {{funding_round}} — congrats!
Given your role as {{job_title}}, I imagine {{pain_point}} is top of mind.
{{mutual_connection}} suggested I reach out...
```
Use custom fields for personalization that goes beyond first name and company. Mentioning a recent funding round, a shared connection, or a specific pain point dramatically increases reply rates.
## Lead Statuses
Every lead in a campaign has a status that reflects where they are in the outreach lifecycle:
| Status | Description |
| ---------------- | ----------------------------------- |
| `NOT_CONTACTED` | Lead imported but no email sent yet |
| `IN_PROGRESS` | Currently receiving sequence emails |
| `COMPLETED` | All sequence steps have been sent |
| `INTERESTED` | Lead replied with positive intent |
| `NOT_INTERESTED` | Lead replied with negative intent |
| `DO_NOT_CONTACT` | Lead requested removal |
| `BOUNCED` | Email address bounced |
| `UNSUBSCRIBED` | Lead clicked unsubscribe link |
### Fetching Leads by Status
```python Python theme={null}
# Get all leads in a campaign with a specific status
response = requests.get(
f"{BASE_URL}/campaigns/{campaign_id}/leads",
params={
"api_key": API_KEY,
"status": "INTERESTED"
}
)
interested_leads = response.json()
for lead in interested_leads.get("leads", []):
print(f"{lead['first_name']} {lead['last_name']} ({lead['email']})")
```
### Updating Lead Status
```python Python theme={null}
lead_id = 67890
response = requests.patch(
f"{BASE_URL}/campaigns/{campaign_id}/leads/{lead_id}/status",
params={"api_key": API_KEY},
json={"status": "INTERESTED"}
)
print("Lead status updated!")
```
## Managing Leads Across Campaigns
### Getting Lead Activity
Track what emails a lead has received and how they engaged:
```python Python theme={null}
response = requests.get(
f"{BASE_URL}/campaigns/{campaign_id}/leads/{lead_id}/activity",
params={"api_key": API_KEY}
)
activity = response.json()
for event in activity.get("events", []):
print(f"{event['type']} — {event['timestamp']}")
```
### Block List Management
Add leads to your global block list to prevent contacting them across all campaigns:
```python Python theme={null}
# Add to global block list
response = requests.post(
f"{BASE_URL}/leads/block-list",
params={"api_key": API_KEY},
json={
"emails": ["donotcontact@company.com", "optedout@example.com"]
}
)
print("Leads added to block list")
```
Blocked leads are automatically skipped during import. This applies across all campaigns in your account, not just the campaign where the lead was blocked.
## Deduplication
SmartLead handles deduplication automatically during import:
1. **Within the same campaign** — Duplicate emails are always skipped
2. **Across campaigns** — Controlled by `ignore_duplicate_leads_in_other_campaign` setting
3. **Against block lists** — Leads on the global block list are skipped
4. **Against unsubscribes** — Previously unsubscribed leads are skipped
The import response tells you exactly what was skipped and why:
```json theme={null}
{
"added_count": 45,
"skipped_count": 5,
"skipped_leads": [
{
"email": "duplicate@company.com",
"reason": "Already exists in this campaign"
},
{
"email": "blocked@company.com",
"reason": "On global block list"
}
]
}
```
## Troubleshooting
Check the `skipped_leads` array in the response for reasons. Common causes: duplicate email in the same campaign, lead on the global block list, lead previously unsubscribed, or lead exists in another campaign (when `ignore_duplicate_leads_in_other_campaign` is false).
Ensure the custom field name in your email template matches the key name in the `custom_fields` object exactly (case-sensitive). Check that the lead was imported with that custom field populated.
Check that your batch size doesn't exceed 400 leads. Verify all required fields (`email` at minimum) are present. Ensure email addresses are valid format.
## What's Next?
Configure campaigns and sequences for your leads
Get real-time notifications when leads reply or bounce
# Rate Limits Guide
Source: https://api.smartlead.ai/guides/rate-limits
Understand SmartLead API rate limits, implement backoff strategies, and optimize your request patterns to avoid throttling
## Overview
SmartLead applies rate limits to protect the platform and ensure fair access for all users. This guide explains the rate limit structure, how to detect when you're being throttled, and strategies for building efficient integrations.
## Rate Limit Structure
SmartLead enforces rate limits on a per-API-key basis:
| Tier | Requests per Minute | Requests per Hour | Burst Limit |
| ---------- | ------------------- | ----------------- | ------------------ |
| Standard | 60 | 1,000 | 10 requests/second |
| Pro | 120 | 3,000 | 20 requests/second |
| Enterprise | Custom | Custom | Custom |
Rate limits apply to your API key across all endpoints combined. A mix of campaign, lead, and analytics requests all count toward the same limit.
## Detecting Rate Limits
When you exceed the limit, the API returns a `429 Too Many Requests` response:
```json theme={null}
{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Please retry after 30 seconds.",
"retry_after": 30
}
}
```
### Rate Limit Headers
Check response headers to monitor your usage:
| Header | Description |
| ----------------------- | --------------------------------------------- |
| `X-RateLimit-Limit` | Maximum requests allowed in the window |
| `X-RateLimit-Remaining` | Requests remaining in the current window |
| `X-RateLimit-Reset` | Unix timestamp when the window resets |
| `Retry-After` | Seconds to wait before retrying (only on 429) |
```python Python theme={null}
import requests
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
BASE_URL = "https://server.smartlead.ai/api/v1"
response = requests.get(
f"{BASE_URL}/campaigns/",
params={"api_key": API_KEY}
)
# Check rate limit status
limit = response.headers.get("X-RateLimit-Limit")
remaining = response.headers.get("X-RateLimit-Remaining")
reset = response.headers.get("X-RateLimit-Reset")
print(f"Limit: {limit} | Remaining: {remaining} | Resets at: {reset}")
```
## Backoff Strategies
### Exponential Backoff with Jitter
The recommended approach for handling rate limits:
```python Python theme={null}
import time
import random
def request_with_backoff(method, endpoint, payload=None, max_retries=5):
"""Make request with exponential backoff on rate limits."""
for attempt in range(max_retries + 1):
response = requests.request(
method,
f"{BASE_URL}/{endpoint}",
params={"api_key": API_KEY},
json=payload,
timeout=30
)
if response.status_code == 429:
if attempt == max_retries:
raise Exception("Rate limit exceeded after max retries")
# Use Retry-After header if available
retry_after = response.headers.get("Retry-After")
if retry_after:
delay = float(retry_after)
else:
# Exponential backoff: 1s, 2s, 4s, 8s, 16s
delay = (2 ** attempt) + random.uniform(0, 1)
print(f"Rate limited. Waiting {delay:.1f}s (attempt {attempt + 1})")
time.sleep(delay)
continue
response.raise_for_status()
return response.json()
```
### Proactive Rate Limiting
Instead of waiting for 429s, track your usage and throttle proactively:
```python Python theme={null}
import time
from collections import deque
class RateLimiter:
"""Client-side rate limiter to avoid 429 errors."""
def __init__(self, max_per_minute=50):
self.max_per_minute = max_per_minute
self.requests = deque()
def wait_if_needed(self):
"""Block until it's safe to make another request."""
now = time.time()
# Remove requests older than 60 seconds
while self.requests and self.requests[0] < now - 60:
self.requests.popleft()
if len(self.requests) >= self.max_per_minute:
# Wait until the oldest request expires
wait_time = 60 - (now - self.requests[0])
if wait_time > 0:
print(f"Throttling: waiting {wait_time:.1f}s")
time.sleep(wait_time)
self.requests.append(time.time())
# Usage
limiter = RateLimiter(max_per_minute=50) # Stay under the 60/min limit
for campaign_id in campaign_ids:
limiter.wait_if_needed()
data = make_request("GET", f"campaigns/{campaign_id}/analytics")
```
Set your client-side limit to 80% of the actual limit (e.g., 50 requests/minute when the limit is 60). This buffer accounts for timing differences and prevents edge-case throttling.
## Optimizing Request Patterns
### Batch Operations
Instead of making individual requests per lead, use batch endpoints:
```python Python theme={null}
# Bad: 100 individual requests
for lead in leads:
requests.post(f"{BASE_URL}/campaigns/{cid}/leads",
params={"api_key": API_KEY},
json={"lead_list": [lead]})
# Good: 1 batch request for up to 400 leads
requests.post(f"{BASE_URL}/campaigns/{cid}/leads",
params={"api_key": API_KEY},
json={"lead_list": leads[:400]})
```
### Cache Responses
Cache data that doesn't change often to reduce API calls:
```python Python theme={null}
import functools
import time
_cache = {}
def cached_request(endpoint, ttl_seconds=300):
"""Cache GET requests for a specified TTL."""
now = time.time()
if endpoint in _cache:
data, cached_at = _cache[endpoint]
if now - cached_at < ttl_seconds:
return data
data = make_request("GET", endpoint)
_cache[endpoint] = (data, now)
return data
# Campaigns list doesn't change often — cache for 5 minutes
campaigns = cached_request("campaigns/", ttl_seconds=300)
# Analytics change frequently — cache for 1 minute
analytics = cached_request(f"campaigns/{cid}/analytics", ttl_seconds=60)
```
### Use Webhooks Instead of Polling
Instead of polling for new replies every few seconds:
```python Python theme={null}
# Bad: Polling every 30 seconds (2 requests/minute per campaign)
while True:
response = requests.get(f"{BASE_URL}/campaigns/{cid}/leads",
params={"api_key": API_KEY, "status": "INTERESTED"})
time.sleep(30)
```
Set up a webhook to receive events in real time with zero API calls:
```python Python theme={null}
# Good: Register a webhook once, receive events instantly
requests.post(f"{BASE_URL}/webhooks",
params={"api_key": API_KEY},
json={
"webhook_url": "https://yourapp.com/hooks/smartlead",
"event_types": ["EMAIL_REPLIED"]
})
```
See the [Webhook Integration Guide](/guides/webhook-integration) for full details.
### Parallelize with Rate Awareness
When you need to make many requests, use controlled concurrency:
```python Python theme={null}
import concurrent.futures
import time
limiter = RateLimiter(max_per_minute=50)
def fetch_campaign_data(campaign_id):
limiter.wait_if_needed()
return make_request("GET", f"campaigns/{campaign_id}/analytics")
# Process campaigns with controlled parallelism
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = {
executor.submit(fetch_campaign_data, cid): cid
for cid in campaign_ids
}
for future in concurrent.futures.as_completed(futures):
cid = futures[future]
try:
data = future.result()
print(f"Campaign {cid}: {data.get('total_sent', 0)} sent")
except Exception as e:
print(f"Campaign {cid} failed: {e}")
```
## Troubleshooting
Check if another integration or script is using the same API key. Rate limits are per-key, not per-client. Consider using separate API keys for different integrations.
Review your request patterns — are you polling when you could use webhooks? Are you making individual requests when batch endpoints are available? If you genuinely need higher limits, contact SmartLead support about Enterprise plans.
Default to exponential backoff starting at 1 second. Most rate limit windows reset within 60 seconds.
## What's Next?
Handle all API errors gracefully
Build production-grade SmartLead integrations
# Webhook Integration Guide
Source: https://api.smartlead.ai/guides/webhook-integration
Set up real-time webhooks to sync SmartLead events with your CRM, database, or automation tools — including event types, payload formats, and best practices
## Overview
Webhooks let SmartLead push real-time event notifications to your server whenever something happens in a campaign — a lead replies, an email bounces, someone unsubscribes, or a message is sent. Instead of polling the API for updates, you receive instant HTTP POST requests to your endpoint.
This guide covers how to set up webhooks, handle events, verify payloads, and integrate with common tools like CRMs and Slack.
## Setting Up a Webhook
Register a webhook URL using the [Create Webhook](/api-reference/webhooks/create) endpoint:
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/webhook/create?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Campaign Notifications",
"webhook_url": "https://yourapp.com/webhooks/smartlead",
"association_type": "campaign",
"email_campaign_id": 123,
"event_type_map": {
"EMAIL_SENT": true,
"EMAIL_OPEN": true,
"EMAIL_REPLY": true,
"EMAIL_BOUNCE": true,
"LEAD_UNSUBSCRIBED": true,
"LEAD_CATEGORY_UPDATED": true
}
}'
```
```python Python theme={null}
import requests
import os
API_KEY = os.getenv("SMARTLEAD_API_KEY")
webhook_payload = {
"name": "Campaign Notifications",
"webhook_url": "https://yourapp.com/webhooks/smartlead",
"association_type": "campaign",
"email_campaign_id": 123,
"event_type_map": {
"EMAIL_SENT": True,
"EMAIL_OPEN": True,
"EMAIL_REPLY": True,
"EMAIL_BOUNCE": True,
"LEAD_UNSUBSCRIBED": True,
"LEAD_CATEGORY_UPDATED": True
}
}
response = requests.post(
"https://server.smartlead.ai/api/v1/webhook/create",
params={"api_key": API_KEY},
json=webhook_payload
)
webhook = response.json()
print(f"Webhook created: {webhook['id']}")
```
```javascript JavaScript theme={null}
const API_KEY = process.env.SMARTLEAD_API_KEY;
const response = await fetch(
`https://server.smartlead.ai/api/v1/webhook/create?api_key=${API_KEY}`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Campaign Notifications',
webhook_url: 'https://yourapp.com/webhooks/smartlead',
association_type: 'campaign',
email_campaign_id: 123,
event_type_map: {
EMAIL_SENT: true,
EMAIL_OPEN: true,
EMAIL_REPLY: true,
EMAIL_BOUNCE: true,
LEAD_UNSUBSCRIBED: true,
LEAD_CATEGORY_UPDATED: true
}
})
}
);
const webhook = await response.json();
console.log(`Webhook created: ${webhook.id}`);
```
## Webhook Levels
SmartLead supports three webhook scopes, set via the `association_type` field:
| Level | `association_type` | Scope | Use Case |
| ------------ | ------------------ | ----------------------------------- | ------------------------- |
| **User** | `"user"` | All campaigns owned by the user | Centralized notifications |
| **Client** | `"client"` | All campaigns for a specific client | Agency/white-label setups |
| **Campaign** | `"campaign"` | A single campaign | Per-campaign tracking |
If a **User-level** webhook exists, it takes priority over Client and Campaign-level webhooks for the same event type. Keep this in mind when configuring webhooks at multiple levels.
## Event Types
| Event | Description | When It Fires |
| ------------------------- | ------------------------------ | ------------------------------- |
| `EMAIL_SENT` | Email was sent to a lead | Each sequence step send |
| `FIRST_EMAIL_SENT` | First email of a sequence sent | Only sequence step 1 |
| `EMAIL_OPEN` | Lead opened an email | First open detected |
| `EMAIL_LINK_CLICK` | Lead clicked a tracked link | Each unique link click |
| `EMAIL_REPLY` | Lead replied to an email | Each reply received |
| `EMAIL_BOUNCE` | Email bounced | Soft or hard bounce |
| `LEAD_UNSUBSCRIBED` | Lead clicked unsubscribe | Unsubscribe action |
| `LEAD_CATEGORY_UPDATED` | Lead's category changed | Manual or auto-categorization |
| `CAMPAIGN_STATUS_CHANGED` | Campaign status changed | Start, pause, complete, etc. |
| `UNTRACKED_REPLIES` | Untracked reply received | Reply from unknown sender |
| `MANUAL_STEP_REACHED` | Lead reached a manual step | Phone call, LinkedIn step, etc. |
Start with `EMAIL_REPLY`, `EMAIL_BOUNCE`, and `LEAD_UNSUBSCRIBED` — these are the events that typically require action in your CRM. Add others as needed.
## Webhook Payload Format
Every webhook sends a JSON POST request. The payload is a flat JSON object with an `event_type` field identifying the event. The remaining fields vary by event type.
### EMAIL\_SENT / FIRST\_EMAIL\_SENT
```json theme={null}
{
"event_type": "EMAIL_SENT",
"from_email": "sender@yourcompany.com",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_sent": "2025-01-15T09:00:00Z",
"campaign_name": "Q1 SaaS Outreach",
"campaign_id": 123,
"sequence_number": 1,
"custom_subject": "Quick question about Acme Corp",
"custom_email_message": "Email body...",
"message_id": "abc123def456"
}
```
### EMAIL\_REPLY
```json theme={null}
{
"event_type": "EMAIL_REPLY",
"from_email": "sender@yourcompany.com",
"subject": "Re: Quick question about Acme Corp",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_replied": "2025-01-15T11:00:00Z",
"reply_body": "Thanks for reaching out. Let's set up a call.",
"preview_text": "Thanks for reaching out. Let's set up a call.",
"campaign_name": "Q1 SaaS Outreach",
"campaign_id": 123,
"client_id": 456,
"sequence_number": 1
}
```
### EMAIL\_OPEN
```json theme={null}
{
"event_type": "EMAIL_OPEN",
"from_email": "sender@yourcompany.com",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_opened": "2025-01-15T10:30:00Z",
"campaign_name": "Q1 SaaS Outreach",
"campaign_id": 123,
"sequence_number": 1
}
```
### EMAIL\_LINK\_CLICK
```json theme={null}
{
"event_type": "EMAIL_LINK_CLICK",
"from_email": "sender@yourcompany.com",
"to_email": "lead@example.com",
"to_name": "John Doe",
"time_clicked": "2025-01-15T10:45:00Z",
"link_clicked": ["https://example.com/demo"],
"campaign_name": "Q1 SaaS Outreach",
"campaign_id": 123,
"sequence_number": 1
}
```
### LEAD\_UNSUBSCRIBED
```json theme={null}
{
"event_type": "LEAD_UNSUBSCRIBED",
"lead_email": "lead@example.com",
"lead_name": "John Doe",
"campaign_name": "Q1 SaaS Outreach",
"campaign_id": 123,
"unsubscribed_client_id_map": {}
}
```
### LEAD\_CATEGORY\_UPDATED
```json theme={null}
{
"event_type": "LEAD_CATEGORY_UPDATED",
"lead_id": 789,
"lead_email": "lead@example.com",
"lead_name": "John",
"lead_data": {
"email": "lead@example.com",
"first_name": "John",
"last_name": "Doe",
"company_name": "Acme Corp",
"custom_fields": {},
"category": {
"name": "Interested",
"sentiment_type": "positive"
}
},
"category": "Interested",
"lead_category_id": 5,
"campaign_name": "Q1 SaaS Outreach",
"campaign_id": 123,
"from": "sender@yourcompany.com",
"to": "lead@example.com",
"history": [
{"type": "SENT", "time": "2025-01-15T09:00:00Z", "email_body": "...", "subject": "Quick question"},
{"type": "REPLY", "time": "2025-01-15T11:00:00Z", "email_body": "Thanks for reaching out..."}
],
"lastReply": {
"type": "REPLY",
"time": "2025-01-15T11:00:00Z",
"email_body": "Thanks for reaching out..."
}
}
```
The `LEAD_CATEGORY_UPDATED` payload includes the full conversation `history` between the sending account and the lead, including all sent emails, replies, and threaded replies.
For complete payload details on all event types, see the [Webhook Events Reference](/api-reference/webhooks/events).
## Handling Webhooks
### Node.js / Express
```javascript theme={null}
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhooks/smartlead', (req, res) => {
const event = req.body;
// Acknowledge receipt immediately
res.status(200).json({ received: true });
// Process asynchronously
switch (event.event_type) {
case 'EMAIL_REPLY':
console.log(`Reply from ${event.to_email}: ${event.preview_text}`);
// Update CRM, notify sales team, etc.
break;
case 'EMAIL_BOUNCE':
console.log(`Bounce: ${event.to_email}`);
// Remove from mailing lists, flag in CRM
break;
case 'LEAD_UNSUBSCRIBED':
console.log(`Unsubscribed: ${event.lead_email}`);
// Update suppression list
break;
case 'LEAD_CATEGORY_UPDATED':
console.log(`${event.lead_email} categorized as ${event.category}`);
// Sync category to CRM
break;
default:
console.log(`Event: ${event.event_type}`);
}
});
app.listen(3000, () => console.log('Webhook server running on port 3000'));
```
### Python / Flask
```python theme={null}
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/webhooks/smartlead', methods=['POST'])
def handle_webhook():
event = request.json
if event['event_type'] == 'EMAIL_REPLY':
print(f"Reply from {event['to_email']}")
# Sync to CRM, create task, notify Slack
elif event['event_type'] == 'EMAIL_BOUNCE':
print(f"Bounce: {event.get('to_email')}")
# Flag in database, update lead quality score
elif event['event_type'] == 'LEAD_UNSUBSCRIBED':
print(f"Unsubscribed: {event['lead_email']}")
# Add to suppression list
elif event['event_type'] == 'LEAD_CATEGORY_UPDATED':
print(f"{event['lead_email']} -> {event['category']}")
# Sync category to CRM
return jsonify({'received': True}), 200
if __name__ == '__main__':
app.run(port=3000)
```
Always return a `200` status code quickly. If your endpoint times out or returns an error, SmartLead will retry the webhook. Return `2xx` for success, `4xx` for permanent failures (no retry), `5xx` for temporary failures (will retry).
## Webhook Headers
SmartLead includes the following headers with webhook deliveries:
| Header | Description |
| ----------------------- | ---------------------------------------------- |
| `Content-Type` | `application/json` |
| `X-Smartlead-Signature` | HMAC SHA256 signature for payload verification |
| `X-Request-Id` | Unique identifier for each webhook delivery |
| `X-Webhook-Level` | Webhook scope: `user`, `client`, or `campaign` |
### Verifying Webhook Signatures
Use the `X-Smartlead-Signature` header and your signing secret to validate that webhook payloads are authentically from SmartLead:
```python Python theme={null}
import hmac
import hashlib
def verify_webhook_signature(payload_body, signature_header, signing_secret):
"""Verify the webhook signature using HMAC SHA256."""
expected_signature = 'sha256=' + hmac.new(
signing_secret.encode('utf-8'),
payload_body,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected_signature, signature_header)
# In your Flask handler:
@app.route('/webhooks/smartlead', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-Smartlead-Signature', '')
request_id = request.headers.get('X-Request-Id', '')
if not verify_webhook_signature(request.data, signature, SIGNING_SECRET):
return jsonify({'error': 'Invalid signature'}), 401
# Process event...
return jsonify({'received': True}), 200
```
### Implementing Idempotency
Use the `X-Request-Id` header to prevent processing duplicate webhook deliveries:
```python Python theme={null}
processed_events = set() # Use Redis or a database in production
@app.route('/webhooks/smartlead', methods=['POST'])
def handle_webhook():
request_id = request.headers.get('X-Request-Id', '')
if request_id in processed_events:
return jsonify({'status': 'already_processed'}), 200
processed_events.add(request_id)
# Process event...
return jsonify({'received': True}), 200
```
## Category Filtering
For `LEAD_CATEGORY_UPDATED` events, you can filter which categories trigger the webhook using the `category_id_map`:
```python Python theme={null}
payload = {
"name": "Hot Lead Alerts",
"webhook_url": "https://yourapp.com/webhooks/hot-leads",
"association_type": "campaign",
"email_campaign_id": 123,
"event_type_map": {
"LEAD_CATEGORY_UPDATED": True
},
"category_id_map": {
"5": True, # Interested
"7": True # Meeting Booked
}
}
response = requests.post(
"https://server.smartlead.ai/api/v1/webhook/create",
params={"api_key": API_KEY},
json=payload
)
```
## CRM Integration Examples
### Syncing Replies to HubSpot
```python Python theme={null}
import requests
import os
HUBSPOT_API_KEY = os.getenv("HUBSPOT_API_KEY")
def sync_reply_to_hubspot(event):
"""Create a HubSpot engagement when a lead replies."""
contact_response = requests.get(
f"https://api.hubapi.com/contacts/v1/contact/email/{event['to_email']}/profile",
headers={"Authorization": f"Bearer {HUBSPOT_API_KEY}"}
)
if contact_response.status_code == 200:
contact_id = contact_response.json()["vid"]
requests.post(
"https://api.hubapi.com/engagements/v1/engagements",
headers={
"Authorization": f"Bearer {HUBSPOT_API_KEY}",
"Content-Type": "application/json"
},
json={
"engagement": {"type": "EMAIL"},
"associations": {"contactIds": [contact_id]},
"metadata": {
"subject": event.get("subject", ""),
"text": event.get("preview_text", "")
}
}
)
```
### Sending Slack Notifications
```python Python theme={null}
import requests
import os
SLACK_WEBHOOK_URL = os.getenv("SLACK_WEBHOOK_URL")
def notify_slack(event):
"""Send a Slack message when a lead replies."""
message = {
"text": (
f"*New reply from {event['to_name']}* ({event['to_email']})\n"
f"Campaign: {event['campaign_name']}\n"
f"Reply: _{event.get('preview_text', 'N/A')[:200]}_"
)
}
requests.post(SLACK_WEBHOOK_URL, json=message)
```
## Retry Logic
SmartLead retries failed webhook deliveries automatically:
| Attempt | Delay | Description |
| --------- | ---------- | --------------------------------- |
| 1st retry | 1 minute | First retry after initial failure |
| 2nd retry | 5 minutes | Second retry |
| 3rd retry | 30 minutes | Final retry |
After 3 failed attempts, the event is marked as failed. Use the [Retrigger Webhooks](/api-reference/campaigns/retrigger-webhooks) endpoint to manually retry failed deliveries, or view webhook statistics via the [Webhook Summary](/api-reference/campaigns/get-webhook-summary) endpoint.
**Response code behavior:**
* `2xx` — Success, no retry
* `4xx` — Permanent failure, no retry
* `5xx` — Temporary failure, SmartLead will retry
## Managing Webhooks
### Get Webhook Details
```python Python theme={null}
webhook_id = 456
response = requests.get(
f"https://server.smartlead.ai/api/v1/webhook/{webhook_id}",
params={"api_key": API_KEY}
)
webhook = response.json()
print(f"ID: {webhook['id']} | URL: {webhook['webhook_url']}")
```
### Update a Webhook
```python Python theme={null}
webhook_id = 456
response = requests.put(
f"https://server.smartlead.ai/api/v1/webhook/update/{webhook_id}",
params={"api_key": API_KEY},
json={
"event_type_map": {
"EMAIL_REPLY": True,
"EMAIL_BOUNCE": True,
"LEAD_CATEGORY_UPDATED": True
}
}
)
```
### Delete a Webhook
```python Python theme={null}
webhook_id = 456
response = requests.delete(
f"https://server.smartlead.ai/api/v1/webhook/delete/{webhook_id}",
params={"api_key": API_KEY}
)
```
## Troubleshooting
Verify your endpoint is publicly accessible (not localhost). Check that the webhook is active. Ensure your endpoint returns a `200` response within 30 seconds. Check server logs for incoming requests. Use a tool like [webhook.site](https://webhook.site) for testing.
SmartLead may retry if your server didn't respond with `200` in time. Implement idempotency by checking the `X-Request-Id` header — skip events you've already processed.
Not all event types include all fields. For example, `reply_body` and `preview_text` are only present on `EMAIL_REPLY` events. The `LEAD_UNSUBSCRIBED` event uses `lead_email` instead of `to_email`. Always check for field existence before accessing.
If a User-level webhook exists for the same event type, it takes priority over Client and Campaign-level webhooks. Check your webhook configuration at all levels.
## What's Next?
See all event types with complete payload structures
API reference for creating webhooks
Monitor webhook delivery statistics
Manually retry failed webhook deliveries
# Introduction
Source: https://api.smartlead.ai/introduction
SmartLead API documentation — automate cold email campaigns, manage leads, rotate email accounts, and track performance programmatically
## Welcome to SmartLead API
SmartLead is a powerful cold email outreach platform that helps you scale your email campaigns with advanced features like:
* **Multi-account rotation**: Send from multiple email accounts to maximize deliverability
* **Email warmup**: Automatically warm up new email accounts to build sender reputation
* **Unified inbox**: Manage all responses from one centralized location
* **Advanced analytics**: Track opens, clicks, replies, and more
* **Webhook integrations**: Connect to your CRM and other tools
* **Lead management**: Organize and categorize your prospects
## Getting Started
Get your API key and make your first request in minutes
Explore our comprehensive API documentation
Learn how to authenticate your API requests
Set up real-time notifications for campaign events
## Core Features
### Campaign Management
Create and manage email campaigns with multiple sequences, A/B testing, and advanced scheduling options.
### Email Account Rotation
Add multiple email accounts (SMTP, Gmail, Outlook) and let SmartLead rotate them automatically to maximize deliverability.
### Intelligent Warmup
Our AI-powered warmup system gradually increases your sending volume while maintaining high deliverability rates.
### Unified Inbox
Manage all replies from all campaigns in one place, with AI-powered categorization and response suggestions.
## API Versions
We offer two API versions:
* **V1 API** (Recommended): `/api/v1/...` - Latest version with all features
* **Legacy API**: `/api/...` - Maintained for backward compatibility
We recommend using V1 API for all new integrations. The V1 API offers better performance, more features, and improved response formats.
## Base URL
All API requests should be made to:
```
https://server.smartlead.ai/api
```
For V1 endpoints:
```
https://server.smartlead.ai/api/v1
```
## Authentication
SmartLead API uses API keys for authentication. You can generate your API key from your dashboard settings.
```bash theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/campaigns/?api_key=YOUR_API_KEY"
```
## Rate Limits
Rate limits vary by subscription plan. Please contact customer support.
If you exceed your rate limit, you'll receive a 429 status code. Implement exponential backoff to handle rate limits gracefully.
## Support
Need help? We're here for you:
* **Email**: [support@smartlead.ai](mailto:support@smartlead.ai)
## What's Next?
Learn how to set up your first email campaign
Add and configure your sending email accounts
# Quickstart
Source: https://api.smartlead.ai/quickstart
Start sending cold emails in under 5 minutes
## Get Your API Key
If you haven't already, create an account at [app.smartlead.ai](https://app.smartlead.ai/signup)
Go to your dashboard and click on Settings → API
Click "Generate New API Key" and copy it securely
Keep your API key secure! Never commit it to version control or expose it in client-side code.
## Make Your First Request
Let's fetch all your campaigns:
```bash cURL theme={null}
curl -X GET "https://server.smartlead.ai/api/v1/campaigns/?api_key=YOUR_API_KEY"
```
```python Python theme={null}
import requests
api_key = "YOUR_API_KEY"
url = "https://server.smartlead.ai/api/v1/campaigns/"
response = requests.get(url, params={"api_key": api_key})
campaigns = response.json()
print(f"Total campaigns: {len(campaigns.get('campaigns', []))}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://server.smartlead.ai/api/v1';
async function getCampaigns() {
const response = await fetch(
`${BASE_URL}/campaigns/?api_key=${API_KEY}`
);
const data = await response.json();
console.log(`Total campaigns: ${data.campaigns.length}`);
return data.campaigns;
}
getCampaigns();
```
```php PHP theme={null}
```
## Create Your First Campaign
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/campaigns/new?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "My First Campaign",
"track_settings": {
"track_open": true,
"track_click": true
}
}'
```
```python Python theme={null}
import requests
api_key = "YOUR_API_KEY"
url = "https://server.smartlead.ai/api/v1/campaigns/new"
payload = {
"name": "My First Campaign",
"track_settings": {
"track_open": True,
"track_click": True
}
}
response = requests.post(
url,
params={"api_key": api_key},
json=payload
)
campaign = response.json()
print(f"Campaign created with ID: {campaign['campaign']['id']}")
```
```javascript JavaScript theme={null}
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = 'https://server.smartlead.ai/api/v1';
async function createCampaign() {
const response = await fetch(
`${BASE_URL}/campaigns/new?api_key=${API_KEY}`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'My First Campaign',
track_settings: {
track_open: true,
track_click: true,
},
}),
}
);
const data = await response.json();
console.log(`Campaign created with ID: ${data.campaign.id}`);
return data.campaign;
}
createCampaign();
```
## Add Email Account
Before sending emails, you need to add at least one email account:
```bash cURL theme={null}
curl -X POST "https://server.smartlead.ai/api/v1/email-accounts/save?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from_name": "John Doe",
"from_email": "john@example.com",
"user_name": "john@example.com",
"password": "your_email_password",
"smtp_host": "smtp.example.com",
"smtp_port": 587,
"imap_host": "imap.example.com",
"imap_port": 993,
"max_email_per_day": 50,
"warmup_enabled": true,
"total_warmup_per_day": 20,
"daily_rampup": 2,
"reply_rate_percentage": 30
}'
```
```python Python theme={null}
import requests
api_key = "YOUR_API_KEY"
url = "https://server.smartlead.ai/api/v1/email-accounts/save"
payload = {
"from_name": "John Doe",
"from_email": "john@example.com",
"user_name": "john@example.com",
"password": "your_email_password",
"smtp_host": "smtp.example.com",
"smtp_port": 587,
"imap_host": "imap.example.com",
"imap_port": 993,
"max_email_per_day": 50,
"warmup_enabled": True,
"total_warmup_per_day": 20,
"daily_rampup": 2,
"reply_rate_percentage": 30
}
response = requests.post(
url,
params={"api_key": api_key},
json=payload
)
account = response.json()
print(f"Email account added with ID: {account['email_account']['id']}")
```
## Add Leads to Campaign
Now add some leads to your campaign:
```python Python theme={null}
import requests
api_key = "YOUR_API_KEY"
campaign_id = 123 # Replace with your campaign ID
url = f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/leads"
leads = [
{
"first_name": "Jane",
"last_name": "Doe",
"email": "jane.doe@example.com",
"company_name": "Acme Corp",
"custom_fields": {
"job_title": "CEO",
"industry": "Technology"
}
},
{
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@techco.com",
"company_name": "Tech Co",
"custom_fields": {
"job_title": "CTO"
}
}
]
response = requests.post(
url,
params={"api_key": api_key},
json={"lead_list": leads}
)
result = response.json()
print(f"Added {result['added_count']} leads successfully")
```
## Create Email Sequences
Add email sequences to your campaign:
```python Python theme={null}
import requests
api_key = "YOUR_API_KEY"
campaign_id = 123
url = f"https://server.smartlead.ai/api/v1/campaigns/{campaign_id}/sequences"
sequences = [
{
"seq_number": 1,
"subject": "Quick question about {{company_name}}",
"email_body": "Hi {{first_name}},\n\nI noticed {{company_name}} is...",
"seq_delay_details": {
"delay_in_days": 0
}
},
{
"seq_number": 2,
"subject": "Following up - {{company_name}}",
"email_body": "Hi {{first_name}},\n\nFollowing up on my previous email...",
"seq_delay_details": {
"delay_in_days": 3
}
}
]
response = requests.post(
url,
params={"api_key": api_key},
json={"sequences": sequences}
)
print("Sequences created successfully!")
```
## Start Your Campaign
Finally, start your campaign:
```bash theme={null}
curl -X PATCH "https://server.smartlead.ai/api/v1/campaigns/123/status?api_key=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "ACTIVE"}'
```
Congratulations! Your first campaign is now running. You can monitor its performance in the dashboard or via the analytics API.
## What's Next?
Receive real-time notifications when leads reply
Manage all your campaign replies in one place
Learn about A/B testing and conditional logic
Track your campaign performance in detail
## Need Help?
* Check out our [comprehensive guides](/guides/getting-started)
* Join our [Discord community](https://discord.gg/smartlead)
* Email us at [support@smartlead.ai](mailto:support@smartlead.ai)