# 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 Offer

Special 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\n

Special 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)