- Every platform here deduplicates on an ID you supply, but the field is called something different on each:
event_idoreventID(Meta, TikTok, Pinterest),client_dedup_id(Snapchat tag),eventId(LinkedIn),order_id(Google Ads) andtransaction_id(GA4). - The 48-hour window is the common rule for Meta, TikTok, Snapchat and Pinterest. LinkedIn, Google Ads and GA4 do not state a window on the pages we checked.
- Batch limits range from 25 events (GA4) to 5,000 (LinkedIn). Max event age ranges from 72 hours (GA4) to 7 days (Meta) and 90 days (LinkedIn).
- Click IDs are not interchangeable:
fbclid,ttclid,ScCid,epik,li_fat_idandgclid/gbraid/wbraideach only work on their own platform. - Where we could not confirm a fact from a page we fetched, the tables say “not confirmed” instead of guessing. Table data checked October 2026.
Send the same purchase to Meta, TikTok, Snapchat, Pinterest and LinkedIn and you meet five different sets of rules for the same idea. Each one wants an ID so it can tell your browser tag and your server apart. Each has its own batch size, its own idea of how old an event may be, and its own spelling of the click ID.
The details sit in five documentation sites. This article puts them in one place. It is a reference first and an explainer second: skip to the tables, and read the notes underneath when a cell surprises you.
How this table was built, and how far to trust it
Every value below was taken from an official documentation page fetched in October 2026, and each source is listed at the end of the article. Where a page did not state a value, or where two pages of the same vendor disagree, the cell says “not confirmed” or “conflict”. We did not fill gaps from memory, from forum posts or from third-party plugin docs.
One caveat: documentation changes. LinkedIn, for example, versions its API monthly, and its FAQ documented that marketing version 202510 sunsets on 15 October 2026. See “How to re-check any cell” near the end.
Table 1: deduplication, key by key
If you read only one table, read this one. Dedup only works when four things line up: the ID, the event name, the time window, and (on several platforms) the destination asset.
| Platform | Dedup key | Window | Which event is kept | Must also match |
|---|---|---|---|---|
| Meta | Pixel eventID = API event_id
|
48 h from first event | Generally the first received | Same event name; keys must match exactly |
| TikTok |
event_source_id + event + event_id
|
48 h; copies within 5 minutes are merged | First kept, later copies dropped | Same Pixel code and event name |
| Snapchat | Pixel client_dedup_id = API event_id; purchases also transaction_id = order_id
|
48 h; up to 30 days for the order pair | Not confirmed | Same Pixel ID and event name; the dedup-ID pair takes precedence |
event_id and event_name
|
48 h | Not confirmed | Same event_id and event_name; offline events cannot be deduplicated |
|
Tag event_id = API eventId
|
Not confirmed | Insight Tag event kept; API event discarded | Same ad account; a separate conversion rule per source | |
| Google Ads |
order_id (transaction ID) |
Not confirmed | Duplicates are not counted | Same conversion action, time and unique ID |
| GA4 Measurement Protocol |
transaction_id on purchase
|
Not confirmed | Not confirmed | Web streams only; same user |
Notes on Table 1
Meta. Per Meta, events are only deduplicated if received within 48 hours of the first event with that ID, and when browser and server events do not differ meaningfully it generally prefers the one received first. There is a fallback on event_name plus fbp and/or external_id, but it only works when the browser event arrives first. The full story is in Meta Conversions API deduplication: event_id explained (source: Meta, deduplicate Pixel and server events).
TikTok. TikTok deduplicates on event_source_id (the Pixel code), event and event_id. It keeps the first copy and drops later ones within 48 hours. The 5 minutes is a merge window, not a delay: a copy arriving within 5 minutes of the first has its data merged into it, for example an added email. A separate fallback on Pixel code, event and the _ttp cookie, also with a 5-minute window, applies only when the Events API payload has no event_id, so always send one (TikTok, About event deduplication; TikTok developer docs, event deduplication).
Snapchat. Snap’s deduplication guide pairs the Pixel’s client_dedup_id with the Conversions API event_id (48 hours) and, for PURCHASE only, the Pixel’s transaction_id with the API’s order_id, which is protected for up to 30 days. When both pairs exist, the dedup-ID pair takes precedence. Snap says to treat the values as opaque strings: same casing, same whitespace, and never a placeholder like null or NA (Snap, Deduplication; Snap, Best practices).
Pinterest. Pinterest asks you to pass event_id and event_name in every source and to keep the ID identical for each redundant event; it removes duplicates within 48 hours. In the API reference event_id is a required field, and order_id is recommended to help deduplicate when necessary. Pinterest also notes that events which took place offline cannot be deduplicated (Pinterest developers; Pinterest v5 OpenAPI description).
LinkedIn. LinkedIn’s rule is the one most likely to surprise you. You create one conversion rule for the browser source and one for the server source. If an Insight Tag event and a Conversions API event from the same account share an eventId, LinkedIn counts the Insight Tag event and discards the API event, so the Insight Tag conversion should show the higher count when it works (LinkedIn, Deduplication). More in LinkedIn Conversions API for WordPress.
Google Ads. Google’s help page says Google Ads does not count duplicate conversions and returns an error naming them; uniqueness is judged on the conversion action name, the conversion time and the relevant unique identifier. order_id is optional but strongly recommended, and if you set it on import you must use it for any adjustments (Google Ads Help; Google Ads API, upload clicks). For enhanced conversions for web, Google states you need the transaction ID so tag and API conversions can be matched (Google Ads Help).
GA4. Google Analytics deduplicates purchase events that share a transaction ID, but only for web streams, and sending an empty string as the ID makes it deduplicate all such events together. No time window is stated, and whether this applies across a gtag event and a Measurement Protocol event is not confirmed (Google Analytics Help). We found no event_id deduplication key in the Measurement Protocol documentation.
Table 2: limits and test tools
Limits decide how you design your queue: a retried delivery can be older than a platform allows.
Notes on Table 2
Meta is strict about age and batches. Events can be dated up to 7 days in the past; a single event_time older than that makes Meta return an error for the whole request, and one invalid event rejects the entire batch. Offline events get 62 days. Meta also documents no specific rate limit for the Conversions API. Careful with the test code: Meta states that events sent with test_event_code are not dropped. They flow into Events Manager and are used for targeting and measurement, so remove the code in production (Meta, using the API).
Snapchat contradicts itself on age. The Conversions API parameters page says event_time cannot be more than 7 days in the past, while the introduction page says events can be dated at most 37 days back. We could not tell which applies where, so the cell says conflict. If your queue can hold events for days, test an old event against /validate and design for the 7-day figure (Snap, Parameters; Snap, Introduction). Batches go up to 2,000 events (Snap, Get started).
LinkedIn is the most generous, and the most throttled. You may send 5,000 events in a batch, but only 600 requests a minute and 500,000 a day per member access token, and the API error table says conversion time must fall within the past 90 days. A batch is all-or-nothing on validation errors (LinkedIn, Conversions API; LinkedIn, FAQ). Expect up to 72 hours (24 to ingest, 48 for reporting) before data is complete.
TikTok. The Events API takes up to 1,000 events per request (a larger request is rejected whole) and allows 1,000 QPS per ad account. An event-age limit is not stated on the pages we read (TikTok, Events API 2.0).
Pinterest. The API reference caps data at 1,000 items and states a rate limit of 5,000 calls per minute per ad account. Test requests with test=true are limited to 20 events per batch. An HTTP 200 can still contain failed events, so read the per-event status. An event-age limit is not stated on any page we could read.
Google Ads. Google’s quota page limits UploadClickConversions to 2,000 conversions per request, with a daily operations quota that depends on access level. It also states that from 15 June 2026 this service is restricted for new adopters, who are directed to the Data Manager API (Google Ads API, quotas). The click-age rule for imports was not stated on the pages we fetched, so the cell stays “not confirmed” even though the figure is widely repeated.
GA4 Measurement Protocol. 25 events per request, 25 parameters per event, 130 kB body, events backdated up to 72 hours. Beyond that, the default (RELAXED) behaviour accepts the event but overrides the timestamp to 72 hours ago, which can silently move your data; ENFORCE_RECOMMENDATIONS rejects it. The documentation also warns that for conversion attribution, events received later than 48 hours may not be processed as expected (GA4 Measurement Protocol, sending events). See also GA4 Measurement Protocol limits.
Table 3: click IDs, hashing and required fields
This is where most “low match rate” problems start. A click ID is only a pointer into one platform’s own click log, so you must capture the right one from the landing-page URL and send it to the right place.
Notes on Table 3
Meta. The fbc value is the click ID wrapped in a version, a domain-level index and a creation timestamp in milliseconds. When the _fbc cookie is missing you can build it from the fbclid, read from the query string and left unmodified because it is case-sensitive. Neither fbc nor fbp is hashed (Meta, fbp and fbc). Meta’s hashing rules for the other fields are in our Meta Conversions API for WordPress guide.
TikTok. TikTok’s help center recommends sending ttclid through the Events API for all website events and holding on to it for the session. TikTok’s developer docs say the Pixel stores it in a first-party cookie called ttclid and recommend keeping it for 28 days or more. Email, phone and external ID are SHA-256 hashed; IP and user agent are not (TikTok, matching events).
Snapchat. sc_click_id takes the value of the &ScCid= query parameter; alternatively, pass the full landing URL in event_source_url and Snap extracts it. Normalize before hashing (trim, lowercase email, digits-only phone with country code) and use lowercase hex (Snap, using the API).
Pinterest. click_id holds the _epik cookie value or the &epik= URL parameter. At least one of hashed email, hashed mobile ad IDs, or the pair IP plus user agent is required in user_data.
LinkedIn. li_fat_id exists only if first-party cookies are enabled for the Insight Tag (enhanced conversion tracking). LinkedIn states the mapping to a member profile is kept for 365 days, so it stays usable after the browser cookie expires. A request must carry at least one of: hashed email, li_fat_id, Acxiom ID, IP address, Google advertising ID, first and last name, external IDs or a lead form URN.
Google Ads and the three IDs. A gclid is captured when someone clicks your ad and lands on your site; a gbraid appears when a web ad click leads to an iOS app; a wbraid when an iOS app ad click leads to a web page. Where both a gclid and a gbraid are available Google recommends setting both, and wbraid cannot be combined with custom variables. Details in GCLID, GBRAID and WBRAID explained.
The same purchase, five platforms, one shared ID
The pattern that makes the tables manageable is to decide on the ID once, at the moment the event occurs, and then hand the same value to every consumer. For a purchase that is the order number; for anything else, a UUID created once and stored with the event.
In payload terms, a Pinterest server event and a LinkedIn server event for the same order differ in shape but share one value:
// Pinterest: POST /v5/ad_accounts/{id}/events
{ "data": [{ "event_name": "checkout", "event_id": "order-1042",
"action_source": "web", "event_time": 1790000000, ... }] }
// LinkedIn: POST /rest/conversionEvents
{ "conversion": "urn:lla:llaPartnerConversion:123",
"eventId": "order-1042", "conversionHappenedAt": 1790000000000, ... }
Note the timestamps: Pinterest takes Unix seconds, LinkedIn takes milliseconds, and Google Ads wants a formatted string with a timezone. Mixing these up gives “event too old” errors that are really unit errors.
Decision flow: which ID goes where
-
Does a browser tag fire the same event? Then both sides must send the shared ID. If the server is the only sender you can still send an ID: Pinterest requires
event_id, and Meta recommends it. -
Is it a purchase? Use the order number. It is unique, it survives retries, and it also doubles as Google Ads
order_id, GA4transaction_id, Snaporder_idand Pinterestorder_id. Otherwise create a UUID once. - Did the visitor arrive from an ad click? Forward the click ID that belongs to that platform. If not, rely on hashed email or phone, IP address and user agent.
On WordPress there is a catch: full-page caching can serve the same HTML, and so the same embedded ID, to many visitors. The browser side should create the ID per event, not per page build. The same reasoning applies to click IDs, which only exist in the landing URL: if you do not store them on the first page view, they are gone by checkout. For why browsers lose data in the first place, see Safari ITP and WordPress cookies and why your WordPress analytics data is missing.
How to re-check any cell
This table is dated October 2026. Platforms change limits without announcements, so treat any number you are about to build on as a claim to verify. A quick routine:
- Open the primary page. Use the links in this article. For LinkedIn, check the version selector, because the docs are versioned monthly. Look at the page’s “last updated” date where one is shown.
- Search the page for the term. Search for “48”, “batch”, “days”, “rate” and the ID field name rather than skimming.
-
Run the platform’s test tool. Meta Test Events, TikTok Test Events, Snap
/validate, Pinterest?test=true, GA4’s validation server, Google Adsvalidate_only. Send one event with an old timestamp and one oversized batch. - Look at the diagnostics. Meta’s Event Deduplication tab and TikTok’s Event Details show whether keys are being matched; LinkedIn’s conversion breakdown should show the Insight Tag count above the API count.
The most reliable evidence is your own log of what each platform returned for each event.
Where Traculo fits
Traculo’s WordPress plugin forwards events from Traculo’s servers to Google Analytics 4, Meta, Google Ads, LinkedIn, TikTok, Snapchat, Pinterest and Plausible, and keeps a delivery log with the response from each integration, so you can see per event whether a platform accepted or rejected it. Traculo sends one event per request, with the stored event’s numeric ID as event_id (Google Ads gets the order ID where there is one). That log is exactly where an “event too old” or missing-ID error will show up.
Frequently asked questions
Can I use the same event_id on every platform?
Yes, and it is the cleanest approach. In practice each platform compares IDs inside your own account or asset, so a shared value does not collide. What must differ is the value for each distinct conversion: two different orders must never share an ID.
Does Google Ads or GA4 deduplicate on event_id?
No. Google Ads uses the order ID (with the conversion action and time), and GA4 uses transaction_id on purchase events. Neither has an event_id dedup key.
What happens if my server event is older than the limit?
It depends on the platform. Meta rejects the whole request if any event_time is more than 7 days old. GA4’s default mode keeps the event but moves its timestamp to 72 hours ago. LinkedIn returns a validation error for conversion times beyond 90 days. Check the delivery response rather than assuming success.
Why does LinkedIn show fewer API conversions than Insight Tag conversions?
That is deduplication working. LinkedIn counts a duplicate under the Insight Tag conversion and removes it from the API count, so the tag number is typically higher.
Related reading
- Meta Conversions API for WordPress: the complete guide
- Meta Conversions API deduplication: event_id explained
- GA4 Measurement Protocol limits: the cheat sheet
- GCLID, GBRAID and WBRAID explained
- LinkedIn Conversions API for WordPress
- TikTok, Snapchat and Pinterest Conversions API on WooCommerce
- GA4 server-side tracking for WordPress
- Server-side tracking for WordPress: a beginner’s guide
Want to see which of these platforms accepted each event? Take a look at Traculo’s integrations and the server-side event tracking delivery log.