Meta CAPI vs TikTok Events API: The Complete Setup Guide [2026]
Meta Conversions API (CAPI) and TikTok Events API are the two most popular server-side tracking solutions for paid social. If you're running ads on Facebook/Instagram or TikTok, you need to understand how these APIs work—and how to use them together.
This guide compares both platforms, walks through setup for each, and shows you how to send events to both simultaneously.
Why Server-Side Tracking Matters
Before diving into the APIs, let's understand why server-side tracking is essential:
The Problem with Browser Pixels
Traditional tracking uses JavaScript pixels in the browser:
<!-- Facebook Pixel -->
<script>
fbq('track', 'Purchase', {value: 99.99, currency: 'USD'});
</script>
<!-- TikTok Pixel -->
<script>
ttq.track('CompletePayment', {value: 99.99, currency: 'USD'});
</script>
These pixels are blocked by:
- Ad blockers (40% of users)
- iOS 14.5+ privacy restrictions
- Firefox/Brave tracking protection
- Safari's Intelligent Tracking Prevention
Result: You're losing visibility into 30-40% of conversions.
Server-Side Solution
Server-side APIs bypass the browser entirely:
User Action → Your Server → Meta/TikTok API
↓
(No browser blocking)
Benefits:
- ✅ Bypasses ad blockers
- ✅ Longer attribution windows
- ✅ More reliable data
- ✅ Better privacy compliance
Meta Conversions API (CAPI)
What is Meta CAPI?
Meta Conversions API is Facebook's server-to-server tracking solution. It sends conversion events directly from your server to Meta's servers, bypassing browser-based restrictions.
Key Features
| Feature | Description |
|---|---|
| Event Types | Standard + Custom events |
| User Data | Email, phone, IP, user agent (hashed) |
| Attribution | 28-day click, 1-day view |
| Deduplication | Event ID prevents double-counting |
| Offline Events | Support for in-store conversions |
Meta CAPI Event Structure
{
"data": [{
"event_name": "Purchase",
"event_time": 1706613000,
"event_id": "order_12345_1706613000",
"user_data": {
"em": "5d41402abc4b2a76b9719d911017c592",
"ph": "c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862b068eea",
"client_ip_address": "192.168.1.1",
"client_user_agent": "Mozilla/5.0..."
},
"custom_data": {
"value": 99.99,
"currency": "USD",
"content_ids": ["SKU-123"],
"content_type": "product",
"order_id": "ORDER-12345"
},
"action_source": "website"
}],
"access_token": "YOUR_ACCESS_TOKEN"
}
Setting Up Meta CAPI
Step 1: Create a Facebook App
- Go to developers.facebook.com
- Create a new app (Business type)
- Add "Marketing API" product
- Note your App ID and App Secret
Step 2: Generate Access Token
- Go to Events Manager
- Select your Pixel
- Click "Settings" → "Conversions API"
- Generate access token under "Generate access token"
Step 3: Test Events
Use the Test Events tool before going live:
curl -X POST "https://graph.facebook.com/v18.0/YOUR_PIXEL_ID/events" \
-H "Content-Type: application/json" \
-d '{
"data": [{
"event_name": "TestEvent",
"event_time": '$(date +%s)',
"user_data": {
"client_ip_address": "127.0.0.1",
"client_user_agent": "TestAgent"
},
"action_source": "website"
}],
"test_event_code": "TEST12345",
"access_token": "YOUR_ACCESS_TOKEN"
}'
Step 4: Production Implementation
Option A: Direct API Call
async function sendToMetaCAPI(event) {
const payload = {
data: [{
event_name: event.name,
event_time: Math.floor(Date.now() / 1000),
event_id: event.id,
user_data: {
em: hashSHA256(event.user.email),
ph: hashSHA256(event.user.phone),
client_ip_address: event.user.ip,
client_user_agent: event.user.userAgent,
},
custom_data: {
value: event.value,
currency: event.currency,
content_ids: event.productIds,
content_type: 'product',
},
action_source: 'website',
}],
access_token: process.env.META_ACCESS_TOKEN,
};
const response = await fetch(
`https://graph.facebook.com/v18.0/${process.env.META_PIXEL_ID}/events`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
}
);
return response.json();
}
Option B: Using Anacoic (Recommended)
// Send once, Anacoic routes to Meta automatically
await fetch('https://gateway.anacoic.com/track', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Gateway-Host': 'your-domain.com',
},
body: JSON.stringify({
event_name: 'Purchase',
event_id: 'order_12345',
user_data: {
email: 'customer@example.com',
phone: '+1234567890',
},
custom_data: {
value: 99.99,
currency: 'USD',
content_ids: ['SKU-123'],
},
}),
});
TikTok Events API
What is TikTok Events API?
TikTok Events API is TikTok's server-to-server tracking solution. It's similar to Meta CAPI but with TikTok-specific event types and attribution models.
Key Features
| Feature | Description |
|---|---|
| Event Types | TikTok-specific (CompletePayment, ClickButton, etc.) |
| User Data | External ID, phone, email, ttp (hashed) |
| Attribution | 7-day click, 1-day view |
| Deduplication | Event ID + ttp cookie |
| Web Events | Support for web + app events |
TikTok Events API Structure
{
"event_source": "web",
"event_source_id": "YOUR_PIXEL_ID",
"data": [{
"event": "CompletePayment",
"event_time": 1706613000,
"event_id": "order_12345_1706613000",
"user": {
"external_id": "user_12345",
"phone": "c775e7b757ede630cd0aa1113bd102661ab38829ca52a6422ab782862b068eea",
"email": "5d41402abc4b2a76b9719d911017c592",
"ttp": "94e5d1c8-8d59-4a9c-9a7e-2c9e8f3d5b1a"
},
"properties": {
"value": 99.99,
"currency": "USD",
"content_id": "SKU-123",
"content_type": "product",
"order_id": "ORDER-12345"
}
}]
}
Setting Up TikTok Events API
Step 1: Create TikTok App
- Go to TikTok for Developers
- Create a developer account
- Create a new app
- Request "TikTok Marketing API" permission
Step 2: Get Access Token
- Go to TikTok Business Center
- Navigate to "Events" → "Web Events"
- Create or select your Pixel
- Generate Access Token under "Events API"
Step 3: Test Events
curl -X POST "https://business-api.tiktok.com/open_api/v1.3/event/track/" \
-H "Access-Token: YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"event_source": "web",
"event_source_id": "YOUR_PIXEL_ID",
"data": [{
"event": "TestEvent",
"event_time": '$(date +%s)',
"user": {
"external_id": "test_user"
},
"properties": {
"value": 1.00,
"currency": "USD"
}
}]
}'
Step 4: Production Implementation
Option A: Direct API Call
async function sendToTiktokEventsAPI(event) {
const payload = {
event_source: 'web',
event_source_id: process.env.TIKTOK_PIXEL_ID,
data: [{
event: mapEventName(event.name), // Convert to TikTok event names
event_time: Math.floor(Date.now() / 1000),
event_id: event.id,
user: {
external_id: hashSHA256(event.user.id),
email: hashSHA256(event.user.email),
phone: hashSHA256(event.user.phone),
ttp: event.user.ttpCookie, // TikTok Click ID
},
properties: {
value: event.value,
currency: event.currency,
content_id: event.productId,
content_type: 'product',
},
}],
};
const response = await fetch(
'https://business-api.tiktok.com/open_api/v1.3/event/track/',
{
method: 'POST',
headers: {
'Access-Token': process.env.TIKTOK_ACCESS_TOKEN,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
}
);
return response.json();
}
// Map your events to TikTok event names
function mapEventName(name) {
const mapping = {
'Purchase': 'CompletePayment',
'AddToCart': 'AddToCart',
'PageView': 'ViewContent',
'InitiateCheckout': 'InitiateCheckout',
'Lead': 'SubmitForm',
};
return mapping[name] || 'CustomEvent';
}
Option B: Using Anacoic (Recommended)
Anacoic automatically maps event names and handles both platforms:
// Same code sends to both Meta and TikTok
await fetch('https://gateway.anacoic.com/track', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Gateway-Host': 'your-domain.com',
},
body: JSON.stringify({
event_name: 'Purchase',
event_id: 'order_12345',
user_data: {
email: 'customer@example.com',
phone: '+1234567890',
},
custom_data: {
value: 99.99,
currency: 'USD',
content_ids: ['SKU-123'],
},
}),
});
// Automatically routes to Meta CAPI + TikTok Events API
Meta CAPI vs TikTok Events API: Comparison
Feature Comparison
| Feature | Meta CAPI | TikTok Events API |
|---|---|---|
| Setup Complexity | Medium | Medium |
| Documentation | Extensive | Good |
| Test Events Tool | ✅ Yes | ✅ Yes |
| Event Deduplication | ✅ Event ID | ✅ Event ID + ttp |
| Offline Events | ✅ Yes | ❌ No |
| Custom Events | ✅ Yes | ✅ Limited |
| Rate Limits | 100 events/sec | 1000 events/min |
| Attribution Window | 28-day click | 7-day click |
Event Name Mapping
| Standard Event | Meta CAPI | TikTok Events API |
|---|---|---|
| Purchase | Purchase | CompletePayment |
| Add to Cart | AddToCart | AddToCart |
| View Content | ViewContent | ViewContent |
| Initiate Checkout | InitiateCheckout | InitiateCheckout |
| Lead | Lead | SubmitForm |
| Search | Search | Search |
| Add Payment Info | AddPaymentInfo | AddBilling |
| Complete Registration | CompleteRegistration | CompleteRegistration |
User Data Requirements
| Field | Meta CAPI | TikTok Events API | Format |
|---|---|---|---|
| Required | Required | SHA-256 hashed | |
| Phone | Recommended | Required | SHA-256 hashed |
| IP Address | Required | Recommended | Plain text |
| User Agent | Required | Recommended | Plain text |
| External ID | Optional | Recommended | SHA-256 hashed |
| TikTok Click ID | N/A | Recommended | ttp parameter |
Sending to Both Platforms Simultaneously
Option 1: Manual Implementation
async function trackEvent(event) {
// Send to Meta
const metaPromise = sendToMetaCAPI(event);
// Send to TikTok
const tiktokPromise = sendToTiktokEventsAPI(event);
// Wait for both
const [metaResult, tiktokResult] = await Promise.allSettled([
metaPromise,
tiktokPromise,
]);
// Log results
console.log('Meta:', metaResult.status);
console.log('TikTok:', tiktokResult.status);
}
Cons:
- Double the code
- Double the maintenance
- Different error handling
- Different retry logic
Option 2: Using Anacoic (Recommended)
Configure both integrations in the Anacoic dashboard, then send once:
await fetch('https://gateway.anacoic.com/track', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-Gateway-Host': 'your-domain.com',
},
body: JSON.stringify({
event_name: 'Purchase',
event_id: 'order_12345',
user_data: {
email: 'customer@example.com',
phone: '+1234567890',
},
custom_data: {
value: 99.99,
currency: 'USD',
content_ids: ['SKU-123'],
},
}),
});
Anacoic automatically:
- ✅ Routes to Meta CAPI
- ✅ Routes to TikTok Events API
- ✅ Maps event names correctly
- ✅ Hashes PII data
- ✅ Handles retries
- ✅ Provides unified logging
Best Practices
1. Always Include Event IDs
Prevents duplicate conversions:
const eventId = `${orderId}_${timestamp}`;
// Use same ID for both platforms
metaEvent.event_id = eventId;
tiktokEvent.event_id = eventId;
2. Hash PII Consistently
Both platforms expect SHA-256:
function hashPII(value) {
return crypto
.createHash('sha256')
.update(value.trim().toLowerCase())
.digest('hex');
}
3. Include TikTok Click ID (ttclid)
Capture from URL and pass to TikTok:
// Capture on page load
const urlParams = new URLSearchParams(window.location.search);
const ttclid = urlParams.get('ttclid');
// Store in cookie
if (ttclid) {
document.cookie = `ttp=${ttclid}; max-age=604800; path=/`; // 7 days
}
// Read cookie when sending events
const ttp = getCookie('ttp');
4. Test Before Production
Meta: Use Test Events tool in Events Manager
TikTok: Use Events Manager Test Events
5. Monitor Event Match Quality
Meta: Check "Event Match Quality" in Events Manager
TikTok: Check "Match Rate" in TikTok Business Center
Aim for >70% match rate on both platforms.
Troubleshooting
Common Meta CAPI Issues
| Issue | Solution |
|---|---|
| "Invalid token" | Regenerate access token |
| "Event not received" | Check event_time is Unix timestamp |
| "Low match rate" | Include more user data fields |
| "Duplicate events" | Ensure unique event_id per event |
Common TikTok Events API Issues
| Issue | Solution |
|---|---|
| "Invalid access token" | Token expires every 90 days, regenerate |
| "Event rejected" | Check event name is valid TikTok event |
| "Low match rate" | Include ttp cookie and more user data |
| "Rate limit exceeded" | Max 1000 events/min, implement queuing |
Which Should You Use?
Use Meta CAPI if:
- You run Facebook/Instagram ads
- You need 28-day attribution
- You have offline events to track
- You want extensive custom event support
Use TikTok Events API if:
- You run TikTok ads
- Your audience is on TikTok (Gen Z, millennials)
- You want lower cost per acquisition (typically)
- You're in e-commerce or app install verticals
Use Both if:
- You run ads on both platforms
- You want complete attribution coverage
- You have the engineering resources
- Or use Anacoic to send to both with one integration
Conclusion
Meta CAPI and TikTok Events API are both essential tools for modern paid social advertising. While they have similar architectures, they differ in:
- Attribution windows (28-day vs 7-day)
- Event naming (slightly different conventions)
- User data requirements (TikTok requires phone)
- Audience demographics (broader vs younger)
The best approach: Use both platforms if you're advertising on both. Server-side tracking on Facebook and TikTok can recover 30-40% of conversions lost to ad blockers and privacy restrictions.
The easiest approach: Use a unified gateway like Anacoic to send events once and route to both platforms automatically.
Resources
- Meta Conversions API Documentation
- TikTok Events API Documentation
- Anacoic Meta CAPI Setup
- Anacoic TikTok Setup
Need help setting up server-side tracking? Book a demo or read our quickstart guide.