TikTokGuide

TikTok Attribution Setup Guide

Complete dual-tracking stack setup: TikTok Pixel + Events API, event mapping, three integration methods, and verification.

March 27, 20268 min read

Why Dual Tracking (Pixel + Events API)?

The gold standard for TikTok attribution is running both browser-side (Pixel) and server-side (Events API) in parallel, with deduplication enabled.

LayerMethodWhy it matters
Browser-sideTikTok Pixel (JS)Real-time optimization signal for TikTok's ad algorithm
Server-sideEvents API (CAPI)Captures events missed by ad blockers, iOS restrictions, and browser privacy changes. Expect 20–30% of browser events to drop off without it.

TikTok uses an event ID to deduplicate — when the same event arrives from both sources with a matching ID, it keeps one and discards the other.

Rule of thumb: Browser-side for immediacy, server-side for reliability. Both together = best signal quality.

Step 1 — Get Your Credentials

Pixel ID

  1. Log in to TikTok Ads Manager
  2. Go to Tools → Events Manager
  3. Under Web Events, select your Pixel
  4. Copy the Pixel ID from Settings

Events API Access Token

  1. In the same Pixel Settings page, scroll to Access Token Generation
  2. Click Generate Access Token
  3. Copy and store securely

Step 2 — Event Mapping

Map your funnel stages to TikTok's standard event names. TikTok optimizes specifically against these names — custom or misspelled event names significantly reduce algorithm performance.

Standard Event Reference

Funnel StageTikTok Event NameKey Parameters
Page load / site visitPageView
User clicks primary CTA / starts signupInitiateCheckout
Account created / registration completeCompleteRegistrationexternal_id
Payment page reachedAddPaymentInfo
Purchase confirmedPurchasevalue, currency, content_ids
Subscription startedSubscribevalue, currency
Event names are case-sensitive. purchasePurchase. TikTok will accept the event but won't optimize against it correctly.
Match KeyFieldNotes
emailHashed emailMost important identifier
phone_numberHashed phoneE.164 format before hashing: +12125551234
ttclidTikTok Click IDFrom URL param — gold standard for attribution
external_idYour internal user ID / order IDUnique per user or transaction
ipUser IP addressDo not hash — send raw
user_agentBrowser user agentDo not hash — send raw

All PII should be SHA-256 hashed before sending.

Event ID for Deduplication

Every event fired from both browser and server must include a shared event_id.

// Generate once per event, share across both layers
const eventId = `${userId}-${eventName}-${Date.now()}`;

Step 3 — Integration Methods

Best for: clients with a custom backend (Laravel, Node, Python, etc.) who want full control.

Browser-side: Install the TikTok Pixel base code

Add to <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]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src=r+"?sdkid="+e+"&lib="+t;e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(n,e)};
  ttq.load('YOUR_PIXEL_ID');
  ttq.page();
}(window, document, 'ttq');
</script>

Fire browser-side events

// On CTA click (InitiateCheckout)
ttq.track('InitiateCheckout', {
  event_id: eventId
});

// On registration complete
ttq.track('CompleteRegistration', {
  event_id: eventId,
  external_id: sha256(userId)
});

// On purchase
ttq.track('Purchase', {
  event_id: eventId,
  value: 29.99,
  currency: 'USD',
  content_ids: ['driver-ed-ca']
});

Server-side: Events API call

Fire this from your backend on the same events — ideally from a Stripe webhook for purchases.

// Node.js example
const crypto = require('crypto');

function sha256(value) {
  return crypto.createHash('sha256').update(value.toLowerCase().trim()).digest('hex');
}

async function sendTikTokEvent({ eventName, eventId, user, value, currency }) {
  const payload = {
    pixel_code: process.env.TIKTOK_PIXEL_ID,
    event: eventName,
    event_id: eventId,
    timestamp: new Date().toISOString(),
    context: {
      ip: user.ip,
      user_agent: user.userAgent,
      user: {
        email: sha256(user.email),
        phone_number: user.phone ? sha256(user.phone) : undefined,
        external_id: sha256(user.id),
        ttclid: user.ttclid
      }
    },
    properties: {
      value: value,
      currency: currency || 'USD'
    }
  };

  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({ data: [payload] })
    }
  );

  return response.json();
}

Handling the TikTok Click ID (ttclid)

The ttclid is appended to your URL by TikTok when a user clicks an ad. It's the highest-confidence attribution signal available.

// On page load — capture and store in session
const urlParams = new URLSearchParams(window.location.search);
const ttclid = urlParams.get('ttclid');
if (ttclid) {
  sessionStorage.setItem('ttclid', ttclid);
}

// Retrieve when building event payload
const storedTtclid = sessionStorage.getItem('ttclid');
Cross-domain note: If users navigate from a marketing site to a separate checkout/app domain, pass ttclid as a URL parameter in the CTA button link and re-capture it on the destination domain.

Method B — Google Tag Manager (Server-Side)

Best for: clients already using GTM, or those using Google Tag Gateway / sGTM for server-side routing.

Prerequisites

  • GTM web container installed on the site
  • GTM server container deployed (via Google Cloud or App Engine)
  • TikTok Pixel ID and Events API Access Token

1. Install TikTok Pixel via GTM web container

  1. In your web container, create a new tag
  2. Select TikTok Pixel from the Community Template Gallery
  3. Enter your Pixel ID
  4. Set trigger to All Pages
  5. Publish

2. Add the TikTok Events API tag in your server container

  1. Open your server container
  2. Go to Tags → New
  3. Select TikTok Events API (Official) from the Community Template Gallery
  4. Enter your Access Token and Pixel ID
  5. Map event parameters: event_name, value, currency, user identifiers (email, phone, external_id), ip, user_agent

3. Configure triggers

Set the TikTok Events API tag to fire on the relevant server-side events.

// Push to data layer from your site code
dataLayer.push({
  event: 'purchase',
  tiktok_event_id: eventId,
  transaction_id: orderId,
  value: 29.99,
  currency: 'USD',
  user_email: sha256(email)
});

4. Enable deduplication

In the TikTok Events API tag configuration, map the event_id field to the same value used by the browser-side pixel.

Method C — Segment (CDP routing)

Best for: clients already using Segment who want to route events to TikTok alongside other destinations.

Setup

  1. In Segment, go to Connections → Destinations → Add Destination
  2. Search for TikTok Conversions and connect
  3. Enter your Pixel ID and Access Token
  4. Map your Segment track events to TikTok standard event names
// Segment track call
analytics.track('Order Completed', {
  event_id: eventId,
  order_id: orderId,
  revenue: 29.99,
  currency: 'USD',
  email: email
});
Segment's TikTok destination sends server-side by default. You still need the browser-side Pixel base code installed separately for real-time optimization signals.

Step 4 — Testing & Verification

TikTok Pixel Helper (Chrome Extension)

Install the TikTok Pixel Helper Chrome extension. Browse your site and confirm:

  • Base code fires on every page (PageView)
  • Conversion events fire at the correct funnel stages
  • No duplicate events on a single page load
  • Event names match the standard names exactly (case-sensitive)

Test Events Tool (TikTok Ads Manager)

  1. In TikTok Ads Manager, go to Tools → Events Manager
  2. Select your Pixel → Test Events tab
  3. Enter your site URL
  4. Go through the funnel — events should stream in live
  5. Confirm you see both browser and server events for each action

Events Manager Diagnostics

Use the Diagnostics tab in Events Manager to catch:

  • Unnamed events (missing or mismatched event names)
  • Low match rates (missing identifiers)
  • Missing deduplication (event ID not being passed)
  • Currency/value formatting issues

Common Issues

IssueLikely causeFix
Events showing as "Unnamed"Event name is missing or casing is wrongCheck exact casing — Purchase not purchase
Low match rateMissing identifiersAdd email, ttclid, external_id to payload
Double countingDeduplication not configuredEnsure event_id is identical across browser + server events
Value showing 100x too highSending value in cents (Stripe format)Convert to decimal before sending: amount / 100
No server eventsWebhook not firingCheck success webhook from payment processor

Orbit MCP Integration

If your team uses Claude Code or Cursor for development, you can connect the Orbit MCP server to your AI assistant. The MCP has access to:

  • This setup guide as a reference document
  • Live TikTok Events Manager diagnostics for your account
  • Pixel audit tools that can detect the issues in the table above
  • Test event triggers to validate your implementation in real time

Ask your Orbit contact to get your MCP credentials.

Last updated: March 2026 · Maintained by Orbit (orbitllm.com)

TikTok Attribution Setup Guide — Orbit