Docs/Webhooks/Event Reference

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 server

Fired 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

FieldTypeDescription
emailIdstringUnique identifier for this individual email send
campaignIdstringThe campaign this email belongs to
campaignNamestringHuman-readable campaign name
contactIdstringThe recipient contact ID
contactEmailstringThe recipient email address
sentAtstringISO 8601 timestamp when the email was sent
deliveredAtstringISO 8601 timestamp when delivery was confirmed

Example Payload

json
{
  "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

Open tracking works by embedding a 1×1 tracking pixel in the email. An open is recorded when the image loads. Email clients that block images by default (like some Outlook versions) will not trigger this event. Conversely, Apple Mail Privacy Protection (MPP) may pre-load images, causing false positives for Apple Mail users.
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

FieldTypeDescription
emailIdstringUnique identifier for this individual email send
campaignIdstringThe campaign this email belongs to
contactIdstringThe recipient contact ID
contactEmailstringThe recipient email address
openedAtstringISO 8601 timestamp of the open event
userAgentstringUser-Agent string from the request (email client / device info)
ipstringIP address from which the open was recorded

Example Payload

json
{
  "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 email

Fired 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

FieldTypeDescription
emailIdstringUnique identifier for this individual email send
campaignIdstringThe campaign this email belongs to
contactIdstringThe recipient contact ID
contactEmailstringThe recipient email address
clickedAtstringISO 8601 timestamp of the click event
urlstringThe original destination URL that was clicked (before redirect)
userAgentstringUser-Agent string from the click request
ipstringIP address from which the click was recorded

Example Payload

json
{
  "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

When a hard bounce occurs, EmailSendX automatically sets the contact's status to 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 server

Fired 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

FieldTypeDescription
emailIdstringUnique identifier for this individual email send
campaignIdstringThe campaign this email belongs to
contactIdstringThe recipient contact ID
contactEmailstringThe recipient email address
bouncedAtstringISO 8601 timestamp of the bounce event
bounceTypeenum"hard" (permanent failure) or "soft" (temporary failure)
bounceMessagestringSMTP bounce message from the receiving server

Example Payload

json
{
  "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

A complaint rate above 0.1% can significantly damage your sender reputation and deliverability. EmailSendX automatically suppresses the contact when a complaint is received. If you're seeing elevated complaint rates, review your list hygiene and sending frequency.
email.complainedtrigger: Recipient marked the email as spam via their email client

Fired 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

FieldTypeDescription
emailIdstringUnique identifier for this individual email send
campaignIdstringThe campaign this email belongs to
contactIdstringThe recipient contact ID
contactEmailstringThe recipient email address
complainedAtstringISO 8601 timestamp when the complaint was received

Example Payload

json
{
  "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 unsubscribe

Fired 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

FieldTypeDescription
emailIdstringThe email from which they unsubscribed
campaignIdstringThe campaign this email belongs to
contactIdstringThe unsubscribed contact ID
contactEmailstringThe unsubscribed email address
unsubscribedAtstringISO 8601 timestamp of the unsubscribe event
methodenum"link" (clicked footer link) or "one-click" (RFC 8058 one-click unsubscribe from email client)

Example Payload

json
{
  "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 workspace

Fired 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

FieldTypeDescription
contactIdstringThe newly created contact ID
contactEmailstringThe new contact's email address
firstNamestringFirst name (if provided)
lastNamestringLast name (if provided)
sourceenumHow the contact was added: "api", "import", "form", or "manual"
createdAtstringISO 8601 timestamp of contact creation

Example Payload

json
{
  "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 changed

Fired 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

FieldTypeDescription
contactIdstringThe updated contact ID
contactEmailstringThe contact's email address
changesarrayArray of changed fields with oldValue and newValue
changes[].fieldstringThe field name that changed (e.g. status, firstName, metadata.plan)
changes[].oldValueanyThe previous value of the field
changes[].newValueanyThe new value of the field
updatedAtstringISO 8601 timestamp of the update

Example Payload

json
{
  "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 recipients

Fired 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

FieldTypeDescription
campaignIdstringThe campaign ID
campaignNamestringThe campaign name
subjectstringThe campaign subject line
totalRecipientsintegerTotal number of contacts the campaign was sent to
sentAtstringISO 8601 timestamp when the campaign finished sending
estimatedDeliveryRatenumberEstimated percentage of emails that will be delivered (based on initial delivery confirmations)

Example Payload

json
{
  "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.