Switching ad trackers? Test what it sends back to each ad platform
Published 2026-10-18
When you replace an ad tracker, test what it sends back to each ad platform, not the dashboard. The dashboard is what you see in the demo. The conversions it sends back are what each ad platform sees. Each platform wants them in its own format and by its own deadline, and in five places a platform’s own pages give two different rules.
What an ad tracker does, in four steps
- It stores the click ID when a visitor lands from an ad.
- It ties the click ID to the sale. The sale often comes later and from somewhere else: a CRM, a phone call, a renewal.
- It sends the conversion back to each ad platform’s server-side API, with the click ID and hashed customer data such as an email address.
- It joins ad spend and revenue in its own reports.
Steps 1 to 3 decide which sales each ad platform receives. Step 4 is the dashboard. A trial that only looks at step 4 never tests steps 1 to 3.
What each ad platform expects
Read on 12 October 2026 from each platform’s own developer and help pages. Every value is in the sources under the article.
| Platform | Click ID in the URL → field in the API | Duplicate check | How old an event can be when sent |
|---|---|---|---|
| Meta | fbclid → fbc, as fb.1.<time>.<fbclid>, not hashed | event_id + event_name, 48 hours | 7 days after the event. 62 days for physical store sales |
| Google Ads | gclid, gbraid or wbraid → adIdentifiers | transactionId, window not stated | 90 days with a GCLID. 63 days with customer data only |
| Microsoft Advertising | msclkid → userData.msclkid, a UUID | eventId, window not stated | 7 days by API. 90 days by offline import |
| TikTok | ttclid → user.ttclid | event_id, 48 hours | Not stated for web. 28 days for offline uploads |
rdt_cid → click_id | conversion_id, sent within 2 days | 7 days after the event | |
| Snapchat | ScCid → sc_click_id | event_id, 48 hours | 7 days or 37 days. Two pages disagree |
epik or the _epik cookie → click_id | event_id + event_name, 48 hours | Not stated. “Real time” or a lag of up to one hour | |
li_fat_id → LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID | eventId. The browser tag’s event wins | 90 days |
Two columns need a second look:
- Late sends. Most limits count from the time on the event, not from the click. A sale sent 8 days after the time it carries is refused by Meta’s web events and Microsoft’s API, too late for Reddit, and possibly too late for Snapchat. Meta rejects the whole request it arrives in. LinkedIn still takes it, and so does Google with a GCLID inside its 90 days. That happens when a tracker sends in weekly batches, or stamps a sale with the order date and sends it when payment clears. Ask how soon after a sale it sends, and which time it puts on the event.
- Which duplicate survives. When the Insight Tag and the API send the same event ID, LinkedIn discards the API event and counts the tag event. TikTok and Pinterest keep whichever arrives first.
One email address, five hashes
Seven of the eight platforms require a hashed email, and Reddit takes it hashed or plain. All eight give a rule for normalising it first, and they do not agree. Here is one address, normalised by each platform’s own rule and hashed with SHA-256:
| Platforms | Normalised address | SHA-256, first 8 characters |
|---|---|---|
| Meta, TikTok, Snapchat, Pinterest, LinkedIn | jane.doe-smith+ads@gmail.com | b56a7a2d |
| Google Ads (rule for gmail.com), Microsoft Advertising, Reddit’s API guide | janedoe-smith@gmail.com | ae89c237 |
| Reddit’s help centre | janedoesmith@gmail.com | 0a9b869f |
| Google’s C#, PHP, Ruby and Perl code samples | janedoe-smith+ads@gmail.com | 897dbd37 |
| Google’s Python upload example | janedoe-smithads@gmail.com | 3cc070e5 |
The address as typed was Jane.Doe-Smith+ads@Gmail.com. The written rules give three hashes, and
Google’s own code samples add two more. A hash matches only when both sides hashed the
same string, so a tracker that normalises once and sends one hash to every platform gets the rule right
for some platforms and wrong for others. A wrong hash does not cause an error. The sale arrives, and the
platform cannot tie it to a person by email. That shows up as a lower match rate, not as
a failure.
Where a platform’s own pages disagree
- Snapchat, event age. The Parameters page says
event_time“cannot be more than 7 days in the past”. The Introduction says events can go back 37 days. - Snapchat, purchases. The Using the API page puts a purchase’s
transaction_idinevent_id, deduplicated within 48 hours. The Deduplication page pairs it withcustom_data.order_idinstead, for up to 30 days. - Reddit, email. The API guide removes dots and the
+alias. The help centre removes every non-alphanumeric character, sodoe-smithbecomesdoesmith. - LinkedIn, lowercase. The API schema says an email “must be converted to lower case”. The FAQ calls it “recommended”.
- Google, +alias. Both Google pages say to drop the dots and the
+aliason gmail.com. The code samples on the Google Ads API page do not: C#, PHP, Ruby and Perl drop only the dots, and Python drops the+sign but keepsads.
None of these is your problem to solve. It is a question for any tracker you test: which rule does it follow, and how does it know the result matches?
How to test a tracker during the trial
- Click your own ad on each platform you run. Compare the click ID in the landing page URL with the
one the tracker stored. They must be identical, character for character. For Meta, compare the fbclid at the end of
fbc. - Send a test conversion into each platform’s test tool. Meta and TikTok use a
test_event_code, Reddit atest_id, Snapchat a/events/validateendpoint, Pinteresttest=true. Google offersvalidateOnly, which checks a request without storing it. Microsoft’s API page names no test tool, but its offline import takes sandbox uploads, which reports do not attribute. LinkedIn’s Payload Builder writes to production. Meta says events sent with a test code “are not dropped”: they count in Events Manager and in ad measurement. - Fire the browser tag and the server event for one order. Check the platform counts one conversion, not two. This is the deduplication key from the table.
- Time the send. Note when a test sale happens and when it reaches each platform’s test tool. Ask which time the tracker puts on the event: the order, the payment or the send.
- Use an awkward email. Capitals, a dot, a hyphen and a
+alias, like the one above. Ask the vendor which hash went to each platform. - Reconcile one week. Count the orders in your own system, then the conversions each platform received from the tracker. Every gap needs a reason.
Step 1 compares two click IDs, and it raises a question to settle before you sign. Which click ID should the tracker send back: the one the ad platform created, or its own? They look alike, and there are two kinds of click ID that never swap.
Sources
- Meta's Conversions API takes the click ID in the fbc parameter, in the form version.subdomainIndex.creationTime.fbclid. The version is always fb, and a server that generates the value without saving an _fbc cookie uses 1 as the subdomain index. verified 2026-10-12
- Meta: email must be trimmed of leading and trailing spaces and lowercased before SHA-256 hashing. fbc, the client IP address and the user agent must not be hashed. verified 2026-10-12
- Meta deduplicates a server event against a browser event when the same event_id and event_name (eventID and event in the browser) reach the same Pixel ID within 48 hours. verified 2026-10-12
- Meta returns an error for the entire request if any event_time in it is more than 7 days in the past. verified 2026-10-12
- Meta: offline and physical store events with physical_store as action_source should be uploaded within 62 days of the conversion. Test events are sent with a test_event_code from Test Events. Events sent with test_event_code are not dropped: they flow into Events Manager and are used for targeting and ads measurement. verified 2026-10-12
- Google Ads: starting 15 June 2026, UploadClickConversions requests fail if the developer token has not previously sent such requests, and Google points to the Data Manager API instead. The page's prose removes the dots and the + suffix from gmail.com and googlemail.com usernames, but its C#, PHP, Ruby and Perl code samples remove only the dots, and its Python upload example removes the . and + characters and keeps the text after the +. verified 2026-10-12
- Google's Data Manager API carries the click ID in adIdentifiers as gclid, gbraid or wbraid. Within one conversion action, Google Ads uses transactionId to deduplicate conversions sent from different sources. validateOnly checks a request for errors without ingesting data. verified 2026-10-12
- Google Ads accepts a conversion with a GCLID if it is no older than 90 days, and a conversion with personally identifiable information for enhanced conversions if it is no older than 63 days. verified 2026-10-12
- Google's Data Manager formatting rules: lowercase the email. For gmail.com and googlemail.com, remove all dots before the @, and remove the plus sign and all characters that follow it in the local part. Other domains keep their dots and plus signs. The client IP address is not hashed. verified 2026-10-12
- Microsoft Advertising's Conversions API: auto-tagging appends msclkid to the landing page, and userData.msclkid must be a valid UUID. A shared eventId, with the same UET tagId and eventName, deduplicates UET and API events. eventTime must be within the last 7 days. verified 2026-10-12
- Microsoft Advertising's email rule: trim whitespace from both ends, remove all dots from the user portion, remove any +alias from the end of the user portion, lowercase the whole address, then SHA-256 hash it as lowercase hex. verified 2026-10-12
- Microsoft Advertising offline conversions must have a conversion time within the last 90 days, otherwise the operation fails. Duplicates with the same MicrosoftClickId and ConversionTime are ignored. Offline conversions uploaded in sandbox for testing are not attributed in sandbox reporting. verified 2026-10-12
- TikTok appends ttclid to the landing page URL on an ad click, and the Events API takes it in user.ttclid. verified 2026-10-12
- TikTok deduplicates on event_source_id, event and event_id: it keeps the first event and discards later ones received within 48 hours, and tries to merge an event received within 5 minutes into the first. verified 2026-10-12
- TikTok: for offline events, you have 28 days to upload your Offline Event Set data. verified 2026-10-12
- TikTok Events API: email must be trimmed and lowercased before SHA-256 hashing. IP address and user agent are sent unhashed. verified 2026-10-12
- TikTok: copy the test code from the Test Events tab and add it to the API request as test_event_code, and remove it before switching to production. verified 2026-10-12
- Reddit: the rdt_cid value in the landing page URL must match data.events[].click_id in the Conversions API request. verified 2026-10-12
- Reddit deduplicates on conversion_id with the same event type, and events must be sent within two days for proper deduplication. verified 2026-10-12
- Reddit's Conversions API guide: events must be sent within seven days after they occur, and the local part of an email address should have any dots removed and any text after a plus sign removed. verified 2026-10-12
- Reddit's help centre: strip the email alias from the first + to the end of the username, and remove all non-alphanumeric characters from the username. verified 2026-10-12
- Reddit: match keys such as email can be shared unhashed or pre-hashed. verified 2026-10-12
- Reddit: copy the test ID from Event Testing in Ads Manager and set it as test_id in the POST request. verified 2026-10-12
- Snapchat's Conversions API takes the ScCid click ID in the sc_click_id field, and deduplicates on event_id and timestamp within a 48 hour window. For purchase events, event_id can carry the Pixel's transaction_id values. verified 2026-10-12
- Snapchat's Parameters page: event_time cannot be more than 7 days in the past. Email: trim spaces and convert to lowercase before hashing. verified 2026-10-12
- Snapchat's Conversions API introduction: events can go a maximum of 37 days back to be eligible to be reported via the Conversions API. verified 2026-10-12
- Snapchat's Deduplication page pairs the Pixel transaction_id with custom_data.order_id for purchases, for up to 30 days. verified 2026-10-12
- Snapchat's Conversions API provides Test Event Tool endpoints, including /events/validate, to send test events and validate them. verified 2026-10-12
- Pinterest: send the _epik cookie or the epik URL parameter as user_data.click_id. Pinterest keeps the first event and removes duplicates with the same event_id and event_name within 48 hours. Send event data in real time or with a maximum lag of one hour. verified 2026-10-12
- Pinterest: email is sent as the SHA-256 hash of the address in lower case. Requests with test=true go to a sandbox, visible under Test events in Ads Manager. verified 2026-10-12
- LinkedIn: send li_fat_id as LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID. LinkedIn appends li_fat_id only when enhanced conversion tracking is on. verified 2026-10-12
- LinkedIn: when an Insight Tag event and a Conversions API event share the same event ID, LinkedIn discards the Conversions API event and counts only the Insight Tag event. verified 2026-10-12
- LinkedIn Conversions API schema: the conversion timestamp must be within the past 90 days, and an email must be converted to lower case, without any whitespace, then hashed with SHA-256. verified 2026-10-12
- LinkedIn's Conversions API FAQ says it is recommended to convert emails to lowercase before hashing them for better match rates. verified 2026-10-12
- LinkedIn's Conversions API Payload Builder creates events in the production environment. verified 2026-10-12