{"slug": "chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector", "title": "ChatGPT now knows what you do on other websites via ad collector", "summary": "OpenAI's ad measurement system sets a first-party cookie called __obi on the .openai.com domain that is sent back to OpenAI from advertiser websites running its measurement pixel, letting the company tie browsing and purchase activity on those sites to a user's ChatGPT account, according to an independent technical analysis that reproduced the mechanism on a phone and cross-checked 936 advertiser pixels across 1,029 hostnames. The __obi cookie is issued via an RS256 JWT from the /backend-api/bazaar/obi/sync-token endpoint, scoped to Domain=.openai.com with SameSite=none, Secure, HttpOnly and a one-year Max-Age, and is transmitted to bzr.openai.com even on the script load of the SDK. The same SDK scrapes identity from advertiser pages, with scraped identity outnumbering advertiser-supplied identity 685 events to 255 in observed traffic, and version 0.1.31 also collected names and geography before the scope was narrowed on 27 August.", "body_md": "# ChatGPT now knows what you do on other websites via ad collector\n\nOpenAI's ad collector at `bzr.openai.com` sets a cookie called `__obi`, scoped to `.openai.com`. The value is while you are on ChatGPT and tied to your ChatGPT account. `__obi` is then sent to OpenAI from ordinary websites you visit.\n\nAny company that buys ads on ChatGPT installs a [small piece of OpenAI code](https://developers.openai.com/ads/measurement-pixel?ref=buchodi.com) on its own site, the same way retailers already install Meta and Google tracking code. Loading that code, sends `__obi` to OpenAI along with data about the page you are browsing. This includes products you are searching for, articles you are reading, and purchase behaviors.\n\nThe bottom line is that OpenAI can connect what you do on those sites to your ChatGPT account.\n\nI reproduced the full mechanism on my own phone, verified with two independent capture methods, and cross-checked against several months of observed traffic covering 936 distinct advertiser pixels across 1,029 hostnames.\n\n## How it works\n\n**Step 1. ChatGPT creates an identifier and signs it.**\n\nOn `chatgpt.com`, the client generates 16 random bytes and calls `POST /backend-api/bazaar/obi/sync-token` (or `/backend-anon/` when signed out). The backend returns an RS256 JWT:\n\n```\n{\n  \"iss\": \"chatgpt-wadi\",\n  \"aud\": \"bzr.openai.com\",\n  \"purpose\": \"obi_sync\",\n  \"operation\": \"set\",\n  \"consent_decision\": \"analytics_allowed\",\n  \"consent_policy_version\": \"user_granular_consent_v1\",\n  \"sub\": \"«redacted: 64-hex account subject»\",\n  \"subject_type\": \"account_user\",\n  \"obi\": \"«redacted: 22-char identifier»\",\n  \"exp\": \"«iat + 60s»\"\n}\n```\n\n`sub` is the account. `obi` is the identifier. The token binds them, is scoped to the collector, and expires in 60 seconds. `bzr` stands for `bazaar`, OpenAI's internal name for the ads platform; `wadi` is the issuing service.\n\n**Step 2. The identifier becomes a cookie on OpenAI's domain.**\n\nThe client POSTs `{\"token\": \"«JWT»\"}` cross-site to `bzr.openai.com/v1/obi/sync`. The response:\n\n```\nSet-Cookie: __obi=«redacted»; Domain=.openai.com; HttpOnly;\n            Max-Age=31536000; Path=/; SameSite=none; Secure\n```\n\n`SameSite=none` with `Secure` is the configuration a cookie needs to be sent on cross-site requests. `Max-Age` is one year. The `obi` value in the JWT and the value in the cookie are identical.\n\n**Step 3. Advertiser sites send it back.**\n\nThree request classes go from an advertiser's page to OpenAI's hosts. On a phone with `__obi` in the jar, all three carried it:\n\n| Request | Carried `__obi` | Notes | \n|---|---|---|\n| `GET bzrcdn.openai.com/sdk/oaiq.min.js` | yes | the script load itself | \n| `POST bzr.openai.com/v1/sdk/events` with`obref` | yes | conversion events | \n| `POST bzr.openai.com/v1/sdk/events` , bare body | yes | the SDK's \"no credentials\" path | \n| `GET bzrcdn.openai.com/pixel-config/…` | no cookie header at all | control | \n\nThe first row is particularly interesting. The pixel SDK has a code path that omits credentials, and it does not help: the browser attaches cookies to the `<script src>` request that loads the SDK before any of OpenAI's code runs. By the virtue of loading the tag the identifier is disclosed.\n\n## What travels with it\n\nThe same SDK also collects identity from the advertiser's page. The payload separates four sources, labelled by OpenAI itself: `in` for values the advertiser passes deliberately, and `fm`, `ht`, `js` for values the SDK scrapes from form fields, rendered page text, and the tag-manager bus. In observed traffic, scraped identity outnumbered advertiser-supplied identity 685 events to 255.\n\nThe tag-manager bus is the largest source of email. The SDK replaces `window.dataLayer.push` with its own function, also reads `adobeDataLayer`, and locates renamed GTM layers by parsing the `l=` parameter off the `gtm.js` script tag. Current versions take email and phone from it. Version 0.1.31 also took names and geography before the scope was narrowed on 27 August.\n\nEmail, phone, first and last name are SHA-256 hashed before transmission. Country, region, city and postal code are sent in the clear. Postal code was the most-harvested form field, 100 events across 28 sites.\n\nURLs are reduced to origin plus path before sending; none of 23,929 observed carried a query string. Paths survive, and paths reaching the collector included a medical condition, a debt-solutions funnel and a litigation intake form.\n\nAutomatic matching was enabled for 638 of 881 pixels with a known setting, including every credit and lending advertiser observed. It is controlled from OpenAI's Ads Manager. A denylist excludes passwords, one-time codes, card numbers, SSN, date of birth, medical history, diagnosis and court fields.\n\n## The cookie is built to cross sites\n\nOn the same advertiser-page requests, every other OpenAI cookie was blocked by the browser:\n\n| Cookie | Outcome | \n|---|---|\n| `oai-did` ,`oaicom-stable-id` | blocked, `SameSite=Lax` | \n| `oai-client-auth-info` , session cookies | blocked, domain mismatch | \n| `__obi` | sent | \n\n`__obi` is the only OpenAI identifier configured with `SameSite=None`.\n\n## Observed reach\n\nOn my device, one `__obi` value was sent to OpenAI from 12 commercial websites under 13 distinct pixel IDs, including Chewy, Wayfair, ThriftBooks, Eventbrite, HelloFresh, Coursera and SeatGeek. Every request was accepted with `202`.\n\nIn the broader traffic, 12 of 30 distinct `__obi` values appeared under more than one advertiser, one under ten.\n\n## It works when you are logged out\n\nAcross 932 decoded sync tokens, 736 carried `subject_type: account_user` and 196 carried `anonymous`. The anonymous subject is as stable as the account subject: one per device, persisting at least 27 days.\n\n## What OpenAI's cookie policy says\n\nOpenAI's [cookie policy](https://openai.com/policies/cookie-policy/?ref=buchodi.com) lists `__obi` under Analytics cookies, one year, on `chatgpt.com` and `openai.com`. It is the only entry in that section. The policy describes analytics cookies as helping OpenAI understand how its services perform and are used.\n\nOpenAI runs analytics and marketing as two separate consent choices, `oai_consent_analytics` and `oai_consent_marketing`, and every sync token I decoded carried `consent_decision: analytics_allowed`. Someone who allows analytics and refuses marketing gets this.\n\n## OpenAI's response\n\nI sent the mechanism and two questions to [press@openai.com](mailto:press@openai.com) and [privacy@openai.com](mailto:privacy@openai.com) on 14 September: why `__obi` is classified as an analytics cookie, and whether a user who grants analytics consent and refuses marketing consent still receives it. The reply came from OpenAI Support. It acknowledged the inquiry, said the observations would be shared internally for review, and did not answer either question. The script-load observation above was made after the inquiry was sent. I will update this post if OpenAI responds.\n\n## Limits\n\n**Browsers.** Observed on Chrome for Android. [Safari's Intelligent Tracking Prevention](https://webkit.org/tracking-prevention/?ref=buchodi.com) blocks all third-party cookies, and Chrome on iOS runs on WebKit, so the mechanism does not operate on any iOS browser. Desktop Chrome is untested.\n\n**Gating.** Roughly one ChatGPT session in five produced a sync token. ChatGPT's mobile web client serves ads without syncing at all. Someone following the steps below may see the pixel fire with no cookie attached.\n\n**The join is not observed.** `202` means the collector accepted the event with the cookie attached. That OpenAI resolves it to the account server-side follows from the design; I did not watch it happen.\n\n**Meta built the structural equivalent years ago.** A logged-in account, third-party cookies on pixel fires, off-site conversions resolved to a profile. The mechanism is standard adtech. What has no precedent is running it on an AI chat product. People tell these products things they would not put on a social network, and these products increasingly act on their behalf.\n\n**The pixel's other cookie does not do this.** `__obref` is set on the advertiser's own domain. Each site gets a different value and no site can see another's. Of 2,860 values observed, 2,828 appeared under exactly one advertiser.\n\n**Advertisers cannot see this.** `__obi` belongs to a domain their scripts cannot read. They installed a conversion pixel and have no way to know their visitors are being resolved to a ChatGPT identity.", "url": "https://wpnews.pro/news/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector", "canonical_source": "https://www.buchodi.com/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector/", "published_at": "2026-09-20 15:18:44+00:00", "updated_at": "2026-09-20 15:22:47.110613+00:00", "lang": "en", "topics": ["ai-products", "ai-crawlers", "structured-data", "ai-policy"], "entities": ["OpenAI", "ChatGPT", "bzr.openai.com", "__obi", "bzrcdn.openai.com", "oaiq.min.js", "Google Tag Manager", "adobeDataLayer"], "alternates": {"html": "https://wpnews.pro/news/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector", "markdown": "https://wpnews.pro/news/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector.md", "text": "https://wpnews.pro/news/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector.txt", "jsonld": "https://wpnews.pro/news/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector.jsonld"}}