Data and consent
A developer-facing summary of what the AB Test storefront runtime reads and writes, the anonymous visitor id it works with, and the opt-out signal that stops tracking when a shopper declines.
What the runtime handles
The AB Test app embed adds a small runtime to your storefront. On the data side it does three things: it holds an anonymous id for the current visitor, it reports a few tracked events through the Web Pixel, and it carries that id onto the cart so a purchase can be credited to the right variant. Everything it works with is pseudonymous — there is no customer name, email, phone, or address anywhere in this path.
This page describes those data flows so you can reason about them when you build a JavaScript API test or integrate the runtime with your own consent tooling. For the merchant-facing summary, see the privacy documentation.
Nothing here runs until the app embed is enabled. Enable AB Test under Online Store > Themes > Customize > App embeds and keep the Web Pixel on. See the API reference overview.
The anonymous visitor id (_ab_vid)
When a visitor is assigned to a variant, the runtime issues a random, anonymous visitor id and stores it in a first-party cookie named _ab_vid. This id is the only handle the app keeps for a visitor. It exists to do two things:
- Keep assignment stable. The same
_ab_vidmaps to the same variant for the rest of the visit, so repeated calls towindow.abtest.isHypothesisActive()return a consistent answer. - Attribute revenue. The runtime stamps
_ab_vidas a Shopify cart attribute so it can be matched back to a variant when the order is created.
The id is not linked to a Shopify customer record, an account, or any contact detail. It is a random token that only means something inside AB Test.
Carrying the id to the order
The storefront Web Pixel can only see conversions that complete on the storefront. Shop Pay on a separate host, and India's order-creating third-party checkouts (Razorpay Magic, GoKwik, Shopflo, Shiprocket/Fastrr), bypass it. To capture those sales the runtime writes the visitor id onto the cart:
- For a visitor who is actually in a test, the runtime checks the cart's real attributes with a small
GET /cart.js. - If
_ab_vidis missing, it posts the attribute withPOST /cart/update.js. - Shopify copies cart attributes onto the order's
note_attributes, so_ab_vidrides to the order. - An
orders/createwebhook reads it back and resolves the variant server-side.
Full detail on the attribution path is in Revenue attribution.
The cart is only stamped for visitors who are in a running test, and only when the attribute is not already present — so the runtime does not touch carts for untested traffic.
What events are captured
Tracking is delivered by the Web Pixel, which subscribes to a small set of standard storefront events and forwards only those tied to a running experiment. In practice this covers:
- Page views — so a tested visit is counted against the variant the visitor was assigned.
- Conversions — the checkout completion that records a result and, with the order total, feeds revenue.
Each forwarded event carries the anonymous _ab_vid and the assignment it belongs to. An event that cannot be attributed to any experiment is dropped, so event volume stays proportional to tested traffic rather than to all storefront activity.
What the orders webhook reads
Revenue attribution reads a deliberately small slice of each order. From an incoming order the orders/create webhook reads only:
| Field | Why it is read |
|---|---|
id | Identify the order and de-duplicate it against the pixel-reported conversion. |
total | Book the sale amount to the assigned variant. |
currency | Record the amount in the correct currency. |
note_attributes._ab_vid | The anonymous visitor id the runtime stamped earlier — resolves the variant. |
That is the complete set. The webhook never reads a customer's name, email, phone number, or address, and the app stores no customer profile. The only visitor value it looks at is the same anonymous token it wrote to the cart, so reading it back exposes no personal information.
Because it touches only order id, total, currency, and its own note attribute, this stays within Shopify's Protected Customer Data Level 1 — the tier that involves no personally identifiable information. Webhooks are HMAC-verified and served over TLS.
The consent signal (_ab_consent)
Consent is represented by a single cookie, _ab_consent, with two values:
| Value | Meaning |
|---|---|
"1" | Analytics consent granted — the runtime tracks normally. |
"0" | Opted out — the runtime suppresses tracking and stamping. |
The model is opt-out: tracking runs by default, and the moment the signal reads "0" the runtime stops. Concretely, when a shopper has declined:
- the Web Pixel suppresses events for that visitor,
- the runtime does not ride
_ab_vidonto the cart, so theorders/createwebhook cannot attribute a declined shopper, and - no result is recorded for that visitor in any experiment.
The revenue path honours the same signal as the pixel. If _ab_consent is "0" — or a consent manager has not confirmed a choice yet — the cart is not stamped, so a declined or undecided shopper is never attributed.
Where the consent decision comes from
You do not set _ab_consent by hand in the common case. The runtime derives it automatically from whatever consent mechanism your store already uses:
- Shopify Customer Privacy API. The runtime reflects
window.Shopify.customerPrivacy.analyticsProcessingAllowed()and re-syncs when the shopper changes their choice, so an accept after an initial "not yet decided" is picked up. - OneTrust. Auto-detected. The runtime bridges the Performance/analytics group to the consent signal and follows consent changes — no merchant wiring.
- Cookiebot. Auto-detected. The statistics category is treated as analytics consent, with accept and decline events honoured.
When a third-party consent manager is present it drives the signal and the Shopify-native sync stands down, so the two never conflict.
Setting consent from your own code
If you run a custom consent solution that AB Test does not auto-detect, you can record the decision directly. Call this once the visitor's analytics choice is known:
<script>
window.abtest = window.abtest || {};
(window.abtest.q = window.abtest.q || []).push(function () {
// true -> consent granted, tracking continues
// false -> opt-out, tracking and stamping stop
window.abtest.setAnalyticsConsent(shopperAllowedAnalytics);
});
</script>
Passing false writes _ab_consent="0" and the runtime suppresses tracking exactly as it does for a Customer Privacy or CMP opt-out.
If your store already uses Shopify's consent banner, OneTrust, or Cookiebot, you do not need this call — keep that banner enabled and the runtime reads its decision automatically.
Retention
Visitor and event data is kept only as long as it is useful for reporting — roughly 180 days — after which it is purged. Uninstalling the app triggers Shopify's app-uninstalled and shop-redact webhooks, which remove your store's data on AB Test's side. The mandatory customers/data_request, customers/redact, and shop/redact webhooks are implemented so shopper data requests and deletions flow through Shopify's standard process.
Related pages
- Privacy and consent — the merchant-facing summary of everything on this page.
- Assignment endpoint — the request that assigns a visitor and issues the id.
- Revenue attribution — how
_ab_vidcredits a sale to a variant. window.abtestAPI — the methods available to your code, includingsetAnalyticsConsent().- AB Test privacy policy — the full policy, with yadav.creators@gmail.com for questions.