Keep Salesforce email consent in step with Iterable. When a user subscribes to or unsubscribes from an Iterable email channel, the integration updates Email Opt Out on the matching Salesforce Contacts and Leads. Your sales and service teams see the same consent your marketing team does, so they do not email someone who has opted out.
This is a one-way sync from Iterable to Salesforce. To sync Salesforce records into Iterable, use the Salesforce Inbound integration. You can run both at the same time.
# In this article
# Requirements
- Salesforce Enterprise, Unlimited, or Developer edition, with API access enabled.
- A Salesforce user to authorize the connection: a System Administrator or a dedicated
integration user. That user needs:
- API Enabled.
- Read and Edit on Contacts and Leads.
- Field-level Edit access to Email Opt Out (
HasOptedOutOfEmail) on both Contact and Lead.
- The Iterable Salesforce OAuth package installed in the Salesforce org you are connecting. If you already use Salesforce Inbound, you can reuse its saved connection. No new authorization is needed.
- An Iterable server-side API key for the project you want to sync from.
The integration syncs subscription changes that happen after you deploy it. It doesn't copy existing subscription status from Iterable into Salesforce.
# Set up
# 1. Connect Salesforce
On Connections, pick a saved Salesforce connection or create a new one. When you create one, set Environment to Production or Sandbox to match the org where you installed the OAuth package, then sign in to Salesforce and approve access.
# 2. Connect Iterable
On the same page, pick a saved Iterable connection or create one with a server-side API key for your project.
# 3. Choose an email channel
On Channel Selection, choose the Iterable Email channel to sync. Only Email channels are listed. The list loads from the Iterable connection you chose in the previous step. If it is empty, check that the API key belongs to the right project and that the project has an Email channel.
To see the Email channels in your project, go to Settings → Current Project → Message Channels & Types in Iterable (US or EU).
The integration syncs one channel.
# 4. Deploy the instance
Deploy the instance. Iterable starts capturing subscription changes on the selected channel as soon as the deploy finishes. The first ones should appear in Salesforce within a few minutes.
# 5. Test a subscribed user
- Pick a test user in Iterable whose email address also belongs to a Contact or Lead in Salesforce.
- Unsubscribe that user from the selected channel in Iterable.
- Within a few minutes, open the Contact or Lead in Salesforce and confirm Email Opt Out is checked.
- Subscribe the user to the channel again, and confirm Email Opt Out is cleared.
# What is synced
| Change in Iterable | Salesforce field | New value |
|---|---|---|
| User unsubscribes from the selected channel | Email Opt Out on Contact and Lead | Checked (true) |
| User subscribes to the selected channel | Email Opt Out on Contact and Lead | Cleared (false) |
Only Email Opt Out is written. No other Salesforce field is changed, and changes on other Iterable channels are ignored.
Subscribing clears Email Opt Out, even if someone checked it in Salesforce. Iterable's latest subscription status for the channel is treated as the source of truth.
# How users are matched
Iterable users are matched to Salesforce records by email address. Matching ignores letter case and leading or trailing spaces.
- Contacts. Every Contact with that email address is updated.
- Leads. Every Lead with that email address that has not been converted is updated. Converted Leads are skipped, so the change lands only on the Contact the Lead became.
- Both. If the email address matches a Contact and a Lead, both are updated.
- No match. If no Contact or unconverted Lead has that email address, the change is skipped. The integration never creates a Contact or Lead.
Users without an email address in Iterable cannot be matched and are skipped.
# Timing and ordering
The integration checks Iterable for new subscription changes about once a minute. Most changes reach Salesforce within a few minutes. If many users change their subscriptions at once, the integration works through the backlog over the next several runs.
When the same user changes their subscription several times between runs, only the most recent change is written. If two changes have exactly the same time, the unsubscribe is kept.
Salesforce applies each update as a Bulk API job. It can take a short time after the job is submitted before the new value shows on the record.
# Pausing, editing, and deleting
- Pausing. Changes keep being captured while the instance is paused. They sync when you resume, as long as you resume within seven days. Changes older than that are discarded.
- Changing the channel. Edit the instance, choose a different channel on Channel Selection, and redeploy. Changes on the new channel sync from then on.
- Deleting. Deleting the instance stops capturing changes and discards any that have not synced yet. Salesforce records already updated are not changed back.
# Frequently asked questions
# Which subscription changes update Salesforce?
Salesforce is updated whenever Iterable records that a user subscribed to or unsubscribed from the selected channel, whatever caused the change. Subscription changes to a single message type or a list do not update Salesforce.
| What happens in Iterable | Salesforce updated? | Email Opt Out |
|---|---|---|
The user clicks the standard unsubscribe link ({{unsubscribeUrl}}) in an email sent from the channel. | Yes | Checked |
The user clicks the one-click unsubscribe button their email client shows (the List-Unsubscribe header). | Yes | Checked |
| The user marks an email from the channel as spam, their mailbox provider reports an unsubscribe, or the sending provider blocks the address. | Yes | Checked |
| An email hard-bounces. Iterable unsubscribes the address from the channel the email came from and from every marketing email channel. | Yes, if the selected channel is one of those | Checked |
| The user resubscribes to the channel from the page shown after they unsubscribe. | Yes | Cleared |
Someone changes the user's channel subscription: on the user's profile in Iterable, from a journey, or through the API (for example, unsubscribedChannelIds on POST /api/users/updateSubscriptions). | Yes | Checked or cleared |
The user subscribes to or unsubscribes from a single message type: the message type unsubscribe link ({{unsubscribeMessageTypeUrl}}), a profile or journey change, or the API. | No | Unchanged |
| The user is added to or removed from a list. | No | Unchanged |
| A new user is created with your project's default subscription status. | No | Unchanged |
To make sure email unsubscribes reach Salesforce, use {{unsubscribeUrl}} in templates sent from the selected channel, not {{unsubscribeMessageTypeUrl}}.
# How do opt-in and opt-out message types affect the sync?
They don't. Email Opt Out is a single on/off setting on each Salesforce record, so it can only reflect whether the user is subscribed to the channel as a whole. Message-type subscriptions are not synced, whichever policy the message type uses:
- Opt-out message types. Users receive these until they unsubscribe. Unsubscribing from only that message type leaves the user subscribed to the channel, so Email Opt Out doesn't change.
- Opt-in message types. Users receive these only after they subscribe. Subscribing to or unsubscribing from the message type does not change the user's channel status, so Email Opt Out doesn't change.
In both cases, Salesforce is updated only when the user subscribes to or unsubscribes from the channel itself.
# Does creating a user in Iterable update Salesforce?
No. A new user starts with your project's default subscription status, and the integration does not sync that starting status. Salesforce is updated the first time the user's subscription to the selected channel changes.