How TikTok Tracking Works
TikTok's measurement stack has two tracking paths: the browser-side TikTok Pixel and the server-side Events API. Both feed data into TikTok Ads Manager for attribution, audience building, and campaign optimization.
Browser-side (TikTok Pixel):
The pixel loads analytics.tiktok.com/i18n/pixel/events.js, which initializes a global ttq object. This script sets a first-party _ttp cookie that acts as TikTok's browser identifier. When events fire, the pixel sends POST requests to analytics.tiktok.com containing the event name, parameters, the _ttp value, and any Advanced Matching data (email, phone).
Server-side (Events API):
The Events API accepts event data via HTTPS POST to business-api.tiktok.com/open_api/v1.3/event/track/. Events sent server-side bypass ad blockers and browser restrictions. The API requires an access token and pixel ID for authentication.
Deduplication:
When running both pixel and Events API, TikTok deduplicates using the event_id parameter. If the same event_id arrives from both sources within a 48-hour window, TikTok keeps one and discards the duplicate. Always send matching event_id values from both client and server.
Identity resolution:
TikTok matches users through the _ttp cookie (browser), click ID (ttclid URL parameter from ad clicks), and Advanced Matching parameters (hashed email, phone, external ID). The ttclid has a 7-day attribution window by default.
Installing the TikTok Pixel
Add the base pixel code inside <head> on every page:
<script>
!function (w, d, t) {
w.TiktokAnalyticsObject=t;
var ttq=w[t]=w[t]||[];
ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"];
ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};
for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);
ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e};
ttq.load=function(e,n){var r="https://analytics.tiktok.com/i18n/pixel/events.js",o=n&&n.partner;ttq._i=ttq._i||{};ttq._i[e]=[];ttq._i[e]._u=r;ttq._t=ttq._t||{};ttq._t[e+\"_\"+o]=1;var a=d.createElement("script");a.type="text/javascript";a.async=!0;a.src=r+"?sdkid="+e+"&lib="+t;var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(a,s)};
ttq.load('YOUR_PIXEL_ID');
ttq.page();
}(window, document, 'ttq');
</script>
Replace YOUR_PIXEL_ID with the pixel ID from TikTok Ads Manager > Assets > Events.
Via Google Tag Manager: Use the TikTok Pixel template from the GTM Community Gallery. Set the pixel ID in the template configuration and fire it on All Pages.
Conversion Tracking
Standard Events
TikTok defines a set of standard events for optimization and reporting. Fire them with ttq.track():
// Purchase event
ttq.track('CompletePayment', {
content_id: 'product_123',
content_type: 'product',
content_name: 'Blue Widget',
quantity: 2,
price: 29.99,
value: 59.98,
currency: 'USD'
});
// Add to Cart
ttq.track('AddToCart', {
content_id: 'product_123',
content_type: 'product',
value: 29.99,
currency: 'USD'
});
// Form submission
ttq.track('SubmitForm');
// View content
ttq.track('ViewContent', {
content_id: 'article_456',
content_type: 'product'
});
// Initiate Checkout
ttq.track('InitiateCheckout', {
content_id: 'product_123',
value: 59.98,
currency: 'USD'
});
Full list of standard events: ViewContent, ClickButton, Search, AddToWishlist, AddToCart, InitiateCheckout, AddPaymentInfo, CompletePayment, PlaceAnOrder, Contact, Download, SubmitForm, CompleteRegistration, Subscribe.
Custom Events
For events not covered by standard types:
ttq.track('CustomEvent', {
content_id: 'quiz_result_a',
content_name: 'Style Quiz Completed'
});
Custom events can be used for audience creation but not for standard conversion optimization campaigns.
Advanced Matching
Advanced Matching sends hashed PII alongside events to improve match rates. TikTok auto-hashes when using the identify method:
ttq.identify({
email: 'user@example.com', // auto-hashed to SHA-256
phone_number: '+11234567890', // include country code
external_id: 'customer_abc_123' // your internal user ID
});
// Subsequent track calls include this identity data
ttq.track('CompletePayment', {
value: 59.98,
currency: 'USD'
});
Call ttq.identify() as early as possible (login, form submission, checkout) before firing conversion events. The identity persists for subsequent track calls in the same page session.
Automatic Advanced Matching:
Enable in TikTok Ads Manager under Events > Manage > Settings. When enabled, the pixel scans form fields for email and phone inputs and auto-includes them. This is less reliable than explicit identify() calls.
Server-Side Events API
The Events API sends conversion data from your server, bypassing ad blockers and browser limitations.
Authentication
Generate an access token in TikTok Ads Manager > Assets > Events > Settings > Generate Access Token.
Sending Events
curl -X POST "https://business-api.tiktok.com/open_api/v1.3/event/track/" \
-H "Content-Type: application/json" \
-H "Access-Token: YOUR_ACCESS_TOKEN" \
-d '{
"pixel_code": "YOUR_PIXEL_ID",
"event": "CompletePayment",
"event_id": "order_12345_1709510400",
"timestamp": "2025-03-04T00:00:00Z",
"context": {
"user_agent": "Mozilla/5.0...",
"ip": "203.0.113.42"
},
"user": {
"email": "a]c4db8a2e6...",
"phone": "1a2b3c4d5e...",
"ttp": "value_from_ttp_cookie",
"external_id": "customer_abc_123"
},
"properties": {
"contents": [
{
"content_id": "product_123",
"content_type": "product",
"content_name": "Blue Widget",
"quantity": 2,
"price": 29.99
}
],
"value": 59.98,
"currency": "USD"
}
}'
Key fields for deduplication: The event_id must match between the pixel ttq.track() call and the Events API request. Send both for maximum coverage:
// Browser-side: include event_id
ttq.track('CompletePayment', {
value: 59.98,
currency: 'USD',
event_id: 'order_12345_1709510400'
});
Passing the _ttp cookie: Read the _ttp cookie from the browser and send it to your server with the order/form data. Include it as ttp in the Events API user object. This links the server event to the TikTok browser session.
Audience Building and Retargeting
TikTok builds audiences from pixel activity:
- Website Custom Audiences: Target users who triggered specific pixel events (ViewContent, AddToCart) within a lookback window (1-180 days)
- Customer File Audiences: Upload hashed emails or phone numbers for direct matching
- Lookalike Audiences: Expand from custom audiences to find similar users
- App Activity Audiences: Target users based on app events (requires TikTok SDK)
Create audiences in TikTok Ads Manager > Assets > Audiences. Minimum audience size is 1,000 matched users.
Example audience rules:
- Viewed product pages in the last 30 days but did not purchase
- Added to cart in the last 7 days
- Purchased in the last 180 days (for exclusion or upsell)
iOS ATT and Privacy Handling
After Apple's App Tracking Transparency (ATT) framework, TikTok cannot track users who opt out of tracking on iOS 14.5+.
Impact:
- The
_ttpcookie may not be set on Safari with ITP restrictions ttclidclick attribution still works (first-party URL parameter)- Events API becomes critical for iOS attribution since it bypasses browser restrictions
- Aggregated Event Measurement (AEM) limits reporting to 8 conversion events per domain, ranked by priority
Configuration:
- Verify your domain in TikTok Ads Manager > Assets > Events > Manage
- Prioritize your top 8 conversion events in order of importance
- Run Events API alongside the pixel to recover attribution lost from browser restrictions
- Use the
ttclidparameter: TikTok appends it to landing page URLs from ad clicks. Capture it server-side and include it in Events API calls
Common Issues
Pixel not firing:
Check that the ttq.load() call uses the correct pixel ID. Verify with TikTok Pixel Helper (Chrome extension). Ensure the pixel script is not blocked by consent management platforms or ad blockers.
Duplicate conversions:
When using both pixel and Events API, missing or mismatched event_id values cause double-counting. Generate a unique event_id on the client, pass it to both ttq.track() and your server for the Events API call.
Low match rates on Events API:
Include as many user parameters as possible: ttp cookie, hashed email, hashed phone, external_id, IP address, and user agent. The ttp cookie is the strongest signal for matching.
ttclid not appearing in URLs:
Auto-tagging must be enabled at the campaign level in TikTok Ads Manager. Check that your landing page URL does not strip query parameters through redirects.
Events API 40001 error (invalid access token): Access tokens expire. Regenerate in TikTok Ads Manager. Tokens are scoped to a specific advertiser account.
Conversion value showing $0:
The value and currency fields are required for revenue tracking. currency must be a valid ISO 4217 code (e.g., USD, EUR, GBP).
Platform-Specific Considerations
TikTok Shop integration: TikTok Shop has built-in tracking that does not require separate pixel installation. Product catalog events (ViewProduct, AddToCart, Purchase) are tracked automatically within the TikTok app. External website tracking still requires the pixel or Events API.
Spark Ads attribution: Spark Ads (boosted organic posts) use the same pixel attribution as standard ads. The ttclid parameter is appended to the CTA link.
Event batching: The Events API accepts up to 50 events per request. For high-volume sites, batch events in server-side queues and send them in bulk, within 15 minutes of the actual event occurrence for accurate attribution.
Data residency: TikTok processes data through regional endpoints. For EU data, use business-api.tiktok.com with EU-specific pixel codes. Check TikTok's data processing documentation for GDPR compliance requirements.
Testing: Use TikTok's Test Events tool in Ads Manager > Events > Test Events. Send test events from your development environment and verify they appear in the dashboard before launching campaigns.