TikTok server-side tracking: _ttp, ttclid and the Events API
21 May 2026 · 3 min read · Neill Brookman
TikTok’s Events API accepts conversion events from your server rather than from the browser. Sending the request is straightforward. What decides whether TikTok can use the event is everything that travels with it: the _ttp browser identifier, the ttclid click ID, hashed customer data, and the visitor’s IP address and user agent.
The two identifiers that matter
`_ttp` is TikTok’s anonymous browser identifier. The TikTok Pixel (ttq.js) normally sets it on the first visit as a JavaScript cookie. It lets TikTok link events from the same browser over time.
`ttclid` is the click ID. When someone taps a TikTok ad, the landing URL carries ttclid, and TikTok uses it to tie a later conversion to that click. Like every click ID, it appears only on the landing page: miss it there and it is gone.
Both are fragile in the browser. Ad blockers frequently stop ttq.js from loading, and Safari deletes JavaScript cookies after 7 days without a return visit. A buyer who clicks an ad on Monday and comes back to buy a fortnight later has, from TikTok’s point of view, never clicked anything.
How Datafly Signal handles them
- `ttclid` is captured on landing. Datafly.js reads it from the URL and the gateway stores it in a server-set first-party cookie on your own subdomain, alongside
_ttp, for up to 400 days. - `_ttp` is generated on the server in the format TikTok expects and set with a
Set-Cookieheader from your domain. To TikTok’s identity graph it is the same as a valuettq.jswould have set, so server events match the same identity as any earlier browser events. - Customer data is hashed before it leaves your infrastructure. Email and phone are normalised and hashed with SHA-256, the format the Events API expects.
- Every event carries the visitor’s IP address and user agent, which TikTok uses as additional match signals.
Do you still need ttq.js?
For measurement, no. ttq.js exists to set _ttp, capture ttclid and fire events, and all three move to the server. Removing it takes roughly 50 KB of JavaScript off every page and removes a script that ad blockers target. Some teams keep it during migration; see below.
Running the Pixel and the Events API together
The safe migration runs both paths in parallel. TikTok deduplicates a Pixel event and an Events API event when they share the same event_id, so the ID must be created once and sent down both paths. Datafly Signal generates a deterministic event_id for every event, so while ttq.js is still on the page, TikTok receives two copies with the same ID and keeps one.
A sensible order:
1. Send server events alongside the Pixel with matching event_id values.
2. Check TikTok Events Manager: server events should show as received and deduplicated, not doubled.
3. Compare conversions over a couple of weeks. The server path typically adds the conversions the Pixel was missing.
4. Remove ttq.js once the numbers are stable.
Why match quality improves
TikTok’s optimisation, including Smart Performance Campaigns, learns from the events it receives. Two things change when delivery moves server-side: events that ad blockers and Safari were hiding start arriving, and each event carries the full identifier set (_ttp, ttclid, hashed email and phone, IP and user agent) instead of whatever the Pixel managed to send before it was blocked.
Checklist
- Capture
ttclidon the landing page and keep it for the length of your buying cycle. - Set
_ttpfrom your server so Safari does not cap it at 7 days. - Use one
event_idper event across Pixel and server. - Hash email and phone before sending; never send them raw.
- Forward the visitor’s IP and user agent, not your server’s.
See how TikTok server-side tracking works in Datafly Signal, or read the TikTok integration docs.
Want more posts like this?
No spam newsletter, no drip campaigns. If you want technical posts on server-side data infrastructure, bookmark /blog or follow the RSS feed.