The OpenAI Pixel: Installation, Events, and the __oppref Cookie
How the OpenAI measurement pixel (oaiq.min.js) actually works: the init snippet, the standard events, event_id deduplication, and the __oppref first-party cookie that links ChatGPT ad clicks to conversions. Implementation notes from shipping it on our own Next.js site.
Viren Inaniyan · August 29, 2026 · ChatGPT Ads

The OpenAI pixel is the piece of ChatGPT ads most advertisers get wrong first. It is a small script with a simple job - capture a click id into a first-party cookie, report conversions against it - but miss the SPA caveat or skip event_id and your campaign optimizes toward noise. We installed it on our own Next.js site; here is exactly how it works.
What the OpenAI pixel is
When OpenAI opened self-serve ChatGPT ads at ads.openai.com in May 2026, it shipped a measurement stack that will look familiar to anyone who has installed the Meta pixel: a browser JavaScript tag plus a server-side Conversions API, joined by a shared event id (OpenAI Ads Manager docs, 2026).
The browser half is oaiq.min.js. You generate a pixel id in Ads Manager under Tools, then Conversions, paste a loader snippet into your site's head, and call two functions:
oaiq("init", { pixelId })- loads the pixel, measures the first page view, and captures the click id (more on that below).oaiq("measure", event, data, options)- reports a named event, such as a lead or an order, with optional value data.
The loader is the standard async-queue pattern: it defines a stub oaiq function that queues calls until the real script arrives from OpenAI's CDN, so nothing blocks your page render and calls made before load are not lost.
Why it matters: conversion-optimized CPC bidding steers delivery toward your selected conversion event while still charging per click (OpenAI Help Center, article 20001210). Without the pixel, that bidding has nothing to optimize toward, and you are left judging the channel on clicks. Chatbot ad CTR runs around 0.9% against a 6.4% Google search benchmark (eMarketer, 2026), so per-click judgment undersells the channel - ChatGPT-referred ecommerce traffic converts at 15.9% versus 1.76% for Google organic (Adobe, 2025). The pixel is how you see that second number in your own account.
The __oppref cookie: how attribution actually works
Every click on a ChatGPT ad lands on your site with an oppref parameter appended to the destination URL. That is the click id - OpenAI's equivalent of Google's gclid or Meta's fbclid.
On init, the pixel reads oppref from the landing URL and writes it into a first-party cookie named __oppref on your domain. Every subsequent measure call sends that stored click id along with the event, which is how OpenAI ties a conversion on Tuesday back to an ad click the previous week. The default conversion window is 30 days (OpenAI docs, 2026).
Three practical consequences:
- First-party means your domain, your cookie. The
__opprefcookie is not a third-party tracker; it lives on your site like any analytics cookie, which is why it survives browser third-party-cookie restrictions. - Do not strip query parameters before the pixel runs. If a redirect chain or a consent tool rewrites the landing URL and drops
opprefbeforeinitfires, attribution is gone for that click. We put the pixel in the root layout precisely so it sees the raw landing URL first. - Keep your UTMs too.
opprefis for OpenAI's attribution; it does nothing for GA4. We appendutm_source=chatgpt&utm_medium=paid_chatat the ad-group level so this traffic does not hide as Direct - the exact failure mode we cover in our guide to dark agentic commerce traffic.
The standard events
The pixel ships with a set of standard events. Use the standard names rather than inventing custom ones - standard events are what Ads Manager's conversion-optimized bidding can target.
Ecommerce funnel: page_viewed, contents_viewed (product detail views), items_added (add to cart), checkout_started, order_created.
Lead-gen and SaaS funnel: lead_created, registration_completed, appointment_scheduled, subscription_created, trial_started.
Everything else: custom, for events that genuinely fit no standard name.
A typical measure call for an ecommerce order passes value data alongside the event name - order value, currency, an order id. For our own B2B funnel, the event that matters is lead_created: we fan out every lead-form submission sitewide into a single lead_created event, and that is the conversion event our campaigns optimize toward. Pick one primary event that represents real business value and let the campaign optimize against it; a campaign optimizing toward page_viewed will happily buy you cheap, worthless clicks.
event_id: the deduplication key
Every measure call accepts an options object with an event_id - a unique string per event occurrence. Generate one (a UUID is fine) and send it on every event, even before you have server-side tracking.
The reason is the Conversions API. OpenAI's server-side endpoint accepts the same events as HTTP posts to bzr.openai.com/v1/events, authenticated with a bearer key from Ads Manager (OpenAI docs, 2026). When the browser pixel and your server both report the same conversion - same pixel id, same event name, same event_id - OpenAI counts it once instead of twice.
Browser pixels miss events: ad blockers, abandoned tabs, script failures. Server-side sends miss nothing but lack browser context. Running both with shared event ids gets you redundancy without double-counting - but only if event_id flows from day one. We generate a crypto.randomUUID() per event in a small helper and attach it to every pixel call automatically, so the server-side leg can be added later with zero changes to the browser side.
The SPA caveat: our Next.js implementation notes
This is the mistake we made first, so learn from it. init measures one page view - the first. On a traditional multi-page site, every navigation reloads the page and re-runs the pixel. On a single-page app - Next.js App Router, React Router, Nuxt, SvelteKit - client-side navigations swap content without a reload, and the pixel sees none of them.
If you do not handle this, OpenAI sees a user who landed once and never moved, which starves both your reporting and the conversational matching signals the ad system learns from.
Our fix, on our Next.js App Router site:
- The pixel lives in a client component in the root layout, injected with
next/scriptusing theafterInteractivestrategy, so it never blocks render. - The component watches the current pathname with
usePathnameand firesoaiq("measure", "page_viewed")on every pathname change - except the very first render, becauseinitalready measured the landing view. Skip that guard and you double-count every landing page. - The whole component renders nothing unless a
NEXT_PUBLIC_OPENAI_PIXEL_IDenvironment variable is set and the build is production. That means the code ships safely before the pixel exists in Ads Manager, and staging builds never pollute campaign data.
Total implementation: one small client component and one typed helper. This is not a heavy integration.
Consent and SHA-256 advanced matching
Two compliance notes worth getting right on day one.
Consent. The async-queue loader makes consent gating straightforward: do not call init until your consent platform reports marketing consent, and the pixel never loads or sets __oppref for users who declined. Because calls queue, you can also load the stub immediately and defer only the init call until consent arrives. OpenAI's broader posture helps here - user data is not sold to advertisers, no demographic profiles are sold, and conversations are kept private from advertisers (OpenAI, stated repeatedly since February 2026) - but your pixel install is still your cookie, so it belongs under your consent banner like any other marketing tag.
Advanced matching. Like other ad platforms' pixels, OpenAI's measurement stack supports passing hashed customer identifiers - an email address hashed with SHA-256 - alongside conversion events to improve match rates when the cookie is missing, which matters most on the server-side Conversions API where there is no cookie at all. The rule is absolute: hash before sending, never pass a raw email. Normalize first (trim, lowercase), then hash. If you cannot hash it, do not send it.
Where Tru Commerce fits
The pixel measures the layer you rent. Every ChatGPT ad is a single labeled sponsored box below the answer - and the answer itself is the layer you cannot buy. As we told The Hindu BusinessLine in August 2026: "Brands cannot buy influence over ChatGPT's answers." Plus and Pro users never see ads at all (OpenAI), so for them the organic recommendation is the only layer that exists.
That is why we tell brands to instrument both. Install the pixel, wire up event_id, run the campaign - our ChatGPT Ads hub and our campaign setup guide cover the buying side, and our conversion tracking setup guide goes deeper on the measurement stack. But before you spend, find out where you stand on the earned layer: run the free Citation Rank scan and see where ChatGPT, Gemini, and Perplexity rank your brand today - results in 24 hours, no login, no credit card.
FAQ
Sources
- 1.Ads in ChatGPT: The Basics - OpenAI Help Center, 2026
- 2.Ads Measurement Pixel documentation - OpenAI Developers, 2026
- 3.Ads Conversions API documentation - OpenAI Developers, 2026
- 4.Conversion measurement - OpenAI Help Center, 2026
Continue reading
August 29, 2026
Context Hints, Not Keywords: How ChatGPT Ads Targeting Actually Works
There is no keyword bidding in ChatGPT ads - just a free-text field called context hints. How to write hints that put your ad inside the right conversations, with the framework we use for our own campaigns.
August 29, 2026
Who Is Advertising on ChatGPT? The Named Brands So Far
Target, Williams-Sonoma, Adobe, Ford, Audible, HelloFresh - the confirmed ChatGPT advertisers from the launch pilot, the agencies running them, the India wave, and what the roster tells you about who this channel is for.
August 29, 2026
ChatGPT Ads on Reddit: What Advertisers Actually Report
OpenAI publishes almost no benchmarks, so r/PPC built its own. We read the threads: real CPCs of $2-8, CTRs from 0% to 2.4%, and one recurring complaint that matters more than any number.