Skip to main content

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 endpoint:

Webhook Levels

SmartLead supports three webhook scopes, set via the association_type field:
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

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

EMAIL_REPLY

EMAIL_OPEN

LEAD_UNSUBSCRIBED

LEAD_CATEGORY_UPDATED

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.

Handling Webhooks

Node.js / Express

Python / Flask

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:

Verifying Webhook Signatures

Use the X-Smartlead-Signature header and your signing secret to validate that webhook payloads are authentically from SmartLead:
Python

Implementing Idempotency

Use the X-Request-Id header to prevent processing duplicate webhook deliveries:
Python

Category Filtering

For LEAD_CATEGORY_UPDATED events, you can filter which categories trigger the webhook using the category_id_map:
Python

CRM Integration Examples

Syncing Replies to HubSpot

Python

Sending Slack Notifications

Python

Retry Logic

SmartLead retries failed webhook deliveries automatically: After 3 failed attempts, the event is marked as failed. Use the Retrigger Webhooks endpoint to manually retry failed deliveries, or view webhook statistics via the 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

Update a Webhook

Python

Delete a Webhook

Python

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 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?

Webhook Events Reference

See all event types with complete payload structures

Create Webhook API

API reference for creating webhooks

Webhook Summary

Monitor webhook delivery statistics

Retrigger Webhooks

Manually retry failed webhook deliveries