---
title: "How to set up the TikTok Events API (with deduplication)"
description: "TikTok Events API setup: partner apps, Events API Gateway, server-side GTM or direct code. Access token, payload, event_id deduplication, testing and fixes."
updated: "2026-10-23"
url: "https://ispixelworking.com/guides/tiktok.events_api_setup/generic"
---

# How to set up the TikTok Events API (with deduplication)

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


## What the TikTok Events API is and what it fixes

The TikTok Pixel sends events from the visitor's browser. The **Events API** sends them from a server: yours, your shop platform's, or one run by a service. This is server-side tracking for TikTok. The current version is Events API 2.0. TikTok recommends it "as a second channel together with your TikTok Pixel": both send the same key events, and TikTok deduplicates them through a shared event ID.

What the server copy helps with:

- **Events the browser loses.** A purchase your server records when the order is created still reaches TikTok if the visitor closed the tab before the thank-you page loaded, or if the browser blocked the pixel.
- **Better matching.** Server events can carry customer details you already have, such as the (hashed) email from an order, plus the visitor's TikTok click ID and browser ID. TikTok uses them to match events to people and credit conversions to your ads. Events Manager shows the result as an **EMQ** (Event Match Quality) score.
- **Control.** Your server decides what is sent and when.

We report "No server-side tracking detected" when we see no sign of server-side tracking. Server-to-server traffic is invisible from a browser, so this is not proof you have none. If you already send server events, go straight to "How to test and verify".

## What it does not fix

- **Consent.** Sending from a server does not change which consent you need. TikTok asks advertisers to provide notices and obtain consents as required by applicable laws. Where your pixel waits for cookie consent, your server events should respect the same choice; check how your tool treats visitors who reject cookies. We report technical behaviour only and cannot tell you what the law requires.
- **A broken pixel setup.** Several routes below (the Events API Gateway, most server-side Tag Manager setups) collect events in the browser and forward them, and server events usually take the click ID and browser ID from the pixel's cookies (`ttclid` and `_ttp`). If the pixel fires before consent, never fires after consent, runs twice or loses the click ID, the server copy inherits the problem. Fix those first: [fires before consent](https://ispixelworking.com/guides/tiktok.fires_before_consent/generic), [does not fire after consent](https://ispixelworking.com/guides/tiktok.not_firing_after_consent/generic), [duplicate events](https://ispixelworking.com/guides/tiktok.duplicate_pixel/generic), [click ID not stored](https://ispixelworking.com/guides/tiktok.click_id_not_set/generic).

## What you need before you start

- **Your pixel code.** Server events for a website go to the same pixel as the browser events: the pixel code is the `event_source_id` of every server event. You find it in TikTok Events Manager under **Tools > Events > Data sources**.
- **Access to the ad account** that owns the pixel, as an Admin or Operator.
- **An access token**, if your own code or server-side Tag Manager sends the events: in Events Manager, open the pixel, go to the **Settings** tab and click **Generate Access Token**. The token only works for pixels created under the same ad account. Keep it on your server, like a password.
- **An events plan.** List the events you will send, using TikTok's standard names where they fit: `Purchase`, `Lead`, `CompleteRegistration`, `InitiateCheckout`, `AddToCart`, `ViewContent`, `Contact`, `Subscribe`, `StartTrial` and others. (In 2025 TikTok renamed `CompletePayment` to `Purchase` and `SubmitForm` to `Lead`; old names are still accepted.) Names are case-sensitive and must be the same on browser and server. Decide where each event's ID comes from.
- **First-party cookies on** for the pixel (**Settings** tab of the pixel), together with Automatic Advanced Matching, as TikTok recommends. Without first-party cookies there is no `_ttp` browser ID to pass to the server.

## How much does the TikTok Events API cost?

TikTok does not list a fee for the Events API itself. The cost depends on the route:

- **Partner integrations** for shop platforms: depends on the platform's app (TikTok's own apps for Shopify and WooCommerce are free to install).
- **Events API Gateway:** self-hosted in your own Amazon Web Services account (cloud fees), or hosted for you. Stape, for example, lists $10 a month per pixel after a 7-day free trial.
- **Server-side Google Tag Manager:** Stape has a free plan for low traffic; on your own Google Cloud account, Google estimates about $45 a month per server and recommends at least two. TikTok's interactive GTM setup needs a Google Cloud billing account, though its test server usually costs nothing while used only for testing.
- **Direct integration:** your developer's time, plus hosting and upkeep.

## Pick a setup route

TikTok's Events Manager offers two starting points for web data: **Partner integrations** and **Manual setup** (TikTok Pixel only, Events API only, or TikTok Pixel + Events API). Open it under **Tools > Events > Connect data source > Web**.

| Route | Fits | Cost | Developer needed |
|---|---|---|---|
| Partner integration (TikTok's apps for Shopify, WooCommerce and other platforms) | Shops on a supported platform | Usually free | No |
| Events API Gateway | Any site with a working pixel | Cloud fees or hosting | No, if hosted for you |
| Server-side Google Tag Manager | Any site, best if you already use Tag Manager | Hosting | Usually |
| Data platforms (Segment, Tealium, RudderStack, Elevar and others) | Sites that already use one | Their pricing | Usually |
| Direct Events API integration | Any site | Developer time | Yes |

## Set it up without a developer

**Partner integrations.** TikTok's partner list marks Shopify, WooCommerce, Wix, PrestaShop, OpenCart, Adobe Commerce and several others as sending both pixel and Events API data; for some platforms, WordPress among them, it lists the pixel only. Connect the platform from Events Manager or from the platform's TikTok app, turn on its server-side or "Events API" option if it has one, and keep that integration as your only pixel installation: remove any TikTok base code pasted into your theme by hand, or events are counted twice.

**Events API Gateway.** TikTok's codeless option copies the events your pixel already collects and sends them to the Events API from a server you administer. TikTok says it avoids duplicates by matching IDs such as `event_id` or `_ttp`. The self-hosted version runs in your own AWS account, with an installation link generated by your TikTok representative; you then connect it on the pixel's **Settings** tab, in the **Events API Gateway** section. Hosting partners such as Stape run it for you. Like any pixel-based relay, it adds nothing where the pixel does not run.

## Set it up with a developer

**Server-side Google Tag Manager.** TikTok publishes an official server template, **TikTok Events API (Official)**, in the Tag Manager gallery, and recommends installing it through the interactive GTM flow in Events Manager. That flow needs a web container, a server container, a GA4 Measurement ID and a tagging server URL, and it fills in your pixel code and access token. It also sets up an `event_id` variable for deduplication.

**Direct integration.** Your backend sends events itself, for example a `Purchase` when payment is confirmed:

1. Generate an access token, as described above.
2. Send events in a POST request to `https://business-api.tiktok.com/open_api/v1.3/event/track/` with the headers `Access-Token: <your token>` and `Content-Type: application/json`.

A minimal website event:

```json
{
  "event_source": "web",
  "event_source_id": "<PIXEL CODE>",
  "data": [{
    "event": "Purchase",
    "event_time": 1792771200,
    "event_id": "order-10482",
    "user": {
      "ttclid": "<value of the ttclid cookie or URL parameter>",
      "ttp": "<value of the _ttp cookie>",
      "email": "<SHA-256 hash of the trimmed, lower-case email>",
      "phone": "<SHA-256 hash of the phone number in E.164 format>",
      "external_id": "<SHA-256 hash of your customer ID>",
      "ip": "203.0.113.7",
      "user_agent": "Mozilla/5.0 ..."
    },
    "properties": {
      "currency": "EUR",
      "value": 49.90,
      "content_type": "product",
      "contents": [{ "content_id": "SKU-123", "content_name": "Starter bundle", "price": 49.90 }],
      "order_id": "10482"
    },
    "page": { "url": "https://example.com/thank-you" }
  }]
}
```

`event_time` is a Unix timestamp in **seconds** (UTC). One request can carry up to 1,000 events; a request with more is rejected as a whole. TikTok recommends sending events in real time rather than in batches. A successful request returns HTTP 200 with `"code": 0` in the body; `40002` means an invalid payload (bad JSON, an unhashed email, too many events) and the message names the first invalid field, such as `data.2.event_id`.

## Prevent duplicate events between the pixel and the Events API

TikTok deduplicates on three keys: the pixel code (`event_source_id`), the event name and the `event_id`. It keeps the first copy it receives and discards later copies within 48 hours; if a later copy arrives within 5 minutes, TikTok tries to merge its data into the first. For the purchase above, the thank-you page sends:

```js
ttq.track('Purchase', {
  currency: 'EUR',
  value: 49.90,
  content_type: 'product',
  contents: [{ content_id: 'SKU-123', price: 49.90, quantity: 1 }]
}, { event_id: 'order-10482' });
```

TikTok suggests order numbers or transaction IDs; a random value works as long as the pixel and the Events API use the same one. Three things to know:

- **The pixel does not create an `event_id`.** TikTok asks you to choose a unique ID per event; if your code passes none, the field in the pixel's request stays empty (you can see it in the Network tab). See [TikTok events have no event ID](https://ispixelworking.com/guides/tiktok.missing_event_id/generic).
- **Without an `event_id`,** TikTok can fall back to the `_ttp` cookie, but only within 5 minutes, only when first-party cookies are on and your server sends `ttp`, and only by dropping the server copy. Don't rely on it.
- **Reused IDs drop real events,** because TikTok discards every later event with the same name and ID within 48 hours, also among pixel events. See [TikTok event IDs repeat across visits](https://ispixelworking.com/guides/tiktok.event_id_reused/generic).

If your site sends events to its own server first and the server forwards them, the forwarded copy must carry the browser's ID: [TikTok Events API deduplication](https://ispixelworking.com/guides/tiktok.server_copy_without_event_id/generic). Keep one pixel installation and one server-side sender per pixel.

## Improve Event Match Quality

With each web event, send what you have:

- `ttclid`, the TikTok click ID, from the `ttclid` cookie the pixel writes (or the landing page URL). TikTok's backend also picks it up from a `ttclid` parameter in `page.url`. If you store it yourself, keep it for 28 days or more.
- `ttp`, the `_ttp` cookie value (the pixel's browser ID), unchanged.
- `ip` and `user_agent` of the visitor's device, not hashed.
- `email` (trimmed and lower case before hashing), `phone` (E.164 format before hashing) and `external_id`, each hashed with SHA-256.
- `page.url`, which is required for web events.

On the browser side, Automatic Advanced Matching (in the pixel's settings) or `ttq.identify(...)` adds hashed customer data to pixel events. Events Manager's **Overview** shows the EMQ score per event, which TikTok calculates from how many of your events carry each match key.

## How to test and verify

1. **Test Events.** In Events Manager, open your pixel and the **Test Events** tab. For browser events, open your website from there. For server events, copy the `test_event_code` from **Test Server Events**, add it to your request body, and remove it before you go live.
2. **Overview.** The **Connection Method** column should read "server & browser" for events you send both ways. Event data is not shown in real time.
3. **Deduplication.** The pixel's detail page shows "Browser", "Server" and "Server & Browser" figures. TikTok says that if the "Server & Browser" numbers are too low, check your deduplication. **View details** under **Event Health** shows matching and deduplication health.
4. **Diagnostics** lists problems TikTok has detected, with suggested fixes.
5. **Re-run the check on IsPixelWorking.** If your setup leaves signs in the browser (tracking requests to your own domain, a server-side Tag Manager address), the report shows them, and whether those copies carry the browser's event ID. A purely server-to-server setup can still show "not detected", because we cannot see it; Events Manager is the real test.

## If events are missing or duplicated

**Server events are missing:**

- Read the API response: anything other than `"code": 0` is an error, and the message names the first invalid field.
- Check that `event_time` is in seconds, `event_source` is `web`, `event_source_id` is your pixel code and `page.url` is set.
- Check that emails and phone numbers are hashed: TikTok rejects an unhashed email.
- Check that the access token was generated for a pixel in the same ad account.
- Allow time: reports are not real time. Visitors who reject cookies may be left out on purpose, if your tool follows their choice.

**Events are counted twice:**

- The browser events have an empty `event_id`, or the server uses a different one.
- The event names differ (case counts).
- Server copies go to a different pixel code.
- The same browser event appears twice: a second pixel installation ([duplicate events](https://ispixelworking.com/guides/tiktok.duplicate_pixel/generic)). Also check for a second server-side sender, such as a partner app and server-side GTM both sending purchases.
- Server copies arrive more than 48 hours after the browser copy.

**Far fewer conversions after adding IDs:** the ID is probably reused. Each action needs its own value.

## Sources

- TikTok Business Help Center, Getting started with the Events API (second channel together with the pixel, direct integration): https://ads.tiktok.com/resources/help/article/getting-started-events-api?lang=en
- TikTok API for Business, Events API changelog (Events API 2.0 is the latest): https://business-api.tiktok.com/portal/docs?id=1771101231937537
- TikTok API for Business, Events API 2.0 setup guide for Web (Connect data source, Partner integrations and Manual setup, endpoint, headers, payload fields, first-party cookies and Automatic Advanced Matching): https://business-api.tiktok.com/portal/docs?id=1771100865818625
- TikTok API for Business, Authentication (Settings tab, Admin or Operator, same ad account): https://business-api.tiktok.com/portal/docs?id=1771101130925058
- TikTok API for Business, Event Deduplication (keys, 48 hours, merge within 5 minutes, `_ttp` fallback, unique IDs, Server & Browser metrics, Event Health): https://business-api.tiktok.com/portal/docs?id=1771100965992450
- TikTok Business Help Center, Event deduplication: https://ads.tiktok.com/resources/help/article/event-deduplication?lang=en
- TikTok API for Business, Send TikTok Click ID (ttclid) (`ttclid` cookie, `page.url` parsing, store for 28 days or more): https://business-api.tiktok.com/portal/docs?id=1771100879787009
- TikTok API for Business, Send TikTok Cookie (_ttp) (`user.ttp` from the `_ttp` cookie): https://business-api.tiktok.com/portal/docs?id=1771100936446977
- TikTok API for Business, Report App, Web, Offline, or CRM Events (up to 1,000 events per request): https://business-api.tiktok.com/portal/docs?id=1771101303285761
- TikTok API for Business, Responses and errors: https://business-api.tiktok.com/portal/docs?id=1771101162079234
- TikTok API for Business, Verify Events API setup (`test_event_code`, remove before production): https://business-api.tiktok.com/portal/docs?id=1771100984456193
- TikTok API for Business, Events API and Pixel setup with Google Tag Manager (interactive flow, requirements, `event_id` variable, Google Cloud billing): https://business-api.tiktok.com/portal/docs?id=1799004052020225
- TikTok API for Business, Events API Gateway (copy of pixel events sent from an advertiser-administered server): https://business-api.tiktok.com/portal/docs?id=1834543156864002
- TikTok Business Help Center, About Events API Gateway (deduplication by event_id or _ttp): https://ads.tiktok.com/resources/help/article/about-events-api-gateway?lang=en
- TikTok Business Help Center, Partner integrations for web tracking (platforms with Pixel and Events API): https://ads.tiktok.com/resources/help/article/partner-integrations-for-web-tracking?lang=en
- TikTok Business Help Center, How to adopt TikTok's updated standard events: https://ads.tiktok.com/resources/help/article/how-to-adopt-tiktoks-updated-standard-events?lang=en
- TikTok Business Help Center, Events Manager: monitor and diagnose (EMQ score, Connection Method, data not in real time): https://ads.tiktok.com/resources/help/article/tiktok-events-manager-monitor-and-diagnose?lang=en
- TikTok Business Help Center, How to use cookies with TikTok Pixel (notices and consents): https://ads.tiktok.com/resources/help/article/how-to-use-cookies-with-tiktok-pixel?lang=en
- GitHub, TikTok Events API (Official) server-side GTM template: https://github.com/tiktok/gtm-template-eapi
- Stape, TikTok server-side tracking with the Events API (Events API Gateway, $10 a month per pixel): https://stape.io/blog/tiktok-server-side-tracking
- Stape, Gateways (7-day free trial): https://stape.io/gateways
- Google Tag Manager, Cloud Run setup guide for server-side tagging (about $45 a month per server, at least two instances): https://developers.google.com/tag-platform/tag-manager/server-side/cloud-run-setup-guide
- Stape, pricing: https://stape.io/price
