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
Conversionsnumber, 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_headhook. 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:
2599means USD 25.99. If you sendamount, sendcurrencytoo.quantityis an integer as well. - Use only documented fields inside
contents[]. - Custom events use the name
"custom",{ type: "custom" }and acustom_event_namein 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.
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:
// 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 (
__oppreffor the ad click,__obreffor 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_cartorsign_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
initfor each, and usemeasureSinglefor events meant for only one. See More than one OpenAI Pixel. - User data: you can add a
userobject toinitwith 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.cominscript-srcandconnect-src, andhttps://bzr.openai.cominconnect-srcandimg-src. Use a nonce or hash for the inline snippet rather than'unsafe-inline'.
How to test the pixel
- Turn on debug mode while testing: add
debug: trueto theinitcall on a test copy, and watch the SDK’s messages in the browser console. - Watch the requests: open developer tools (F12), go to Network and filter by
bzr.openai.com. Each request’s payload carries a list ofeventswith atype(the event name) and anid. 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 withopenai::oroai::); ignore them. - Check the cookies: open your page with
?oppref=test123added to the address, accept cookies, and look under Application > Cookies (Chrome) for__opprefwith the valuetest123, and for__obref. Then open another page:__opprefshould still be there. - Check consent: in a private window, none of your events before you answer the banner,
page_viewedright after you accept, nothing after you reject. - 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 channelpixel_sdkfor browser events. - 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
- OpenAI Developers, Measurement Pixel (attribution reporting, installation snippet,
pixelIdfrom 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
More OpenAI guides
- OpenAI Pixel fires before cookie consent: how to fix it
- OpenAI Pixel not firing after cookie consent: how to fix it
- Repeated OpenAI event IDs drop ChatGPT Ads conversions
- Duplicate OpenAI Pixel events: how to find and remove them
- OpenAI Pixel event_id missing: fix ChatGPT Ads deduplication
- ChatGPT Ads click ID (oppref) lost after an ad click
- OpenAI Pixel tracks a button on desktop but not on mobile
- Two OpenAI Pixel IDs on one site: when it's fine, how to fix
- OpenAI Conversions API deduplication: match the pixel event_id
- How to set up the OpenAI Conversions API for ChatGPT Ads