---
title: "TikTok Events API deduplication: match the pixel's event_id"
description: "Your server copy of a TikTok event has no event_id or a different one, so TikTok may count the conversion twice. How to pass one ID through to the Events API."
updated: "2026-10-23"
url: "https://ispixelworking.com/guides/tiktok.server_copy_without_event_id/generic"
---

# TikTok Events API deduplication: match the pixel's event_id

Fix guide · Any website · advanced · about 60 min · updated 2026-10-23

For the findings “TikTok server events have no event ID” (`tiktok.server_copy_without_event_id`) and “TikTok server events carry a different event ID” (`tiktok.server_event_id_mismatch`).

## What this means

Your site sends its TikTok events twice, on purpose: once from the browser through the TikTok Pixel, and once more to your own server, which forwards them to TikTok through the Events API. TikTok recommends the Events API as a second channel together with the pixel, as long as both copies of an event can be recognized as one.

The server copy we saw does not carry the browser event's ID:

- **No event ID:** the request to your server has the event name but no ID.
- **A different event ID:** the request carries an ID, but not the one the browser event had.

TikTok deduplicates on the pixel code (`event_source_id`), the event name and the `event_id`. It keeps the first copy and discards later ones within 48 hours. If the server event carries a different ID, both copies count. If it carries no ID at all, TikTok can fall back to the `_ttp` cookie, but only within 5 minutes, only if first-party cookies are on and your server sends `ttp`; otherwise both count too.

We report this as **possible**: we can see the request from the browser to your server, but never the request from your server to TikTok, so check the server side yourself.

Why it costs you money:

- Purchases and leads count twice in TikTok, so results and return on ad spend look better than they are.
- Campaigns learn from inflated numbers and may spend on the wrong people.
- When someone later "fixes" the double counting by switching one side off, you lose the reason you added the server copy.

## How to confirm it yourself

1. Open your page in a **private (incognito) window**, open developer tools (F12) and go to the **Network** tab. Accept cookies and trigger the conversion (for example, submit a test lead).
2. Filter by `analytics.tiktok.com/api/v2/pixel`, open the request for that event and note `event` and `event_id` in the payload. An empty `event_id` means the browser event has no ID at all (see "TikTok events have no event ID").
3. Clear the filter and find the request your site sends to its own server at the same moment: a form submission, an `/api/...` call, or a request to your server-side tag manager address. Open its payload.
4. Compare: does it contain the same ID? If there is no ID, or a different one, the copies cannot be matched.
5. In TikTok Events Manager, the pixel's detail page shows "Browser", "Server" and "Server & Browser" figures. TikTok says that if the "Server & Browser" numbers are too low, you should check your deduplication.

## How to fix

The rule: **one action, one ID, created in one place and used by both copies.**

1. **Pick where the ID is created.**
   - For purchases, the order number is ideal: the confirmation page can use it in the browser, and your backend already has it. TikTok suggests order numbers or transaction IDs.
   - For leads, page views and clicks, create a random ID in the browser when the action happens (for example `crypto.randomUUID()`), or create it on your server when it renders the page or handles the form, and hand it to the browser.
2. **Pass it to the pixel** in the third argument of `ttq.track`:

   ```js
   const eventId = crypto.randomUUID();
   ttq.track('Lead', {}, { event_id: eventId });
   ```

3. **Send the same value to your server** with the request it already receives: a hidden form field, a property in your `/api/...` call, or an event parameter in your server-side tag manager feed.
4. **Use it as `event_id` in the Events API event**, with the same event name and your pixel code as `event_source_id`:

   ```json
   {
     "event_source": "web",
     "event_source_id": "<PIXEL CODE>",
     "data": [{
       "event": "Lead",
       "event_time": 1792771200,
       "event_id": "4b1f0c6e-2f7d-4f6b-9a51-2d3c8e7f9a10",
       "user": { "ttclid": "<from the ttclid cookie>", "ttp": "<from the _ttp cookie>", "ip": "203.0.113.7", "user_agent": "Mozilla/5.0 ..." },
       "page": { "url": "https://example.com/contact" }
     }]
   }
   ```

5. **Do not create a second ID on the server.** A server that makes its own random ID, prefixes it, or sends a different value (a database row ID while the browser used the order number) produces a mismatch even though both copies "have an ID".
6. **Keep the names identical.** Event names are case-sensitive. TikTok renamed `CompletePayment` to `Purchase` and `SubmitForm` to `Lead` in 2025 and converts the old names automatically, but use the same name on both sides to be safe.
7. **With server-side Google Tag Manager:** use one variable for the ID in the web **TikTok Pixel** tag and pass it to the server container, where TikTok's **TikTok Events API (Official)** tag sends it as `event_id`. If you set GTM up through TikTok's interactive flow in Events Manager, TikTok configures an `event_id` variable for you. Check both containers in Preview mode: they must show the same value for the same event.
8. **With a partner integration or the Events API Gateway:** these handle IDs for events they collect themselves. A separate, older pixel that sends its own browser events will not match; remove it.
9. **Publish** and run a test conversion.

## Common causes

- The browser events have an empty `event_id`, so there is nothing for the server to copy.
- The server-side code was added later and never received the ID from the browser.
- Browser and server each generate their own random ID.
- The server sends a different identifier or a different event name.
- In server-side GTM, the web tag and the server tag read different variables.

## How to verify the fix

1. For one test conversion, the pixel's `event_id`, the ID in the request to your server and the `event_id` your server sends to TikTok are identical, and so are the event names.
2. Send a server test event with the `test_event_code` from the **Test Events** tab (**Test Server Events**) and check that browser and server copies arrive; remove the code afterwards.
3. Over the following days, the "Server & Browser" figures for the event grow.
4. Re-run the check on IsPixelWorking. The finding should be gone.

## Sources

- TikTok API for Business, Event Deduplication (keys, 48 hours, merge within 5 minutes, `_ttp` fallback, unique IDs, Server & Browser metrics): https://business-api.tiktok.com/portal/docs?id=1771100965992450
- TikTok API for Business, Events API 2.0 setup guide for Web (payload, `event_id` required when sending from pixel and Events API): https://business-api.tiktok.com/portal/docs?id=1771100865818625
- TikTok API for Business, Events API and Pixel setup with Google Tag Manager (interactive flow configures an `event_id` variable): https://business-api.tiktok.com/portal/docs?id=1799004052020225
- TikTok API for Business, Verify Events API setup: https://business-api.tiktok.com/portal/docs?id=1771100984456193
- TikTok Business Help Center, How to adopt TikTok's updated standard events (CompletePayment to Purchase, SubmitForm to Lead): https://ads.tiktok.com/resources/help/article/how-to-adopt-tiktoks-updated-standard-events?lang=en
- TikTok Business Help Center, Getting started with the Events API (second channel with the pixel): https://ads.tiktok.com/resources/help/article/getting-started-events-api?lang=en
