TikTok Pixel & Events API Guide 2026
Complete guide to TikTok Pixel installation and Events API implementation. Learn conversion tracking, advanced matching, server-side tagging, and iOS 14+ optimization strategies.
Understanding TikTok Tracking
TikTok's conversion tracking ecosystem consists of two complementary technologies: the browser-based Pixel and the server-side Events API. For optimal performance in 2026, you need both working together.
TikTok Tracking Architecture:
┌─────────────────────────────────────────────────────────────────┐
│ TikTok Tracking Stack │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Browser-Side (Pixel) Server-Side (Events API) │
│ ┌─────────────────────────┐ ┌─────────────────────────┐ │
│ │ • JavaScript snippet │ │ • Direct API calls │ │
│ │ • Automatic page views │ │ • Server-to-server │ │
│ │ • Click tracking │ │ • Ad blocker resistant │ │
│ │ • Form interactions │ │ • iOS 14+ compatible │ │
│ │ • Easy implementation │ │ • Higher match rates │ │
│ └──────────┬──────────────┘ └──────────┬──────────────┘ │
│ │ │ │
│ └────────────┬───────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ Event Deduplication │ │
│ │ (event_id matching) │ │
│ └───────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────┐ │
│ │ TikTok Attribution │ │
│ │ & Reporting │ │
│ └───────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘Why You Need Both
| Capability | Pixel Only | Events API Only | Both Together | |------------|------------|-----------------|---------------| | Basic tracking | ✓ | ✓ | ✓ | | Ad blocker resilience | ✗ | ✓ | ✓ | | iOS 14+ tracking | Limited | ✓ | ✓ | | Real-time events | ✓ | Delayed | ✓ | | Match rate | 50-60% | 70-80% | 80-95% | | Implementation | Easy | Complex | Moderate | | Recommended | Testing | Never alone | Production |
TikTok Pixel Installation
Getting Your Pixel ID
Pixel Setup Steps:
1. Access TikTok Ads Manager
└── ads.tiktok.com/i/events_manager
2. Create New Pixel (if needed)
├── Assets → Events → Web Events
├── Click "Create Pixel"
├── Name your pixel
└── Get Pixel ID (format: XXXXXXXXXX)
3. Choose Installation Method
├── Manual: Copy/paste code
├── Partner Integration: Shopify, WooCommerce, etc.
└── Google Tag Manager: Tag templateManual Installation
Add this code before the closing </head> tag on all pages:
<!-- TikTok Pixel Base Code -->
<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"],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 i="https://analytics.tiktok.com/i18n/pixel/events.js";ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=i,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};var o=document.createElement("script");o.type="text/javascript",o.async=!0,o.src=i+"?sdkid="+e+"&lib="+t;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(o,a)};
ttq.load('YOUR_PIXEL_ID');
ttq.page();
}(window, document, 'ttq');
</script>
<!-- End TikTok Pixel Base Code -->Framework-Specific Installation
// React / Next.js Installation
// 1. Create a TikTok Pixel component
// components/TikTokPixel.tsx
'use client';
import { useEffect } from 'react';
import { usePathname, useSearchParams } from 'next/navigation';
declare global {
interface Window {
ttq: any;
}
}
const PIXEL_ID = process.env.NEXT_PUBLIC_TIKTOK_PIXEL_ID!;
export function TikTokPixel() {
const pathname = usePathname();
const searchParams = useSearchParams();
useEffect(() => {
// Initialize TikTok Pixel
if (typeof window !== 'undefined' && !window.ttq) {
(function(w: any, 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"];
ttq.setAndDefer = function(t: any, e: string) {
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: string) {
var e = ttq._i[t] || [];
for (var n = 0; n < ttq.methods.length; n++) {
ttq.setAndDefer(e, ttq.methods[n]);
}
return e;
};
ttq.load = function(e: string, n?: object) {
var i = "https://analytics.tiktok.com/i18n/pixel/events.js";
ttq._i = ttq._i || {};
ttq._i[e] = [];
ttq._i[e]._u = i;
ttq._t = ttq._t || {};
ttq._t[e] = +new Date();
ttq._o = ttq._o || {};
ttq._o[e] = n || {};
var o = document.createElement("script");
o.type = "text/javascript";
o.async = true;
o.src = i + "?sdkid=" + e + "&lib=" + t;
var a = document.getElementsByTagName("script")[0];
a.parentNode?.insertBefore(o, a);
};
ttq.load(PIXEL_ID);
ttq.page();
})(window, document, 'ttq');
}
}, []);
// Track page views on route change
useEffect(() => {
if (window.ttq) {
window.ttq.page();
}
}, [pathname, searchParams]);
return null;
}
// 2. Add to layout
// app/layout.tsx
import { TikTokPixel } from '@/components/TikTokPixel';
import { Suspense } from 'react';
export default function RootLayout({ children }) {
return (
<html>
<body>
<Suspense fallback={null}>
<TikTokPixel />
</Suspense>
{children}
</body>
</html>
);
}Google Tag Manager Installation
GTM Setup:
1. Create New Tag
├── Tag Type: TikTok Pixel
├── Pixel ID: YOUR_PIXEL_ID
└── Event: Page View
2. Set Trigger
├── All Pages (for base code)
└── OR specific triggers for events
3. Configure Variables
├── Create Data Layer variables
├── Map to TikTok parameters
└── Enable Enhanced Matching
4. Event Tags (create separately)
├── ViewContent
├── AddToCart
├── Purchase
└── Custom eventsStandard Events
Event Reference
| Event Name | When to Fire | Required Parameters |
|------------|--------------|---------------------|
| PageView | All pages (automatic) | None |
| ViewContent | Product page viewed | content_id, content_type |
| AddToCart | Add to cart click | content_id, content_type, value, currency |
| InitiateCheckout | Checkout started | value, currency |
| AddPaymentInfo | Payment info added | None |
| CompletePayment | Purchase completed | value, currency, content_id |
| PlaceAnOrder | Order confirmed | value, currency, order_id |
| Subscribe | Subscription started | value, currency |
| SubmitForm | Form submitted | None |
| Contact | Contact initiated | None |
| Download | Download completed | None |
| Search | Search performed | query |
| AddToWishlist | Wishlist addition | content_id |
| ClickButton | CTA clicked | None |
| CompleteRegistration | Signup completed | None |
Event Implementation
// Standard event implementations
// ViewContent - Product page viewed
ttq.track('ViewContent', {
content_id: 'product_123',
content_type: 'product',
content_name: 'Blue Running Shoes',
content_category: 'Footwear',
price: 89.99,
currency: 'USD',
quantity: 1
});
// AddToCart
ttq.track('AddToCart', {
content_id: 'product_123',
content_type: 'product',
content_name: 'Blue Running Shoes',
price: 89.99,
currency: 'USD',
quantity: 1,
value: 89.99
});
// InitiateCheckout
ttq.track('InitiateCheckout', {
contents: [
{ content_id: 'product_123', quantity: 1, price: 89.99 },
{ content_id: 'product_456', quantity: 2, price: 49.99 }
],
content_type: 'product',
currency: 'USD',
value: 189.97
});
// CompletePayment (Purchase)
ttq.track('CompletePayment', {
contents: [
{ content_id: 'product_123', quantity: 1, price: 89.99 }
],
content_type: 'product',
currency: 'USD',
value: 89.99,
order_id: 'order_789'
});
// Lead Generation
ttq.track('SubmitForm', {
content_name: 'Demo Request Form',
content_category: 'Lead Gen'
});
// Search
ttq.track('Search', {
query: 'running shoes',
content_type: 'product'
});Custom Events
// Custom event tracking
ttq.track('CustomEvent', {
// Your custom parameters
event_category: 'Engagement',
event_action: 'video_play',
event_label: 'hero_video',
value: 1
});
// Example: Track video engagement
ttq.track('VideoPlay', {
video_id: 'hero_promo_2026',
video_title: 'New Collection Launch',
video_duration: 30,
video_percent: 50 // Played 50%
});
// Example: Track quiz completion
ttq.track('QuizComplete', {
quiz_name: 'Style Finder',
quiz_result: 'Casual Athletic',
quiz_score: 85
});Advanced Matching
Advanced Matching improves event match rates by sending hashed user data with events.
Automatic Advanced Matching
<!-- Enable automatic advanced matching -->
<script>
ttq.load('YOUR_PIXEL_ID', {
advanced_matching: true
});
</script>Manual Advanced Matching
// Identify user with PII (hashed automatically)
ttq.identify({
email: 'user@example.com', // Hashed automatically
phone_number: '+14155551234', // Hashed automatically
external_id: 'user_abc123' // Your internal user ID
});
// Or include with events
ttq.track('CompletePayment', {
value: 89.99,
currency: 'USD',
order_id: 'order_789',
// User data for matching
email: 'user@example.com',
phone_number: '+14155551234',
external_id: 'user_abc123'
});Advanced Matching Parameters
Supported User Parameters:
Highly Recommended:
├── email (hashed SHA256)
├── phone_number (E.164 format, hashed)
├── external_id (your user ID)
└── ttp (TikTok click ID from URL)
Additional Parameters:
├── first_name (hashed)
├── last_name (hashed)
├── city (normalized, hashed)
├── state (2-letter code)
├── zip_code (5 digits US)
├── country (2-letter ISO)
├── date_of_birth (YYYYMMDD)
└── gender (m/f)
Match Rate Impact:
├── Email only: ~50% match rate
├── Email + Phone: ~65% match rate
├── All parameters: ~80%+ match rate
└── With Events API: ~90%+ match rateEvents API (Server-Side)
The Events API enables server-to-server tracking, bypassing ad blockers and improving iOS 14+ tracking accuracy.
Events API Setup
Events API Prerequisites:
1. Create Events API Access Token
├── TikTok Ads Manager → Events Manager
├── Settings → Generate Access Token
└── Store securely (never expose client-side)
2. Note Your Pixel ID
└── Same pixel used for browser tracking
3. Plan Event Deduplication
├── Use event_id for each event
├── Same event_id for pixel + API
└── TikTok deduplicates automaticallyServer-Side Implementation
// Node.js Events API Implementation
import crypto from 'crypto';
const TIKTOK_PIXEL_ID = process.env.TIKTOK_PIXEL_ID;
const TIKTOK_ACCESS_TOKEN = process.env.TIKTOK_ACCESS_TOKEN;
const EVENTS_API_URL = 'https://business-api.tiktok.com/open_api/v1.3/pixel/track/';
// Hash function for PII
function hashSHA256(value: string): string {
if (!value) return '';
return crypto.createHash('sha256')
.update(value.toLowerCase().trim())
.digest('hex');
}
// Send event to TikTok Events API
async function sendTikTokEvent(event: TikTokEvent) {
const payload = {
pixel_code: TIKTOK_PIXEL_ID,
event: event.event_name,
event_id: event.event_id, // For deduplication
timestamp: new Date().toISOString(),
context: {
user_agent: event.user_agent,
ip: event.ip_address,
page: {
url: event.page_url,
referrer: event.referrer
},
user: {
external_id: event.user_id,
email: hashSHA256(event.email),
phone: hashSHA256(event.phone),
ttp: event.ttclid // TikTok click ID
}
},
properties: event.properties
};
const response = await fetch(EVENTS_API_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Access-Token': TIKTOK_ACCESS_TOKEN
},
body: JSON.stringify({ data: [payload] })
});
return response.json();
}
// Example: Track purchase server-side
interface TikTokEvent {
event_name: string;
event_id: string;
user_agent?: string;
ip_address?: string;
page_url?: string;
referrer?: string;
user_id?: string;
email?: string;
phone?: string;
ttclid?: string;
properties?: Record<string, any>;
}
// Usage in your purchase handler
async function handlePurchase(order: Order, request: Request) {
const event: TikTokEvent = {
event_name: 'CompletePayment',
event_id: `purchase_${order.id}`, // Unique per event
user_agent: request.headers.get('user-agent') || '',
ip_address: request.headers.get('x-forwarded-for') || '',
page_url: 'https://yoursite.com/checkout/success',
user_id: order.userId,
email: order.email,
phone: order.phone,
ttclid: getCookie(request, 'ttclid'), // TikTok click ID
properties: {
currency: 'USD',
value: order.total,
order_id: order.id,
contents: order.items.map(item => ({
content_id: item.productId,
content_type: 'product',
quantity: item.quantity,
price: item.price
}))
}
};
await sendTikTokEvent(event);
}Event Deduplication
// Deduplication strategy
// The same event_id sent from both Pixel and Events API
// TikTok will count it only once
// Browser-side (Pixel)
const eventId = crypto.randomUUID();
ttq.track('CompletePayment', {
event_id: eventId, // Same ID
value: 89.99,
currency: 'USD'
});
// Server-side (Events API) - sends the same event_id
await sendTikTokEvent({
event_name: 'CompletePayment',
event_id: eventId, // Same ID - deduped
properties: {
value: 89.99,
currency: 'USD'
}
});
// Best practice: Generate event_id on server, pass to browser
// This ensures both sides have the same IDTikTok Click ID (ttclid)
The TikTok Click ID (ttclid) is automatically appended to URLs when users click TikTok ads. Capturing and using this improves attribution accuracy.
Capturing ttclid
// Capture ttclid from URL on landing
function captureTTCLID() {
const urlParams = new URLSearchParams(window.location.search);
const ttclid = urlParams.get('ttclid');
if (ttclid) {
// Store in first-party cookie (1 year)
document.cookie = `ttclid=${ttclid}; max-age=31536000; path=/; SameSite=Lax`;
// Also store in localStorage as backup
localStorage.setItem('ttclid', ttclid);
}
}
// Call on page load
if (typeof window !== 'undefined') {
captureTTCLID();
}
// Retrieve ttclid for events
function getTTCLID(): string | null {
// Try cookie first
const cookieMatch = document.cookie.match(/ttclid=([^;]+)/);
if (cookieMatch) return cookieMatch[1];
// Fallback to localStorage
return localStorage.getItem('ttclid');
}Using ttclid with Events
// Include ttclid in all events
const ttclid = getTTCLID();
ttq.track('CompletePayment', {
value: 89.99,
currency: 'USD',
ttp: ttclid // TikTok uses 'ttp' parameter
});
// Server-side Events API
const event = {
event_name: 'CompletePayment',
context: {
user: {
ttp: ttclid // Include in user context
}
},
properties: {
value: 89.99,
currency: 'USD'
}
};iOS 14+ Optimization
SKAdNetwork Integration
SKAdNetwork Setup:
TikTok Requirements:
├── Register for SKAdNetwork with TikTok
├── Configure conversion value mapping
├── Implement postback handling
└── Set up measurement partner (optional)
Conversion Value Mapping:
├── Value 0-5: Awareness/engagement events
├── Value 6-15: Consideration events
├── Value 16-35: Low-value purchases
├── Value 36-55: Medium-value purchases
├── Value 56-63: High-value purchases
Implementation:
├── TikTok handles SKAdNetwork registration
├── Focus on Events API for accuracy
├── Use aggregate reporting for optimization
└── Test with conversion modelingPrivacy-Compliant Tracking
// Privacy-respecting implementation
// Check for consent before tracking
function initTikTokTracking() {
// Check consent status (from your consent manager)
const hasConsent = checkAnalyticsConsent();
if (hasConsent) {
// Full tracking
ttq.load('YOUR_PIXEL_ID', {
advanced_matching: true
});
} else {
// Limited tracking (no PII)
ttq.load('YOUR_PIXEL_ID', {
advanced_matching: false
});
}
}
// Handle consent updates
function onConsentUpdate(consentStatus: boolean) {
if (consentStatus) {
ttq.enableCookie();
} else {
ttq.disableCookie();
}
}Verification & Debugging
TikTok Pixel Helper
Using TikTok Pixel Helper:
1. Install Chrome Extension
└── "TikTok Pixel Helper" from Chrome Web Store
2. Navigate to Your Site
└── Extension icon shows pixel status
3. Check Events
├── Green checkmark = Event firing correctly
├── Warning = Potential issues
└── Red X = Event errors
4. Verify Parameters
├── Click event to expand
├── Check all required parameters
└── Verify values are correctTest Events in Ads Manager
Test Event Tool:
1. Access Events Manager
└── Assets → Events → Your Pixel
2. Open Test Events
├── Click "Test Events" tab
└── View real-time events
3. Trigger Events on Your Site
├── Open your site in new tab
├── Perform actions (page view, add to cart, etc.)
└── Watch events appear in Test Events
4. Verify Data
├── Check event names
├── Verify parameters
├── Confirm match quality
└── Test Events API separatelyCommon Issues & Solutions
Troubleshooting Guide:
Events Not Appearing:
├── Check: Pixel ID correct?
├── Check: Script loading before </head>?
├── Check: Ad blockers disabled?
├── Check: Console errors?
└── Solution: Use Events API as backup
Low Match Rates:
├── Check: Advanced matching enabled?
├── Check: Email/phone being passed?
├── Check: ttclid being captured?
├── Check: Events API configured?
└── Solution: Implement all matching parameters
Duplicate Events:
├── Check: event_id being sent?
├── Check: Same event_id on both pixel + API?
├── Check: Event firing multiple times?
└── Solution: Implement proper deduplication
Parameter Errors:
├── Check: Value is numeric (not string)?
├── Check: Currency is valid ISO code?
├── Check: content_id matches catalog?
└── Solution: Validate before sendingIntegration with pxlpeak
// pxlpeak TikTok Pixel integration
import { pxlpeak } from '@pxlpeak/tracker';
// Configure TikTok tracking
pxlpeak.integrations.tiktok.configure({
pixelId: process.env.TIKTOK_PIXEL_ID!,
eventsApi: {
enabled: true,
accessToken: process.env.TIKTOK_ACCESS_TOKEN
},
advancedMatching: {
enabled: true,
parameters: ['email', 'phone', 'external_id']
},
eventMapping: {
'pxlpeak:purchase': 'CompletePayment',
'pxlpeak:add_to_cart': 'AddToCart',
'pxlpeak:page_view': 'PageView',
'pxlpeak:lead': 'SubmitForm'
},
deduplication: {
enabled: true,
window: 3600 // 1 hour
}
});
// Automatic event forwarding
pxlpeak.on('event', (event) => {
// Events automatically forwarded to TikTok
// Based on eventMapping configuration
});Quick Reference
Implementation Checklist
TikTok Tracking Setup Checklist:
Pixel Setup:
□ Pixel ID created in Ads Manager
□ Base code installed on all pages
□ Page view tracking verified
□ Advanced matching enabled
Standard Events:
□ ViewContent on product pages
□ AddToCart on cart additions
□ InitiateCheckout on checkout start
□ CompletePayment on purchase
□ Lead events for form submissions
Events API:
□ Access token generated
□ Server-side events implemented
□ event_id deduplication configured
□ ttclid capture implemented
Verification:
□ Pixel Helper shows green
□ Test Events receiving data
□ Match rate > 70%
□ Events flowing to campaignsEvent Quick Reference
| Action | Event Name | Key Parameters |
|--------|------------|----------------|
| Page load | PageView | (automatic) |
| View product | ViewContent | content_id, content_type, price |
| Add to cart | AddToCart | content_id, value, currency |
| Checkout | InitiateCheckout | value, currency, contents |
| Purchase | CompletePayment | value, currency, order_id |
| Lead form | SubmitForm | content_name |
| Search | Search | query |
| Signup | CompleteRegistration | None |
Related Documentation
- TikTok Complete Guide - Full platform overview
- TikTok Optimization - Bidding and scaling
- Meta Pixel Guide - Compare with Meta tracking
- GTM Guide - Tag Manager setup
- Attribution Models - Cross-platform attribution