X Ads API Custom Audiences & Conversion API: The Hashing Rule and Token Gate Nobody Reads
An approved X Ads API app (see our X Ads API access guide) can call every endpoint in the product. That does not mean Custom Audiences and the Conversion API behave the way most integrators expect. Both accept a request, return a success response, and then quietly do nothing useful — because a normalization step was skipped or the wrong token was used.
Custom Audiences: what actually has to be true before upload
Every identifier gets hashed the same exact way
Email, phone, X handle, X user ID, and device ID must each be normalized first (lowercase, trimmed, correct casing per identifier type), then hashed with SHA-256 and no salt, with the output lower-cased. There is no per-identifier variation X will accept.
A mismatch is invisible, not an error
If normalization is wrong — a stray space, an uppercased email, the wrong Android ID casing — the hash simply will not match an X user. The API does not return a validation error for bad hashing; the user is just absent from the audience.
Hard payload ceilings
A single Audience API request is capped at 2,500 operations and 5,000,000 bytes. The Audience endpoint itself carries its own 1,500-request-per-1-minute rate limit, separate from the account-wide limits already covered in our X Ads API rate-limit guide.
A minimum size gate on targeting
An audience only becomes usable for ad targeting once it matches at least 100 users active on X within the past 90 days — a threshold X lowered from 500 users under the current Audience API.
Conversion API: the token check most integrations miss
Ads API access is necessary, not sufficient
Conversion API sits on top of the same Ads API access already covered in our access guide — but that alone does not authorize a token to send conversion events.
The account-role check
Any access token used for Conversion API calls must belong to a user holding AD_MANAGER or ACCOUNT_ADMIN account-level access, verified via the authenticated_user_access endpoint. A token from a Campaign Analyst or Creative Manager role — both valid Ads API roles — will not pass this check.
Identifiers required per event
Every conversion event needs at least one of: X Click ID (twclid, unhashed), a SHA-256-hashed email, or a SHA-256-hashed phone number. IP address and user agent can be sent, but only alongside one of those three — neither works alone.
A published ceiling, cross-checked
Conversion API events are capped at 60,000 per account per 15-minute window — the same figure already listed in our X Ads API rate-limit breakdown, confirming it applies at the account level regardless of which endpoint triggers it.
How the pieces actually connect
- An Event Source (X Pixel) and at least one Conversion Event must exist inside Ads Manager before the Conversion API can send anything — the API cannot create the event source itself.
- A Custom Audience starts as an empty “shell” created through the Audience API, then users are added or removed against that shell using operation_type Update or Delete.
- Every identifier going into that shell is normalized and hashed client-side before it ever reaches X — there is no server-side normalization step to fall back on.
- If the same event fires through both the X Pixel and the Conversion API, both must carry the same conversion_id, or the same purchase gets counted twice in reporting.
- Before any of this goes to production, the token being used is checked against the AD_MANAGER/ACCOUNT_ADMIN requirement — not just against whether the app has Ads API access.
The numbers that actually matter
Where syncs quietly break
- An audience shows “TOO_SMALL” for hours after a large upload — this is a processing-lag artifact of the async matching job, not a rejection.
- Hashed values never match because a normalization step (spaces, casing, device ID format) was skipped — X returns no “bad hash” error, the user is just never matched.
- Conversion API calls return HTTP 200 but reporting numbers look inflated — almost always a missing or mismatched conversion_id causing double-counting against the same Pixel event.
- Conversion API calls fail the permission check even though the app has valid Ads API access — the token belongs to a role below AD_MANAGER/ACCOUNT_ADMIN.
None of this is exotic — it is exactly the kind of integration detail that looks trivial in the reference docs and then costs a week of silently missing conversions or an unusable audience before anyone notices. Preparing this correctly the first time, alongside the access approval and rate-limit handling covered in our other X Ads API guides, is what our X API setup and approval support covers end to end.
Sourced from X's official Ads API documentation (docs.x.com/x-ads-api/audiences and docs.x.com/x-ads-api/measurement/web-conversions), fetched live 2026-08-06.