---
title: "OpenAI Ads Pixel setup: install the ChatGPT Measurement Pixel"
description: "Install the ChatGPT Ads Measurement Pixel step by step: the oaiq snippet, conversion events, event IDs, cookie consent, Tag Manager and testing."
updated: "2026-10-23"
url: "https://ispixelworking.com/guides/openai.pixel_setup/generic"
---

# OpenAI Ads Pixel setup: install the ChatGPT Measurement Pixel

Fix guide · Any website · medium · about 45 min · updated 2026-10-23


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

```html
<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:

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

A lead, when the form is sent successfully:

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

A purchase, on the order confirmation:

```js
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](https://ispixelworking.com/guides/openai.missing_event_id/generic) and [OpenAI event IDs repeat across visits](https://ispixelworking.com/guides/openai.event_id_reused/generic).

## Step 4: connect the pixel to cookie consent

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:

```js
// 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](https://ispixelworking.com/guides/openai.fires_before_consent/generic) and [does not fire after consent](https://ispixelworking.com/guides/openai.not_firing_after_consent/generic).

## 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](https://ispixelworking.com/guides/openai.multiple_pixels/generic).
- **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](https://ispixelworking.com/guides/openai.conversions_api_setup/generic).

## Sources

- OpenAI Developers, Measurement Pixel (attribution reporting, installation snippet, `pixelId` from the conversions tab, debug, consent, CSP, user data, automatic advanced matching, events, custom events, deduplication, cookies, troubleshooting): https://developers.openai.com/ads/measurement-pixel
- OpenAI Developers, Supported Events (event names and data shapes, minor units): https://developers.openai.com/ads/supported-events
- OpenAI Developers, Conversion Tracking (data sources, conversion event settings, 30-day click attribution window in the setup example, Monitoring Events, custom events cannot be used for conversion optimization): https://developers.openai.com/ads/conversion-tracking
- OpenAI Developers, Multiple Pixel IDs (`measureSingle`): https://developers.openai.com/ads/multiple-pixels
- OpenAI on GitHub, Ads Measurement Pixel GTM template (manual import, gallery later, event ID field, opt-out flag does not block transport): https://github.com/openai/ads-measurement-pixel-gtm-template
- Stape, OpenAI Ads Pixel tag for web GTM: https://stape.io/helpdesk/documentation/openai-ads-pixel-tag
- Framer Help, How to add Google Tag Manager to your site (Site Settings > Code, placement "Start of `<head>`"): https://www.framer.com/help/articles/how-to-add-google-tag-manager-to-your-site/
- WPCode, How to add header and footer code in WordPress: https://wpcode.com/how-to-add-header-and-footer-code-in-wordpress/
- PixelYourSite, OpenAI pixel: https://www.pixelyoursite.com/openai-pixel
- Google Tag Manager Help, Tag Manager consent mode support: https://support.google.com/tagmanager/answer/10718549
