Is your digital marketing in shape? Book a free audit.

How I Added the ChatGPT Ads Pixel to Our Shopify Store in 15 Minutes

How I Added the ChatGPT Ads Pixel to Our Shopify Store in 15 Minutes

Erik Back |

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.