A system webhook sends data from Iterable to a third-party system whenever a specified event occurs (for example, an email send, an email open, etc.).
Each system webhook is specific to an Iterable project, but not to a particular template, campaign, or journey. The webhook sends whenever a specified system event occurs anywhere in the project.
NOTE
To call a webhook as part of a specific journey, use a journey webhook.
# In this article
- How system webhooks work
- System webhook endpoint requirements
- Creating a system webhook
- Editing a system webhook
- System webhook settings
- Customizing system webhooks with merge tags
- System webhook request headers
- System webhook request body
-
Example system webhook payloads
- Email Blast Send
- Email Bounce
- Email Click
- Email Complaint
- Email Open
- Email Send Skip
- Email Subscribe
- Email Triggered Send
- Email Unsubscribe
- Embedded Click
- Embedded Impression
- Embedded Received
- Embedded Session
- Hosted Unsubscribe Click
- In-App Click
- In-App Delete (consume)
- In-App Recall
- In-App Open
- In-App Send
- In-App Send Skip
- Journey Exit
- Push Bounce
- Push Open
- Push Send
- Push Send Skip
- Push Uninstall
- SMS Bounce
- SMS Click
- SMS Received
- SMS Send
- SMS Send Skip
- Web Push Click
- Web Push Send
- Web Push Send Skip
- WhatsApp Received
- WhatsApp Seen
- WhatsApp Send
- WhatsApp Click
- WhatsApp Bounce
- WhatsApp Send Skip
- Want to learn more?
# How system webhooks work
System webhooks send a POST request to your endpoint whenever a triggering
event occurs in your project. For example, if you set up a system webhook for
SMS Received, Iterable sends a webhook each time a user replies to an SMS.
The payload is sent in JSON format and includes event data and related metadata, such as the event timestamp, a user's unique identifier, and the campaign or journey context. Example payloads for each event type are available below.
# Delivery characteristics
- Delivery is not guaranteed. Iterable retries failed requests, but it may drop an event when retries are exhausted.
- Order is not guaranteed. Webhooks can be sent out of order because triggering events can occur asynchronously or in parallel.
-
Duplicate deliveries are possible. A later retry can arrive after an earlier
attempt succeeds. This can happen when a request is retried after a timeout.
- To handle duplicate deliveries, use the event timestamp to deduplicate events.
- To prevent duplicates, ensure your endpoint responds in 2 seconds or less.
IMPORTANT
System webhooks are not a definitive data export
Iterable doesn't guarantee successful delivery of every system webhook event.
If you need to set up a definitive data export, consider using dedicated data export tools instead (for example, Data Sync and Export APIs).
# Response times, retries, and timeouts
Iterable applies a 2-second timeout to webhook requests. If your endpoint takes longer than 2 seconds to respond, Iterable treats that attempt as failed and may retry (even if your endpoint later completes successfully).
Iterable retries failed webhook requests up to 3 times, with increasing delays over the next few minutes.
Each endpoint can receive up to 4 requests for the same event (one initial attempt and up to 3 retries). If all attempts fail, Iterable drops the event.
# HTTP response code handling
Iterable uses HTTP response status codes to decide whether to retry:
| HTTP status | Description |
|---|---|
2xx | Successful response. |
429, 502, 503, 504
| Failed response, Iterable retries the request (up to 3 retries total). |
All other 4xx and 5xx
| Failed response, Iterable does not retry the request. |
Iterable does not use Retry-After, or similar response headers, to decide
whether to retry a webhook request.
DNS resolution errors, connection errors, unsupported URL/service errors, and TLS/SSL failures are treated as non-retryable.
# Elevated error handling
In the scenario where an endpoint is experiencing high error rates, Iterable temporarily pauses delivery to that endpoint.
This happens when a circuit-breaker threshold is met:
- At least 500 errors within a 10-second window
- An error rate of 90% or higher in that same window
Iterable pauses webhook delivery for 60 seconds, then automatically resumes.
TIP
As a best practice, set up a monitoring system to alert you when your webhook endpoint is experiencing high error rates.
# System webhook endpoint requirements
To work with Iterable, your system webhook endpoint must:
- Use
HTTPS. The URL must begin withhttps://. - Use a TLS certificate signed by a certificate authority trusted by Iterable.
- Accept HTTP
POSTrequests with a JSON request body. - Return a
2xxstatus code for successful processing. - Respond within 2 seconds.
For retry behavior, HTTP status handling, and elevated error handling, see How system webhooks work.
# Creating a system webhook
Before creating a system webhook in Iterable, log in as a user with the Manage Integrations project permission, or as an org admin.
To create a new system webhook:
Go to Integrations > System Webhooks.
Click Create Webhook to bring up the system webhook creation form:
Enter the Webhook URL. The URL must begin with
https://.Click Create. Iterable takes you to the Edit System Webhook screen.
Configure the system webhook settings as needed.
Set the Status to Enabled to activate your new webhook.
Click Save Webhook.
# Editing a system webhook
When you change an existing system webhook, the changes take some time to propagate due to caching. For example, if you change the URL, Iterable may continue to send data to the old webhook URL for a short time after you update it.
To edit a system webhook:
Go to Integrations > System Webhooks.
Click the Edit button for the system webhook you want to change.
Update system webhook settings as needed.
Click Save Webhook.
# System webhook settings
When creating or editing a system webhook, you can configure the following settings:
- Endpoint URL (required)
- Status (Enabled or Disabled)
- Authentication (None, Basic, or OAuth2)
- Exclude list update events (if enabled)
- Custom HTTP headers (optional)
- Triggering events (one or more)
NOTE
There isn't a way to add custom fields to a system webhook, but you can use a journey webhook to build custom payloads.
# Endpoint URL
The endpoint URL is a URL that you provide as a location for Iterable send
data. Typically this is a third-party service, but can be any URL that can
receive a POST request.
You can edit this URL later, and you can add merge tags to customize it.
The URL must be able to accept a POST request, and must begin with https://.
# Status
By default, new system webhooks are set to Disabled.
To activate the system webhook, set Status to Enabled.
You can also disable the system webhook later by setting Status to Disabled.
# Authentication
When you create a system webhook, select one of the following authentication settings:
- None
- Basic
- OAuth 2.0
IMPORTANT
Security warnings about Authorization headers:
- Authorization headers are hidden after creation: Once you save the webhook, the token string is hidden. You cannot view it after saving the webhook. This is a security best practice to prevent sensitive information from being exposed.
- Authorization headers aren't encoded automatically: Iterable doesn't encode the token string for you. To provide an encoded token value in your header, encode the value before entering it in the webhook settings.
# None
Select this when no authentication is required. The webhook request will not
include an Authorization header.
This is the default setting, however, it's best practice to use some form of authentication to secure your webhook.
# Basic
When the webhook uses Basic authentication, Iterable adds an Authorization
header to the webhook request along with the exact value you enter in the
Authentication Token field.
When the system webhook is triggered, Iterable sends the following Authorization
header format:
"Authorization": "<YOUR_TOKEN>",
For example, if you need to use a Basic authentication token of abc123, you
would enter it in the Authentication Token field like this: Basic abc123
Then, when the system webhook is triggered, Iterable sends the following Authorization
header:
"Authorization": "Basic abc123",
If you need the value to be encoded, you should encode it before entering it in the Authentication Token field in Iterable.
For example, you would first Base64-encode the token value, then enter it in the
Authentication Token field in Iterable along with the Basic prefix.
For a password of abc123, the encoded value would be YWJjMTIz. In Iterable,
you would enter it like this: Basic YWJjMTIz.
Then, when the system webhook is triggered, Iterable sends the following Authorization
header format:
"Authorization": "Basic YWJjMTIz",
# OAuth 2.0 (Bearer token)
System webhooks support OAuth 2.0 bearer token authentication with a static access token.
To configure this:
- Select OAuth 2.0 for Authentication.
- Enter the access token value in Authentication Token
- Enter only the token, without the
Bearerprefix. - If the value needs to be encoded, encode it before entering it in the
Authentication Token field. For example, if the token value is
abc123, you would enter it asYWJjMTIz.
- Enter only the token, without the
Iterable sends this header when the webhook is triggered:
"Authorization": "Bearer <YOUR_TOKEN>",
Use this option when your token strategy is compatible with a static token (for example, long-lived tokens or scheduled manual token rotation).
If your endpoint requires automatic OAuth token renewal, use a journey webhook, which supports OAuth 2.0 client credentials and token refresh.
Both system webhooks and journey webhooks are valid options. Choose the one that matches your use case and token lifecycle requirements.
# Excluding list update events
By default, actions like adding or removing users from a list (which update the
emailListIds or userIdListIds field in the user profile) create subscribe
(emailSubscribe) and unsubscribe (emailUnsubscribe)
events in the user's history, and trigger system webhooks.
This occurs when you:
- Upload a CSV file to create or add users to a list.
- Use certain API endpoints to subscribe or unsubscribe users from a list.
- Use a List Membership journey tile to change a user's list membership.
These events can trigger webhooks in large numbers in a short period of time, potentially causing rate limit issues. They may also be irrelevant to your use case as they do not indicate user engagement.
To trigger webhooks only for user-initiated events like subscribing and
unsubscribing from message channels and message types, enable
Exclude List Update Events. This setting prevents list update events from
triggering webhooks for subscribe (emailSubscribe) and unsubscribe
(emailUnsubscribe) events.
# Custom HTTP headers
You can add additional custom headers to the webhook request. This is useful for sending more information with the webhook endpoint.
Click on Add HTTP Header to add custom headers to the webhook request.
For each header, enter a Name and a Value.
# Security considerations for custom headers
IMPORTANT
Custom headers are less secure than Authorization headers. Use them with caution.
Custom headers are visible as plain text to any Iterable user with the Manage Integrations project permission.
Keep this in mind if you need to include sensitive information in a custom header.
To have Iterable securely handle tokens, consider using Authentication headers whenever possible.
# Example custom header for an API key
There are multiple ways to include API keys in a webhook request. Always check with the service you are sending the webhook to for the correct way to include an API key in the request headers.
Example: For a system that accepts Api-Key as the header name, you can add a
custom header like this:
- Enter
Api-Keyin the Name field. - Enter
<YOUR_API_KEY>(the actual value of your API key) in the Value field.
IMPORTANT
For security reasons, do not include API keys in the URL of your webhook. Instead, include them in the headers.
Iterable doesn't accept API keys in the URL of a webhook request.
# Triggering events
Select one or more events that trigger the webhook:
The following events can trigger a system webhook:
# Email webhooks
- Blast send
- Triggered send
- Click
- Open
- Subscribe - Universal event for all channels. Optional filter available - learn more.
- Unsubscribe - Universal event for all channels. Optional filter available - learn more.
- Hosted unsubscribe
- Bounce
- Complaint
- Send skip
# Embedded webhooks
- Click
- Impression
- Received
- Session
# In-App webhooks
- Click
- Close
- Delete
- Delivery
- Open
- Recall
- Send
- Send skip
For subscribe and unsubscribe events, use Email Subscribe and Unsubscribe webhooks. These events are universal to all channels.
# Journey webhooks
- Journey exit
Journey events are only tracked for journeys that are enabled to do so. To learn more about journey event tracking, see Monitoring Journey Engagement.
# Push webhooks
- Send
- Click
- Received
- Bounce
- Uninstall
- Send skip
For subscribe and unsubscribe events, use Email Subscribe and Unsubscribe webhooks. These events are universal to all channels.
# SMS webhooks
- Send
- Click
- Received
- Bounce
- Send skip
For subscribe and unsubscribe events, use Email Subscribe and Unsubscribe webhooks. These events are universal to all channels.
# Web push webhooks
- Send
- Click
- Send skip
For subscribe and unsubscribe events, use Email Subscribe and Unsubscribe webhooks. These events are universal to all channels.
# WhatsApp webhooks
- Send
- Received
- Bounce
- Seen
- Click
- Send skip
For subscribe and unsubscribe events, use Email Subscribe and Unsubscribe webhooks. These events are universal to all channels.
# Customizing system webhooks with merge tags
Merge tags are placeholders that are replaced with actual values when the webhook is triggered.
You can add merge tags to the webhook's URL to customize the data sent to
the webhook endpoint, as well as in the webhook's custom headers. Make sure to
use curly braces ({{ and }}) around the merge tags.
The following merge tags can be used in the webhook's URL:
campaignIdcampaignNametemplateIdtemplateNamechannelIdworkflowIdworkflowNameexperimentIdmessageTypeId
For example, you can enter merge tags in the webhook URL like this:
https://mywebhook.example.com/XXXXXX?src=iterable&cname={{campaignName}}&cid={{campaignId}}
If any of these parameters are not defined when the webhook is called, they will render as blank.
# System webhook request headers
A webhook sends a POST request with the following headers:
Content-Type: application/json-
Authorization: <authType> <authToken>(when configured)For example:
-
Selecting Basic for Authentication and providing an Authentication Token of
XXXXXXXXXXXXXXXXXXXXXXXXXXXyields the following header:Authorization: XXXXXXXXXXXXXXXXXXXXXXXXXXX -
Selecting OAuth2 for Authentication and providing an Authentication Token of
XXXXXXXXXXXXXXXXXXXXXXXXXXXwould yield the following header:Authorization: Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXX By selecting Authentication of None, the webhook request doesn't
include anAuthorizationheader.
-
# Example system webhook request headers
{
"user-agent": "AHC/2.1",
"content-length": "951",
"accept": "*/*",
"authorization": "Basic QWxhZGRpbjpPcGVuU2VzYW1l",
"content-type": "application/json",
"x-forwarded-for": "192.0.2.23",
"x-forwarded-host": "https://my-webhook.example.com",
"x-forwarded-proto": "https",
"accept-encoding": "gzip"
}
# System webhook request body
The body of a webhook request is provided in JSON. It often contain the following fields:
-
emailoruserId- The unique identifier for the user associated with the event. This field varies by project type and user data. For example, in hybrid projects, users may haveemailand/oruserIdfields set in their profile. If a user has both fields set on their profile, Iterable's webhook payload includes both fields. -
eventName- The name of the event for which a webhook has been triggered. -
dataFields- An object that contains fields related to the webhook's triggering event. The fields indataFieldsvary depending on the event, your webhook settings, and your project's configuration.
# Example system webhook payloads
The following examples reflect JSON payloads that Iterable sends to a webhook endpoint for various system events. These examples are intended to provide a general idea of the data that Iterable sends in a webhook payload.
IMPORTANT
These webhook payloads are examples, not exhaustive schemas.
Iterable reserves the right to add new fields to webhook payloads at any time without prior notice. The payloads in this article are not exhaustive, and may not be up to date. Do not rely on the payloads in this article as a source of truth for system webhook schemas.
To see all the fields that Iterable sends in a given webhook payload, you should test your webhook with real data. The payload for a webhook always varies greatly depending on the event that triggered it, the settings you have configured for the webhook and your project.
# Email Blast Send
{ "email": "user@example.com", "eventName": "emailSend", "dataFields": { "contentId": 331201, "email": "user@example.com", "createdAt": "2016-12-02 20:21:04 +00:00", "campaignId": 59667, "templateId": 93849, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailSubject": "My subject", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "My template name", "channelId": 3420, "messageTypeId": 3866, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "emailId": "c123456:t456789:user@example.com" } }
# Email Bounce
{ "email": "user@example.com", "eventName": "emailBounce", "dataFields": { "emailSubject": "My subject", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "My template name", "channelId": 2598, "messageTypeId": 2870, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "recipientState": "HardBounce", "templateId": 167484, "email": "user@example.com", "createdAt": "2017-05-15 23:59:47 +00:00", "campaignId": 114746, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailId": "c123456:t456789:user@example.com" } }
# Email Click
{ "email": "user@example.com", "eventName": "emailClick", "dataFields": { "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.98 Safari/537.36", "ip": "192.0.2.23", "templateId": 93849, "userAgentDevice": "Mac", "proxySource": null, "isBot": false, "url": "https://www.iterable.com", "hrefIndex": 1, "canonicalUrlId": "3145668988", "city": "San Francisco", "region": "CA", "country": "United States", "timeZone": "America/Los_Angeles", "locale": "en-US", "email": "user@example.com", "createdAt": "2016-12-02 20:31:39 +00:00", "campaignId": 59667, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailSubject": "My subject", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "My template name", "channelId": 3420, "messageTypeId": 3866, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "linkUrl": "https://www.iterable.com", "emailId": "c123456:t456789:user@example.com" } }
# Email Complaint
{ "email": "user@example.com", "eventName": "emailComplaint", "dataFields": { "recipientState": "Complaint", "templateId": 79190, "email": "user@example.com", "createdAt": "2016-12-09 18:52:19 +00:00", "campaignId": 49313, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailSubject": "My subject", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "test template", "channelId": 3420, "messageTypeId": 3866, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "emailId": "c123456:t456789:user@example.com" } }
# Email Open
NOTE
Location data is unavailable when Geoip lookup is disabled, and for email open events from Gmail.
Iterable does not include location data in the city, region, country, and timeZone
fields if the event's proxySource field is set to Gmail, because these
events have location data from Google image proxy, not the user's actual device
location.
{ "email": "user@example.com", "eventName": "emailOpen", "dataFields": { "userAgent": "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0 (via ggpht.com GoogleImageProxy)", "city": "San Francisco", "region": "CA", "proxySource": "Gmail", "ip": "192.0.2.23", "country": "United States", "timeZone": "America/Los_Angeles", "templateId": 79190, "userAgentDevice": "Gmail", "email": "user@example.com", "createdAt": "2016-12-02 18:51:45 +00:00", "campaignId": 49313, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailSubject": "My subject", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "My template name", "locale": "en-us", "contentId": 1234567890, "isBot": false, "channelId": 3420, "messageTypeId": 3866, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "emailId": "c123456:t456789:user@example.com" } }
# Email Send Skip
{ "email": "user@example.com", "eventName": "emailSendSkip", "dataFields": { "createdAt": "2019-08-07 18:56:10 +00:00", "reason": "FrequencyCapping", "campaignId": 721398, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "email": "user@example.com" } }
# Email Subscribe
These events are universal to all channels.
Optional filter available - learn more.
{ "email": "user@example.com", "eventName": "emailSubscribe", "dataFields": { "createdAt": "2020-03-20 23:12:00 +00:00", "signupSource": "UpdateSubscriptionsAPI", "emailListIds": [ // Note: This could be "userListIds" depending on project type 27449 ], "messageTypeIds": [], "channelIds": [], "email": "user@example.com", "profileUpdatedAt": "2020-03-20 23:11:58 +00:00" } }
# Email Triggered Send
{ "email": "user@example.com", "eventName": "emailSend", "dataFields": { "contentId": 274222, "email": "user@example.com", "createdAt": "2016-12-02 18:51:40 +00:00", "campaignId": 49313, "transactionalData": { "__comment": "transactionalData lists the fields contained in the dataFields property of the API call or event used to trigger the email, campaign, or journey. transactionalData must contain no more than 12k characters in total." }, "templateId": 79190, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailSubject": "My subject", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "My template name", "channelId": 3420, "messageTypeId": 3866, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "emailId": "c123456:t9876543:user@example.com" } }
# Email Unsubscribe
These events are universal to all channels.
Optional filter available - learn more.
{ "email": "user@example.com", "eventName": "emailUnSubscribe", "dataFields": { "campaignId": 1089024, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailId": "c123456:t456789:user@example.com", "workflowName": "My test journey", "messageTypeIds": [], "locale": null, "templateId": 1526112, "emailSubject": "Upcoming events!", "labels": [ "Example", "test-1", "test-2", "test-3" ], "unsubSource": "EmailLink", "createdAt": "2020-03-20 23:34:15 +00:00", "templateName": "My test template", "emailListIds": [], // Note: This could be "userListIds" depending on project type "messageTypeId": 31082, "experimentId": null, "channelIds": [ 27447 ], "campaignName": "My test campaign", "workflowId": 76786, "email": "user@example.com", "channelId": 27447 } }
# Embedded Click
An embeddedClick event indicates that a user clicked on an embedded message
and includes details about which link was clicked.
{ "email": "user@example.com", "eventName": "embeddedClick", "dataFields": { "campaignId": 9950575, "campaignName": "Some Embedded Campaign Name", "workflowId": null, "workflowName": null, "templateName": "Some Template Name", "locale": "en-US", "channelId": 84101, "messageTypeId": 104680, "experimentId": null, "labels": [], "embeddedBodyField": "test embedded message title", "deviceInfo": { "deviceId": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36", "platform": "Web", "appPackageName": "com.example.app" }, "embeddedButtonId": "", "embeddedTargetUrl": "null", "email": "user@example.com", "createdAt": "2025-03-05 00:49:55 +00:00", "templateId": 13137427, "messageId": "dXNlckBleGFtcGxlLmNvbS8xMjM0LzExMTEyMjIvMzMzNDQ0NTU1L2ZhbHNlCg==", "emailId": "c9950575:t16747897:user@example.com" } }
# Embedded Impression
An embeddedImpression event represents the number of times a given embedded
message was visible during the session, and the total amount of time the message
was visible (in seconds) across all those appearances.
{ "email": "user@example.com", "eventName": "embeddedImpression", "dataFields": { "campaignId": 9950575, "campaignName": "Some Embedded Campaign Name", "workflowId": null, "workflowName": null, "templateName": "Some Template Name", "locale": "en-US", "channelId": 11111, "messageTypeId": 104680, "experimentId": null, "labels": [], "embeddedBodyField": "test embedded message title", "deviceInfo": null, "embeddedImpressionDisplayCount": 1, "embeddedImpressionDisplayDuration": 12.675, "embeddedImpressionPlacementId": 434892, "embeddedSessionId": "fc159ed9-05f7-45f1-9eae-47b21847b7f5", "email": "user@example.com", "createdAt": "2025-03-05 00:48:41 +00:00", "templateId": 16747897, "messageId": "dXNlckBleGFtcGxlLmNvbS8xMjM0LzExMTEyMjIvMzMzNDQ0NTU1L2ZhbHNlCg==", "emailId": "c9950575:t16747897:user@example.com" } }
# Embedded Received
An embeddedReceived event indicates that a device has retrieved a message to
display for the user. (It does not mean that the message has been displayed.)
{ "email": "user@example.com", "eventName": "embeddedReceived", "dataFields": { "campaignId": 9950575, "campaignName": "Some Embedded Campaign Name", "workflowId": null, "workflowName": null, "templateName": "Some Template Name", "locale": "en-US", "channelId": 84101, "messageTypeId": 104680, "experimentId": null, "labels": [], "embeddedBodyField": "test embedded message title", "deviceInfo": { "deviceId": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36", "platform": "Web", "appPackageName": "com.example.app" }, "email": "user@example.com", "createdAt": "2025-03-05 00:48:59 +00:00", "templateId": 16747897, "messageId": "dXNlckBleGFtcGxlLmNvbS8xMjM0LzExMTEyMjIvMzMzNDQ0NTU1L2ZhbHNlCg==", "emailId": "c9950575:t16747897:user@example.com" } }
# Embedded Session
An embeddedSession event represents a session in which a user interacted with
a page on your app or website that contained an embedded message.
{ "email": "user@example.com", "eventName": "embeddedSession", "deviceInfo": { "deviceId": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36", "platform": "Web", "appPackageName": "com.example.app" }, "email": "user@example.com", "embeddedSessionEndTime": 1718652660218, "embeddedSessionStartTime": 1718652647592, "embeddedSessionId": "fc159ed9-05f7-45f1-9eae-47b21847b7f5", "createdAt": "2024-06-17 19:31:00 +00:00" }
# Hosted Unsubscribe Click
{ "email": "user@example.com", "userId": "1", "eventName": "hostedUnsubscribeClick", "dataFields": { "country": "United States", "city": "San Jose", "campaignId": 1074721, "ip": "192.0.2.23", "userAgentDevice": "Mac", "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailId": "c123456:t456789:user@example.com", "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36", "proxySource": null, "workflowName": "My journey", "locale": null, "templateId": 1506266, "emailSubject": "My email subject", "url": "my-custom-preference-center.example.com", "labels": [ "Example", "test-1", "test-2", "test-3" ], "createdAt": "2020-03-21 00:24:08 +00:00", "templateName": "My email template", "messageTypeId": 13406, "experimentId": null, "region": "CA", "campaignName": "My email campaign", "workflowId": 60102, "email": "user@example.com", "channelId": 12466 } }
# In-App Click
{ "email": "user@example.com", "eventName": "inAppClick", "dataFields": { "email": "user@example.com", "createdAt": "2018-03-27 00:44:40 +00:00", "campaignId": 269450 } }
# In-App Delete (consume)
{ "email": "user@example.com", "eventName": "inAppDelete", "dataFields": { "campaignId": 269450, "campaignName": "Example Campaign", "workflowId": null, "workflowName": null, "templateName": "Example Template", "locale": null, "channelId": 1234, "messageTypeId": 5678, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "inAppBody": "...", "messageContext": null, "deleteAction": "click-delete", "expiresAt": "2024-02-15 10:30:00 +00:00", "deviceInfo": null, "inboxSessionId": null, "email": "user@example.com", "createdAt": "2023-10-01 14:15:16 +00:00", "templateId": 12345678, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailId": "c123456:t456789:user@example.com" } }
# In-App Recall
{ "email": "user@example.com", "eventName": "inAppRecall", "dataFields": { "total": 1, "email": "user@example.com", "createdAt": "2023-11-15 17:15:15 +00:00", "campaignId": 269450 } }
total is the total number of messages recalled for the user, for the campaign
identified by campaignId.
# In-App Open
{ "email": "user@example.com", "eventName": "inAppOpen", "dataFields": { "email": "user@example.com", "createdAt": "2018-03-27 00:44:30 +00:00", "campaignId": 269450 } }
# In-App Send
{ "email": "user@example.com", "eventName": "inAppSend", "dataFields": { "messageContext": { "saveToInbox": false, "trigger": "immediate" }, "campaignId": 732678, "contentId": 18997, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "workflowName": null, "emailId": "c123456:t456789:user@example.com", "locale": null, "templateId": 1032729, "inAppBody": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML", "expiresAt": "2019-08-08 22:37:40 +00:00", "labels": [ "Example", "test-1", "test-2", "test-3" ], "createdAt": "2019-08-07 22:37:40 +00:00", "templateName": "My template name", "messageTypeId": 14381, "experimentId": null, "campaignName": "My campaign name", "workflowId": null, "channelId": 13353, "email": "user@example.com" } }
# In-App Send Skip
{ "email": "user@example.com", "eventName": "inAppSendSkip", "dataFields": { "createdAt": "2019-08-07 22:42:18 +00:00", "reason": "FrequencyCapping", "campaignId": 732678, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "email": "user@example.com" } }
# Journey Exit
For a full list of exitReason values for journey exits, see Defining How Users Exit Journeys.
{ "email": "user@example.com", "eventName": "journeyExit", "dataFields": { "orgId": 12345, "projectId": 67890, "workflowId": 123456, "entranceTime": "2025-12-16 02:03:48 +00:00", "exitTime": "2025-12-16 02:03:58 +00:00", "exitNodeId": 1234567, "exitReason": "Completed", "exitRuleId": "", "nodePath": "2345678,3456789,1123456,2234567,3345678,4456789,5567890,1212345,2212345,1234567", "nodeCount": 10, "email": "user@example.com", "createdAt": "2025-12-16 02:03:58 +00:00" } }
# Push Bounce
{ "email": "user@example.com", "eventName": "pushBounce", "dataFields": { "platformEndpoint": "<Platform endpoint>", "email": "user@example.com", "createdAt": "2016-12-10 01:00:38 +00:00", "campaignId": 74768, "templateId": 113554, "pushMessage": "Push message text", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "My template name", "channelId": 2203, "messageTypeId": 2439, "experimentId": null, "payload": { "path": "yourpath/subpath" }, "sound": "", "badge": null, "contentAvailable": false, "deeplink": null, "locale": null } }
# Push Open
{ "email": "user@example.com", "eventName": "pushOpen", "dataFields": { "appAlreadyRunning": false, "email": "user@example.com", "createdAt": "2016-12-08 01:25:22 +00:00", "campaignId": 74768, "templateId": 113554, "pushMessage": "Push message text", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "My template name", "channelId": 2203, "messageTypeId": 2439, "experimentId": null, "payload": { "path": "shop_home" }, "sound": null, "badge": null, "contentAvailable": false, "deeplink": null, "locale": null } }
# Push Send
{ "email": "user@example.com", "eventName": "pushSend", "dataFields": { "campaignId": 74758, "campaignName": "Campaign name", "workflowId": null, "workflowName": null, "templateName": "Template name", "channelId": 1744, "messageTypeId": 1759, "experimentId": null, "pushMessage": "Message body", "payload": { "field": "value" }, "sound": null, "badge": "3", "contentAvailable": false, "deeplink": null, "attachmentUrlAndroid": "https://example.com/images/android_image.png", "attachmentUrlIos": "https://example.com/images/ios_image.png", "platformEndpoint": "...", "email": "user@example.com", "createdAt": "2016-12-08 00:53:11 +00:00", "templateId": 113541, "contentId": 6724, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", } }
# Push Send Skip
{ "email": "user@example.com", "eventName": "pushSendSkip", "dataFields": { "createdAt": "2019-08-07 22:28:51 +00:00", "reason": "FrequencyCapping", "campaignId": 732667, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "email": "user@example.com" } }
# Push Uninstall
{ "email": "user@example.com", "eventName": "pushUninstall", "dataFields": { "isGhostPush": false, "platformEndpoint": "<Platform endpoint>", "email": "user@example.com", "createdAt": "2016-12-09 20:50:54 +00:00", "campaignId": 74768, "templateId": 113554, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "pushMessage": "Push message text", "campaignName": "My campaign name", "workflowId": null, "workflowName": null, "templateName": "My template name", "channelId": 2203, "messageTypeId": 2439, "experimentId": null, "payload": { "path": "your_folder/30" }, "sound": "", "badge": null, "contentAvailable": false, "deeplink": null, "locale": null } }
# SMS Bounce
{ "email": "user@example.com", "eventName": "smsBounce", "dataFields": { "campaignId": 3333333, "campaignName": "Campaign name", "workflowId": null, "workflowName": null, "templateName": "Template name", "locale": null, "channelId": 11111, "messageTypeId": 22222, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "smsMessage": "Template SMS message body text here with an unshortened link without UTM parameters https://www.example.com/ and Handlebars unprocessed for {{firstName}}", "fromPhoneNumberId": 2072, "imageUrl": null, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "messageStatus": "undelivered", "toPhoneNumber": "+14155550132", "errorCode": "30003", "email": "user@example.com", "createdAt": "2022-05-18 16:11:20 +00:00", "templateId": 5555555, "emailId": "c123456:t456789:user@example.com" } }
# SMS Click
Keep in mind that these fields are impacted by link shortening and UTM parameters:
clickedUrl- This is the URL that the shortlink redirects to, and reflects UTM parameters if they were added in the template settings.smsMessage- The text of the original SMS message body with the original URL without UTM parameters, and Handlebars expressions before processing.
The unique shortened URL, along with the final version of the message body sent
to an individual user, is available in the renderedSmsMessage property in the
SMS Send webhook.
{ "email": "user@example.com", "eventName": "smsClick", "dataFields": { "campaignId": 1234567, "campaignName": "My Campaign Name", "workflowId": null, "workflowName": null, "templateName": "My Template Name", "locale": "en-us", "channelId": 12345, "messageTypeId": 123456, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "smsMessage": "Template SMS message body text here with an unshortened link without UTM parameters https://www.example.com/ and Handlebars unprocessed for {{firstName}}", "fromPhoneNumberId": 5870, "imageUrl": null, "clickedUrl": "https://www.example.com/?parameter=value", "userAgent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Mobile Safari/537.36", "userAgentDevice": "Android", "isBot": false, "city": "San Francisco", "region": "CA", "country": "United States", "email": "user@example.com", "createdAt": "2024-11-08 18:27:14 +00:00", "templateId": 12345678, "messageId": "e98354206abb484da8a9a5abcde6523ef", "emailId": "c9515555:t12574400:user@example.com" } }
# SMS Received
{ "email": "user@example.com", "eventName": "smsReceived", "dataFields": { "fromPhoneNumber": "+14155550132", "toPhoneNumber": "+14155550133", "smsMessage": "Received SMS message body text here", "smsReceiveCount": 1, "mmsReceiveCount": 0, "espName": "Telnyx", "billingParty": "FirstParty", "espAccountId": "12345", "senderPhoneNumberType": "LongCode", "recipientCountryName": "United States", "recipientCountryCallingCode": "1", "email": "user@example.com", "createdAt": "2025-01-06 21:25:34 +00:00" } }
# SMS Send
Note that for SMS sends, there are multiple fields that contain the message content:
renderedSmsMessage- The final personalized version of the message that was sent to the user, with all merge tags and Handlebars replaced by their actual values, the opt-out instructions that were included (when applicable, based on your SMS Opt-Out settings), and any UTM parameters and/or shortlinks unique to themessageId.smsMessage- The message body of the template that was used to send the campaign. This text string includes raw merge tags, Handlebars expressions, and unparsed URLs (before adding UTM parameters and/or link shortening).
{ "email": "user@example.com", "eventName": "smsSend", "dataFields": { "campaignId": 4444444, "campaignName": "Campaign name", "workflowId": null, "workflowName": null, "templateName": "Template name", "locale": "en-gb", "channelId": 99999, "messageTypeId": 99999, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "smsMessage": "Template SMS message body text here with an unshortened link without UTM parameters https://www.example.com/ and Handlebars unprocessed for {{firstName}}", "fromPhoneNumberId": 1111, "imageUrl": null, "toPhoneNumber": "+14155550132", "fromSMSSenderId": 1111, "mmsSendCount": 0, "smsSendCount": 1, "isSMSEstimation": false, "espName": "Telnyx", "billingParty": "FirstParty", "espAccountId": "12345", "renderedSmsMessage": "Actual SMS message body text here with the shortlink sent to the user https://itbl.co/qqD~nNoDM and Handlebars processed for John", "timeZone": "America/Los_Angeles", "catalogLookupCount": 0, "catalogCollectionCount": 0, "productRecommendationCount": 0, "transactionalData": { "__comment": "transactionalData lists the fields contained in the dataFields property of the API call or event used to trigger the email, campaign, or journey. transactionalData must contain no more than 12k characters in total." }, "email": "user@example.com", "createdAt": "2022-05-17 23:07:53 +00:00", "templateId": 555555, "contentId": 444444, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailId": "c123456:t9876543:user@example.com" } }
# SMS Send Skip
{ "email": "user@example.com", "eventName": "smsSendSkip", "dataFields": { "createdAt": "2019-08-07 18:49:48 +00:00", "reason": "FrequencyCapping", "campaignId": 729390, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "email": "user@example.com" } }
# Web Push Click
{ "email": "user@example.com", "userId": "some-userId-value", "eventName": "webPushClick", "dataFields": { "campaignId": 12345678, "campaignName": "Web Push campaign name", "workflowId": null, "workflowName": null, "templateName": "Template name", "locale": null, "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "webPushMessage": "Web Push Title", "webPushBody": "Web Push message body", "webPushIcon": "https://www.example.com/icon.png", "webPushClickAction": "https://www.example.com", "email": "user@example.com", "createdAt": "2024-10-16 22:53:52 +00:00", "templateId": 12345678, "messageId": "79cd703b9999999d8bf3bab6f27e96d5f" } }
# Web Push Send
{ "email": "user@example.com", "userId": "some-userId-value", "eventName": "webPushSend", "dataFields": { "campaignId": 12345678, "campaignName": "Web Push campaign name", "workflowId": null, "workflowName": null, "templateName": "Template name", "locale": null, "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "webPushMessage": "Web Push Title", "webPushBody": "Web Push message body", "webPushIcon": "https://www.example.com/icon.png", "webPushClickAction": "https://www.example.com", "browserToken": "some-browser-token", "catalogLookupCount": 0, "catalogCollectionCount": 0, "productRecommendationCount": 0, "email": "user@example.com", "createdAt": "2024-10-16 22:27:28 +00:00", "templateId": 12345678, "contentId": 123456, "messageId": "79cd703b9999999d8bf3bab6f27e96d5f" } }
# Web Push Send Skip
{ "email": "user@example.com", "userId": "some-userId-value", "eventName": "webPushSendSkip", "dataFields": { "campaignId": 12345678, "campaignName": "Web Push campaign name", "workflowId": null, "workflowName": null, "templateName": "Template name", "locale": null, "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [ "Example", "test-1", "test-2", "test-3" ], "webPushMessage": "Web Push Title", "webPushBody": "Web Push message body", "webPushIcon": "https://www.example.com/icon.png", "webPushClickAction": "https://www.example.com", "email": "user@example.com", "createdAt": "2024-10-16 22:41:55 +00:00", "templateId": 12345678, "contentId": 123456, "messageId": "79cd703b9999999d8bf3bab6f27e96d5f", "reason": "MisconfiguredMessageService" } }
# WhatsApp Received
{ "email": "customer@example.com", "eventName": "whatsAppReceived", "dataFields": { "campaignId": 12345678, "campaignName": "Campaign created on Fri, Mar 20, 2026 2:54 PM", "workflowId": null, "workflowName": null, "templateName": "template_created_on_tue_sep_30_2025_8_58_am", "locale": "en", "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [], "whatsAppBodyField": "Hi {{#if firstName}}{{firstName}}{{else}}there{{/if}}!\\n\\nYour booking is confirmed.\\nView details: {{{trackingUrl}}}\\n\\nReply STOP to unsubscribe.", "createdAt": "2026-03-20 19:48:49 +00:00", "receivedAt": "2026-03-20 19:48:47 +00:00", "email": "customer@example.com", "fromWhatsAppPhoneNumber": "14155550111", "toWhatsAppPhoneNumber": "14155550133", "espName": "Infobip", "espAccountId": "acct_12345", "replyToMessageId": "E_ABCD1234EXAMPLEREPLYID5678XYZ90", "attributionType": "LAST_TOUCH", "templateId": 12345678, "sanitized": { "inputText": "example reply from a whatsapp user" }, "whatsAppMessage": { "type": "TEXT", "text": "Example reply from a WhatsApp user" }, "emailId": "c12345678:t12345678:customer@example.com" } }
# WhatsApp Seen
{ "email": "user@example.com", "eventName": "whatsAppSeen", "dataFields": { "campaignId": 12345678, "campaignName": "WhatsApp Campaign Name", "workflowId": null, "workflowName": null, "templateName": "WhatsApp Template Name", "locale": "en_US", "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [], "whatsAppBodyField": "Hi {{#if firstName}}{{firstName}}{{else}}there{{/if}}!\\n\\nYour booking is confirmed.\\nView details: {{{trackingUrl}}}\\n\\nReply STOP to unsubscribe.", "createdAt": "2025-04-30 17:53:23 +00:00", "email": "user@example.com", "espAccountId": 12345, "espName": "Infobip", "fromWhatsAppPhoneNumber": "14155550111", "toWhatsAppPhoneNumber": "14155550133", "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "seenMessageId": "9c438a20d26e4e9f8ad4edea23f811cd", "sentAt": "2025-04-30 17:52:54 +00:00", "seenAt": "2025-04-30 17:53:05 +00:00", "templateId": 12345678, "emailId": "c12345678:t12345678:user@example.com" } }
# WhatsApp Send
Schema notes:
-
renderedWhatsAppMessage: For user-initiated WhatsApp templates, this field contains the final rendered WhatsApp message that was sent to the user (for example, resolved Handlebars expressions rewritten with links).- This field is blank for business-initiated WhatsApp templates. Final WhatsApp template rendering is processed by Meta.
{ "email": "user@example.com", "eventName": "whatsAppSend", "dataFields": { "campaignId": 12345678, "campaignName": "WhatsApp Campaign Name", "workflowId": null, "workflowName": null, "templateName": "WhatsApp Template Name", "locale": "en_US", "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [], "whatsAppBodyField": "Hi {{#if firstName}}{{firstName}}{{else}}there{{/if}}!\\n\\nYour booking is confirmed.\\nView details: {{{trackingUrl}}}\\n\\nReply STOP to unsubscribe.", "toWhatsAppPhoneNumber": "14155550133", "fromWhatsAppSenderId": 7, "espName": "WhatsApp", "billingParty": "FirstParty", "espAccountId": "12345", "renderedWhatsAppMessage": "", "catalogLookupCount": 0, "catalogCollectionCount": 0, "productRecommendationCount": 0, "transactionalData": { "__comment": "transactionalData lists the fields contained in the dataFields property of the API call or event used to trigger the email, campaign, or journey. transactionalData must contain no more than 12k characters in total." }, "email": "user@example.com", "createdAt": "2025-12-17 17:50:10 +00:00", "templateId": 12345678, "contentId": 1234, "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "emailId": "c12345678:t12345678:user@example.com" } }
# WhatsApp Click
{ "email": "user@example.com", "eventName": "whatsAppClick", "dataFields": { "campaignId": 12345678, "campaignName": "WhatsApp Campaign Name", "workflowId": null, "workflowName": null, "templateName": "WhatsApp Template Name", "locale": "en_US", "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [], "whatsAppBodyField": "Hi {{#if firstName}}{{firstName}}{{else}}there{{/if}}!\\n\\nYour booking is confirmed.\\nView details: {{{trackingUrl}}}\\n\\nReply STOP to unsubscribe.", "createdAt": "2025-04-29 22:04:44 +00:00", "messageId": "9c438a20d26e4e9f8ad4edea23f811cd", "clickedUrl": "https://example.com?utm_source=Iterable&utm_medium=whatsApp&utm_campaign=campaign_12345678", "userAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X)", "userAgentDevice": "Mobile", "templateId": 12345678, "email": "user@example.com", "emailId": "c12345678:t12345678:user@example.com" } }
# WhatsApp Bounce
{ "email": "customer@example.com", "eventName": "whatsAppBounce", "dataFields": { "campaignId": 12345678, "campaignName": "WhatsApp Campaign Name", "workflowId": null, "workflowName": null, "templateName": "template_created_on_tue_sep_30_2025_8_58_am", "locale": "en", "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [], "whatsAppBodyField": "Hi {{#if firstName}}{{firstName}}{{else}}there{{/if}}!\\n\\nYour booking is confirmed.\\nView details: {{{trackingUrl}}}\\n\\nReply STOP to unsubscribe.", "contentId": 12345, "createdAt": "2026-03-20 18:58:08 +00:00", "email": "customer@example.com", "errorCode": 7032, "messageId": "735b8fa7151e4d37a8800a812a8db0d9", "messageStatus": "UNDELIVERABLE_NOT_DELIVERED", "templateId": 12345678, "toWhatsAppPhoneNumber": "14155550133", "emailId": "c12345678:t12345678:customer@example.com" } }
# WhatsApp Send Skip
{ "email": "customer@example.com", "eventName": "whatsAppSendSkip", "dataFields": { "campaignId": 12345678, "campaignName": "WhatsApp Campaign Name", "workflowId": null, "workflowName": null, "templateName": "template_created_on_tue_sep_30_2025_8_58_am", "locale": "en", "channelId": 123456, "messageTypeId": 123456, "experimentId": null, "labels": [], "whatsAppBodyField": "Hi {{#if firstName}}{{firstName}}{{else}}there{{/if}}!\\n\\nYour booking is confirmed.\\nView details: {{{trackingUrl}}}\\n\\nReply STOP to unsubscribe.", "email": "customer@example.com", "createdAt": "2026-03-20 18:52:01 +00:00", "templateId": 12345678, "messageId": "966f9a165070408daf383287b26cf10a", "reason": "LocaleMismatch", "esDocumentId": "esdoc_1234567890abcdefghijklmnopqrstuvwxyz", "emailId": "c12345678:t12345678:customer@example.com" } }
# Want to learn more?
For more information about some of the topics in this article, check out this Iterable Academy course. Iterable Academy is open to everyone — you don't need to be an Iterable customer!