Fix guide · Any website · advanced · about 90 min

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

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, does not fire after consent, duplicate events, click ID not stored.

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:

{
  "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:

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.
  • 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.

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. 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). 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

More TikTok guides