Skip to main content
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": "EMAIL_SENT",
  "timestamp": "2024-11-25T09:00:00Z",
  "campaign_id": 123,
  "campaign_name": "Q1 Outreach",
  "lead_id": 789,
  "email_account_id": 456,
  "sequence_number": 1,
  "lead": {
    "email": "lead@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "company_name": "Acme Corp"
  }
}

EMAIL_OPENED

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": "EMAIL_OPENED",
  "timestamp": "2024-11-25T10:30:00Z",
  "campaign_id": 123,
  "lead_id": 789,
  "sequence_number": 1,
  "opened_count": 3,
  "first_opened_at": "2024-11-25T10:30:00Z",
  "last_opened_at": "2024-11-25T14:20:00Z",
  "lead": {
    "email": "lead@example.com",
    "first_name": "John"
  }
}

EMAIL_CLICKED

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": "EMAIL_CLICKED",
  "timestamp": "2024-11-25T10:45:00Z",
  "campaign_id": 123,
  "lead_id": 789,
  "sequence_number": 1,
  "link": {
    "url": "https://example.com/demo",
    "clicked_at": "2024-11-25T10:45:00Z"
  },
  "lead": {
    "email": "lead@example.com"
  }
}

EMAIL_REPLIED

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": "EMAIL_REPLIED",
  "timestamp": "2024-11-25T11:00:00Z",
  "campaign_id": 123,
  "campaign_name": "Q1 Outreach",
  "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-11-25T11:00:00Z",
    "message_id": "reply-abc123"
  },
  "lead": {
    "email": "lead@example.com",
    "first_name": "John",
    "last_name": "Doe",
    "company_name": "Acme Corp"
  }
}

EMAIL_BOUNCED

Triggered when an email bounces (delivery fails). When: When email server returns bounce notification
Use For: List cleaning, deliverability monitoring, account health
Payload Example:
{
  "event": "EMAIL_BOUNCED",
  "timestamp": "2024-11-25T09:05:00Z",
  "campaign_id": 123,
  "lead_id": 789,
  "email_account_id": 456,
  "sequence_number": 1,
  "bounce_type": "hard",
  "bounce_reason": "Mailbox does not exist",
  "lead": {
    "email": "invalid@example.com"
  }
}

EMAIL_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": "EMAIL_UNSUBSCRIBED",
  "timestamp": "2024-11-25T12:00:00Z",
  "campaign_id": 123,
  "lead_id": 789,
  "lead": {
    "email": "lead@example.com",
    "first_name": "John"
  }
}

Webhook Configuration

When creating a webhook, specify which events you want to receive:
Webhook Config Example
{
  "webhook_url": "https://your-server.com/webhook",
  "event_type_map": {
    "EMAIL_SENT": true,
    "EMAIL_OPENED": true,
    "EMAIL_CLICKED": true,
    "EMAIL_REPLIED": true,
    "EMAIL_BOUNCED": true,
    "EMAIL_UNSUBSCRIBED": false
  }
}

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']
    
    if event == 'EMAIL_REPLIED':
        # High priority - lead replied!
        send_slack_notification(
            f"🎉 New reply from {data['lead']['email']}"
        )
        update_crm(data['lead']['email'], status='Engaged')
        
    elif event == 'EMAIL_OPENED':
        # Medium priority - lead is interested
        increment_lead_score(data['lead_id'])
        
    elif event == 'EMAIL_BOUNCED':
        # Clean up - remove from lists
        remove_from_all_campaigns(data['lead']['email'])
    
    return {'status': 'received'}, 200

Example Handler (JavaScript/Express)

app.post('/webhook', express.json(), (req, res) => {
  const { event, lead, reply } = req.body;
  
  // Acknowledge receipt immediately
  res.status(200).json({ status: 'received' });
  
  // Process asynchronously
  switch(event) {
    case 'EMAIL_REPLIED':
      console.log(`Reply from ${lead.email}: ${reply.body}`);
      // Send to CRM, trigger workflows, etc.
      break;
      
    case 'EMAIL_OPENED':
      console.log(`${lead.email} opened email`);
      // Update lead score
      break;
  }
});

Best Practices

Return 200 Quickly: Process webhooks asynchronously to avoid timeouts
Implement Idempotency: Use event ID + timestamp to handle duplicate deliveries
Verify Webhook Source: Always validate webhooks come from SmartLead’s IPs