If you send hashed customer data to ChatGPT Ads — through the Measurement Pixel's user object or the Conversions API — OpenAI changed the rules for how to format those values before you hash them, and it did so without a changelog entry, an advertiser email, or a word in the help centre.
The change is small enough to read as housekeeping and consequential enough to silently break a match rate. This post gives you the exact previous and current wording, the one case where the output actually differs, and the rule that most normalization code already gets wrong for reasons that have nothing to do with this update.
Verified 2026-08-31 against OpenAI's official developer documentation. Sources are linked in full at the end.
What actually changed
OpenAI publishes the normalization rules in two places — the Measurement Pixel document and the Conversions API document — and they carry the same text. Both were rewritten in the same window, identically. That consistency is worth noting up front, because when these two surfaces disagree the disagreement is usually the story; here they do not.
Here is the phone-number rule as it read in our 2026-08-28 capture:
Phone number: convert the value to international digits-only form. Keep the country calling code, but remove the leading
+or00international-access prefix and all whitespace, parentheses, periods, and hyphens. Hash the resulting 8–15 digits. For example,+1 (415) 555-2671becomes14155552671.
And as it reads in the 2026-08-31 capture:
Phone number: keep the country calling code. Remove all whitespace, parentheses, periods, and hyphens, then remove a leading
+and any leading zeroes. Hash the resulting 8–15 digits. For example,+1 (415) 555-2671becomes14155552671.
The worked example is identical in both versions, which is exactly why this is easy to skim past. The example is a US number in international form, and it is the one case where the two rules cannot disagree.
Alongside the rewrite, OpenAI added two tables that were not there before. The first is a set of worked normalization examples:
| Identifier | Input | Normalized value |
|---|---|---|
| Phone number | +1 (415) 555-2671 | 14155552671 |
| First name | Mary Jane | maryjane |
| Last name | O'Connor | oconnor |
| First name | José | josé |
The second is a per-field description table that restates each rule against the wire field name — phone_number_sha256 is now documented as the "SHA-256 hash of 8–15 digits after removing a leading +, leading zeroes, whitespace, parentheses, periods, and hyphens", and the name fields as "SHA-256 hash of the lowercase first name after removing whitespace and ASCII punctuation; non-ASCII characters are preserved."
A new sentence also appears above the examples: "The normalized value is the exact string to encode and hash." That is the sentence doing the most work in the whole update, and we will come back to it.
The one case where the output actually differs
Read the two phone rules literally and they diverge on exactly one input class: a number stored with a leading zero that is not part of a 00 international-access prefix.
The previous rule removed + or the two-character sequence 00. The current rule removes + and then any leading zeroes. For a number already in international form, that is the same operation. For a number stored the way most European and many Asian CRMs store it — in national format, with a trunk prefix 0 — it is not.
| Stored value | Previous rule | Current rule | Same digest? |
|---|---|---|---|
+1 (415) 555-2671 | 14155552671 | 14155552671 | Yes |
0044 20 7946 0958 | 442079460958 | 442079460958 | Yes |
020 7946 0958 | 02079460958 | 2079460958 | No |
+44 (0)20 7946 0958 | 4402079460958 | 4402079460958 | Yes — but see below |
That last row deserves care rather than a confident answer. The rule says to remove a leading + and any leading zeroes — leading, meaning at the start of the string. A number written +44 (0)20 7946 0958 has an interior 0 inside the parentheses, and once the parentheses are removed that zero is no longer at the front. A literal reading keeps it: 440207946 0958 → 4402079460958. That is thirteen digits, inside the accepted 8–15 range, so nothing rejects it — and it is almost certainly not the number OpenAI's own copy of the identifier hashes to.
This is the sharpest practical point in the whole update. The documentation tells you how to strip a leading trunk prefix. It does not tell you what to do with the parenthesised trunk digit that British and several other conventions write in the middle of an international number, and the 8–15 digit validation will not catch it, because the wrong answer is still a plausible length.
If you store numbers in national format, this update changes your hashes. If you store them in +-prefixed international form with no interior trunk digit, it does not.
The rule almost everyone gets wrong, and it is not the new one
The name rule did not change in this update. It is still the rule most likely to be broken in your codebase:
First and last name: convert the value to lowercase and remove all whitespace and ASCII punctuation. Apart from converting to lowercase, preserve non-ASCII characters; don't strip accents or transliterate. For example,
O'Connorbecomesoconnor, andJosébecomesjosé.
Read that twice. OpenAI wants josé, with the accent intact.
This is the opposite of what a lot of shared normalization code does. Unicode NFKD folding followed by an ASCII filter, unidecode, iconv //TRANSLIT, and most "slugify" helpers all turn José into jose. Any of them, dropped in front of this field because it looked like a reasonable normalization step, produces a digest that can never match OpenAI's, for every customer with an accented name — which in several European and Latin American markets is a large and systematically biased slice of your file, not a random one.
The new sentence — "The normalized value is the exact string to encode and hash" — reads like it was added to close exactly this gap. It is telling you that the normalized value is not a suggestion to be further tidied by your own pipeline before hashing.
The ASCII punctuation clause is the mirror image and is easy to get right once stated: O'Connor loses the apostrophe because an apostrophe is ASCII punctuation, while José keeps its accent because é is not ASCII at all.
Where this contradicts guidance written for other platforms
Advanced matching looks similar across ad platforms, and normalization guidance gets copied between them. For phone numbers, that copying is now wrong.
Google's enhanced conversions formatting requirements ask for E.164, and E.164 as conventionally written includes the leading + — +11231234567. OpenAI asks for the digits without the +: 14155552671. Two platforms, two different strings, two different digests, from the same stored number.
We say this plainly because our own earlier guide to setting up user objects for ChatGPT Ads conversion tracking presented Google's formatting table as a stand-in at a time when OpenAI had not published its own. OpenAI has now published its own, it differs on this field, and OpenAI's is the one that governs. That post has been corrected to point here.
The practical rule: do not share one normalization function across ad platforms for phone numbers. Email and names are close enough to share. Phone is not.
What this does not change
Worth stating, because a documentation diff invites over-reading:
- Email is unchanged: trim leading and trailing whitespace, convert to lowercase. Note there is no Gmail dot-stripping rule here, unlike Google's guidance.
- External ID is unchanged: trim leading and trailing whitespace, preserve case and all other characters.
- The hashing step is unchanged: encode the normalized value as UTF-8, take the SHA-256 digest, send it as a lowercase 64-character hexadecimal string.
- The instruction not to send raw values is unchanged.
- The
userobject's non-hashed fields —country,city,region,postal_code— are unchanged, andcityis still documented as trimmed and lowercased by OpenAI on receipt rather than by you.
Nothing in this update alters whether advanced matching is on, who it applies to, or the automatic advanced matching default that turned on for existing pixels earlier this month. This is purely about the string you hash.
The help centre still says none of this
As of 2026-08-31, the normalization rules appear only in the developer documentation. The help.openai.com ChatGPT Ads collection covers conversion measurement and pixel setup at a conceptual level and does not state the normalization format, the hashing format, or the field names.
That is a real gap rather than a stylistic choice, because the help centre is where most advertisers land and the developer docs are where most advertisers do not. If your pixel implementation was scoped from the help centre, it was scoped without ever seeing the rules on this page.
There is no advertiser product-update email covering this change either. OpenAI's most recent ChatGPT Ads Product Updates email in our inbox is dated 2026-08-20 and predates the rewrite; nothing has been sent since. The documentation diff is the only notice this change received.
Also changed in this window
Two smaller items landed in the same documentation window and are worth recording:
India was added to the Ads Manager availability table as Coming Soon. This matters more than another row on a long list, because India is not part of the 31-country Europe expansion that accounts for most of the existing Coming Soon entries. It is the first Coming Soon market added outside that expansion, which makes it the earliest documented signal of where self-service goes after Europe. Self-service remains Available in Australia, Brazil, Canada, Japan, Korea, Mexico, New Zealand and the United States.
One help-centre article was delisted. "Managing ads users in the global admin console" was present in the ChatGPT Ads help collection on 2026-08-28 and is absent from the collection index on 2026-08-31. We are reporting the delisting rather than a deletion: the article dropped out of the collection listing, which is a weaker and more precise claim than saying the page is gone.
What to do this week
- Find your phone normalization and check what it does with a leading zero. If it only strips
+and00, it is now out of date. If your CRM stores national-format numbers, this is not theoretical. - Decide the parenthesised trunk digit case deliberately.
+44 (0)20 ...is not covered by the documented rule. Pick a behaviour, write it down, and treat it as an assumption to revisit rather than a settled answer. - Grep for transliteration in front of the name fields.
unidecode, NFKD-plus-ASCII-filter, and slugify helpers all break the accent rule. This one is costing you matches today and has been since before this update. - Stop sharing one phone normalizer across ad platforms. Google wants the
+; OpenAI does not. - Watch match quality, not just conversion count. A normalization bug does not throw an error. It quietly lowers the share of conversions that match, and the first visible symptom is usually a bidder that has quietly got worse.
The honest summary
This was a clarification that carries one real behavioural change. OpenAI tightened language that was ambiguous about which leading characters to strip from a phone number, and in doing so moved from a rule about international-access prefixes to a rule about leading zeroes generally. For advertisers storing numbers in international form, nothing changes. For advertisers storing them nationally, the hashes change and the matches change with them.
The larger point is the one about where the rules live. The only place OpenAI documents how to format the data it will match on is a developer page that the help centre does not link to and does not summarise, and the change arrived with no email and no changelog. If you are running ChatGPT Ads conversion measurement, the developer documentation is not optional reading, and diffing it is not paranoid.
Sources
All quotations above are from OpenAI's official documentation, captured 2026-08-31:
- Measurement Pixel — developers.openai.com/ads/measurement-pixel
- Conversions API — developers.openai.com/ads/conversions-api
- Ads Manager availability — help.openai.com
- Conversion measurement — help.openai.com
Previous wording is quoted from our own 2026-08-28 capture of the same two developer pages. Everything outside the block quotes and the documented tables is Soku's analysis, not OpenAI's.










