All News
openaichatgptprivacyadvertisingtracking

A year-long OpenAI cookie follows you off ChatGPT. Its policy label says analytics.

A researcher's teardown traces how one year-long OpenAI cookie carries your ChatGPT identity onto advertisers' websites, and why it is filed as analytics.

Vlad MakarovVlad Makarovreviewed and published
6 min read
A year-long OpenAI cookie follows you off ChatGPT. Its policy label says analytics.

A researcher publishing as Buchodi has documented, request by request, how OpenAI's advertising stack ties the websites you visit to your ChatGPT account. The mechanism is one cookie, __obi. It is set on OpenAI's own domain with the attributes a cookie needs to travel on cross-site requests, and OpenAI's public documentation explains how advertisers' pages send it back. The teardown reached the front page of Hacker News, where the thread sat at roughly 470 points and more than 250 comments as of this writing — an approximate snapshot, not a settled total. OpenAI has answered neither of the two questions the author sent it on 14 September.

How the identifier is minted

On chatgpt.com, the page generates 16 random bytes and calls POST /backend-api/bazaar/obi/sync-token — or /backend-anon/ when you are signed out. The backend returns a signed RS256 JWT carrying iss: chatgpt-wadi, aud: bzr.openai.com, purpose: obi_sync, a 64-hex account subject in sub, a 22-character identifier in obi, consent_decision: analytics_allowed, and a 60-second expiry. bzr is OpenAI's internal name for its ads platform, bazaar; wadi is the service that issues the token.

The page then posts that token to bzr.openai.com/v1/obi/sync, and the collector answers with a Set-Cookie for __obi scoped to .openai.com: HttpOnly, Secure, SameSite=None, Max-Age one year. The cookie value is the value in the JWT. SameSite=None with Secure is precisely the configuration a cookie must carry to be sent on requests originating from other sites; the default, SameSite=Lax, does not travel that way.

The pixel sends it back

Any advertiser buying ads on ChatGPT installs OpenAI's measurement pixel on its own site, the way retailers already install Meta's and Google's tags. OpenAI's measurement-pixel documentation shows the snippet: a script from bzrcdn.openai.com/sdk/oaiq.min.js, initialised with a pixel ID, plus an optional user object for conversion matching.

What matters is which requests carried __obi. From advertiser pages on the author's phone, three request classes reached OpenAI with the cookie attached: the load of the SDK script itself, the POST bzr.openai.com/v1/sdk/events calls carrying obref conversion events, and the SDK's own "no credentials" event path. A pixel-configuration GET sent no cookie header at all, as the control. Every __obi-bearing request was accepted with HTTP 202. The first is the uncomfortable one: the SDK has a code path that omits credentials, and it does not help, because the browser attaches cookies to the script tag that loads the SDK before any OpenAI code runs.

On the same requests, every other OpenAI cookie was stopped: oai-did and oaicom-stable-id blocked as SameSite=Lax, oai-client-auth-info and the session cookies failing on domain mismatch. __obi was sent. That is a configuration comparison, not an inference — it is the only OpenAI identifier set with SameSite=None.

What travels with it, and what does not

The SDK also harvests identity from the advertiser's page, and its payload labels the source: in for values the advertiser supplies, and fm, ht and js for values scraped from form fields, rendered page text and the tag-manager bus. Scraped identity outnumbered advertiser-supplied 685 events to 255.

The tag-manager bus is the largest single source of email. The SDK replaces window.dataLayer.push with its own function, also reads adobeDataLayer, and finds renamed Google Tag Manager layers by parsing the l= parameter off the gtm.js tag. Version 0.1.31 collected names and geography as well, until the scope was narrowed on 27 August 2026.

What leaves the browser is partly hashed: email, phone, first and last name are SHA-256 hashed before transmission, while country, region, city and postal code go in the clear. Postal code was the most-harvested form field, 100 events across 28 sites. URLs are reduced to origin plus path, and none of 23,929 observed carried a query string — but paths survive, and observed ones included a medical condition, a debt-solutions funnel and a litigation intake form. Automatic matching was on for 638 of 881 pixels with a known setting, including every credit and lending advertiser observed. A denylist excludes passwords, one-time codes, card numbers, SSN, date of birth, medical history, diagnosis and court fields.

The label says analytics

OpenAI's cookie policy lists __obi in a table of its own: Analytics, one year, on chatgpt.com and openai.com. It is the only entry in that section, and the policy describes analytics cookies as helping OpenAI "understand how our Services perform and are used."

Consent is split in two. oai_consent_analytics and oai_consent_marketing are separate choices, each lasting six months on chatgpt.com. Every sync token the author decoded carried consent_decision: analytics_allowed, which means a user who allows analytics and refuses marketing still gets the cookie minted and sent. The marketing refusal never touches it, because the mechanism is labelled as the other thing.

The author put two questions to OpenAI on 14 September, to its press and privacy addresses: why __obi is classified as an analytics cookie, and whether a user granting only analytics consent still receives it. Support acknowledged the inquiry and said the observations would be shared internally for review. Neither question was answered.

The party left out of the loop

Advertisers install a conversion pixel they cannot read __obi from; it belongs to a domain their scripts are not allowed to touch. The cookie that stays on their own domain, __obref, is per-site — of 2,860 values observed, 2,828 appeared under exactly one advertiser. Whoever installs the tag cannot know its visitors are being resolved to a ChatGPT identity, or which of them.

The reach is small but concrete: on the author's own device, one __obi value reached OpenAI from 12 commercial websites under 13 distinct pixel IDs, Chewy, Wayfair, ThriftBooks, Eventbrite, HelloFresh, Coursera and SeatGeek among them. Across the wider sample — 936 advertiser pixels on 1,029 hostnames gathered over several months — 12 of 30 distinct __obi values appeared under more than one advertiser, one under ten.

Little of this is structurally new. Meta built the equivalent years ago: a logged-in account, third-party cookies on pixel fires, off-site conversions resolved to a profile. OpenAI's ad business is young enough that this is not the first thing about it to go sideways. What has no precedent is the surface — people tell a chat product what they would not post to a social network.

What the teardown does not show

The limits are the author's own. It was observed on Chrome for Android; Safari's Intelligent Tracking Prevention blocks all third-party cookies, and Chrome on iOS runs on WebKit, so the mechanism does not operate on any iOS browser. Desktop Chrome was not tested. Roughly one ChatGPT session in five produced a sync token at all, and ChatGPT's mobile web client serves ads without syncing.

Signed out, it works too: of 932 decoded tokens, 736 carried subject_type: account_user and 196 carried anonymous, with the anonymous subject per device and persisting at least 27 days.

The join itself was not observed. HTTP 202 means the collector accepted the event with the cookie attached; that OpenAI resolves it to the account server-side follows from the design, and the author says plainly that he did not watch it happen. Method matters too: one person's phone, two independent capture methods, cross-checked against months of observed traffic. That is single-author research, not an audited third-party study.

What would settle it

Three things. An answer from OpenAI to the two questions it has held since 14 September — the classification, and what a consent screen that refuses marketing is supposed to mean. An independent replication, which the published detail is specific enough to support: endpoint names, JWT fields, request classes. And a check of the two surfaces left untested, the desktop client and any iOS browser, the second of which stays shut as long as WebKit's cookie blocking holds.

Until then the piece stands as what it is: a documented mechanism, a policy label that does not describe it, and a company asked twice that answered neither time.

Related Articles

Scroll down

to load the next article