Fix guide · Any website · medium · about 45 min

OpenAI Ads Pixel setup: install the ChatGPT Measurement Pixel

What the OpenAI Pixel does

The OpenAI Pixel, which OpenAI calls the ChatGPT Ads Measurement Pixel, is a small script for your website. It records what visitors do after they click (or, where available, see) an ad in ChatGPT: page views, sign-ups, leads, purchases. ChatGPT Ads uses these events to report conversions per campaign and, for conversion-optimized campaigns, as the goal the campaign optimizes toward.

How attribution works, per OpenAI:

  • Click-through: a conversion is credited to an ad click within the click window configured for the conversion setting (OpenAI’s own setup example uses 30 days).
  • View-through: where available for your account, a conversion within one day after an eligible ad impression. It is reported separately and not included in the main Conversions number, nor in CPA, bidding or billing.

No code changes are needed for view-through reporting. The same events serve both.

Before you start

  • A Pixel ID. Create one in the conversions tab of ChatGPT Ads Manager. If you also plan server events through the Conversions API, reuse the same data source and Pixel ID for them.
  • A list of actions to measure, mapped to OpenAI’s standard event names:
Action on your site Event name Data type
A page loads page_viewed contents
A product or article is viewed contents_viewed contents
Add to cart items_added contents
Checkout starts checkout_started contents
A purchase is completed order_created contents
A lead form is sent lead_created customer_action
An account or event registration is finished registration_completed customer_action
A meeting or demo is booked appointment_scheduled customer_action
A paid subscription starts subscription_created plan_enrollment
A free trial starts trial_started plan_enrollment
  • Your cookie consent setup. If your visitors must agree to marketing cookies first, plan the consent wiring now (see below). The pixel assumes consent unless you tell it otherwise.

Step 1: add the base code

Add OpenAI’s snippet to the <head> of every page where you want to measure conversions, near the top so early conversions are not lost while the page loads:

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

Where to paste it on common platforms:

  • Any site with a code editor: in the shared <head> template, so it is on every page.
  • WordPress: a header code plugin such as WPCode (Code Snippets > Header & Footer), or your theme’s wp_head hook. Tracking plugins such as PixelYourSite and Pixel Manager for WooCommerce can also install the OpenAI pixel; they are third-party plugins, not made by OpenAI.
  • Webflow: Site settings > Custom code > Head code, then publish.
  • Framer: Site Settings > Code, a new custom code entry placed at the start of <head> on all pages, then publish. Framer does not run custom code in the canvas preview.
  • Shopify: a custom pixel under Settings > Customer events, or one of the third-party ChatGPT Ads apps in the Shopify App Store (none is made by OpenAI). Custom pixels run in a sandbox frame, so test that the click ID still reaches your store’s cookies (see “How to test”).
  • Google Tag Manager: see below.

The snippet sends no measurement events by itself; those start with your measure calls.

Step 2: send your events

Call measure when an action happens. It takes up to four arguments: the command, the event name, an event data object whose type matches the event, and options.

A page view on every page:

oaiq("measure", "page_viewed", { type: "contents" });

A lead, when the form is sent successfully:

oaiq("measure", "lead_created", { type: "customer_action" }, { event_id: "lead-8f3a2c" });

A purchase, on the order confirmation:

oaiq(
  "measure",
  "order_created",
  {
    type: "contents",
    amount: 2599,
    currency: "USD",
    contents: [{ id: "sku_123", name: "Starter bundle", content_type: "product", quantity: 1 }],
  },
  { event_id: "order_12345" }
);

Details that trip people up:

  • Amounts are integers in the currency’s minor unit: 2599 means USD 25.99. If you send amount, send currency too. quantity is an integer as well.
  • Use only documented fields inside contents[].
  • Custom events use the name "custom", { type: "custom" } and a custom_event_name in the options (1 to 64 letters, digits, underscores or dashes, starting and ending with a letter or digit, not a standard name). Use them only when no standard event fits; OpenAI does not allow custom events as the goal of conversion-optimized campaigns.

Step 3: give each conversion an event ID

The event_id option is optional, but set it for your conversions. Without it, the pixel currently fills in a random ID that only the browser knows (you can see it in the request payload). That breaks deduplication the day you add server events, because OpenAI matches the browser and server copies of a conversion on the Pixel ID, the event name and the event ID, and keeps only the first one.

  • Use the order number for purchases, the form submission ID for leads, a fresh random value (for example crypto.randomUUID()) for everything else.
  • Never use a fixed value: OpenAI would keep only the first event with that ID and drop the rest.

More: OpenAI events have no event ID and OpenAI event IDs repeat across visits.

The pixel starts with consent set to true, unless your site sets it to false or the pixel finds a stored denial. If your visitors must opt in to marketing cookies, wire it to your consent tool:

// Before init: false unless the visitor has already accepted marketing cookies.
oaiq("consent", visitorAcceptedMarketing());
oaiq("init", { pixelId: "<YOUR-PIXEL-ID>" });

// When the visitor accepts:
oaiq("consent", true);
oaiq("measure", "page_viewed", { type: "contents" });

Three rules from OpenAI’s documentation shape this code:

  • While consent is false, no measurement events are sent, and blocked events are not replayed later. That is why the page view is sent again after the visitor accepts.
  • The pixel’s cookies (__oppref for the ad click, __obref for the browser) are used only with consent.
  • oaiq("consent", false) deletes both cookies. Do not call it for visitors who have already accepted, or the stored ad click is lost on every page.

The alternative is to let your consent tool block the whole snippet until the visitor accepts the marketing category. Both are covered in fires before consent and does not fire after consent.

Setting it up in Google Tag Manager

You have three options:

  • OpenAI’s own template. OpenAI publishes a Google Tag Manager tag template on GitHub (openai/ads-measurement-pixel-gtm-template), which you import as a new tag template (Templates > Tag Templates > New, then Import in the editor’s menu); its README says to install it from the Community Template Gallery once it is listed there. The tag loads the SDK and can send an event with an event ID, amount, currency, contents and hashed user data. It does not call the pixel’s consent command, and its per-event opt-out flag only adds metadata (it “does not block transport”), so consent has to come from the tag’s Consent Settings and triggers.
  • A community template, for example Stape’s OpenAI Ads Pixel tag. It can map GA4-style data layer events (such as add_to_cart or sign_up) to OpenAI event names, has consent options (a Consent Granted field and GTM consent mode support), and an event ID field for server-side deduplication. Stape’s documentation notes it currently supports one Pixel ID per page.
  • A Custom HTML tag with the snippet, firing once on all pages, plus further tags (or your site code) for events.

Whichever you choose, add Advanced Settings > Consent Settings > Require additional consent for tag to fire with ad_storage if your consent tool feeds Google Consent Mode, and give the tags a trigger that runs again after consent is granted.

More than one pixel, user data and security headers

  • Two Pixel IDs (for example agency and client): load the SDK once, call init for each, and use measureSingle for events meant for only one. See More than one OpenAI Pixel.
  • User data: you can add a user object to init with SHA-256 hashes of normalized email, phone, external ID and names, plus country, city, region and postal code. Never send raw values. OpenAI also offers automatic advanced matching, which detects customer information on your site and hashes it in the browser.
  • Content Security Policy: if your site sends a CSP header, allow https://bzrcdn.openai.com in script-src and connect-src, and https://bzr.openai.com in connect-src and img-src. Use a nonce or hash for the inline snippet rather than 'unsafe-inline'.

How to test the pixel

  1. Turn on debug mode while testing: add debug: true to the init call on a test copy, and watch the SDK’s messages in the browser console.
  2. Watch the requests: open developer tools (F12), go to Network and filter by bzr.openai.com. Each request’s payload carries a list of events with a type (the event name) and an id. Trigger each action once and check that exactly one matching event leaves. At the time of writing the SDK also sends its own, undocumented service messages (types starting with openai:: or oai::); ignore them.
  3. Check the cookies: open your page with ?oppref=test123 added to the address, accept cookies, and look under Application > Cookies (Chrome) for __oppref with the value test123, and for __obref. Then open another page: __oppref should still be there.
  4. Check consent: in a private window, none of your events before you answer the banner, page_viewed right after you accept, nothing after you reject.
  5. Check arrival at OpenAI: with access to the Advertiser API, the recent-events endpoint (GET /v1/conversions/events?pid=<PIXEL-ID>) shows a sample from roughly the last 15 minutes, with the channel pixel_sdk for browser events.
  6. Run a free check on IsPixelWorking: it tests consent, duplicates, event IDs and the ad click ID for the OpenAI Pixel, next to Meta and TikTok.

There is no official OpenAI “Pixel Helper” browser extension at the time of writing; the steps above cover what one would show.

Count the events as conversions

Sending events does not yet make them conversions. Create a conversion event setting for each action (OpenAI documents this through the Advertiser API; Ads Manager may offer it too) you want to measure (for example purchases from your website’s data source) and attach it to your campaigns. A conversion-optimized campaign uses exactly one standard event as its goal, chosen when the campaign is created.

Next: add the Conversions API

Browser events miss conversions when scripts are blocked or a tab closes too early. OpenAI’s Conversions API sends the same conversions from your server, deduplicated with the pixel through the shared event ID: How to set up the OpenAI Conversions API.

Sources

More OpenAI guides