How to Install the OpenAI Ads Pixel, Directly or Through GTM

By 10 min read

Summarise with

Prompt copied

Screen-print illustration of two stripped cable ends brought almost together, the narrow gap between the exposed strands being the clear centre of the image.

In brief

Install the OpenAI Ads pixel directly or through Google Tag Manager, then verify its base script, conversion calls, and click references.

Last verified: 12 September 2026 | Version: 1.0 | Next scheduled review: 12 October 2026

Two lines of work. Put the base snippet in the head of every page, then call oaiq("measure", ...) at the moment a conversion happens. The direct install and the GTM install differ only in who owns the ordering between those two things, which is also the only part that reliably breaks.

Below is the documented implementation, the parts OpenAI leaves to you, and the verification step most write-ups skip.

What the pixel is

The OpenAI Ads pixel is a JavaScript SDK loaded from bzrcdn.openai.com, exposing a single global command queue called oaiq. It does two jobs. It sends conversion events you name, and it captures OpenAI's click reference, oppref, from the landing page URL and stores it in a first-party cookie so that a conversion happening three pages later can still be joined back to the click.

OpenAI appends oppref to your destination URL on every ad click, in the form https://example.com/?oppref=gAAAAAb123. If your site strips query parameters on redirect, the pixel has nothing to store, and the conversion becomes unattributable inside Ads Manager even though the pixel fired correctly. Check your redirect chain before you check anything else.

Step one: create the pixel

In Ads Manager, the conversions tab issues a Pixel ID. The same object can be created through the Advertiser API:

curl -X POST "https://api.ads.openai.com/v1/conversions/pixels" \
  -H "Authorization: Bearer $OPENAI_ADS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme website", "client_type": "web" }'

The response carries a source ID and a Pixel ID. Separately, you create an event setting, which is the object a conversion campaign actually optimises toward. It takes name, event_type, attribution_window_days and source_ids, and each event setting binds to exactly one source. That one-to-one binding matters later: if you run a second pixel for a second domain, the same conversion event needs its own event setting.

The direct install

OpenAI's documented base code, as published on the Measurement Pixel page, goes in the <head> of every page:

<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>

The stub queues calls before the SDK finishes loading, which is why a measure call placed after init is safe even on a slow connection. It is not safe before init.

If you run a consent banner, OpenAI documents a consent command that sets state around initialisation:

oaiq("consent", false);
oaiq("init", { pixelId: "<YOUR-PIXEL-ID>" });
// later, once the user has agreed
oaiq("consent", true);

Firing an event

The call takes a command, an event name, an event data object whose type must match the event's data shape, and an options object:

oaiq("measure", "lead_created", { type: "customer_action" }, { event_id: "lead_8842" });

The documented event names are page_viewed, contents_viewed, items_added, checkout_started, order_created, lead_created, registration_completed, appointment_scheduled, subscription_created, trial_started and custom. Two further names, app_installed and app_opened, exist for the Conversions API only and the pixel does not accept them.

Each name belongs to a data type. contents events take type, amount, currency and a contents array. customer_action events take type, amount and currency. plan_enrollment events add plan_id. A custom event requires custom_event_name in the options object.

For B2B, lead_created on the form success state and appointment_scheduled on the booking confirmation are the two that matter. Fire page_viewed on load if you want a delivery signal, but do not make it your conversion event setting, because a campaign optimising toward page views will buy you page views.

Page-load events versus click events

A page-load event is the reliable one. Put the measure call on the thank-you page or the confirmation state, where the server has already committed the record. A click event, fired on a button press before navigation, is faster but races the page unload and can be lost.

If you must fire on click, the pattern is to fire the event, then delay navigation briefly, then navigate. OpenAI does not document a callback or a beacon transport for oaiq, so the length of that delay is a guess you are making, not a number the platform gives you. Prefer the page-load version wherever a confirmation page exists.

Single-page applications need attention for the same reason. The base snippet initialises once on first load. Route changes fire no event by themselves, so a virtual thank-you route needs an explicit measure call in your router.

Dynamic order revenue

For revenue you pass amount and currency in the event data. OpenAI's published example sends "amount": 2599, "currency": "USD" for a single bundle, which reads as minor units, that is cents. Every other field in the documented examples is literal, so this is the one value worth confirming in your own account before you ship it, by sending a known order and reading back what Ads Manager reports.

The shape of the implementation, rather than a snippet you should paste:

  1. On the confirmation page, read the order total and currency from whatever object your platform already exposes, a dataLayer push on Shopify, the order object on WooCommerce, your own template variable otherwise.
  2. Convert to the unit your test confirmed.
  3. Pass the order ID as event_id, not a random string. That ID is what deduplicates the browser event against the same event sent later from your server.
  4. Fire order_created with type: "contents" and, if you have them, a contents array of id, name, content_type and quantity.

Point three is the one people skip and regret. Deduplication is keyed on Pixel ID, event name and event ID, and the first event received wins. A random event_id means the pixel event and the server event both count.

The GTM path

Everything above works inside Google Tag Manager with one structural condition: the base snippet must have run before any measure tag fires.

  • Create a Custom HTML tag containing the base snippet, including the init call, and set it to fire on Initialisation or All Pages. Leave document.write support off.
  • Create a second Custom HTML tag per conversion event, containing only the measure call.
  • Use GTM's tag sequencing on each event tag, naming the base tag as the setup tag. Do not rely on trigger order or on both tags sharing an All Pages trigger. Order between two tags on the same trigger is not guaranteed in a way you should build measurement on.
  • For revenue, read values from dataLayer variables rather than from the DOM. DOM scraping on a confirmation page breaks silently whenever the theme changes.

OpenAI's help documentation states the pixel can be deployed through a tag manager provided it loads reliably and does not block initialisation. That is the whole of the official GTM guidance. The sequencing requirement above is the implementation detail that follows from it, not something OpenAI writes down.

Verification, which is the step that gets skipped

There is a first-party way to check, and it is better than watching the network tab.

curl -X GET "https://api.ads.openai.com/v1/conversions/events?pid=<PIXEL-ID>" \
  -H "Authorization: Bearer $OPENAI_ADS_API_KEY"

This returns up to 50 conversion events received from the pixel SDK in the previous 15 minutes. OpenAI labels it a testing tool and states plainly that it is not for attribution or reporting. Use it to answer three questions: did the event arrive, did it arrive under the event name your event setting expects, and did the amount arrive in the unit you intended.

Two further checks. Load a page with ?oppref=test appended and confirm the pixel still initialises and the parameter survives your redirects, a technique documented by third-party tracking write-ups rather than by OpenAI. And accept the reporting delay: OpenAI states that attributed conversions may take 24 to 48 hours to appear in Ads Manager, so an empty conversions column on day one is not evidence of a broken pixel.

One failure mode has no recovery. If your event setting names an event that your pixel never sends, or names it with a different string, reporting shows zero, and OpenAI states that historical data will not backfill once you correct the mismatch. Get the string right before you spend.

What we cannot tell you

  • The exact unit for amount. The documented example is consistent with minor units but OpenAI does not state the rule in words. Verify with a test order.
  • Whether oaiq uses a beacon or keepalive transport. Undocumented, which is why click-fired events cannot be given a safe delay figure.
  • The first-party cookie lifetime for the stored oppref. Not published, so the effective ceiling on pixel-only attribution is unknown independent of your configured window.
  • Retry behaviour on a failed pixel request. Undocumented. Assume an event that fails in the browser is lost.
  • Whether any of this is materially different for advertisers in the API beta versus the Ads Manager UI. No first-party comparison exists and we have no account of our own to test it in.

Quick answers

Where does the OpenAI Ads pixel go? In the <head> of every page, not only the conversion page. The SDK needs to run on the landing page to capture and store the oppref click reference before the conversion happens later in the session.

What is the pixel's global function called? oaiq. You initialise with oaiq("init", { pixelId: "..." }) and send events with oaiq("measure", eventName, eventData, options).

Can I install the OpenAI pixel through Google Tag Manager? Yes. Put the base snippet in a Custom HTML tag on Initialisation, put each event in its own tag, and use tag sequencing so the base tag is a setup tag for every event tag.

How do I check the pixel is working? Call GET /v1/conversions/events?pid=<PIXEL-ID> on the Advertiser API. It returns up to 50 events from the last 15 minutes. It is a test tool and does not feed reporting.

Why are my conversions showing as zero? Three usual causes: the event name in your event setting does not match the string the pixel sends, oppref is being stripped by a redirect, or you are inside the 24 to 48 hour reporting delay OpenAI documents.

Do I need the Conversions API as well as the pixel? Not to start. Send both only when you can share an event ID between them, since deduplication is keyed on Pixel ID, event name and event ID.

Sources

Claim Source Tier
Base snippet, oaiq global, SDK at bzrcdn.openai.com, init and consent commands OpenAI Developers, Measurement Pixel, 2026 Confirmed, primary
Supported event names, data types and the pixel exclusion of app_installed and app_opened OpenAI Developers, Supported Events, 2026 Confirmed, primary
measure argument order and the event_id, custom_event_name and opt_out options OpenAI Developers, Measurement Pixel, 2026 Confirmed, primary
Pixel creation and event setting fields, including one source per event setting OpenAI Developers, Conversion Setup API reference, 2026 Confirmed, primary
Event stream returns up to 50 events from the last 15 minutes and is not for attribution OpenAI Developers, Conversion Setup API reference, 2026 Confirmed, primary
oppref appended to the landing URL and stored in a first-party cookie OpenAI Help Center, Conversion Measurement, 2026 Confirmed, primary
Deduplication keyed on Pixel ID, event name and event ID, first event wins OpenAI Developers, Conversions API, 2026 Confirmed, primary
24 to 48 hour delay before attributed conversions appear; mismatched events do not backfill OpenAI Help Center, Measure Results, 2026 Confirmed, primary
Pixel may be deployed via a tag manager if it loads reliably OpenAI Help Center, Measure Results, 2026 Confirmed, primary
GTM tag sequencing requirement, SPA route handling, click-event race Inference from the documented load order Inference, ours
Appending ?oppref=test as a verification technique ProAnalytics, OpenAI ads conversion tracking, 2026 Reported, third party
  • How to Measure ChatGPT Ads, and What You Cannot Measure Yet
  • The OpenAI Conversions API, and When Server Side Beats the Pixel
  • UTM Conventions for ChatGPT Ads That Survive Contact With a CRM
  • Why ChatGPT Ads Traffic Lands in Referral in GA4
  • ChatGPT Ads Troubleshooting

Changelog

12 September 2026, v1.0. First publication. Documents the published pixel snippet and event vocabulary, the GTM sequencing requirement, and the conversions event stream as the verification step.

Field kit

Tools

Site

OpenAI (primary)

Share this

AK

Ansh works across GEO strategy, B2B research, and execution. At InPromptAds, he translates new AI advertising products into clear operating advice, tests, and measurement questions for marketing teams.

Get placed before the self-serve rush.

We're onboarding a founding cohort of B2B brands for managed ChatGPT ad placements. Early access, limited seats.

Now capturing early access
Contact us Contact us