ChatGPT Ads is new enough that the conversion tracking setup isn't yet routine. This walks through the whole thing in Google Tag Manager: one Custom HTML tag to load the OpenAI pixel on Initialization, a second to fire the conversion event on a trigger that actually proves the action happened, and two independent checks to confirm it works — including the firing-order trap that breaks the setup without reporting an error.
TL;DR
-
ChatGPT Ads conversion tracking connects entirely through Google Tag Manager. No code gets added to the website itself.
-
One Custom HTML tag loads the OpenAI pixel on every page, using an Initialization trigger so it's always ready first.
-
A second Custom HTML tag fires the actual conversion event when a real action happens, such as a form submission, using whatever trigger reliably proves that action occurred (a thank-you page view works well when the form redirects on success).
-
If your conversion isn't a form submission, swap in whatever trigger already proves that action happened. The same two-tag structure applies.
-
The setup gets verified twice: once in GTM's Preview mode, and once in Ads Manager's own Event Stream, where the event should appear within seconds of a real test.
The Setup in 7 Steps
- In ChatGPT Ads Manager, create a Data Source and copy its Pixel ID and setup script.
- Create a conversion event in Ads Manager and copy its
measure()call. - In GTM, create a Custom HTML tag with the setup script, triggered on Initialization - All Pages.
- Create a second Custom HTML tag with the
measure()call, triggered by whatever proves the conversion happened (a thank-you page view, a click, a purchase). - Publish the GTM container.
- Test in GTM Preview and confirm the Data Source tag fires before the conversion tag.
- Trigger a real conversion and confirm it appears in Ads Manager's Event Stream.
This guide assumes a ChatGPT Ads campaign is already running and covers connecting it to Google Tag Manager (GTM) for conversion tracking, using OpenAI's browser pixel.
OpenAI offers two ways to send conversions: a browser pixel and a server-side Conversions API (CAPI). This guide covers the pixel method through GTM only. CAPI is a separate, backend integration path, not built here (see FAQ for when it's worth adding).
Why Use Google Tag Manager for ChatGPT Ads Conversion Tracking?
GTM centralizes conversion tracking in one place, which matters once ChatGPT Ads isn't the only platform being tracked. If GA4, Google Ads conversions, LinkedIn Ads, or a Meta pixel already run through the same GTM container, adding ChatGPT Ads there keeps everything in one interface, with one Preview mode for debugging, and one place to update tags without a developer or a site deployment.
Triggers get reused instead of rebuilt. In the container below, the same Thank You Page trigger fires the ChatGPT Ads tag, a GA4 event tag, and two Google Ads conversion tags.
For a single, standalone pixel with nothing else to track, pasting OpenAI's script directly into the site's HTML head also works. GTM's advantage shows up once more than one tracking system needs managing from the same place.
Should You Use the Official OpenAI GTM Template Instead of Custom HTML?
Optional, but worth knowing before you start. OpenAI now publishes an official GTM template (openai/ads-measurement-pixel-gtm-template on GitHub, Apache 2.0), and community templates from Stape and TensorOps are also live in the Community Template Gallery. All three configure the pixel and each conversion event through form fields instead of Custom HTML.
With OpenAI's own template, the two-tag structure this guide teaches becomes optional: each event tag initializes the pixel itself, so a separate Data Source tag isn't required. The template's own documentation treats an Initialization trigger and a plain All Pages trigger as interchangeable for that reason, since every tag carries its own initialization.
This guide still builds it in Custom HTML, because the mechanism carries over: understanding how the pixel initializes, how GTM's trigger order works, and how deduplication works is what lets you debug any implementation, template-based or not, when something silently breaks. If you'd rather not maintain HTML directly, install the official template and configure it from Ads Manager's event definitions instead.
What Do You Need Before Setting This Up?
Three things: access to ChatGPT Ads Manager, edit access to the GTM container already installed on the site, and a defined conversion action. This guide uses a form submission that redirects to a thank-you page as the example, but the same steps apply to a phone click, a purchase, or any other action, just swap in whatever trigger proves that action happened.
Also confirm the ad account has passed OpenAI's Brand Review before testing. A missing account favicon is a common reason that review stalls, and conversions won't register until it clears.
What Is a Data Source in ChatGPT Ads Manager?
A data source is the connection between a website and a ChatGPT Ads account that the pixel reports through. It's set up once per site, before anything else in this guide.
In Ads Manager, go to Tools → Conversions, then open the Data Source tab.
Create a data source if none exists. If one already exists, open it and copy the Pixel ID (a unique string identifying the site) and the setup code (a script that initializes the pixel).
The setup script looks like this, with your own Pixel ID in place of the placeholder:
<script>
(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>" });
</script>
oaiq is the global JavaScript function name the pixel uses for every call, both this initialization and every conversion event that follows. The inline part runs immediately and defines it as a command queue, so calls made before the SDK finishes downloading still get queued and replayed in order, not lost.
For better match quality, pass hashed customer data (email, phone, and similar) in this same init call, or leave it to OpenAI's automatic advanced matching, which detects and hashes supported fields on your site without any code changes. Ads Manager's own instructions say to paste this code into the site's HTML head. This guide pastes it into a GTM tag instead, covered below.
How Do You Create a Conversion Event in ChatGPT Ads Manager?
Go to Conversions → Conversion Events → Create → Conversion Event, then set the data source, a base event, a conversion name, and an attribution window.
The base event is an internal action name, such as appointment_scheduled or order_created. The conversion name is what appears in reporting. In this build, the base event is appointment_scheduled, shown in reporting as "Meeting Scheduled."
After creating the event, open it again and copy its Pixel event call, the code that reports the conversion:
oaiq(
"measure",
"appointment_scheduled",
{ type: "customer_action" }
);
This call reports that a customer completed the appointment_scheduled action. Copy it as given; it gets pasted into GTM next.
If your event carries a value instead, a purchase amount or a deal size, send it as a whole integer in minor currency units: 2599 for $25.99, not a decimal. A malformed amount fails silently rather than throwing an error.
How Do You Add the OpenAI Ads Measurement Pixel to GTM?
Create a Custom HTML tag containing the pixel setup code, triggered on Initialization - All Pages so it loads before any other tag can reference it.
Create a new tag and name it clearly, for example "ChatGPT Ads Manager | Data Source."
Set the tag type to Custom HTML.
Paste in the setup script copied from Ads Manager, with the Pixel ID already in it.
Set the trigger to Initialization - All Pages, not a standard Page View / All Pages trigger.
Initialization triggers fire before every other trigger type GTM supports, which guarantees this tag has executed, and oaiq defined, before any conversion tag can call it. A standard Page View trigger usually works too, but GTM doesn't guarantee which of two same-type tags executes first, and that gap is enough to leave oaiq undefined when the conversion tag fires, silently dropping the call.
How Do You Create the ChatGPT Ads Conversion Tag in GTM?
Create a second Custom HTML tag containing the pixel event call, triggered by whatever signal most reliably proves the conversion happened, typically a page view on the confirmation URL rather than GTM's built-in Form Submission trigger.
Create a second tag (here, "ChatGPT Ads | Form Submit"), set it to Custom HTML, and paste in the Pixel event call copied earlier.
GTM's built-in Form Submission trigger doesn't reliably fire for JavaScript-based forms or forms that intercept the native submit event, which covers a lot of modern form builders. A Page View trigger scoped to the thank-you or confirmation URL is more reliable, since it depends only on the visitor reaching that page, not on how the form itself was built. Here, the trigger ("Thank You Page") fires when the page path contains "thank-you."
For a conversion that isn't a form submission (a phone click, a WhatsApp click, a purchase), use whichever trigger already tracks that action elsewhere in the container, or build a new one using the same logic: fire on the most reliable signal that the action occurred.
A single trigger can fire multiple tags. In this account, "Thank You Page" also fires the GA4 event tag and two Google Ads conversion tags.
Why Must the Data Source Tag Use an Initialization Trigger?
Because the setup script defines oaiq as a command queue the instant the tag executes, not after the SDK finishes downloading. Calls made while the SDK is still loading get queued and replayed automatically once it's ready, the same pattern Meta's fbq and Google's gtag use. What actually breaks things is the Custom HTML tag not having run at all yet: call oaiq() before any tag has defined it, and the browser throws an error instead of queuing anything.
That's the real reason the Data Source tag needs an Initialization trigger rather than a regular Page View trigger. GTM guarantees Initialization triggers fire before Page View triggers, but doesn't guarantee execution order between two tags sharing the same trigger type, tag firing priority only affects which one starts first, not which one completes first. If the Data Source tag used a Page View trigger like most conversion tags, GTM wouldn't guarantee it runs first, and a conversion tag could execute before oaiq exists at all.
Initialization - All Pages avoids this by design: it's documented to fire before every trigger type except Consent Initialization, so the Data Source tag has always executed, and oaiq is always defined, before any Page View-based conversion tag can call it.
How Do You Test ChatGPT Ads Conversion Tracking in GTM?
Three checks: GTM Preview mode to confirm tag firing order, browser console logging to confirm the pixel itself is behaving, and Ads Manager's Event Stream to confirm the conversion is actually recorded.
In Preview mode, complete the conversion action as a real visitor would and confirm the Data Source tag fires before the conversion tag.
Add debug: true to the init call while testing, OpenAI's own recommended troubleshooting flag. It logs the pixel's activity to the browser console, which catches problems Preview mode can't see, like a blocked network request.
In Ads Manager, go to Conversions → Event Stream after a real test. A working setup shows the event within seconds, with the API channel listed as pixel_sdk.
What Does the Full Setup Look Like?
A data source and conversion event configured in Ads Manager, a Data Source tag that loads the pixel on Initialization, a conversion tag scoped to the actual conversion signal, and two checks (GTM Preview and Event Stream) to confirm it works. None of it touches the website's code directly.
What Doesn't This Guide Cover?
This guide covers pixel-based tracking through GTM only. It doesn't cover:
- Setting up the ChatGPT Ads campaign itself: targeting, context hints, ad creative, or bidding.
- The server-side Conversions API (CAPI): a separate, backend-only path for sending the same events, mentioned in the FAQ below but not built here.
- Server-side GTM: a more advanced container setup than the standard web GTM container used throughout this guide.
- Mobile app conversion tracking: the Measurement Pixel doesn't support
app_installedorapp_openedat all. Those go through the Conversions API server-side, withaction_sourceset tomobile_app, a separate integration from anything in this guide. - How Google Analytics attributes ChatGPT-referred traffic: a separate, GA4-side question from whether the conversion event itself fires correctly in Ads Manager.
- OpenAI's full account and Brand Review process: flagged earlier as something to check, not walked through step by step.
Frequently Asked Questions
- Do you need to add any code to your website for this to work?
- No. Assuming GTM is already installed on the site, both tags in this setup are Custom HTML tags built inside GTM itself. Nothing gets added to the site's template, header, or codebase, and updating either tag later needs no developer or deployment.
- What if the conversion isn't a form submission?
- The approach still applies. Swap the Thank You Page trigger for whatever GTM trigger already proves the actual conversion happened, a phone click, a WhatsApp click, a completed purchase, or a custom event the site already fires. The two-tag structure and the Initialization-first firing order stay the same regardless.
- Why isn't a conversion showing up in Ads Manager, even though GTM Preview shows the tag firing?
- The two most common reasons are a firing-order problem (the Data Source tag hasn't executed yet, so oaiq isn't defined when the conversion tag fires) and a mismatch between the event name sent by the tag and the base event selected in Ads Manager. Checking Event Stream after a real test, not just GTM Preview, catches this. There's also plain reporting lag: since ChatGPT Ads is still a new platform, give it time before assuming the setup itself is broken.
- Could a Content Security Policy block the pixel?
- Yes, and silently. A CSP that doesn't allow OpenAI's domains blocks the pixel's own network calls with no visible error, GTM Preview still shows the Custom HTML tag firing, since GTM itself isn't what's blocked. If your site enforces a CSP, add script-src https://bzrcdn.openai.com, connect-src https://bzr.openai.com and https://bzrcdn.openai.com, and img-src https://bzr.openai.com to the existing policy.
- Does the pixel respect cookie consent?
- Yes, but only if you wire it up. The pixel sends events by default. To gate it, call oaiq("consent", false) before init and oaiq("consent", true) once the user grants consent. Events blocked by a false consent state aren't queued for later, they're simply not sent, so consent has to be set before init runs, not after.
- Can one Data Source tag support more than one conversion event?
- Yes. The Data Source tag only loads the pixel and isn't tied to a specific conversion. Each conversion, a form submission, a purchase, a phone click, gets its own tag and trigger, all reporting through the same pixel.
- Is the pixel enough, or do you also need the Conversions API?
- For most setups, the pixel alone is enough, which is what this guide covers. The Conversions API is a separate, server-side option for sending the same events more reliably, useful once ad blockers or browser restrictions start meaningfully affecting pixel data, but it isn't required to get started.
- Are view-through conversions included in the Conversions number in Ads Manager?
- No. A view-through conversion, someone who saw the ad but didn't click, then converted within a fixed one-day window, reports as a separate, campaign-level metric. The Conversions total, along with CPA, conversion rate, and bidding, stays click-through only. If your numbers don't reconcile against another source, this is a likely reason, not necessarily a tracking bug.
- Won't reloading or revisiting the thank-you page double-count the conversion? Isn't there a setting to just count it once?
- GTM does have a related setting: set the tag's Advanced Settings → Tag firing options to Once per page instead of Unlimited. Worth doing regardless, but it doesn't fix this specific problem, since a browser refresh is a new page load to GTM and resets that counter. OpenAI's click reference (oppref, stored in a first-party cookie) exists for ad credit, not for catching repeats, so it won't stop a duplicate either. The documented fix is event_id: reuse the same value across duplicate measure() calls, and OpenAI ignores the repeats, matching on Pixel ID, event name, and event_id. That mechanism is documented for deduplicating a browser event against a server-side one, not a browser-only reload, and there's no published time window for how long a match is honored, so treat this as a reasonable extension of a documented behavior, not a guarantee. The harder part is practical: reusing an event_id across a reload needs a stable value the thank-you page actually exposes, a booking reference, an order ID, pulled from a URL parameter, the dataLayer, or the page itself. A generic form-to-thank-you-page redirect, like this guide's own example, often has nothing like that. Without a stable identifier to reuse, dedupe downstream in the CRM instead.
- Do you have to hand-write the Custom HTML tags shown here, or is there a proper GTM template now?
- No, not anymore. OpenAI publishes an official GTM template, and Stape and TensorOps each publish their own, all live in the Community Template Gallery. Any of them configures the pixel and each conversion event through form fields, no Custom HTML required. See "Should You Use the Official GTM Template Instead of Custom HTML?" above for why this guide still teaches the hand-written version and when to reach for a template instead.
Further Reading
Official OpenAI documentation:
- OpenAI Help Center: Conversion Measurement
Formatting guidance and hashing requirements for higher-quality conversion signals. - OpenAI Help Center: Measure Results
How results and conversions surface inside Ads Manager reporting. - OpenAI Developers: Ads Documentation Hub
The full technical reference for the pixel, the Conversions API, and supported events. - OpenAI Developers: Measurement Pixel
The pixel's technical specification, including the oppref click reference and the event_id deduplication behavior referenced above. - OpenAI Developers: Conversions API
The server-side alternative to the pixel, for teams ready to go beyond browser-only tracking. - OpenAI: Ads Measurement Pixel GTM Template (GitHub)
The official, no-code GTM template referenced above, with install instructions included. - OpenAI Help Center: Troubleshooting Common Issues
Covers Brand Review failures, including the missing-favicon block mentioned above.
From the Nexara blog:
- Our Analytics Was Missing 60% of Ad Clicks
A real account of a GTM container loading too late, causing ad clicks to go unrecorded, the same firing-order problem this guide works around. - The Purpose of Analytics
Why tracking more doesn't automatically lead to better decisions, and what tracking should actually be built to answer. - ChatGPT Ads Management at Nexara
How we approach ChatGPT Ads strategy and measurement for clients, beyond just the tracking setup. - Marketing Analytics & Tracking at Nexara
Our broader approach to fixing tracking across GA4, GTM, and CRM integrations.
Other resources:
- Stape: ChatGPT Ads Tracking Configuration Guide
A practical walkthrough of the pixel and Conversions API from a GTM tooling vendor. - PPC Land: GTM Template Fills the Gap Left by OpenAI's Ads Pixel Launch
Coverage of the first community GTM template; OpenAI's own template and Stape's have since followed.