When a user subscribes to or unsubscribes from a message channel, an individual message type, or a list, Iterable sets the following fields in the user profile to a value that identifies the action that triggered the event:
When an
emailSubscribeevent is triggered, Iterable adds asignupSourcefield.When an
emailUnSubscribe,hostedUnsubscribeClick, oremailComplaintevent is triggered, Iterable adds anunsubSourcefield.
NOTE
The event names emailSubscribe and emailUnSubscribe are used universally
for all message channels.
# In this article
- About subscribe and unsubscribe events
- Subscription event tracking
- Viewing subscribe and unsubscribe events
- System events related to subscribe and unsubscribe events
- Sources for subscribe events (signupSource)
- Sources for unsubscribe events (unsubSource)
- Attributing unsubscribe events to a campaign
- Want to learn more?
# About subscribe and unsubscribe events
The following system events reflect subscribe and unsubscribe actions:
# Subscribe (emailSubscribe)
A subscribe event is triggered when a user subscribes to any message channel,
message type, or list, or when a user is added to or removed from a list (such
as with a CSV import, or a journey tile that adds or removes users from a list).
Iterable logs an emailSubscribe system event when this happens.
The signupSource field in the subscribe event provides the reason the user
was subscribed. To learn more, read Sources for subscribe events (signupSource)
below.
# Unsubscribe (emailUnSubscribe)
An unsubscribe event is triggered when a user unsubscribes from any message
channel, message type, or list. Iterable logs an emailUnSubscribe system event
when this happens.
The unsubSource field in the unsubscribe event provides the reason the user
was unsubscribed. To learn more, read Sources for unsubscribe events (unsubSource)
below.
# Subscription event tracking
Iterable tracks subscribe and unsubscribe system events when there are updates to user profile fields related to subscriptions.
For example, when a user subscribes to a list, message channel, or message
type, Iterable logs an emailSubscribe system event.
However, there's an important distinction: Iterable logs these events even when a user's subscription status doesn't actually change. If you send a user update that includes unchanged subscription data, Iterable creates a subscribe or unsubscribe event, even though the user's status remained the same, causing redundant events in the project's event history.
# Smarter subscription event tracking
NOTE
This update applies to new organizations created on or after December 15, 2025.
Existing organizations will receive smarter subscription event tracking in a future release, with no expected disruption to existing journeys and webhooks that rely on subscription event triggers or data.
Iterable will not store subscription-related system events when no actual subscription changes occur.
With Iterable's smarter subscription event tracking, you can expect fewer redundant subscription events in your exports and user profiles.
- Subscription events are still tracked and processed by Iterable.
- All subscription events still trigger journeys and webhooks as expected, whether or not the subscription state actually changed.
- Subscription events are not stored when no actual subscription changes occur.
- You'll see fewer redundant subscription events in your exports and user profiles.
Examples of when this applies:
- API calls that include subscriptions to lists that the user is already subscribed to (such as from a custom subscription preference center)
- Bulk imports that include users already in the target lists (such as from a CSV import)
- Journey tiles that add users to lists they're already members of (such as from a subscription preferences tile)
- Any subscription operation that doesn't result in a net change to the user's subscription state
# Viewing subscribe and unsubscribe events
View information about a user's subscribe or unsubscribe events using one of the following methods:
-
The user profile page in Iterable:
To view a user's profile, navigate to Audience > Contact Lookup and enter their email address or their user ID (the search box reflects the necessary field).
On the Event History tab, find the unsubscribe or subscribe event and look for the
unsubSourceorsignupSourcefield. -
For subscribes, set the
dataTypeNamefield toemailSubscribeand review thesignupSourcefield in the exported data.For unsubscribes, set the
dataTypeNamefield toemailUnSubscribeand review theunsubSourcefield in the exported data.
-
System webhooks - Email Subscribe and Email Unsubscribe
A system webhook sends data from Iterable to third-party system when particular campaign-related events are created. To learn how to set up an Email Subscribe or Email Unsubscribe system webhook, read System Webhooks.
For the source of an subscribe or unsubscribe event, look at the
signupSourceorunsubSourcefields in the system webhook data that's captured by the third-party system.
# System events related to subscribe and unsubscribe events
These system events are related to subscribe and unsubscribe events:
Email bounce (
emailBounce): An email sent to the user is returned as a bounce. The user is automatically unsubscribed if the event is a hard bounce.Email complaint (
emailComplaint): The user marked an email as spam. The user is automatically unsubscribed.Hosted unsubscribe click (
hostedUnsubscribeClick): The user clicked the hosted unsubscribe URL in an email template. The user is not automatically unsubscribed.
# Email bounce (emailBounce)
An email bounce event is triggered when an email sent to a user is returned as a
bounce. Iterable logs an emailBounce system event when this happens.
Sometimes, the email bounce is caused by a permanent issue, like an invalid
email address. In these cases, the emailBounce event is classified as a hard
bounce. Iterable sets an event property of "recipientState": "HardBounce",
and the user is automatically unsubscribed from all email channels. When this
unsubscribe event is triggered, Iterable logs an emailUnSubscribe event with
the unsubSource field set to HardBounce.
To learn more about email bounces, read Email Bounces and Email Bounce Event Properties.
# Email complaint (emailComplaint)
An email complaint event is triggered when a user marks an email as spam.
Iterable logs an emailComplaint system event when this happens.
When a user marks an email as spam, Iterable automatically unsubscribes them from all email channels.
An unsubscribe event is triggered, and Iterable sets an event property of
"unsubSource": "Complaint", and the user is automatically unsubscribed from
all email channels.
# Hosted unsubscribe click (hostedUnsubscribeClick)
If you are using a custom preference center,
Iterable logs a hostedUnsubscribeClick system event when a user clicks the
hosted unsubscribe URL from a template. This means that the user has viewed
the hosted unsubscribe page. If they made a change to their preferences, then
an API call should be made to Iterable to update their subscription
preferences. This API call would log an emailSubscribe or emailUnSubscribe
event signifying their updated preferences.
Exception: This event is not tracked when the user clicks the hosted unsubscribe link in an easy unsubscribe header.
IMPORTANT
Hosted unsubscribe clicks are click events, not unsubscribe events.
When the hosted unsubscribe click event is logged in Iterable, it means that the user clicked on the link. It does not mean that the user submitted your form or has been unsubscribed in any way.
When you use a custom preference center, your implementation is responsible for staying compliant with sender requirements.
When the user confirms their preferences and submits your web form, your website should send an API call to Iterable that updates the user's subscription preferences based on their form response.
Once that API call is made, Iterable logs an unsubscribe
event with the unsubSource field set to API.
To learn more about using the hosted unsubscribe URL to send a user to a custom preference center, read Creating a Subscription Preference Center.
# Sources for subscribe events (signupSource)
The signupSource event field provides one of the following reasons a user was
subscribed.
# API
An API call was made to one of these endpoints:
PATCH /api/subscriptions/{subscriptionGroup}/{subscriptionGroupId}/user/{userEmail}PATCH /api/subscriptions/{subscriptionGroup}/{subscriptionGroupId}/byUserId/{userId}}PUT /api/subscriptions/{subscriptionGroup}/{subscriptionGroupId}
NOTE
API is a common source for subscribe events because it's used in many different scenarios depending on how you manage your audience.
For example, this may have been an API call made during a Smart Ingest sync.
# CartAPI
An API call was made to POST /api/commerce/updateCart.
# DeviceAPI
An API call was made to POST /api/users/registerDeviceToken
call from one of Iterable's mobile SDKs.
# DoubleOptInAPI
A user has confirmed their subscription to an SMS Double Opt-In message type.
Before this happens, an API call is made to POST /api/subscriptions/subscribeToDoubleOptIn.
This triggers the SMS Double Opt-In subscription flow. The subscribe event is
recorded when the user confirms their subscription by replying "Y" via SMS.
To learn more, read SMS Double Opt-In Overview.
# Import
On the Audience > Lists page, the user was included in a list update submitted after clicking Update.
On the Audience > Lists page, the user was included in a list of users provided after clicking Subscribe to Channel.
A new static list was saved (perhaps by saving a dynamic list as a new static list or creating static list from another static list).
# ListAPI
An API call was made to POST /api/lists/subscribe.
# PurchaseAPI
An API call was made to POST /api/commerce/trackPurchase.
# ResubscribePage
The user subscribed to a message type or channel using the Resubscribe button on an unsubscribe success page.
# SendMessageAPI
An API call was made to POST /api/email/target
(the user was sent a triggered campaign).
# SmartOptIn
The user subscribed to an SMS message type or channel using SMS Smart Opt-In.
Exception: If the SMS Smart Opt-In link uses a double opt-in SMS message type,
signupSource is DoubleOptInAPI.
# SMS
This signup source is only used for SMS messages.
User profiles are updated with this value only when one of these conditions is met:
-
The user resubscribed to an SMS message type or channel using an SMS message with one of the following keywords:
STARTUNSTOP
The project received an inbound SMS message to opt-in and there was no existing user profile for the phone number. When this happens, Iterable creates a new user profile with a placeholder
emailvalue and sets thesignupSourcetoSMS. This is an optional feature and is not default behavior. (By default, Iterable does not create new user profiles for inbound SMS opt-ins.) To learn more, read Creating new user profiles for inbound SMS opt-ins.
# UpdateSubscriptionsAPI
An API call was made to one of these endpoints:
# WebApp
- A user was added manually on the user profile page in Iterable.
- In a userID-based project, a user was created when you sent a proof of template.
# WebForm
The user subscribed through an HTML signup form like the example shown in Building a Signup Form for Static Lists.
# Workflow
The user was added to a journey by an API call to POST /api/workflows/triggerWorkflow.
# Sources for unsubscribe events (unsubSource)
The unsubSource field provides one of the following reasons a user was
unsubscribed.
# API
The user was unsubscribed after an API call was made to one of these endpoints:
DELETE /api/subscriptions/{subscriptionGroup}/{subscriptionGroupId}/byUserId/{userId}PUT /api/subscriptions/{subscriptionGroup}/{subscriptionGroupId}
API is a common source for unsubscribe events because it's used in many different scenarios depending on how you manage your audience.
For example, this may have been an API call made during a Smart Ingest sync or when your users unsubscribe using a custom subscription preference center.
# Complaint
The user marked an email they received as spam, so Iterable automatically unsubscribed them from all email channels.
IMPORTANT
Some providers limit their spam complaint reports to aggregated, anonymous data to protect user privacy. Iterable can't associate an anonymous spam complaint to a particular user. For users of these mailbox providers, their user histories can't reflect spam complaint events, and they aren't auto-unsubscribed.
This limitation is true for Gmail users, for example. To learn more, read Are Gmail Users Who Make Spam Complaints Automatically Unsubscribed?
# EmailLink
The user clicked an unsubscribe link in the email template, either a
{{unsubscribeUrl}} or {{unsubscribeMessageTypeUrl}}.
NOTE
When a user clicks on the hosted unsubscribe URL, Iterable logs a
hostedUnsubscribeClick system event. This event is a click event, not an
unsubscribe event. To learn more, read Hosted unsubscribe click (hostedUnsubscribeClick).
# ESP
The email service provider (ESP) has placed the user on a suppression list.
ESPs often maintain their own suppression lists to help protect sender
reputation. Each ESP has its own rules for managing suppression lists.
When a user is added to an ESP suppression list, the ESP sends an unsubscribe
event to Iterable with the unsubSource field set to ESP.
To learn more, read ESP suppression.
# HardBounce
An email was sent to the user, and it was returned as a hard bounce. Iterable unsubscribes users who hard bounce, but these unsubscribes aren't included in unsubscribe metrics reported in Campaign Analytics and Messaging Insights. To learn more, read Email Bounces.
# Import
On the Audience > Segmentation page, an Iterable member selected the user and then clicked Other Actions > Remove Contacts from List.
On the Audience > Lists page, the user was included in a list update submitted to remove users from a list.
On the Audience > Lists page, the user was included in a list of users provided after clicking Unsubscribe from Channel.
# ISP
Iterable received an unsubscribe request directly from the user's internet service provider (ISP) or their email client (like Gmail or Yahoo).
This happens most often when the user clicks on an easy unsubscribe (one-click
unsubscribe) link in the email message. These unsubscribe requests are
processed using either the http or mailto methods.
To learn more about this process, read Easy Unsubscribe and List-Unsubscribe Email Headers.
NOTE
ESP vs ISP unsubscribe event sources
ESP — The email service provider placed the user on a suppression list, for a reason like a hard bounce or spam complaint, which for some ESPs triggers an unsubscribe event in Iterable. In this case, the ESP is the service you use to send your emails, like SendGrid or SparkPost.
ISP — The user clicked an easy unsubscribe link in the email message and the user was unsubscribed. In this case, the ISP is their internet service provider or email client, like Gmail or Yahoo.
# ListAPI
An API call was made to POST /api/lists/unsubscribe.
# SMS
The user replied to an SMS message with one of the following keywords:
STOPCANCELSTOPALLUNSUBSCRIBEQUITEND
# UpdateSubscriptionsAPI
An API call was made to one of these endpoints:
# WebApp
The unsubscribe was triggered manually on the user profile page in Iterable.
# Workflow
The user was unsubscribed because of an unsubscribe tile in a journey.
# Attributing unsubscribe events to a campaign
The following unsubscribe event types can be used to attribute an unsubscribe to a particular campaign:
API(if the API passes the optionalcampaignIdfield)ComplaintEmailLinkESPISPListAPI(if the API passes the optionalcampaignIdfield)SMS(if Iterable receives an opt-out keyword response, such as STOP or NO, within three hours of the send. To learn more, read SMS Unsubscribes and Resubscribes).UpdateSubscriptionsAPI(if the API passes the optionalcampaignIdfield)
TIP
To find the campaignId associated with a certain unsubscribe event, you can
create a user list in segmentation that filters for unsubscribes, or you can
use the GET /api/events/{email}
API endpoint to locate the campaignId field for the type of unsubscribe event
you're interested in for a specific user.
# 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!
Iterable Academy
Support docs