Webhook Event Reference
Detailed payload documentation and field descriptions for all 9 EmailSendX webhook event types.
email.delivered
email.deliveredtrigger: Email was successfully accepted by recipient's mail serverFired when an email is accepted and confirmed delivered by the recipient's mail server. This means the server acknowledged receipt — not necessarily that it was placed in the inbox.
Payload Fields
| Field | Type | Description |
|---|---|---|
| emailId | string | Unique identifier for this individual email send |
| campaignId | string | The campaign this email belongs to |
| campaignName | string | Human-readable campaign name |
| contactId | string | The recipient contact ID |
| contactEmail | string | The recipient email address |
| sentAt | string | ISO 8601 timestamp when the email was sent |
| deliveredAt | string | ISO 8601 timestamp when delivery was confirmed |
Example Payload
{
"event": "email.delivered",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-15T10:01:23Z",
"data": {
"emailId": "email_del_abc123",
"campaignId": "clx_camp_april_nl_id",
"campaignName": "April Newsletter",
"contactId": "clx1a2b3c4d5e6f7g8h9i0j",
"contactEmail": "john@example.com",
"sentAt": "2026-04-15T10:00:00Z",
"deliveredAt": "2026-04-15T10:01:23Z"
}
}email.opened
Open tracking relies on image loading
email.openedtrigger: Recipient opened the email (tracking pixel loaded)Fired when the tracking pixel in the email is loaded, indicating the recipient opened the email. Multiple opens by the same contact will fire this event each time.
Payload Fields
| Field | Type | Description |
|---|---|---|
| emailId | string | Unique identifier for this individual email send |
| campaignId | string | The campaign this email belongs to |
| contactId | string | The recipient contact ID |
| contactEmail | string | The recipient email address |
| openedAt | string | ISO 8601 timestamp of the open event |
| userAgent | string | User-Agent string from the request (email client / device info) |
| ip | string | IP address from which the open was recorded |
Example Payload
{
"event": "email.opened",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-15T10:45:00Z",
"data": {
"emailId": "email_del_abc123",
"campaignId": "clx_camp_april_nl_id",
"contactId": "clx1a2b3c4d5e6f7g8h9i0j",
"contactEmail": "john@example.com",
"openedAt": "2026-04-15T10:45:00Z",
"userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_4 like Mac OS X) AppleWebKit/605.1.15",
"ip": "203.0.113.42"
}
}email.clicked
email.clickedtrigger: Recipient clicked a tracked link in the emailFired when a recipient clicks a tracked link in the email. The redirect happens in under 50ms. Multiple clicks by the same contact on the same or different links all fire this event.
Payload Fields
| Field | Type | Description |
|---|---|---|
| emailId | string | Unique identifier for this individual email send |
| campaignId | string | The campaign this email belongs to |
| contactId | string | The recipient contact ID |
| contactEmail | string | The recipient email address |
| clickedAt | string | ISO 8601 timestamp of the click event |
| url | string | The original destination URL that was clicked (before redirect) |
| userAgent | string | User-Agent string from the click request |
| ip | string | IP address from which the click was recorded |
Example Payload
{
"event": "email.clicked",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-15T11:02:14Z",
"data": {
"emailId": "email_del_abc123",
"campaignId": "clx_camp_april_nl_id",
"contactId": "clx1a2b3c4d5e6f7g8h9i0j",
"contactEmail": "john@example.com",
"clickedAt": "2026-04-15T11:02:14Z",
"url": "https://acmecorp.com/blog/whats-new-april?utm_source=newsletter",
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"ip": "203.0.113.42"
}
}email.bounced
Hard bounces auto-suppress the contact
bounced and suppresses them from future sends. Soft bounces (temporary failures) do not suppress the contact and may resolve on their own.email.bouncedtrigger: Email was rejected or could not be delivered by recipient's mail serverFired when an email could not be delivered. Hard bounces indicate a permanent delivery failure (invalid address, domain doesn't exist). Soft bounces indicate a temporary issue (mailbox full, server temporarily unavailable).
Payload Fields
| Field | Type | Description |
|---|---|---|
| emailId | string | Unique identifier for this individual email send |
| campaignId | string | The campaign this email belongs to |
| contactId | string | The recipient contact ID |
| contactEmail | string | The recipient email address |
| bouncedAt | string | ISO 8601 timestamp of the bounce event |
| bounceType | enum | "hard" (permanent failure) or "soft" (temporary failure) |
| bounceMessage | string | SMTP bounce message from the receiving server |
Example Payload
{
"event": "email.bounced",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-15T10:02:00Z",
"data": {
"emailId": "email_del_xyz789",
"campaignId": "clx_camp_april_nl_id",
"contactId": "clx9z8y7x6w5v4u3t2s1r0q",
"contactEmail": "invalid@nonexistentdomain.com",
"bouncedAt": "2026-04-15T10:02:00Z",
"bounceType": "hard",
"bounceMessage": "550 5.1.1 The email account that you tried to reach does not exist"
}
}email.complained
Complaints hurt your sender reputation
email.complainedtrigger: Recipient marked the email as spam via their email clientFired when a recipient marks the email as spam via their email client. EmailSendX receives this via feedback loops from email providers. The contact is automatically suppressed.
Payload Fields
| Field | Type | Description |
|---|---|---|
| emailId | string | Unique identifier for this individual email send |
| campaignId | string | The campaign this email belongs to |
| contactId | string | The recipient contact ID |
| contactEmail | string | The recipient email address |
| complainedAt | string | ISO 8601 timestamp when the complaint was received |
Example Payload
{
"event": "email.complained",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-15T14:22:00Z",
"data": {
"emailId": "email_del_def456",
"campaignId": "clx_camp_april_nl_id",
"contactId": "clxabc999xyz111aaa222bbb",
"contactEmail": "frustrated@example.com",
"complainedAt": "2026-04-15T14:22:00Z"
}
}email.unsubscribed
email.unsubscribedtrigger: Recipient clicked the unsubscribe link or used one-click unsubscribeFired when a recipient unsubscribes from emails, either by clicking the unsubscribe link in the email footer or using the one-click unsubscribe feature in their email client. The contact's status is set to unsubscribed immediately.
Payload Fields
| Field | Type | Description |
|---|---|---|
| emailId | string | The email from which they unsubscribed |
| campaignId | string | The campaign this email belongs to |
| contactId | string | The unsubscribed contact ID |
| contactEmail | string | The unsubscribed email address |
| unsubscribedAt | string | ISO 8601 timestamp of the unsubscribe event |
| method | enum | "link" (clicked footer link) or "one-click" (RFC 8058 one-click unsubscribe from email client) |
Example Payload
{
"event": "email.unsubscribed",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-15T16:30:00Z",
"data": {
"emailId": "email_del_ghi321",
"campaignId": "clx_camp_april_nl_id",
"contactId": "clx5f6g7h8i9j0k1l2m3n4o",
"contactEmail": "unsubber@example.com",
"unsubscribedAt": "2026-04-15T16:30:00Z",
"method": "one-click"
}
}contact.created
contact.createdtrigger: A new contact was added to the workspaceFired when a new contact is added to the workspace, regardless of how they were added — via API, CSV import, signup form, or manually in the dashboard.
Payload Fields
| Field | Type | Description |
|---|---|---|
| contactId | string | The newly created contact ID |
| contactEmail | string | The new contact's email address |
| firstName | string | First name (if provided) |
| lastName | string | Last name (if provided) |
| source | enum | How the contact was added: "api", "import", "form", or "manual" |
| createdAt | string | ISO 8601 timestamp of contact creation |
Example Payload
{
"event": "contact.created",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-22T09:10:00Z",
"data": {
"contactId": "clxnew_abc123_def456",
"contactEmail": "newuser@company.com",
"firstName": "Morgan",
"lastName": "Lee",
"source": "api",
"createdAt": "2026-04-22T09:10:00Z"
}
}contact.updated
contact.updatedtrigger: A contact's status or properties were changedFired when a contact's status or properties are changed. The changes array lists exactly which fields changed, including the old and new values, making it easy to react only to specific changes.
Payload Fields
| Field | Type | Description |
|---|---|---|
| contactId | string | The updated contact ID |
| contactEmail | string | The contact's email address |
| changes | array | Array of changed fields with oldValue and newValue |
| changes[].field | string | The field name that changed (e.g. status, firstName, metadata.plan) |
| changes[].oldValue | any | The previous value of the field |
| changes[].newValue | any | The new value of the field |
| updatedAt | string | ISO 8601 timestamp of the update |
Example Payload
{
"event": "contact.updated",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-22T11:20:00Z",
"data": {
"contactId": "clx1a2b3c4d5e6f7g8h9i0j",
"contactEmail": "john@example.com",
"changes": [
{
"field": "status",
"oldValue": "active",
"newValue": "unsubscribed"
},
{
"field": "metadata.plan",
"oldValue": "starter",
"newValue": "pro"
}
],
"updatedAt": "2026-04-22T11:20:00Z"
}
}campaign.sent
campaign.senttrigger: A campaign finished sending to all recipientsFired when a campaign finishes sending to all recipients. This is a single event per campaign send, not per recipient. Use it to trigger post-send workflows like sending a Slack notification or updating your dashboard.
Payload Fields
| Field | Type | Description |
|---|---|---|
| campaignId | string | The campaign ID |
| campaignName | string | The campaign name |
| subject | string | The campaign subject line |
| totalRecipients | integer | Total number of contacts the campaign was sent to |
| sentAt | string | ISO 8601 timestamp when the campaign finished sending |
| estimatedDeliveryRate | number | Estimated percentage of emails that will be delivered (based on initial delivery confirmations) |
Example Payload
{
"event": "campaign.sent",
"workspaceId": "ws_acme_corp_id",
"timestamp": "2026-04-15T10:08:45Z",
"data": {
"campaignId": "clx_camp_april_nl_id",
"campaignName": "April Newsletter",
"subject": "What's new this April 🌱",
"totalRecipients": 5420,
"sentAt": "2026-04-15T10:08:45Z",
"estimatedDeliveryRate": 99.4
}
}Ready to handle webhook events?
Learn how to secure your endpoint and build a reliable webhook handler.