smartlead-mcp-by-leadmagic
Version:
💜 The Premier Model Context Protocol Server for SmartLead's Cold Email Automation Platform - Complete API coverage with 116+ tools for campaign management, lead tracking, smart delivery, and analytics. Beautiful purple-gradient installer, zero-config set
1,193 lines • 46.8 kB
JavaScript
/**
* SmartLead MCP Server - API Client
*
* A robust HTTP client for the SmartLead API with comprehensive error handling,
* retry logic, rate limiting, and type safety. This client provides a clean
* interface to all SmartLead API endpoints with production-ready features.
*
* Features:
* - Exponential backoff retry logic
* - Rate limiting and request queuing
* - Comprehensive error handling and classification
* - Request/response logging and debugging
* - Type-safe parameter validation
* - Connection testing and health checks
*
* @author LeadMagic Team
* @version 1.0.0
*/
import axios from 'axios';
// ================================
// ERROR HANDLING CLASSES
// ================================
/**
* Custom error class for SmartLead API errors
* Provides detailed error information and classification
*/
export class SmartLeadError extends Error {
code;
status;
response;
isRetryable;
constructor(message, code = 'UNKNOWN_ERROR', status = 500, response, isRetryable = false) {
super(message);
this.name = 'SmartLeadError';
this.code = code;
this.status = status;
this.response = response;
this.isRetryable = isRetryable;
// Maintain proper stack trace for where our error was thrown
if (Error.captureStackTrace) {
Error.captureStackTrace(this, SmartLeadError);
}
}
/**
* Check if this is a client error (4xx status codes)
*/
isClientError() {
return this.status >= 400 && this.status < 500;
}
/**
* Check if this is a server error (5xx status codes)
*/
isServerError() {
return this.status >= 500 && this.status < 600;
}
/**
* Check if this is a network error
*/
isNetworkError() {
return this.code === 'NETWORK_ERROR' || this.code === 'TIMEOUT_ERROR';
}
/**
* Check if this error should trigger a retry
*/
shouldRetry() {
return this.isRetryable || this.isServerError() || this.isNetworkError();
}
}
// ================================
// SMARTLEAD API CLIENT
// ================================
/**
* SmartLead API Client
*
* Provides a comprehensive interface to the SmartLead API with robust error handling,
* retry logic, and type safety. All methods return properly typed responses and
* handle errors gracefully.
*/
export class SmartLeadClient {
apiClient;
config;
requestCount = 0;
rateLimitResetTime = 0;
/**
* Creates a new SmartLead API client
*
* @param config - Client configuration including API key and optional settings
* @throws {SmartLeadError} If configuration is invalid
*/
constructor(config) {
// Validate required configuration
if (!config.apiKey || typeof config.apiKey !== 'string' || config.apiKey.trim().length === 0) {
throw new SmartLeadError('Valid SmartLead API key is required', 'INVALID_CONFIG', 400);
}
// Set default configuration values
this.config = {
apiKey: config.apiKey.trim(),
baseUrl: config.baseUrl || 'https://server.smartlead.ai/api/v1',
timeout: config.timeout || 30000,
maxRetries: config.maxRetries || 3,
retryDelay: config.retryDelay || 1000,
rateLimit: config.rateLimit || 100, // 100 requests per minute default
};
// Initialize Axios client with configuration
this.apiClient = axios.create({
baseURL: this.config.baseUrl,
timeout: this.config.timeout,
headers: {
'Content-Type': 'application/json',
'User-Agent': 'SmartLead-MCP-Server/1.0.0',
},
params: {
api_key: this.config.apiKey,
},
});
// Set up request and response interceptors
this.setupInterceptors();
}
/**
* Rate limiting: Check if we can make a request now
* @private
*/
async checkRateLimit() {
const now = Date.now();
// Reset counter if a minute has passed
if (now > this.rateLimitResetTime) {
this.requestCount = 0;
this.rateLimitResetTime = now + 60000; // Next minute
}
// Check if we've exceeded the rate limit
if (this.requestCount >= this.config.rateLimit) {
const waitTime = this.rateLimitResetTime - now;
if (waitTime > 0) {
await new Promise((resolve) => setTimeout(resolve, waitTime));
this.requestCount = 0;
this.rateLimitResetTime = Date.now() + 60000;
}
}
this.requestCount++;
}
/**
* Parse rate limit info from response headers
* @private
*/
parseRateLimitHeaders(response) {
const remaining = response.headers['x-ratelimit-remaining'];
const reset = response.headers['x-ratelimit-reset'];
const limit = response.headers['x-ratelimit-limit'];
if (remaining !== undefined) {
const remainingRequests = parseInt(remaining, 10);
if (remainingRequests === 0 && reset) {
const resetTime = parseInt(reset, 10) * 1000; // Convert to milliseconds
this.rateLimitResetTime = resetTime;
}
}
if (limit !== undefined) {
const rateLimitFromHeader = parseInt(limit, 10);
if (rateLimitFromHeader > 0) {
// Update our rate limit based on server response
this.config.rateLimit = rateLimitFromHeader;
}
}
}
/**
* Sets up Axios interceptors for request/response handling
* @private
*/
setupInterceptors() {
// Request interceptor for rate limiting and logging
this.apiClient.interceptors.request.use(async (config) => {
// Apply rate limiting
await this.checkRateLimit();
// Log request in debug mode
if (process.env.DEBUG === 'true') {
console.log(`[SmartLead API] ${config.method?.toUpperCase()} ${config.url}`);
}
return config;
}, (error) => {
console.error('[SmartLead API] Request error:', error);
return Promise.reject(error);
});
// Response interceptor for rate limit parsing and error handling
this.apiClient.interceptors.response.use((response) => {
// Parse rate limit headers
this.parseRateLimitHeaders(response);
// Log response in debug mode
if (process.env.DEBUG === 'true') {
console.log(`[SmartLead API] Response ${response.status} from ${response.config.url}`);
}
return response;
}, (error) => {
// Parse rate limit headers from error response
if (error.response) {
this.parseRateLimitHeaders(error.response);
}
console.error('[SmartLead API] Response error:', error.message);
return Promise.reject(error);
});
}
/**
* Handles Axios errors and converts them to SmartLeadError instances
* @private
*/
handleAxiosError(error) {
if (error.response) {
// Server responded with error status
const status = error.response.status;
const data = error.response.data;
const message = data?.message || data?.error || error.message || 'API request failed';
// Determine if error is retryable
const isRetryable = status === 429 || status >= 500;
return new SmartLeadError(message, `HTTP_${status}`, status, data, isRetryable);
}
else if (error.request) {
// Request was made but no response received
return new SmartLeadError('Network error: No response received from server', 'NETWORK_ERROR', 0, undefined, true);
}
else if (error.code === 'ECONNABORTED') {
// Request timeout
return new SmartLeadError(`Request timeout after ${this.config.timeout}ms`, 'TIMEOUT_ERROR', 408, undefined, true);
}
else {
// Something else happened
return new SmartLeadError(error.message || 'Unknown error occurred', 'UNKNOWN_ERROR', 500, undefined, false);
}
}
/**
* Implements exponential backoff retry logic
* @private
*/
async delay(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Executes a request with retry logic
* @private
*/
async withRetry(operation, context, attempt = 1) {
try {
return await operation();
}
catch (error) {
if (error instanceof SmartLeadError &&
error.shouldRetry() &&
attempt < this.config.maxRetries) {
const delayMs = Math.min(this.config.retryDelay * 2 ** (attempt - 1), 10000 // Max 10 second delay
);
console.error(`[SmartLead API] ${context} failed (attempt ${attempt}/${this.config.maxRetries}). ` +
`Retrying in ${delayMs}ms. Error: ${error.message}`);
await this.delay(delayMs);
return this.withRetry(operation, context, attempt + 1);
}
throw error;
}
}
// ================================
// COMPREHENSIVE CAMPAIGN ANALYTICS
// ================================
/**
* Get campaigns with analytics - Combined endpoint for efficiency
* Fetches campaigns and their analytics in one call to reduce API usage
*
* @param options - Filtering and pagination options
* @returns Promise resolving to campaigns with analytics data
*/
async getCampaignsWithAnalytics(options = {}) {
try {
// First get campaigns with filtering
const campaigns = await this.listCampaigns(options);
if (!Array.isArray(campaigns) || campaigns.length === 0) {
return { campaigns: [], analytics: {} };
}
// Get analytics for each campaign
const analyticsPromises = campaigns.map(async (campaign) => {
try {
const startDate = options.start_date || '2024-01-01';
const endDate = options.end_date || new Date().toISOString().split('T')[0];
const analytics = await this.getCampaignAnalyticsByDate(campaign.id, startDate, endDate);
return { campaignId: campaign.id, analytics };
}
catch (error) {
console.warn(`Failed to get analytics for campaign ${campaign.id}:`, error);
return { campaignId: campaign.id, analytics: null };
}
});
const analyticsResults = await Promise.all(analyticsPromises);
const analyticsMap = analyticsResults.reduce((acc, result) => {
acc[result.campaignId] = result.analytics;
return acc;
}, {});
return {
campaigns: campaigns.map((campaign) => ({
...campaign,
analytics: analyticsMap[campaign.id],
})),
summary: {
total_campaigns: campaigns.length,
active_campaigns: campaigns.filter((c) => c.status === 'ACTIVE').length,
paused_campaigns: campaigns.filter((c) => c.status === 'PAUSED').length,
completed_campaigns: campaigns.filter((c) => c.status === 'COMPLETED').length,
},
};
}
catch (error) {
throw this.handleAxiosError(error);
}
}
// ================================
// CAMPAIGN MANAGEMENT METHODS (13+ endpoints)
// ================================
/**
* Create a new campaign
*/
async createCampaign(params) {
const response = await this.withRetry(() => this.apiClient.post('/campaigns/create', params), 'create campaign');
return response.data;
}
/**
* Update campaign schedule
*/
async updateCampaignSchedule(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/schedule`, params), 'update campaign schedule');
return response.data;
}
/**
* Update campaign settings
*/
async updateCampaignSettings(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/settings`, params), 'update campaign settings');
return response.data;
}
/**
* Update campaign status
*/
async updateCampaignStatus(campaignId, status) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/status`, { status }), 'update campaign status');
return response.data;
}
/**
* Get campaign details
*/
async getCampaign(campaignId) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}`), 'get campaign');
return response.data;
}
/**
* List campaigns
*/
async listCampaigns(params) {
const response = await this.withRetry(() => this.apiClient.get('/campaigns', { params }), 'list campaigns');
return response.data;
}
/**
* Save campaign sequence
*/
async saveCampaignSequence(campaignId, sequence) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/sequences`, { sequence }), 'save campaign sequence');
return response.data;
}
/**
* Get campaign sequence
*/
async getCampaignSequence(campaignId) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/sequences`), 'get campaign sequence');
return response.data;
}
// ================================
// LEAD MANAGEMENT METHODS
// ================================
/**
* List leads with filtering options
*/
async listLeads(params) {
const response = await this.withRetry(() => this.apiClient.get('/leads', { params }), 'list leads');
return response.data;
}
/**
* Get lead details by ID
*/
async getLead(leadId) {
const response = await this.withRetry(() => this.apiClient.get(`/leads/${leadId}`), 'get lead');
return response.data;
}
/**
* Add a lead to campaign
*/
async addLeadToCampaign(campaignId, leadData) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/leads`, leadData), 'add lead to campaign');
return response.data;
}
/**
* Update lead information
*/
async updateLead(leadId, leadData) {
const response = await this.withRetry(() => this.apiClient.put(`/leads/${leadId}`, leadData), 'update lead');
return response.data;
}
/**
* Update lead status
*/
async updateLeadStatus(leadId, status) {
const response = await this.withRetry(() => this.apiClient.patch(`/leads/${leadId}/status`, { status }), 'update lead status');
return response.data;
}
/**
* Bulk import leads to campaign
*/
async bulkImportLeads(campaignId, leads) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/leads/bulk`, { leads }), 'bulk import leads');
return response.data;
}
/**
* Delete a lead
*/
async deleteLead(leadId) {
const response = await this.withRetry(() => this.apiClient.delete(`/leads/${leadId}`), 'delete lead');
return response.data;
}
// ================================
// ANALYTICS AND STATISTICS METHODS
// ================================
/**
* Get campaign analytics by date range
*/
async getCampaignAnalyticsByDate(campaignId, startDate, endDate) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/analytics`, {
params: { start_date: startDate, end_date: endDate },
}), 'get campaign analytics by date');
return response.data;
}
/**
* Get campaign statistics
*/
async getCampaignStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/statistics`, { params }), 'get campaign statistics');
return response.data;
}
/**
* Get warmup stats by email
*/
async getWarmupStatsByEmail(emailAccountId) {
const response = await this.withRetry(() => this.apiClient.get(`/email-accounts/${emailAccountId}/warmup-stats`), 'get warmup stats by email');
return response.data;
}
/**
* Get campaign top level analytics
*/
async getCampaignTopLevelAnalytics(campaignId) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/analytics/top-level`), 'get campaign top level analytics');
return response.data;
}
/**
* Get campaign lead statistics
*/
async getCampaignLeadStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/lead-statistics`, { params }), 'get campaign lead statistics');
return response.data;
}
/**
* Get campaign mailbox statistics
*/
async getCampaignMailboxStatistics(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/mailbox-statistics`, { params }), 'get campaign mailbox statistics');
return response.data;
}
// ================================
// WEBHOOK MANAGEMENT METHODS
// ================================
/**
* Fetch webhooks by campaign
*/
async fetchWebhooksByCampaign(campaignId) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/webhooks`), 'fetch webhooks by campaign');
return response.data;
}
/**
* Upsert campaign webhook
*/
async upsertCampaignWebhook(campaignId, webhookData) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/webhooks`, webhookData), 'upsert campaign webhook');
return response.data;
}
/**
* Delete campaign webhook
*/
async deleteCampaignWebhook(campaignId, webhookId) {
const response = await this.withRetry(() => this.apiClient.delete(`/campaigns/${campaignId}/webhooks/${webhookId}`), 'delete campaign webhook');
return response.data;
}
/**
* Get webhook publish summary
*/
async getWebhookPublishSummary(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/webhooks/publish-summary`, { params }), 'get webhook publish summary');
return response.data;
}
/**
* Retrigger failed webhook events
*/
async retriggerFailedEvents(campaignId, fromTime, toTime) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/webhooks/retrigger`, { fromTime, toTime }), 'retrigger failed events');
return response.data;
}
// ================================
// SMART DELIVERY METHODS
// ================================
/**
* Get region wise providers
*/
async getRegionWiseProviders() {
const response = await this.withRetry(() => this.apiClient.get('/smart-delivery/providers'), 'get region wise providers');
return response.data;
}
/**
* Create manual placement test
*/
async createManualPlacementTest(testData) {
const response = await this.withRetry(() => this.apiClient.post('/smart-delivery/tests/manual', testData), 'create manual placement test');
return response.data;
}
/**
* Create automated placement test
*/
async createAutomatedPlacementTest(testData) {
const response = await this.withRetry(() => this.apiClient.post('/smart-delivery/tests/automated', testData), 'create automated placement test');
return response.data;
}
/**
* Get spam test details
*/
async getSpamTestDetails(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}`), 'get spam test details');
return response.data;
}
/**
* Delete smart delivery tests
*/
async deleteSmartDeliveryTests(spamTestIds) {
const response = await this.withRetry(() => this.apiClient.delete('/smart-delivery/tests', { data: { spamTestIds } }), 'delete smart delivery tests');
return response.data;
}
/**
* List all tests
*/
async listAllTests(testType, params) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${testType}`, { params }), 'list all tests');
return response.data;
}
/**
* Create folder
*/
async createFolder(name) {
const response = await this.withRetry(() => this.apiClient.post('/smart-delivery/folders', { name }), 'create folder');
return response.data;
}
/**
* Get folder by ID
*/
async getFolderById(folderId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/folders/${folderId}`), 'get folder by ID');
return response.data;
}
/**
* Delete folder
*/
async deleteFolder(folderId) {
const response = await this.withRetry(() => this.apiClient.delete(`/smart-delivery/folders/${folderId}`), 'delete folder');
return response.data;
}
/**
* Get all folders
*/
async getAllFolders(params) {
const response = await this.withRetry(() => this.apiClient.get('/smart-delivery/folders', { params }), 'get all folders');
return response.data;
}
/**
* Stop automated test
*/
async stopAutomatedTest(spamTestId) {
const response = await this.withRetry(() => this.apiClient.post(`/smart-delivery/tests/${spamTestId}/stop`), 'stop automated test');
return response.data;
}
/**
* Get provider wise report
*/
async getProviderWiseReport(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/reports/provider-wise`), 'get provider wise report');
return response.data;
}
/**
* Get group wise report
*/
async getGroupWiseReport(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/reports/group-wise`), 'get group wise report');
return response.data;
}
/**
* Get sender account wise report
*/
async getSenderAccountWiseReport(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/reports/sender-account-wise`), 'get sender account wise report');
return response.data;
}
/**
* Get spam filter details
*/
async getSpamFilterDetails(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/spam-filter-details`), 'get spam filter details');
return response.data;
}
/**
* Get DKIM details
*/
async getDkimDetails(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/dkim-details`), 'get DKIM details');
return response.data;
}
/**
* Get SPF details
*/
async getSpfDetails(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/spf-details`), 'get SPF details');
return response.data;
}
/**
* Get rDNS details
*/
async getRdnsDetails(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/rdns-details`), 'get rDNS details');
return response.data;
}
/**
* Get sender accounts for spam test
*/
async getSenderAccounts(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/sender-accounts`), 'get sender accounts');
return response.data;
}
/**
* Get blacklist information
*/
async getBlacklist(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/blacklist`), 'get blacklist');
return response.data;
}
/**
* Get email content
*/
async getEmailContent(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/email-content`), 'get email content');
return response.data;
}
/**
* Get IP analytics
*/
async getIpAnalytics(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/ip-analytics`), 'get IP analytics');
return response.data;
}
/**
* Get email headers
*/
async getEmailHeaders(spamTestId, replyId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/emails/${replyId}/headers`), 'get email headers');
return response.data;
}
/**
* Get schedule history
*/
async getScheduleHistory(spamTestId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/schedule-history`), 'get schedule history');
return response.data;
}
/**
* Get IP details
*/
async getIpDetails(spamTestId, replyId) {
const response = await this.withRetry(() => this.apiClient.get(`/smart-delivery/tests/${spamTestId}/emails/${replyId}/ip-details`), 'get IP details');
return response.data;
}
/**
* Get mailbox summary
*/
async getMailboxSummary(params) {
const response = await this.withRetry(() => this.apiClient.get('/smart-delivery/mailbox-summary', { params }), 'get mailbox summary');
return response.data;
}
/**
* Get mailbox count
*/
async getMailboxCount() {
const response = await this.withRetry(() => this.apiClient.get('/smart-delivery/mailbox-count'), 'get mailbox count');
return response.data;
}
// ================================
// LEAD MANAGEMENT METHODS (17+ endpoints)
// ================================
/**
* List leads by campaign ID
*/
async listLeadsByCampaign(campaignId, params) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/leads`, { params }), 'list leads by campaign');
return response.data;
}
/**
* Fetch lead categories
*/
async fetchLeadCategories() {
const response = await this.withRetry(() => this.apiClient.get('/leads/categories'), 'fetch lead categories');
return response.data;
}
/**
* Fetch lead by email address
*/
async fetchLeadByEmail(email) {
const response = await this.withRetry(() => this.apiClient.get(`/leads/email/${email}`), 'fetch lead by email');
return response.data;
}
/**
* Add leads to campaign
*/
async addLeadsToCampaign(campaignId, leads) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/leads`, { leads }), 'add leads to campaign');
return response.data;
}
/**
* Resume lead by campaign ID
*/
async resumeLeadByCampaign(campaignId, leadId) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/leads/${leadId}/resume`), 'resume lead by campaign');
return response.data;
}
/**
* Pause lead by campaign ID
*/
async pauseLeadByCampaign(campaignId, leadId) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/leads/${leadId}/pause`), 'pause lead by campaign');
return response.data;
}
/**
* Delete lead by campaign ID
*/
async deleteLeadByCampaign(campaignId, leadId) {
const response = await this.withRetry(() => this.apiClient.delete(`/campaigns/${campaignId}/leads/${leadId}`), 'delete lead by campaign');
return response.data;
}
/**
* Unsubscribe/Pause lead from campaign
*/
async unsubscribeLeadFromCampaign(campaignId, leadId) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/leads/${leadId}/unsubscribe`), 'unsubscribe lead from campaign');
return response.data;
}
/**
* Unsubscribe lead from all campaigns
*/
async unsubscribeLeadFromAllCampaigns(leadId) {
const response = await this.withRetry(() => this.apiClient.post(`/leads/${leadId}/unsubscribe-all`), 'unsubscribe lead from all campaigns');
return response.data;
}
/**
* Add lead/domain to global block list
*/
async addLeadToGlobalBlocklist(email) {
const response = await this.withRetry(() => this.apiClient.post('/leads/global-blocklist', { email }), 'add lead to global blocklist');
return response.data;
}
/**
* Fetch all leads from entire account
*/
async fetchAllLeadsFromAccount(params) {
const response = await this.withRetry(() => this.apiClient.get('/leads/global', { params }), 'fetch all leads from account');
return response.data;
}
/**
* Fetch leads from global block list
*/
async fetchLeadsFromGlobalBlocklist(params) {
const response = await this.withRetry(() => this.apiClient.get('/leads/global-blocklist', { params }), 'fetch leads from global blocklist');
return response.data;
}
/**
* Update lead using lead ID
*/
async updateLeadById(leadId, leadData) {
const response = await this.withRetry(() => this.apiClient.put(`/leads/${leadId}`, leadData), 'update lead by ID');
return response.data;
}
/**
* Update lead's category based on their campaign
*/
async updateLeadCategory(campaignId, leadId, category) {
const response = await this.withRetry(() => this.apiClient.put(`/campaigns/${campaignId}/leads/${leadId}/category`, { category }), 'update lead category');
return response.data;
}
/**
* Fetch lead message history based on campaign
*/
async fetchLeadMessageHistory(campaignId, leadId) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/leads/${leadId}/messages`), 'fetch lead message history');
return response.data;
}
/**
* Reply to lead from master inbox via API
*/
async replyToLeadFromMasterInbox(campaignId, leadId, replyData) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/leads/${leadId}/reply`, replyData), 'reply to lead from master inbox');
return response.data;
}
/**
* Forward a reply
*/
async forwardReply(campaignId, leadId, forwardData) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/leads/${leadId}/forward`, forwardData), 'forward reply');
return response.data;
}
// ================================
// EMAIL ACCOUNT MANAGEMENT METHODS (10+ endpoints)
// ================================
/**
* List all email accounts per campaign
*/
async listEmailAccountsPerCampaign(campaignId) {
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/email-accounts`), 'list email accounts per campaign');
return response.data;
}
/**
* Add email account to campaign
*/
async addEmailAccountToCampaign(campaignId, emailAccountId) {
const response = await this.withRetry(() => this.apiClient.post(`/campaigns/${campaignId}/email-accounts`, {
email_account_id: emailAccountId,
}), 'add email account to campaign');
return response.data;
}
/**
* Remove email account from campaign
*/
async removeEmailAccountFromCampaign(campaignId, emailAccountId) {
const response = await this.withRetry(() => this.apiClient.delete(`/campaigns/${campaignId}/email-accounts/${emailAccountId}`), 'remove email account from campaign');
return response.data;
}
/**
* Fetch all email accounts associated to a user
*/
async fetchAllEmailAccounts() {
const response = await this.withRetry(() => this.apiClient.get('/email-accounts'), 'fetch all email accounts');
return response.data;
}
/**
* Create an email account
*/
async createEmailAccount(emailAccountData) {
const response = await this.withRetry(() => this.apiClient.post('/email-accounts', emailAccountData), 'create email account');
return response.data;
}
/**
* Update email account
*/
async updateEmailAccount(emailAccountId, emailAccountData) {
const response = await this.withRetry(() => this.apiClient.put(`/email-accounts/${emailAccountId}`, emailAccountData), 'update email account');
return response.data;
}
/**
* Fetch email account by ID
*/
async fetchEmailAccountById(emailAccountId) {
const response = await this.withRetry(() => this.apiClient.get(`/email-accounts/${emailAccountId}`), 'fetch email account by ID');
return response.data;
}
/**
* Add/Update warmup to email account
*/
async addUpdateWarmupToEmailAccount(emailAccountId, warmupData) {
const response = await this.withRetry(() => this.apiClient.post(`/email-accounts/${emailAccountId}/warmup`, warmupData), 'add/update warmup to email account');
return response.data;
}
/**
* Reconnect failed email accounts
*/
async reconnectFailedEmailAccounts(emailAccountIds) {
const response = await this.withRetry(() => this.apiClient.post('/email-accounts/reconnect', { email_account_ids: emailAccountIds }), 'reconnect failed email accounts');
return response.data;
}
/**
* Update email account tag
*/
async updateEmailAccountTag(emailAccountId, tag) {
const response = await this.withRetry(() => this.apiClient.put(`/email-accounts/${emailAccountId}/tag`, { tag }), 'update email account tag');
return response.data;
}
// ================================
// CLIENT MANAGEMENT METHODS
// ================================
/**
* Add client
*/
async addClient(clientData) {
const response = await this.withRetry(() => this.apiClient.post('/clients', clientData), 'add client');
return response.data;
}
/**
* Fetch all clients
*/
async fetchAllClients() {
const response = await this.withRetry(() => this.apiClient.get('/clients'), 'fetch all clients');
return response.data;
}
/**
* Create new client API key
*/
async createNewClientApiKey(clientId, keyData) {
const response = await this.withRetry(() => this.apiClient.post(`/clients/${clientId}/api-keys`, keyData), 'create new client API key');
return response.data;
}
/**
* Get client's API keys
*/
async getClientsApiKeys(clientId) {
const response = await this.withRetry(() => this.apiClient.get(`/clients/${clientId}/api-keys`), 'get client API keys');
return response.data;
}
/**
* Delete client API key
*/
async deleteClientApiKey(clientId, keyId) {
const response = await this.withRetry(() => this.apiClient.delete(`/clients/${clientId}/api-keys/${keyId}`), 'delete client API key');
return response.data;
}
/**
* Reset client API key
*/
async resetClientApiKey(clientId, keyId) {
const response = await this.withRetry(() => this.apiClient.put(`/clients/${clientId}/api-keys/${keyId}/reset`), 'reset client API key');
return response.data;
}
// ================================
// SMART SENDERS METHODS
// ================================
/**
* Get vendors
*/
async getVendors() {
const response = await this.withRetry(() => this.apiClient.get('/smart-senders/vendors'), 'get vendors');
return response.data;
}
/**
* Search domain
*/
async searchDomain(domainName, vendorId) {
const response = await this.withRetry(() => this.apiClient.get('/smart-senders/search-domain', {
params: { domain_name: domainName, vendor_id: vendorId },
}), 'search domain');
return response.data;
}
/**
* Auto generate mailboxes
*/
async autoGenerateMailboxes(data) {
const response = await this.withRetry(() => this.apiClient.post('/smart-senders/auto-generate-mailboxes', data), 'auto generate mailboxes');
return response.data;
}
/**
* Place order for mailboxes
*/
async placeOrderMailboxes(data) {
const response = await this.withRetry(() => this.apiClient.post('/smart-senders/place-order', data), 'place order mailboxes');
return response.data;
}
/**
* Get domain list
*/
async getDomainList() {
const response = await this.withRetry(() => this.apiClient.get('/smart-senders/domains'), 'get domain list');
return response.data;
}
// ================================
// ADDITIONAL STATISTICS METHODS
// ================================
/**
* Download campaign data (supports CSV format)
*/
async downloadCampaignData(campaignId, downloadType, format = 'json', userId) {
const params = {
download_type: downloadType,
format,
};
if (userId)
params.user_id = userId;
const response = await this.withRetry(() => this.apiClient.get(`/campaigns/${campaignId}/download`, {
params,
responseType: format === 'csv' ? 'blob' : 'json',
}), 'download campaign data');
if (format === 'csv') {
// Return blob data for CSV downloads
return response.data;
}
return response.data;
}
/**
* View download statistics
*/
async viewDownloadStatistics(timePeriod, groupBy) {
const params = {};
if (timePeriod)
params.time_period = timePeriod;
if (groupBy)
params.group_by = groupBy;
const response = await this.withRetry(() => this.apiClient.get('/download-statistics', { params }), 'view download statistics');
return response.data;
}
// ================================
// GLOBAL ANALYTICS METHODS (20+ endpoints)
// ================================
/**
* Get campaign list for analytics
*/
async getAnalyticsCampaignList(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/campaign-list', { params }), 'get analytics campaign list');
return response.data;
}
/**
* Get client list for analytics
*/
async getAnalyticsClientList(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/client-list', { params }), 'get analytics client list');
return response.data;
}
/**
* Get month-wise client count
*/
async getAnalyticsClientMonthWiseCount(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/client-month-wise-count', { params }), 'get analytics client month-wise count');
return response.data;
}
/**
* Get overall stats v2
*/
async getAnalyticsOverallStatsV2(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/overall-stats-v2', { params }), 'get analytics overall stats v2');
return response.data;
}
/**
* Get day-wise overall stats
*/
async getAnalyticsDayWiseOverallStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/day-wise-overall-stats', { params }), 'get analytics day-wise overall stats');
return response.data;
}
/**
* Get day-wise positive reply stats
*/
async getAnalyticsDayWisePositiveReplyStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/day-wise-positive-reply-stats', { params }), 'get analytics day-wise positive reply stats');
return response.data;
}
/**
* Get campaign overall stats
*/
async getAnalyticsCampaignOverallStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/campaign-overall-stats', { params }), 'get analytics campaign overall stats');
return response.data;
}
/**
* Get client overall stats
*/
async getAnalyticsClientOverallStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/client-overall-stats', { params }), 'get analytics client overall stats');
return response.data;
}
/**
* Get email-id-wise health metrics
*/
async getAnalyticsMailboxNameWiseHealthMetrics(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/mailbox-name-wise-health-metrics', { params }), 'get analytics mailbox name-wise health metrics');
return response.data;
}
/**
* Get domain-wise health metrics
*/
async getAnalyticsMailboxDomainWiseHealthMetrics(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/mailbox-domain-wise-health-metrics', { params }), 'get analytics mailbox domain-wise health metrics');
return response.data;
}
/**
* Get provider-wise overall performance
*/
async getAnalyticsMailboxProviderWiseOverallPerformance(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/mailbox-provider-wise-overall-performance', { params }), 'get analytics mailbox provider-wise overall performance');
return response.data;
}
/**
* Get team board overall stats
*/
async getAnalyticsTeamBoardOverallStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/team-board-overall-stats', { params }), 'get analytics team board overall stats');
return response.data;
}
/**
* Get lead overall stats
*/
async getAnalyticsLeadOverallStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/lead-overall-stats', { params }), 'get analytics lead overall stats');
return response.data;
}
/**
* Get lead category-wise response
*/
async getAnalyticsLeadCategoryWiseResponse(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/lead-category-wise-response', { params }), 'get analytics lead category-wise response');
return response.data;
}
/**
* Get leads take for first reply
*/
async getAnalyticsCampaignLeadsTakeForFirstReply(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/campaign-leads-take-for-first-reply', { params }), 'get analytics campaign leads take for first reply');
return response.data;
}
/**
* Get follow-up reply rate
*/
async getAnalyticsCampaignFollowUpReplyRate(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/campaign-follow-up-reply-rate', { params }), 'get analytics campaign follow-up reply rate');
return response.data;
}
/**
* Get lead to reply time
*/
async getAnalyticsCampaignLeadToReplyTime(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/campaign-lead-to-reply-time', { params }), 'get analytics campaign lead to reply time');
return response.data;
}
/**
* Get campaign response stats
*/
async getAnalyticsCampaignResponseStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/campaign-response-stats', { params }), 'get analytics campaign response stats');
return response.data;
}
/**
* Get campaign status stats
*/
async getAnalyticsCampaignStatusStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/campaign-status-stats', { params }), 'get analytics campaign status stats');
return response.data;
}
/**
* Get mailbox overall stats
*/
async getAnalyticsMailboxOverallStats(params) {
const response = await this.withRetry(() => this.apiClient.get('/analytics/mailbox-overall-stats', { params }), 'get analytics mailbox overall stats');
return response.data;
}
// ================================
// UTILITY METHODS
// ================================
/**
* Test the API connection and validate credentials
*/
async testConnection() {
try {
// Try to list campaigns as a simple test
await this.listCampaigns({});
return {
success: true,
message: 'Successfully connected to SmartLead API',
};
}
catch (error) {
const smartLeadError = error instanceof SmartLeadError
? error
: new SmartLeadError('Connection test failed', 'CONNECTION_TEST_FAILED');
return {
success: false,
error: smartLeadError.message,
};
}
}
/**
* Get client configuration (excluding sensitive data)
*/
getConfig() {
return {
baseUrl: this.config.baseUrl,
timeout: this.config.timeout,
maxRetries: this.config.maxRetries,
retryDelay: this.config.retryDelay,
};
}
}
//# sourceMappingURL=client.js.map