TikTok’s pixel faces a harder tracking environment than Meta or Google. TikTok’s user base skews heavily toward iOS where ITP aggressively limits third-party cookies, and TikTok’s pixel is blocked by more ad blockers than established platforms. TikTok’s Events API (their server-side tracking solution) provides the path to reliable conversion tracking without depending on browser cookies. This guide covers the complete cookieless TikTok tracking architecture using server-side GTM and the Events API, including the advanced matching parameters that maximize attribution rates.
Why TikTok Pixel Underperforms
TikTok’s browser pixel relies on a cookie called _ttp that stores the TikTok click identifier. This cookie is set when a user clicks a TikTok ad and lands on your site. When the user converts, the pixel reads the _ttp cookie and sends it with the conversion event to TikTok for attribution. ITP on Safari limits this cookie to 7 days with script-writable cookies and blocks it entirely if set by a third-party (TikTok’s pixel script is third-party). The result: conversions from iOS Safari users on TikTok are substantially undercounted compared to Android users, and the undercounting gets worse the longer the conversion window.
TikTok Events API Architecture
TikTok’s Events API works similarly to Meta’s CAPI: your server sends conversion events directly to TikTok’s API, bypassing browser limitations entirely. For best results, implement a hybrid approach where both the browser pixel AND the server-side Events API send conversions, with deduplication to prevent double-counting.
The key matching parameters for TikTok Events API are: ttp (TikTok click ID from the URL parameter), ttclid (same as ttp, TikTok uses both names), hashed email address, hashed phone number, and IP address plus user agent. The ttp/ttclid parameter is the strongest attribution signal — capture it from the landing page URL and store it server-side for use in server Events API calls.
import hashlib
import requests
import time
def send_tiktok_event(pixel_id, access_token, event_data):
url = f'https://business-api.tiktok.com/open_api/v1.3/event/track/'
headers = {
'Access-Token': access_token,
'Content-Type': 'application/json'
}
payload = {
'pixel_code': pixel_id,
'event': event_data['event_name'],
'event_time': int(time.time()),
'user': {
'email': hashlib.sha256(event_data['email'].lower().encode()).hexdigest(),
'phone': hashlib.sha256(event_data['phone'].encode()).hexdigest(),
'ttp': event_data.get('ttp', ''),
'ip': event_data['ip'],
'user_agent': event_data['user_agent']
},
'properties': {
'value': event_data.get('value', 0),
'currency': event_data.get('currency', 'USD'),
'order_id': event_data.get('order_id', '')
}
}
response = requests.post(url, headers=headers, json=payload)
return response.json()

Capturing the TikTok Click ID
When a user clicks a TikTok ad, TikTok appends a ttclid parameter to the landing page URL. You must capture this parameter and store it to use in server-side Events API calls. Capture it in JavaScript on page load and store it in a first-party cookie:
// Capture TikTok click ID from URL
(function() {
const params = new URLSearchParams(window.location.search);
const ttclid = params.get('ttclid');
if (ttclid) {
// Store as first-party cookie, 90-day expiry
const expires = new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toUTCString();
document.cookie = `_ttp=${ttclid}; expires=${expires}; path=/; SameSite=Lax`;
// Also push to dataLayer for GTM
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({ tiktok_click_id: ttclid });
}
})();
Setting the cookie as a first-party cookie (via your own JavaScript rather than TikTok’s script) gives it a full 7-day ITP-compliant lifetime on Safari, and up to 90 days on other browsers. Pass this stored click ID in your server-side Events API calls as the ttp parameter when conversions occur.
Deduplication Between Pixel and Events API
TikTok uses the event_id parameter for deduplication. When both your browser pixel and server Events API send the same conversion, use identical event_id values and TikTok will count it once. Generate a unique event_id at the time of conversion (a UUID or your order ID works), include it in the browser pixel’s event call via the TikTok pixel’s advancedMatching or the event_id property, and include the same value in your server Events API call. Without matching event_ids, TikTok counts both events and your conversion numbers will be doubled.
