The Shopify + Iterable integration lets you automate your multi-channel marketing strategy based on user actions in your Shopify e-commerce website. Connect Shopify to Iterable to boost retention and ROI with campaign strategies like cart abandonment and repeat purchase.
IMPORTANT
New Shopify integration changes are now available and can be accessed by reinstalling the app. These changes include breaking updates, so please review the latest documentation carefully before reinstalling. This only impacts Shopify integrations installed prior to May 7, 2026. See Shopify + Iterable integration (version 2) for the latest version.
# In this article
- Overview
- Installation
- Web pixels
- Tracked Events
- Purchase attribution
- Event payload examples
-
Frequently asked questions
- Can extra data be added to purchase events?
- Can I change the API key the app is using to connect to Iterable?
- I use Iterable journeys to send users an order confirmation message after they make a purchase. How can I prevent users from receiving multiple order confirmation messages after purchase event updates?
- Does this integration populate the userId user profile field?
- Can I use this integration if I have a "headless" or custom Shopify store?
# Overview
This guide walks through how to set up and use Iterable's Shopify app, expected event types and payloads, and best practices for connecting Shopify with your Iterable project.
Once the integration is set up, the app sends customer details, on-site actions (cart updates, purchases, product views), and product information to your Iterable project in real time.
# How it works
Iterable's Shopify app is a fully managed data integration. The integration uses a combination of Shopify's APIs and webhooks, and JavaScript (loaded on the pages of a shop's storefront) to send customer, event, and product data to Iterable.
- Front-end JavaScript is loaded through Shopify's Web Pixel system, which tracks site-side interactions and attribution data in purchase events.
- Shopify's webhooks notify Iterable about particular events in a shop. For example, when a customer's record is updated in Shopify, a webhook notifies Iterable and updates their user profile.
- Shopify's APIs enrich webhook payloads with supplemental product data and perform historical backfills of data during the installation of the app.
# Installation
To learn about the expected functionality of the Iterable Shopify app before placing it into production, install the app on a staging version of your store and connect it to an Iterable sandbox project.
NOTE
If you're using an EDC-based project, you must notify your customer success manager (and opt in with your contract) before installing the Shopify app and connecting it to your project. Please note that while you can connect to an EDC-based project, all Shopify data processed by the integration will happen in the US.
The Shopify integration supports connecting to both of Iterable's data centers, however Iterable EDC-based projects require additional configuration to get started.
# Preparing projects in Iterable's European Data Center (EDC)
If you're using an EDC-based project, first notify your Customer Success Manager to set up your project for Shopify integration. Once your project is set up, you can install the Shopify app and connect it to your project.
WARNING
Data processing occurs in the US.
While you can connect your Shopify account to an EDC-based project, all data processing by Iterable for the Shopify integration occurs in the US.
# Installing the Iterable Shopify app
Download the Iterable app from the Shopify App Store.
Read and accept the required permissions.
-
Enter a server-side API key from the Iterable project you want to connect to Shopify, and an email address (only used once, to notify you of the backfill's completion).
(Optional) Perform a one-time historical backfill of customer and order data. To skip this step, leave the Customers and Orders options unchecked, and click Next.
-
The admin screen lets you control what events are sent to your Iterable project. For a detailed explanation of each option, see the Tracked Events section.
(Optional) Copy the snippet of Liquid code and add it to your store's theme. This snippet enables the integration to more accurately identify a user when tracking logins, logouts, and product views. For help editing your store's theme code, see Shopify's Editing theme code support guide.
Actions tracked within Shopify will now begin flowing to your Iterable project!
# Historical backfill
Perform an optional, one-time backfill of customer and order data.
WARNING
- Events, even if backdated, can trigger journeys. Use caution if your Iterable project includes journeys that are triggered by user updates or purchases.
- Historical backfilling can result in events being overwritten in your Iterable project.
Select Customers to sync customer records — created after the specified date — from your Shopify store to your Iterable project. (This can also create or update users.)
Select Orders to sync customer purchases — created after the specified date — from your Shopify store to your Iterable project. (This can also create or update users.) Additionally, if any purchases in your project share an order ID with any backfilled purchases from Shopify, they may be updated. NOTE: Only orders made within the last 60 days can be backfilled.
Select a date from which to start the backfill, or leave Customers and Orders unchecked to continue without backfilling.
After the historical backfill has finished, the email address you entered in the previous step will receive a count of all synced customers and historical orders.
NOTE
Events synced to Iterable via a historical backfill will contain the field
historical_backfill set to true.
# Verifying the installation
After installing the app, it's a good idea to check whether the Web Pixel is properly configured on your store. To verify the Web Pixel installation:
Check Pixel Manager: In your Shopify admin, go to Settings > Customer events > All to see if the Iterable pixel is listed and has a "Connected" status.
Privacy Settings: Ensure your store's privacy settings are configured according to your requirements. The pixel will only fire when appropriate consent is granted.
# Web pixels
Shopify’s web pixels introduces pixel-based tracking that replaces custom javascript-based tracking. This enhancement redefines how brands understand customer behavior—offering real-time, consent-based insights into every interaction, from product views to purchases. It’s precision marketing built for a privacy-first world.
To use web pixels, you must first install or re-install the Iterable Shopify app.
# Web pixel installation
Web pixels are only installed for stores that added the Iterable Shopify app on or after July 7, 2025.
Stores that installed the app prior to this date will continue using the legacy ScriptTag implementation.
If you installed the Iterable Shopify app before July 7, 2025 and want to use web pixels, reinstall the app to receive the updated version.
# Web pixel privacy
The version of web pixel that's included with the Iterable Shopify app integrates with Shopify's Customer Privacy settings, which govern how and when pixels are allowed to run based on visitor consent. Web pixel app extensions are compatible with the Customer Privacy API in that they honor the consent signals chosen by the customer.
# Web pixel permissions
Shopify's Pixel Manager only loads and runs Iterable's version of web pixel if a visitor has granted permission for all of the privacy categories that Iterable marked as required in the app's configuration. When users are asked for consent, they'll see a cookie banner like this:
When consent is granted and the pixel is allowed to run, it subscribes to a standard set of Shopify Web Pixel events, including page_viewed, product_viewed, product_added_to_cart, and product_removed_from_cart.
# Cookie Banner: Consent Scenarios
Web pixels perform as described in one of these four scenarios, based on the merchant's cookie banner configuration and visitor consent.
| Banner status | Visitor consent | Web Pixel behavior | Behavioral events | Attribution data |
|---|---|---|---|---|
| Not enabled | Implied consent | Triggers by default | ✅ All events tracked | ✅ Full attribution |
| Enabled | Full consent (all categories) | Fires normally | ✅ All events tracked | ✅ Full attribution |
| Enabled | Partial consent (some categories) | Does not fire | ❌ No events captured | ❌ No attribution |
| Enabled | No consent (all declined) | Does not fire | ❌ No events captured | ❌ No attribution |
NOTES
If either Marketing or Analytics consent is not granted, the pixel will not fire.
Server-side events (orders, fulfillments, customer updates) are not affected by front-end consent settings, as they are processed via Shopify webhooks. In all of the above scenarios, server-side events are processed normally.
# Tracked Events
Iterable's Shopify app can create and update user profiles, track user actions such as product views, cart updates and purchases, and sync your store's product inventory with Iterable's Catalog.
The app's admin screen lets you choose which events you want to send to Iterable. This section provides an explanation of the types of events the app tracks and information about event payloads, user profile field mappings, and expected behavior of events.
This integration tracks three types of events:
- Behavioral events
- Commerce events
- Product events
# Behavioral events
Behavioral events are tracked site-side through the Iterable web pixel instance that's loaded on your storefront. Iterable's Shopify app can send the following behavioral events to Iterable:
| Event name | Description |
|---|---|
login | Created when a user logs into their customer account on the store |
logout | Created when a user logs out of their customer account on the store |
productView | Created when a user views a product |
# Commerce events
There are three types of commerce events:
- Order events
- Shipping events
- Customer events
# Order events
Order events are tracked during the checkout, order, draft order, and refund processes. The Order checkbox is responsible for the following events:
| Event name | Description |
|---|---|
purchase | Created when an order is created in Shopify |
updateCart | Created when a Shopify cart is created or updated |
createCheckout | Created when a checkout is created or updated in Shopify |
createDraftOrder | Created when a draft order is created or updated in Shopify |
cancelOrder | Created when an order has been cancelled in Shopify |
createRefund | Created when a refund is issued in Shopify |
NOTE
Purchase events can be updated after the initial purchase date.
When a purchase order is updated in Shopify, the purchase will be updated in
Iterable. To understand when an order has been updated, we've included a Boolean
field in the purchase payload called update. The initial purchase tracked in
Iterable will have update: false. Subsequent updates to a purchase will have
update: true.
# Shipping events
After an order has been placed, details about order fulfillment can be sent to Iterable. For example, the following events can be used to message customers about their purchase being fulfilled, shipped, and delivered.
The Shipping checkbox is responsible for the following events:
When a fulfillment is created on an order in your Shopify Store, Iterable's Shopify app will send a
createFulfillmentevent to Iterable.-
When fulfillments are updated, the fulfillment data in an order is also updated. Iterable's Shopify app will update the associated
purchaseevent with afulfillment_status. Possible values for this field include:-
pending: The fulfillment is pending. -
open: The fulfillment has been acknowledged by the service and is being processed. -
success: The fulfillment was successful. -
cancelled: The fulfillment was cancelled. -
error: There was an error with the fulfillment request. -
failure: The fulfillment request failed.
Specific fulfillment events are also relayed to Iterable. The name of the event is dependent on the
statusfield included in the fulfillment event payload from Shopify. Depending on the status, here are the resulting events:Fulfillment status Iterable event confirmedorderShippingConfirmedin_transitorderInTransitout_for_deliveryorderOutForDeliverydeliveredorderDeliveredfailureorderDeliveryFailureattempted_deliveryorderAttemptedDeliverylabel_printedorderLabelPrintedlabel_purchasedorderLabelPurchasedready_for_pickuporderReadyForPickup -
NOTE
Fulfillment and FulfillmentEvents are treated as separate events in Shopify.
# Customer events
A customer profile is created when a customer interacts with your business. For example, a profile is created when a customer:
- Signs up for your mailing list or a customer account.
- Places an order.
- Starts an order, but abandons their checkout.
- Is added to your customer list manually.
Whenever a customer is created, updated, or enabled/disabled in Shopify, their user profile is updated in Iterable. These are the fields that can be synced from a Shopify customer record to Iterable:
| Field name | Type | Description |
|---|---|---|
accepts_marketing* | Boolean | Whether or not the customer has consented to receive marketing materials via email. |
addresses | Array | A list of the customer's ten most recently updated addresses. |
default_address | Object | The customer's default address. |
email_marketing_consent | Object | Information collected by Shopify when the customer agreed to receiving marketing information by email. |
first_name | String | The customer's first name. |
id | String | A unique identifier for the customer. Shopify's id field maps to Iterable's userId field. |
last_name | String | The customer's last name. |
note | String | A note about the customer. |
orders_count | Long | The number of orders associated with this customer. |
phone_number | String | The unique phone number for this customer. |
shopify_created_at | Date | The date and time when the customer was created. |
shopify_updated_at | Date | The date and time when the customer information was last updated. |
sms_marketing_consent | Object | Information collected by Shopify when the customer agreed to receiving marketing information by SMS. |
state | String | The state of the customer's account with a shop. |
tags | String | Tags that the shop owner has attached to the customer, formatted as a string of comma-separated values. |
tax_exempt | Boolean | Whether the customer is exempt from paying taxes on their order. |
total_spent | Long | The total amount of money that the customer has spent across their order history. |
NOTE
Shopify has deprecated the accepts_marketing field in favor of the
email_marketing_consent and sms_marketing_consent fields. These fields do
not directly affect a user's subscription preferences in Iterable, but they
can be used to update those preferences (for example, in a journey). If you
have questions about how to use these fields, talk to your Iterable CSM or
check out Shopify's documentation.
WARNING
If you have Overwrite Location Fields
turned on in your Iterable project settings, or if you currently use a state
field on the user profile, the state field will be overwritten by Shopify's
state value. There are two common ways to address this problem:
- Use a different field name to contain the state value. For example, use
postalStateto store a user's postal address state. - Nest the state field under a different property on the user profile. For
example,
postalAddress.state.
For more information about user fields, see Shopify's Customer Object support guide.
# Product tracking with catalogs
NOTE
This feature requires a Catalog subscription. Contact your Iterable customer success manager to discuss adding Catalog to your plan.
Selecting Catalog (under Product Tracking) on the admin screen prompts Iterable’s Shopify app to sync data to two catalogs:
- A variant-based catalog, named
shopifyCatalog - A product-based catalog, named using the format
{store domain}-shopifyProductCatalog
Initially, a date picker will appear. All products created after the date you provide will be synced.
# Shopify variant catalog
When enabled, a catalog named shopifyCatalog is created and kept up to
date with the latest product variant information from Shopify.
Variant catalogs tend to be best suited for precise, inventory-aware campaigns, and personalized messaging based on SKU-level data. For example, you might use them for:
- Back-in-stock or low-inventory alerts
- Abandoned cart or browse recovery messaging (with a reference the exact variant browsed)
- Price drop notifications
- Flash sales or SKU-sensitive campaigns
The variant catalog contains the following fields:
| Catalog field | Description |
|---|---|
id | The unique numeric identifier for the product variant. |
url | A link to the product. |
sku | A unique identifier for the product variant in the shop. |
name | The name of the product variant. |
price | The price of the product variant. |
status | The status of the product. |
handle | A unique human-friendly string for the product. |
vendor | The name of the product's vendor. |
discount | The difference between the compare_at_price and the price. |
imageUrl | The URL image of the product variant. |
inventory | An aggregate of inventory across all locations. |
published | Boolean dependent on whether or not the product is published. |
categories | Tags (separated by commas) for searching and filtering products. |
product_id | The unique numeric identifier for the product. |
description | A description of the product. |
product_type | A categorization for the product used for filtering and searching products. |
inventory_policy | Whether customers are allowed to place an order for the product variant when it's out of stock. Valid values are deny or true. |
compare_at_price | The original price of the item before an adjustment or a sale. |
inventory_quantity | An aggregate of inventory across all locations. |
inventory_management | The fulfillment service that tracks the number of items in stock for the product variant. |
sales_channels_and_apps | Whether the product is published to the Point of Sale channel. Valid values are web and global. |
# Shopify product catalog
A product catalog named {store domain}-shopifyProductCatalog, provides
product-level data focused on the overall product rather than individual
variants, and stays up-to-date with your Shopify store.
TIP
If you installed the Shopify integration prior to July 30, 2025, you can resync your catalogs to have the product catalog created in your project.
Product catalogs are best suited for broader, category-based merchandising, when optional variant details aren’t critical to the experience. For example, you might use them for:
- Targeted marketing campaigns, like for new arrivals or best sellers
- Category or collections-based messaging
- Option-based groupings (like size or color)
The product catalog contains the following fields:
| Catalog field | Description |
|---|---|
id | The unique identifier for the product. |
name | The name of the product. |
description | The description of the product, with HTML tags. For example, the description might include bold and italic text. |
product_type | The product type that merchants define. |
category | The name of the taxonomy category. For example, Dog Beds. |
vendor | The name of the product's vendor. |
tags | A comma-separated list of searchable keywords that are associated with the product. |
handle | A unique, human-readable string of the product's title. A handle can contain letters, hyphens (-), and numbers, but no spaces. The handle is used in the online store URL for the product. |
url | The direct URL to the product page on your store, formatted as: https://{shop-domain}/products/{handle}. |
image_url | The URL of the featured image for the product. |
additional_images | A string (e.g., comma-separated URLs or JSON array) containing URLs of additional product images. |
starting_price | The lowest price among all variants of the product. |
max_price | The highest price among all variants of the product. |
compare_at_price_min | The lowest "compare at" price among all variants. |
compare_at_price_max | The highest "compare at" price among all variants. |
on_sale | A boolean indicating if any variant of the product is currently on sale. |
options | Describes the available option types for the product (e.g., "Size", "Color") and their possible values. Each object contains a name field for the option type and a values array listing the available choices. |
total_inventory | The total aggregate inventory count for all variants. |
created_at | The timestamp when the product was created in Shopify. |
updated_at | The timestamp when the product was last updated in Shopify. |
publishes_at | The timestamp when the product was published in Shopify. |
published | A boolean indicating whether the product is currently published and visible. |
status | The publishing status of the product (e.g., "ACTIVE", "DRAFT", "ARCHIVED"). |
# Purchase attribution
Iterable's Shopify integration can attribute purchases back to Iterable campaigns and templates through our Web Pixel. The pixel tracks attribution data and includes it in purchase events through two methods:
Iterable cookies: Iterable's
iterableEmailCampaignIdanditerableTemplateIdcookies are included in purchase events to enable campaign and template attribution. For more information read Tracking Conversions, Purchases, and RevenueURL parameters: When
iterable_campaignoriterable_template(case insensitive) are present in the URL bar when a user visits your store, the integration will include those values as thecampaignIdandtemplateIdin purchases events.
NOTE
If both cookies and URL parameters are present, the URL parameter values take precedence.
# Event payload examples
Here are some examples of what an event in Iterable might look like when sent from the app.
# Cart update
{ "email":"user@example.com", "eventName": "updateCart", "eventType": "customEvent", "shoppingCartItems":[ { "id":"18998762807461", "price":9, "quantity":1, "key":"18998762807461:87f0fe531569cd439f2f63cc68213948", "sku":"ite1", "url":"https://example.myshopify.com/products/margherita-pizza", "name":"Margherita Pizza", "imageUrl":"https://cdn.shopify.com/s/files/1/0574/7366/3153/products/Pizza_Margherita.jpg?v=1622678940", "grams":0, "taxable":false, "gift_card":false, "vendor":"example", "product_id":"2796811046353", "variant_id":"18998762807461", "shopify_store_domain":"example.myshopify.com", "original_price":9, "line_price":9, "total_discount":0, "discounted_price":9, "original_line_price":9, "description":"Pizza Margherita (more commonly known in English as Margherita pizza) is a typical Neapolitan pizza, made with San Marzano tomatoes, mozzarella cheese, fresh basil, salt and extra-virgin olive oil." } ] }
# Purchase
{ "id":"4492994576561", "shoppingCartItems":[ { "id":"11536696770737", "price":9, "quantity":1, "sku":"ite1", "url":"https://example.myshopify.com/products/margherita-pizza", "name":"Margherita Pizza", "imageUrl":"https://cdn.shopify.com/s/files/1/0574/7366/3153/products/Pizza_Margherita.jpg?v=1622678940", "variant_title":"", "vendor":"example", "fulfillment_service":"manual", "variant_inventory_management":"shopify", "product_id":"2796811046353", "requires_shipping":false, "taxable":false, "gift_card":false, "variant_id":"18998762807461", "properties":[ ], "product_exists":true, "fulfillable_quantity":10, "grams":0, "total_discount":0, "fulfillment_status":"fulfilled", "admin_graphql_api_id":"gid://shopify/LineItem/11536696770737", "description":"Pizza Margherita (more commonly known in English as Margherita pizza) is a typical Neapolitan pizza, made with San Marzano tomatoes, mozzarella cheese, fresh basil, salt and extra-virgin olive oil." } ], "createdAt":"2022-05-20T22:07:52.000Z", "email":"user@example.com", "taxes_included":false, "currency":"USD", "buyer_accepts_marketing":false, "name":"#1121", "customer_locale":"en-US", "app_id":"580111", "order_number":"1121", "payment_gateway_names":[ "shopify_payments" ], "note_attributes": { "authenticPizza": true }, "fulfillment_status":"fulfilled", "contact_email":"user@example.com", "order_status_url":"https://example.myshopify.com/34322680223/orders/d43c4d4c44c54cedb56adb0d343b6212/authenticate?key=a0ac882c10a94dce86e1f07262addea3", "billing_address":{ "first_name":"foo", "last_name":"bar", "address1":"123 Main Street", "address2":"", "city":"San Francisco", "province":"California", "country":"United States", "zip":"94105", "name":"foo bar", "province_code":"CA", "country_code":"US", "latitude":37.7749, "longitude":-122.4194 }, "fulfillments":[ { "id":"9322221615472", "order_id":"6771501407078", "status":"success", "created_at":"2022-05-20 16:07:54 -06:00", "updated_at":"2022-05-20 16:07:54 -06:00", "service":"manual", "location_id":"22305121296", "receipt":{ }, "name":"#1121.1" } ], "payment_details":{ "credit_card_bin":"424242", "avs_result_code":"Y", "cvv_result_code":"M", "credit_card_number":"•••• •••• •••• 4242", "credit_card_company":"Visa" }, "total":9, "totals":{ "total_price_usd":9, "total_discounts":0, "total_line_items_price":9, "total_price":9, "total_tax":0, "total_weight":0, "subtotal_price":9 }, "misc":{ "number":"121", "test":true, "admin_graphql_api_id":"gid://shopify/Order/4492994576561", "confirmed":true, "financial_status":"paid", "processing_method":"direct", "checkout_id":"29789212489387", "browser_ip":"127.0.0.1", "source_name":"web" }, "update":false }
# Frequently asked questions
# Can extra data be added to purchase events?
Yes. Custom attributes included in Shopify's cart are mapped to the
note_attributes field in purchase events. For more information on how to
use this field, see Shopify's cart.attributes
support guide.
# Can I change the API key the app is using to connect to Iterable?
Yes. To do this, go to the app's admin screen, and paste a new API key in the Iterable API Key section. Click Update.
# I use Iterable journeys to send users an order confirmation message after they make a purchase. How can I prevent users from receiving multiple order confirmation messages after purchase event updates?
In your journey's Start tile, set the entry rules to only allow purchases
where update equals false. (When a purchase is updated, update becomes
true.) This entry rule will ensure the journey only allows a user to enter if
this is their initial purchase.
# Does this integration populate the userId user profile field?
Yes, Shopify's customer id field maps to Iterable's userId field. Existing
Iterable userId values will be overwritten by incoming Shopify id values.
# Can I use this integration if I have a "headless" or custom Shopify store?
The Iterable + Shopify integration uses Shopify's Web Pixel system, which requires the standard Shopify storefront to function properly. If your store uses Shopify's Storefront API or a custom cart implementation, the Web Pixel may not function correctly and purchase events will not include attribution to Iterable campaigns.