GPT Ads
ChatGPT Ads

How to set up ChatGPT Ads conversion tracking on Shopify

The full setup in seven steps, with the check to run at each stage and a troubleshooting table.

By 6 min read

A seven step path from storefront to target, the first steps completed

If you're running ads on ChatGPT and sending traffic to a Shopify store, you need conversion tracking before the spend tells you anything useful. Without it your ads manager knows people clicked and nothing about what happened next.

This is the whole setup, in order, with the checks I'd do at each stage. It assumes no developer.


Before you start#

You need two things:

A ChatGPT Ads account with a pixel created. Your pixel ID comes from the conversions section of Ads Manager. It looks like a short random string — something in the shape of 4UXjpdPV4FvZUs5fzGDqsA. Copy it now; you'll need it in step two.

Admin access to your Shopify store. Store owner or a staff account that can install apps.

If you also want server-side tracking — and by the end of this you probably will — you'll need an API key from the same conversions section. That one is a secret. It goes on a server, never in your storefront.


Step 1: Decide how you're installing it#

There are two routes and the difference matters more than it looks.

Using an app. You paste in your pixel ID and it handles the rest — mapping Shopify's storefront events onto ChatGPT's event names, formatting amounts correctly, carrying the click reference through checkout. This is what I'd recommend, and not only because I build one: the failure modes below are tedious to get right by hand.

Doing it yourself. Entirely possible. You'll write a Shopify web pixel extension, subscribe to storefront events, and construct the requests. Be aware that Shopify's strict pixel sandbox runs your code in a Web Worker with no DOM access, so the official ChatGPT Ads JavaScript SDK cannot load there. You'll be building the requests directly rather than calling oaiq(). That's a real constraint people discover late.


Step 2: Install and enter your pixel ID#

Whichever route you take, this is where the pixel ID from earlier goes.

If you're using an app, install it from the Shopify App Store, open it from your admin, and paste the ID into the setup field. Nothing fires until an ID is present — an app with no pixel ID configured is inert, which is by design but does mean "installed" and "working" are different states.


Step 3: Turn on the click reference bridge#

This is the step people skip, and it's the one that decides whether your conversions are attributed or anonymous.

When someone clicks your ad, ChatGPT appends a click identifier to your landing page URL:

https://yourstore.com/products/trail-shell?oppref=Cj0KCQiA-example

That oppref value has to survive the shopper browsing, adding to cart, and completing checkout, so it can be attached to the purchase event. If it doesn't arrive, ChatGPT sees a sale it cannot credit to your ad.

Most Shopify integrations carry it in two places at once — a first-party cookie, and something that travels into checkout. If your app has a theme extension or app embed that needs enabling in your theme editor, enable it now. Skipping it is the single most common reason a setup looks fine and attributes nothing.


Step 4: Verify events actually fire#

Don't take the setup screen's word for it. Walk your own funnel and watch.

Load a product page, add to cart, begin checkout, place a test order. You should see, in order:

ActionEvent
Page loadspage_viewed
Product viewedcontents_viewed
Added to cartitems_added
Checkout beginscheckout_started
Order placedorder_created

To see them, use a debugger rather than reading raw network requests. I built a free Chrome extension that opens beside your store and decodes each event as it fires. Anything that shows you the decoded payload will do.

Two things to check on order_created specifically:

The amount is a whole number in the smallest currency unit. A $129.99 order sends 12999, not 129.99 and not 129. If yours shows a decimal or looks a hundred times too small, stop and fix it — every ROAS figure you ever see depends on this.

A currency is present alongside the amount. An amount by itself is rejected.


Step 5: Test the click reference end to end#

Visit your own store with a fake reference on the URL:

https://yourstore.com/?oppref=TEST-12345

Browse, add to cart, complete an order. On order_created, look for oppref. If TEST-12345 is there, attribution works.

Then do it again through express checkout. Tap Shop Pay, Apple Pay or Google Pay directly from a product page, skipping the cart entirely.

This second test matters because express checkout never creates a cart, so anything your integration stored on the cart never reaches the order. A setup that passes the first test and fails the second will quietly lose attribution on exactly the traffic ads produce most of — mobile, decisive, straight from the ad.


Step 6: Add server-side purchases#

Browser events get lost. Ad blockers, Safari and Firefox privacy modes, closed tabs, dropped mobile connections — all silent, all unfixable from the browser.

Sending purchases from your server as well guarantees the one event your return calculation depends on arrives regardless. You'll need the API key from step zero and something that fires when an order is paid.

The thing to get right is deduplication. Both copies of the same purchase must carry the same event ID. ChatGPT matches on pixel ID, event name and that ID together, keeps whichever arrives first, and discards the rest. Get the IDs wrong and you'll count every purchase twice — which looks like a great result right up until you scale spend on a number that was never real.

Most setups also offer a validation mode that checks events without recording them. Send your first few through it.


If you serve the EU or UK, tracking must respect your consent banner.

One behaviour is worth knowing: events blocked by consent are not replayed. If a shopper accepts your banner at checkout, everything they did before that is gone, not queued. So a banner that appears late, or tracking that starts before your consent platform has reported the shopper's choice, loses events from people who actually said yes.

Also, the pixel remembers a stored denial. If you declined during earlier testing, your test browser will keep showing nothing — which looks exactly like a broken install. Clear it before you conclude anything.


When something isn't working#

SymptomUsual cause
No events at allNo pixel ID entered, or your own ad blocker
Events fire, purchases don'tOrder event not wired, or checkout not covered
Revenue looks ~100x too lowAmount sent in whole currency units, not minor units
Conversions counted but not attributedClick reference never reached the order
Conversions doubledBrowser and server events with different event IDs
Works on desktop, not mobileExpress checkout bypassing the cart

What "done" looks like#

You've finished when a test order produces one order_created event carrying the correct amount in minor units, the right currency, the click reference from your landing URL, and — if you've enabled server-side — a matching event ID on both copies.

At that point the numbers in your ads manager mean something, and you can start making decisions from them. Which was the point.


I build LLM Pixels, a Shopify app that handles all of the above. The Chrome extension for verifying any of it is free and works on any store.