This is a reference page, not an API endpoint. Use these event types when creating webhooks via the Create Webhook 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:
{
"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": "<html>Email body content...</html>",
"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:
{
"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:
{
"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:
{
"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": "<html>Thanks for reaching out. I'm interested...</html>",
"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:
{
"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:
{
"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": "<html>...</html>",
"subject": "Quick question"
},
{
"type": "REPLY",
"time": "2025-01-15T11:00:00Z",
"email_body": "<html>Thanks for reaching out...</html>"
}
],
"lastReply": {
"type": "REPLY",
"time": "2025-01-15T11:00:00Z",
"email_body": "<html>Thanks for reaching out...</html>"
}
}
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:
{
"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:
{
"event_type_map": {
"LEAD_CATEGORY_UPDATED": true
},
"category_id_map": {
"5": true,
"6": true
}
}
Handling Webhooks
Example Handler (Python/Flask)
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)
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.