Sisällysluettelo
We recently started running ChatGPT Ads for our outdoor gear store Northpeak.store and needed conversion tracking set up before spending any real budget. I was expecting it to be a whole afternoon of GTM work. It took 15 minutes. Here's exactly what I did.
Step 1: Find your Pixel ID in OpenAI Ads Manager
Before touching Shopify, I logged into ads.openai.com and went to Tools → Conversions → Pixel. That's where the Pixel ID lives — a string that looks something like AbC123xYz456. I copied it and kept it open in a tab.
Step 2: Open Shopify Customer Events
In the Shopify admin for Northpeak.store I went to Settings → Customer events. I hadn't really used this section before — it's where Shopify lets you add third-party tracking pixels natively, without touching your theme or setting up GTM.
I clicked Add custom pixel, named it ChatGPT Ads Pixel, and before pasting any code I set the Customer Privacy settings:
- Permission: Required
- Categories: Marketing and Analytics
This matters. With Required selected, Shopify's own consent banner automatically blocks the pixel from firing until a visitor accepts cookies. No extra code needed — GDPR handled.
Step 3: Paste the pixel code
Then I pasted the pixel code into the editor. The key thing was replacing YOUR_PIXEL_ID with the actual ID from step 1. The rest of the code I left exactly as-is.
Show the pixel code I used ↓
// ── 1. Load OpenAI Pixel SDK ──────────────────────────────────────
(function (w, d, s, u) {
if (w.oaiq) return;
var q = function () { q.q.push(arguments); };
q.q = [];
w.oaiq = q;
var js = d.createElement(s);
js.async = true;
js.src = u;
var f = d.getElementsByTagName(s)[0];
f.parentNode.insertBefore(js, f);
})(window, document, "script", "https://bzrcdn.openai.com/sdk/oaiq.min.js");
oaiq("init", {
pixelId: "YOUR_PIXEL_ID",
});
// ── 2. Standard ecommerce events ─────────────────────────────────
analytics.subscribe("all_standard_events", (event) => {
switch (event.name) {
case "page_viewed":
oaiq("measure", "page_viewed", { type: "contents" });
break;
case "product_viewed":
var p = event.data && event.data.productVariant;
oaiq("measure", "contents_viewed", {
type: "contents",
contents: [{ id: p && p.sku || p && p.id, name: p && p.product && p.product.title, content_type: "product" }],
});
break;
case "product_added_to_cart":
var line = event.data && event.data.cartLine;
var m = line && line.merchandise;
oaiq("measure", "items_added", {
type: "contents",
amount: Math.round(((line && line.cost && line.cost.totalAmount && line.cost.totalAmount.amount) || 0) * 100),
currency: (line && line.cost && line.cost.totalAmount && line.cost.totalAmount.currencyCode) || "EUR",
contents: [{ id: m && m.sku || m && m.id, name: m && m.product && m.product.title, content_type: "product", quantity: (line && line.quantity) || 1 }],
});
break;
case "checkout_started":
var cs = event.data && event.data.checkout;
oaiq("measure", "checkout_started", {
type: "contents",
amount: Math.round(((cs && cs.totalPrice && cs.totalPrice.amount) || 0) * 100),
currency: (cs && cs.totalPrice && cs.totalPrice.currencyCode) || "EUR",
contents: ((cs && cs.lineItems) || []).map(function(i) {
return { id: (i && i.variant && i.variant.sku) || (i && i.variant && i.variant.id), name: i && i.title, content_type: "product", quantity: i && i.quantity };
}),
});
break;
case "checkout_completed":
var co = event.data && event.data.checkout;
oaiq("measure", "order_created", {
type: "contents",
amount: Math.round(((co && co.totalPrice && co.totalPrice.amount) || 0) * 100),
currency: (co && co.totalPrice && co.totalPrice.currencyCode) || "EUR",
contents: ((co && co.lineItems) || []).map(function(i) {
return { id: (i && i.variant && i.variant.sku) || (i && i.variant && i.variant.id), name: i && i.title, content_type: "product", quantity: i && i.quantity };
}),
});
break;
}
});
// ── 3. Form submissions ───────────────────────────────────────────
analytics.subscribe("form_submitted", (event) => {
var element = event.data.element;
var action = element.action || "";
var formId = element.id || "";
var keywords = ["contact", "newsletter", "email", "subscribe"];
var isLead = keywords.some(function(k) {
return action.includes(k) || formId.includes(k);
});
if (isLead) {
oaiq("measure", "lead_created", { type: "customer_action" });
} else {
oaiq("measure", "custom", { type: "custom" }, { custom_event_name: "form_submitted_other" });
}
});
// ── 4. Mailto and tel link clicks ─────────────────────────────────
analytics.subscribe("clicked", (event) => {
var href = event.data.element.href || "";
if (href.startsWith("mailto:")) {
oaiq("measure", "custom", { type: "custom" }, { custom_event_name: "mailto_click" });
} else if (href.startsWith("tel:")) {
oaiq("measure", "custom", { type: "custom" }, { custom_event_name: "tel_click" });
}
});
Hit Save. That's the installation done.
Step 4: Check what was actually firing
I opened Northpeak.store in an incognito window, pulled up the Network tab in Chrome DevTools, and filtered for bzrcdn. Within a few seconds of loading a product page I could see the pixel requests going out. Added something to cart — another request. Started checkout — another one.
Then I went back to OpenAI Ads Manager, opened Tools → Conversions → Event Stream, clicked Start Polling, and refreshed a few pages on the store. Events started appearing after about 10 minutes.
The code tracks eight events out of the box:
- page_viewed — every page load
- contents_viewed — product page views
- items_added — add to cart
- checkout_started — checkout opened
- order_created — purchase completed (this is the one that matters for campaign optimization)
- lead_created — contact or newsletter form submissions
- mailto_click and tel_click — link clicks (custom events, for reporting only)
Step 5: Set the right optimization event in the campaign
When I set up the first ChatGPT Ads campaign, OpenAI asked which conversion event to optimize for. I picked order_created — that's the purchase event, which is what I actually care about for an ecommerce store. If you're running a service business and collecting leads, pick lead_created instead.
One event per campaign. The others are tracked in the background and useful for understanding the funnel, but the algorithm only optimizes toward the one you choose.
What I learned
The whole thing was simpler than I expected. No GTM, no app install, no theme edits. Shopify's Customer Events system does exactly what you need here — and the built-in consent gate means you're compliant by default without writing any extra logic.
The only thing worth knowing before you start: test in incognito without an ad blocker. Privacy browsers like Brave will block the pixel by design, which looks like a broken installation but isn't.
If you're looking for help setting up ChatGPT Ads tracking or launching your first campaign, book a free consultation — we've done this across multiple Shopify stores now.