Iterable SMS Revenue Attribution: Getting campaignId Into the Purchase Event Without Reworking Your Pipeline

I recently worked through an attribution issue in an Iterable, BigCommerce, and Segment stack where email revenue reported correctly and SMS revenue did not. The data pipeline was functioning as implemented. The difference came down to which attribution model each channel was using inside Iterable.

Iterable supports multiple approaches to campaign attribution for purchases and revenue. In practice, you end up choosing between letting Iterable capture campaign context at click time and explicitly attaching campaign context to the conversion or purchase event you send back.

Iterable’s Attribution Options

In Iterable’s documentation on tracking conversions and purchases, the relevant approaches are:

  1. Passing campaignId explicitly with the conversion or purchase event.
  2. Using browser cookies, which Iterable scopes to email-based projects.

The browser cookie option relies on Iterable’s redirect flow to write campaign information into first party cookies at click time. The explicit model relies on ensuring campaignId is present in the purchase event payload that is sent back to Iterable.

Email and SMS operate differently within those constraints.

How Email Was Configured

Email clicks were routed through a branded tracking domain such as links.example.com, implemented as a CNAME to Iterable. Because that domain is a subdomain of the main site, Iterable can set first party cookies during the redirect response.

The flow looked like this:

  1. A user clicks an email link.
  2. The request hits the Iterable tracking domain.
  3. Iterable sets cookies such as iterableEmailCampaignId and iterableTemplateId.
  4. The browser redirects to the final destination URL.

When the landing page loads, those cookies already exist. Storefront JavaScript reads them and includes their values in the purchase event sent to Segment. Segment forwards the purchase to Iterable with the campaign fields populated, and revenue is attributed.

This aligns with Iterable’s documented browser cookie option for email-based projects.

Why SMS Revenue Was Missing

SMS does not use the email redirect and cookie model. Iterable scopes the browser cookie option to email-based projects, and for SMS it requires that campaignId be present on the purchase event.

In this implementation, SMS clicks were not generating iterableEmailCampaignId cookies via redirect. As a result, the purchase event arriving in Iterable did not contain campaignId. Without that field, Iterable has no campaign context to associate revenue with.

User identity was already present in the purchase payload through BigCommerce and Segment. The missing piece was campaign context.

The Correct Adjustment

Since SMS requires explicit campaign context, the fix starts in Iterable by adding link parameters to SMS templates so the landing URL includes campaignId and optionally templateId.

For example:

https://www.example.com/offer?campaignId={{campaignId}}&templateId={{templateId}}

Iterable replaces those values at send time. On landing, you have two implementation paths:

  1. Read campaignId server-side and persist it through checkout so your server-side purchase call includes it.
  2. Normalize the link parameters into whatever your current purchase instrumentation already reads.

In this case, the least invasive change was to read campaignId and templateId from location.search and set the existing cookies that the rest of the pipeline already relied on. That kept Segment mappings and purchase schemas unchanged while ensuring the purchase event sent to Iterable included campaignId.

function setCookie(name, value, days) {
  const date = new Date(Date.now() + days * 864e5);
  document.cookie = `${name}=${encodeURIComponent(value)}; expires=${date.toUTCString()}; path=/; SameSite=Lax`;
}

(function ingestIterableParams() {
  const params = new URLSearchParams(location.search);
  const campaignId = params.get("campaignId");
  const templateId = params.get("templateId");

  if (campaignId) setCookie("iterableEmailCampaignId", campaignId, 1);
  if (templateId) setCookie("iterableTemplateId", templateId, 1);
})();

From the rest of the system’s perspective, nothing changed. Email continued using redirect-set cookies. SMS used explicit link parameters, which were normalized into the same attribution fields before the purchase event was created.

The Practical Takeaway

Iterable does not enforce a single attribution mechanism. Email-based projects can rely on redirect-time browser cookies. SMS requires that your purchase event include campaignId, typically propagated via link parameters.

If different channels rely on different attribution models, revenue reporting will diverge. The fix is not architectural. It is about making sure campaign context consistently reaches the purchase event in the format Iterable expects.