Add Webhook
Creates a webhook that receives real-time POST callbacks for selected events.
Documentation Index
Fetch the complete documentation index at: https://developer.lemlist.com/llms.txt
Use this file to discover all available pages before exploring further.
Available event types
When creating a webhook, you can subscribe to specific events using thetype field. Events are organized by category below.
Lead state groups
These aggregate multiple activity types into a single lead-state change event.| Event | Description |
|---|---|
contacted | Lead was contacted (email sent, LinkedIn message, API call, etc.) |
hooked | Lead opened a message (email, LinkedIn, WhatsApp) |
attracted | Lead clicked a link or accepted a LinkedIn invite |
warmed | Lead replied (email, LinkedIn, WhatsApp, SMS) |
interested | Lead marked as interested |
notInterested | Lead marked as not interested |
Email activities
| Event | Description |
|---|---|
emailsSent | Email sent |
emailsOpened | Email opened |
emailsClicked | Link clicked in email |
emailsReplied | Email replied |
emailsBounced | Email bounced |
emailsFailed | Email failed to send |
emailsInterested | Lead marked as interested via email |
emailsNotInterested | Lead marked as not interested via email |
emailsUnsubscribed | Lead unsubscribed via email |
LinkedIn activities
| Event | Description |
|---|---|
linkedinSent | LinkedIn message sent |
linkedinOpened | LinkedIn message opened |
linkedinReplied | LinkedIn message replied |
linkedinInterested | Lead marked as interested via LinkedIn |
linkedinNotInterested | Lead marked as not interested via LinkedIn |
linkedinSendFailed | LinkedIn message failed to send |
linkedinVisitDone | LinkedIn profile visit completed |
linkedinVisitFailed | LinkedIn profile visit failed |
linkedinFollowDone | LinkedIn follow completed |
linkedinFollowFailed | LinkedIn follow failed |
linkedinFollowSkipped | LinkedIn follow skipped |
linkedinInviteDone | LinkedIn invite sent |
linkedinInviteFailed | LinkedIn invite failed |
linkedinInviteAccepted | LinkedIn invite accepted |
linkedinEndorseDone | LinkedIn endorsement completed |
linkedinEndorseFailed | LinkedIn endorsement failed |
linkedinEndorseSkipped | LinkedIn endorsement skipped |
linkedinVoiceNoteDone | LinkedIn voice note sent |
linkedinVoiceNoteFailed | LinkedIn voice note failed |
linkedinLikeLastPostDone | LinkedIn like last post completed |
linkedinLikeLastPostNoPost | LinkedIn like last post — no post found |
linkedinLikeLastPostFailed | LinkedIn like last post failed |
linkedinWithdrawInvitationDone | LinkedIn invite withdrawn |
linkedinWithdrawInvitationFailed | LinkedIn invite withdrawal failed |
WhatsApp activities
| Event | Description |
|---|---|
whatsappMessageSent | WhatsApp message sent |
whatsappMessageDelivered | WhatsApp message delivered |
whatsappMessageOpened | WhatsApp message opened |
whatsappReplied | WhatsApp message replied |
whatsappMessageFailed | WhatsApp message failed |
SMS activities
| Event | Description |
|---|---|
smsSent | SMS sent |
smsDelivered | SMS delivered |
smsReplied | SMS replied |
smsFailed | SMS failed |
Call activities
| Event | Description |
|---|---|
aircallCreated | Call created |
aircallEnded | Call ended |
aircallDone | Call task completed |
aircallInterested | Lead marked as interested via call |
aircallNotInterested | Lead marked as not interested via call |
callRecordingDone | Call recording ready |
callTranscriptDone | Call transcript ready |
API activities
| Event | Description |
|---|---|
apiDone | API step executed |
apiInterested | Lead marked as interested via API |
apiNotInterested | Lead marked as not interested via API |
apiFailed | API step failed |
Manual activities
| Event | Description |
|---|---|
manualInterested | Lead marked as interested manually |
manualNotInterested | Lead marked as not interested manually |
Task activities
| Event | Description |
|---|---|
annotated | Lead annotated |
Workspace activities
| Event | Description |
|---|---|
paused | Lead paused |
resumed | Lead resumed |
stopped | Lead stopped |
campaignComplete | Campaign completed |
customDomainErrors | Custom domain error detected |
connectionIssue | Email account connection issue |
sendLimitReached | Daily send limit reached |
lemwarmPaused | Lemwarm paused |
Enrichment
| Event | Description |
|---|---|
enrichmentDone | Enrichment completed |
enrichmentError | Enrichment failed |
Inbox activities
| Event | Description |
|---|---|
inboxLabelUpdated | Inbox conversation label changed |
Signal Agents
| Event | Description |
|---|---|
signalRegistered | New signal detected by a Signal Agent |
Deliverability hub
| Event | Description |
|---|---|
deliverabilityAlertTriggered | Deliverability alert triggered |
Deprecated events
These events have been removed from the API. Use the replacements below.| Removed event | Replacement |
|---|---|
skipped | No direct replacement |
emailsSendFailed | Use emailsFailed instead |
opportunitiesDone | Use annotated or task-level webhooks instead |
Verifying webhook authenticity
You can pass an optionalsecret in the request body when creating the webhook. It works like a shared password between lemlist and your endpoint:
- Stored encrypted at rest.
- Never returned by
GET /hooksor any other endpoint. - Immutable — it cannot be changed after creation. To rotate it, delete the webhook and create a new one.
- Sent back to your endpoint as a
secretfield in the JSON body of every webhook call, so you can verify the request originated from lemlist.
Webhook payload
Each event is delivered as aPOST to your targetUrl with a JSON body that mirrors the underlying activity record. Common fields:
| Field | Type | Description |
|---|---|---|
_id | string | Unique activity identifier (act_…) |
type | string | Event type (e.g. emailsSent, emailsReplied) |
teamId | string | Team the activity belongs to |
createdAt | ISO date | When the activity happened |
campaignId | string | Source campaign (absent for non-campaign events) |
campaignName | string | Campaign display name |
sequenceId | string | Sequence the task belonged to |
sequenceStep | number | 0-based step index in the sequence |
leadId | string | Lead targeted by the activity |
leadEmail, leadFirstName, leadLastName | string | Denormalized lead identity |
sendUserId, sendUserEmail, sendUserName | string | Sender (lemlist user) identity |
subject | string | Email subject (email events only) |
secret | string | Echoed back if a secret was set on the webhook |
Email recipients (to / cc / bcc)
Email events (emailsSent, emailsReplied, emailsBounced) carry the full recipient lists as arrays of {address, name}. Addresses are lowercased. Fields are omitted when empty.
to— primary recipient(s). For outbound sends, this is the lead. For inbound replies, this is the mailbox owner; multi-recipienttolines (e.g. reply-all where the lead manually added people) are preserved.cc— explicit CC recipients on the email.bcc— only present for outboundemailsSentevents when the sender has a hidden BCC configured in Settings → Integrations (users.lemlist.bcc). Inbound BCC is never visible because SMTP strips it for non-BCC’d recipients.
Third-party reply flag
When a reply on a thread comes from an address that does not match the original lead’s known contact emails, lemlist attributes the reply to the third-party sender rather than to the lead, and the event carries an extra flag:campaignId, leadId, and sequenceId (since the reply is no longer attached to the original campaign flow). Use the flag to route these events differently if needed.
Examples
zapId if you use Zapier to track the webhook mapping on your side.Authorizations
Basic authentication header of the form Basic <encoded-value>, where <encoded-value> is the base64-encoded string username:password.
Query Parameters
Webhook for specific campaign
Webhook for first activity only
Zapier ID
Body
The URL that will receive webhook POST requests.
Optional event type to subscribe to. When omitted, all events are sent. See the full categorized list in the endpoint documentation.
contacted, hooked, attracted, warmed, interested, notInterested, emailsSent, emailsOpened, emailsClicked, emailsReplied, emailsBounced, emailsFailed, emailsInterested, emailsNotInterested, emailsUnsubscribed, linkedinSent, linkedinOpened, linkedinReplied, linkedinInterested, linkedinNotInterested, linkedinSendFailed, linkedinVisitDone, linkedinVisitFailed, linkedinFollowDone, linkedinFollowFailed, linkedinFollowSkipped, linkedinInviteDone, linkedinInviteFailed, linkedinInviteAccepted, linkedinEndorseDone, linkedinEndorseFailed, linkedinEndorseSkipped, linkedinVoiceNoteDone, linkedinVoiceNoteFailed, linkedinLikeLastPostDone, linkedinLikeLastPostNoPost, linkedinLikeLastPostFailed, linkedinWithdrawInvitationDone, linkedinWithdrawInvitationFailed, whatsappMessageSent, whatsappMessageDelivered, whatsappMessageOpened, whatsappReplied, whatsappMessageFailed, smsSent, smsDelivered, smsReplied, smsFailed, aircallCreated, aircallEnded, aircallDone, aircallInterested, aircallNotInterested, apiDone, apiInterested, apiNotInterested, apiFailed, manualInterested, manualNotInterested, paused, resumed, stopped, campaignComplete, customDomainErrors, connectionIssue, sendLimitReached, lemwarmPaused, annotated, enrichmentDone, enrichmentError, callRecordingDone, callTranscriptDone, inboxLabelUpdated, signalRegistered, deliverabilityAlertTriggered Optional shared secret. Stored encrypted, never returned by GET, and immutable once set. Sent back to your endpoint as a secret field in the body of every webhook call so you can verify the request originated from lemlist.