How to Install the OpenAI Ads Measurement Pixel (Step-by-Step)
The OpenAI Ads measurement pixel goes in the
<head>of every page on your site, as close to the top as possible. Before you write a line of code, get a Pixel ID from the conversions tab in Ads Manager — that ID is the only thing that connects your site's traffic to your ad account. Once the pixel loads on every page, it automatically captures theopprefclick reference from the landing URL and starts a roughly 30-day attribution window.
This guide covers the direct code install, the Google Tag Manager install, the Content Security Policy changes most sites need, and how to confirm the pixel actually fired before you trust any data it sends. If you haven't set up tracking for OpenAI Ads before, read the complete guide to ChatGPT Ads tracking first — it explains how the pixel, the Conversions API, and event data fit together. This post is the hands-on version: get the snippet live, correctly, on every page.
Prerequisites
Before you touch code, confirm you have:
- Admin access to Ads Manager for the OpenAI Ads account running your campaigns, or someone who can grant it.
- A way to edit your site's
<head>— either direct access to your template/theme files, or a Google Tag Manager container already installed. - Knowledge of your CSP setup, if your site enforces a Content Security Policy. This trips up more installs than any other step, so flag it now rather than after the pixel silently fails.
- A staging or preview environment, if you have one, so you can verify the pixel before it goes live to real traffic.
None of this requires a developer for a single-page site, but if your CSP is locked down or your CMS restricts head edits, loop in whoever owns that config before you start.
Step 1: Get your Pixel ID
The Pixel ID is created in the conversions tab of Ads Manager. It's a unique identifier for your ad account's pixel — every oaiq("init", ...) call on your site needs it, and every event that pixel sends gets tagged with it.
- Log in to OpenAI Ads Manager.
- Go to the conversions section.
- Create (or open) your pixel and copy the Pixel ID.
Treat this ID like a public identifier, not a secret — it's visible in your page source the moment the pixel loads. Full setup details live in the OpenAI Ads developer docs and the measurement pixel reference.
Step 2: Direct code install
If you can edit your site's template or <head> partial directly, this is the fastest path. Add the loader script and the init call together, near the top of <head>, on every page:
<head>
<script async src="https://bzrcdn.openai.com/sdk/oaiq.min.js"></script>
<script>
window.oaiq = window.oaiq || function () {
(window.oaiq.q = window.oaiq.q || []).push(arguments);
};
oaiq("init", { pixelId: "YOUR-PIXEL-ID" });
</script>
</head>
Replace YOUR-PIXEL-ID with the ID from Step 1. A few things worth understanding about this snippet:
- The
asyncattribute means the script loads without blocking page render — there's no reason to defer it further or move it to the bottom of the page. In fact, doing so delaysopprefcapture on paid traffic. - The queue pattern (
window.oaiq = window.oaiq || function...) lets you calloaiq("measure", ...)anywhere on the page immediately, even beforeoaiq.min.jshas finished downloading. Calls queue up and fire once the SDK loads. - You can pass
debug: truein the init object while you're testing:
oaiq("init", { pixelId: "YOUR-PIXEL-ID", debug: true });
With debug: true, the SDK logs its activity to the browser console, which makes the verification step below much faster. Turn it off (or leave it out) once you've confirmed everything works — you don't want debug logging running for real visitors.
- If you want better event matching, you can also pass a
userobject inside theinitcall (not inside individualmeasurecalls). Check the measurement pixel reference for the exact shape it expects before adding it.
Once this snippet is in your <head> partial and deployed to every page — not just the homepage or landing pages — move to verification.
Step 3: Install via Google Tag Manager
If your site runs on GTM, you don't need to touch template code. The pixel goes in a Custom HTML tag that fires on All Pages.
- In GTM, create a new tag and choose Custom HTML.
- Paste the same loader and init snippet from Step 2 into the HTML box.
- Set the trigger to All Pages — not a subset, not just checkout or landing pages.
- Name the tag something identifiable, like "OpenAI Ads Pixel — Base," and publish the container.
Why "All Pages" matters more than it looks like it should: the pixel captures the oppref reference from the landing URL into a first-party __oppref cookie the moment it loads, and that cookie feeds a roughly 30-day attribution window. If the pixel only loads on your checkout page, you've missed the click reference entirely for any visitor who landed on a blog post, product page, or homepage first and converted days later. A pixel that fires on some pages but not others isn't a smaller version of a working pixel — it's a broken one with gaps you won't see until you dig into the event stream.
Once the base tag is live everywhere, your conversion event tags (add-to-cart, purchase, lead form, etc.) fire as separate tags tied to their own triggers — those come later, in the event tracking guide.
CSP configuration
If your site enforces a Content Security Policy, the pixel will fail silently — no error banner, just missing data — unless your CSP explicitly allows it. You need:
script-src bzrcdn.openai.com;
connect-src bzr.openai.com;
img-src bzr.openai.com;
bzrcdn.openai.com is where oaiq.min.js loads from. bzr.openai.com is the endpoint the SDK sends events to (via connect-src) and, depending on how it batches data, may also need img-src. If you're loading the inline init script via a nonce or hash-based CSP, apply the nonce/hash to that <script> block too — never add 'unsafe-inline' just to get the pixel working. That weakens your CSP site-wide for a problem that a correctly-scoped nonce or hash solves cleanly.
If you're not sure whether your CSP is blocking the pixel, the browser console will show a CSP violation error naming the blocked domain — that's your first place to look if verification (next section) comes back empty.
How to verify the pixel fired
Don't assume the install worked. Confirm it in two places:
1. Browser dev tools, Network tab:
- Reload the page and filter for
oaiq. You should see a request tooaiq.min.jsfrombzrcdn.openai.comreturning a 200 status. - Filter for
bzr.openai.com. As events fire (including the automatic page view on load), you should see requests tobzr.openai.comreturning 202. - If you set
debug: truein Step 2, check the Console tab too — the SDK logs each event it processes.
2. The free Pixel Helper extension:
Rather than manually reading network requests every time, install the OpenAI Ads Pixel Helper — a free Chrome extension that inspects any page and tells you whether the pixel is present, which Pixel ID it's using, and which events fired. It's the fastest way to check your own site or spot-check a client's before you dig deeper.
3. Ads Manager event stream:
Back in Ads Manager's conversions tab, the event stream should show arrivals a few minutes after you trigger a page load. If dev tools show 202s but nothing shows up in Ads Manager after a reasonable wait, double-check that your Pixel ID in the init call matches the pixel you're viewing in Ads Manager, and that the conversion event you care about is actually linked to the campaign — a pixel sending data to the right ID doesn't help attribution if that event isn't attached to the campaign you're optimizing.
Common install mistakes
| Mistake | What it looks like | Fix |
|---|---|---|
Pixel placed low in <head> or in <body> | Loads late or inconsistently; oppref sometimes missed on fast-navigating users | Move the snippet near the top of <head>, before other render-blocking tags where possible |
| Pixel only on some pages (landing pages, checkout) | __oppref cookie never set for visitors who browse before converting; attribution gaps | Load the base pixel on every page via a global template partial or GTM's All Pages trigger |
| CSP blocks the script or the network calls | oaiq.min.js never loads (404/blocked in Network tab), or it loads but events never reach bzr.openai.com | Add bzrcdn.openai.com to script-src and bzr.openai.com to connect-src/img-src; use nonce/hash for inline scripts |
| Pixel fires twice | Duplicate page-view events in the event stream; inflated (and wrong) counts | Check for the snippet in both a global template AND a GTM tag, or duplicate GTM tags with overlapping triggers — install it in exactly one place |
| Wrong Pixel ID copied | Events technically fire but never show up against the campaign you're checking | Re-copy the Pixel ID from the conversions tab and confirm it matches what's in your init call, character for character |
Forgetting to remove debug: true before launch | Console fills with SDK logs for every real visitor | Strip debug: true from the init call once verification is done |
Most of these show up the moment you actually check the Network tab and the event stream — which is exactly why verification isn't optional.
Next: track your actual conversion events
A correctly installed pixel that only sends automatic page views isn't tracking much yet. The next step is firing oaiq("measure", ...) calls for the events that matter to your business — add-to-cart, checkout started, purchase completed, lead submitted, and so on. That's covered in how to track add-to-cart, checkout, and purchase events for OpenAI Ads, which walks through the supported event types, the required parameters, and example calls you can adapt directly.
If you'd rather not manage the CSP edits, GTM configuration, and cross-page verification yourself, that's exactly what a done-for-you pixel install covers — see the service details below.
Want this done for you?
Fixed-scope setup, tested end-to-end and documented.
Explore the serviceTake the free audit