Fix guide · Shopify · advanced · about 60 min
OpenAI Pixel events have no event ID on Shopify
For the finding “OpenAI events have no event ID”. Also for: Any website, WordPress, Webflow, Framer.
What this means
Each event the OpenAI Pixel (the ChatGPT Ads Measurement Pixel) sends can carry an event ID that your store sets: the event_id option in the fourth argument of oaiq("measure", ...). Your store calls measure without one. The requests still contain an ID, because the pixel then makes up a random one in the browser (OpenAI does not document this, but you can see it in the request payload), but your server never learns that value.
Whether this costs you money depends on whether your store also sends events to OpenAI from a server through the OpenAI Conversions API:
- Yes, or you are not sure: OpenAI treats a browser event and a server event as the same conversion when they share the Pixel ID, the event name and the event ID (
event_idin the pixel,idin the Conversions API). With a random browser ID, the two never match, so the same order can be counted twice. - No, browser pixel only: there is nothing to deduplicate yet, so this has little effect today. It matters the day you add the Conversions API.
We cannot see server-to-server traffic from a browser, so we cannot tell whether your Conversions API works. We only see whether your store passes its own event IDs to the pixel.
On Shopify, Conversions API events usually come from a third-party ChatGPT Ads app (OpenAI does not make a Shopify app) or from your own server. Shopify gives you good ID candidates for free: every customer event has an id, and the checkout_completed event includes the order ID and the checkout token.
How to confirm it yourself
The Network tab cannot tell you whether your store sets an ID, because the pixel fills one in by itself. Look at the code that calls the pixel instead.
-
Custom pixels: under Settings > Customer events, open each custom pixel and search its code for
oaiq("measure"(oroaiq('measure'). Each call should have a fourth argument withevent_id:// No event ID: the pixel makes one up oaiq("measure", "order_created", { type: "contents", amount: 2599, currency: "USD" }); // Your own event ID oaiq("measure", "order_created", { type: "contents", amount: 2599, currency: "USD" }, { event_id: "1234567890" }); -
Theme code: search
theme.liquidand its snippets (Online Store > theme menu > Edit code) foroaiq(in the same way. -
Google Tag Manager: open the OpenAI tag. In OpenAI’s own GTM template, the Event ID field is described as an optional deduplication ID to leave blank unless another system sends the same conversion server-side; if your server does, it must be filled. In Stape’s OpenAI Ads Pixel template, the ID goes in the Server-side tracking settings section.
-
A ChatGPT Ads app: check its documentation for how it sets event IDs. An app can only give matching IDs to the browser events it sends itself, not to a copy of the pixel you installed separately.
-
Compare one conversion. Place a test order (Shopify’s test payment gateway or Shopify Payments’ test mode). With the Network tab filtered by
bzr.openai.com, find theorder_createdevent and note itsid. Compare it with theidyour server or app sends for the same order. If they differ, deduplication fails.
How to fix
OpenAI deduplicates a browser event and a server event when both use the same Pixel ID, the same event name (for custom events, the same custom_event_name) and the same event ID. It keeps the first event it receives with that combination and ignores later ones. On Shopify you have three realistic routes.
Route 1: one app does both sides. If a ChatGPT Ads app sends your Conversions API events, let the same app send the browser events. Then remove every other copy of the pixel: the snippet in theme.liquid, custom pixels under Settings > Customer events, OpenAI tags in GTM and app embeds that add a pixel. Otherwise those copies keep sending events with random IDs, and every event is also sent twice (see “Duplicate OpenAI events”). Run the comparison in step 5 above to confirm the app’s IDs match.
Route 2: a custom pixel plus your own server events (developer). Purchases are the key case. Theme code does not run on checkout pages, and Shopify has retired Additional scripts and script tags on the Thank you and Order status pages, so order_created belongs in a custom pixel that subscribes to Shopify’s checkout_completed event. Use the order ID, which your server also knows, as the event ID:
analytics.subscribe("checkout_completed", (event) => {
const checkout = event.data.checkout;
const currency = checkout.currencyCode;
// Shopify gives the total as a decimal (25.99); OpenAI wants an integer
// in the currency's minor unit: 2599 for USD 25.99. JPY has no minor
// unit, so JPY 2599 stays 2599. Check the result for your currencies.
const digits = new Intl.NumberFormat("en", { style: "currency", currency })
.resolvedOptions().maximumFractionDigits;
oaiq(
"measure",
"order_created",
{
type: "contents",
amount: Math.round(checkout.totalPrice.amount * 10 ** digits),
currency: currency,
},
// Order ID, or the checkout token when Shopify gives no order.
// Must be exactly the value your server sends as id for this order.
{ event_id: checkout.order?.id || checkout.token }
);
});
Shopify types checkout.order as Order | null. Without the fallback, an event with no order ID would get the pixel’s random ID. Your server then sends order_created to the Conversions API with the same Pixel ID and the same value as id, chosen by the same rule. If your server cannot tell which value the browser used, or works with the checkout token anyway, use checkout.token on both sides. Compare the two values from a test order character by character: the same order ID written in two formats (for example a plain number on one side and a longer ID string on the other) does not match.
The server event must also carry oppref, captured on the storefront. The Conversions API does not capture it by itself, and a pasted OpenAI snippet in a custom pixel may never see oppref or may not keep the __oppref cookie. See ChatGPT Ads click ID lost on Shopify.
For other events, pass Shopify’s customer event ID: { event_id: event.id }. Your server can only reuse that value if the browser sends it along, so for most stores the order is the event worth matching.
Two more rules from OpenAI apply here: amount and quantity must be whole numbers, and an event ID must never be a fixed value. OpenAI keeps only the first event with a given ID, so a repeated ID silently drops real orders.
Route 3: Google Tag Manager with a server container. Shopify recommends running GTM as a custom pixel. Push Shopify’s event.id, or the order ID for purchases, into the data layer together with each event, and use that value in the web tag’s event ID field. Map the same value to the event ID in the server tag (Stape’s OpenAI Ads Events API tag has an Event ID parameter for this).
Common causes
- The pixel was pasted into
theme.liquidor a custom pixel with OpenAI’s example calls, which have no fourth argument. - The Conversions API was added later through an app or your own server, but browser events still come from another copy of the pixel.
- Both sides generate their own ID, so each event has one, but they never match.
- The order ID is written in different formats in the browser and on the server.
- In GTM, the event ID field of the web tag is empty, or the server tag reads a different variable.
How to verify the fix
- Every
oaiq("measure", ...)call for your key events passes anevent_id, and the value changes from one order or action to the next. - For one test order, the
idoforder_createdin the browser request equals theidyour server sends. - With access to OpenAI’s Advertiser API, the recent-events endpoint described in the general guide lists browser events with the channel
pixel_sdkand server events withserver_to_server. - Re-run the check on IsPixelWorking. The issue should be gone.
Sources
- OpenAI Developers, Measurement Pixel (
measurearguments;event_idoption; deduplication on Pixel ID, event name andevent_id; first event wins; integeramountandquantity): https://developers.openai.com/ads/measurement-pixel - OpenAI Developers, Supported Events (amounts as integers in the currency’s minor unit): https://developers.openai.com/ads/supported-events
- OpenAI Developers, Conversions API (event
id; deduplication on Pixel ID, event name andid): https://developers.openai.com/ads/conversions-api - OpenAI Developers, Conversion Tracking (same Pixel ID, event name and event ID through both integrations; Monitoring Events): https://developers.openai.com/ads/conversion-tracking
- OpenAI on GitHub, Ads Measurement Pixel GTM template (Event ID field): https://github.com/openai/ads-measurement-pixel-gtm-template
- Stape, OpenAI Ads Pixel tag (third-party template; Server-side tracking settings): https://stape.io/helpdesk/documentation/openai-ads-pixel-tag
- Stape, OpenAI Ads Events API tag (third-party template; Event ID parameter): https://stape.io/helpdesk/documentation/openai-ads-events-api-tag
- Shopify.dev,
checkout_completedevent (order ID, withordertyped asOrder | null, checkout token,totalPriceas a decimal amount,currencyCode; every customer event has anid): https://shopify.dev/docs/api/web-pixels-api/standard-events/checkout_completed - Shopify.dev, Layouts (
theme.liquidapplies to non-checkout pages): https://shopify.dev/docs/storefronts/themes/architecture/layouts - Shopify.dev, checkout.liquid (additional scripts and script tags sunset on the Thank you and Order status pages): https://shopify.dev/docs/storefronts/themes/architecture/layouts/checkout-liquid
- Shopify Help Center, Create custom pixel code: https://help.shopify.com/en/manual/promoting-marketing/pixels/custom-pixels/code
- Shopify Help Center, Google Tag Manager (use GTM through a custom pixel): https://help.shopify.com/en/manual/reports-and-analytics/google-analytics/google-tag-manager
- Shopify Help Center, Placing a test order: https://help.shopify.com/en/manual/checkout-settings/test-orders
More OpenAI guides
- OpenAI Pixel fires before cookie consent on Shopify
- OpenAI Pixel not firing after cookie consent on Shopify
- Repeated OpenAI event IDs drop ChatGPT Ads conversions
- Duplicate OpenAI Pixel events on Shopify
- ChatGPT Ads click ID (oppref) lost on Shopify
- OpenAI Pixel tracks a button on desktop but not on mobile
- Two OpenAI Pixel IDs on one site: when it's fine, how to fix
- OpenAI Conversions API deduplication: match the pixel event_id
- OpenAI Ads Pixel setup: install the ChatGPT Measurement Pixel
- How to set up the OpenAI Conversions API for ChatGPT Ads