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.
X Ads API 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.
X Ads API Custom Audiences depends on exact identifier normalization, SHA-256 hashing without a salt, payload limits, and the correct advertiser account role.
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
100 usersminimum matched, active in 90 days, before an audience is targetable
2,500 / 5MBmax operations and payload size per Audience API request
1,500 / 1 minAudience API's own per-account rate limit
60,000 / 15 minConversion API event ceiling per account
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.
The official X Ads API documentation provides reference material for advertiser endpoints, audience workflows, authentication, and account permissions.
X Ads API Custom Audiences implementations should normalize email addresses and phone numbers before hashing, then test the resulting payload against a known fixture.
A reliable X Ads API Custom Audiences workflow records the audience job response and checks processing status instead of assuming that an accepted request is complete.
Review X Ads API Custom Audiences permissions before diagnosing a hashing failure.
Use separate tests for audience uploads and Conversion API events because their token and role requirements can differ.
Before uploading an audience, create a deterministic normalization test for every supported identifier. Trim whitespace, lowercase where required, format phone numbers consistently, and hash only after normalization. This makes X Ads API Custom Audiences results reproducible across languages and workers.
Keep the audience job identifier and processing status in your database. An accepted request is not the same as a populated audience, and a delayed status should not trigger duplicate uploads. X Ads API Custom Audiences jobs are easier to operate when retries are idempotent.
For Conversion API events, verify the advertiser account, token role, event source, and timestamp together. A valid hash cannot compensate for a token that lacks the required account permission. Log these checks without storing raw customer identifiers.
Finally, test small fixtures before sending production volumes. A staged X Ads API Custom Audiences rollout catches normalization, permission, payload, and status-handling errors while the blast radius is still limited.