---
title: TikTok Pixel
slug: tiktok-pixel
docTags: 
createdAt: 2025-05-29T21:58:15.624Z
---

The **TikTok Pixel** destination loads the TikTok Pixel JavaScript SDK in the browser and forwards ecommerce and engagement events client-side to TikTok Ads. Unlike the [server-side TikTok Conversions API destination](#), device-mode events originate from the browser and can leverage the full TikTok Pixel feature set.

Use this destination alongside the [TikTok Conversions API destination](#) for maximum signal coverage.

# Getting Started

This is a device-mode destination. The TikTok Pixel SDK is loaded automatically — no manual script installation is required. You will need:

- **Pixel Code** — your TikTok Pixel ID, found in your TikTok Ads Manager under **Assets > Events > Web Events**.

Optionally:

- **Limited Data Use (LDU)** — enable Limited Data Use mode for CCPA compliance. Defaults to `false`.
- **Auto Page View** — automatically fire a page view on pixel initialization. Defaults to `true`.
- **Product Content ID Field** — which product field to use as the content ID: `product_id`, `sku`, `variant_id`, or `id`. Defaults to `sku` > `product_id` > `id` fallback chain.

# Connecting to the TikTok Pixel CDP Destination

:::BlockQuote
**Warning:** Before connecting destinations in the Chord CDP, please verify with all Destination owners that all **non-Chord CDP** configured destinations are **disabled**. Running external destinations alongside configured Chord CDP destinations **can result in duplicate events downstream.**
:::

1. Log into the Chord data platform.
2. Navigate to the CDP.
3. Click the **"Add"** button next to Destinations.
4. Select **TikTok Pixel** from the destination catalog.
5. Enter the destination name and your **Pixel Code**.
6. Configure optional settings as needed.
7. Click **"Create"** to connect.

# Events

Every event first calls `ttq.identify()` with available user data before sending the conversion event.

# Event Mapping

| Chord Event                 | TikTok Event                  | Notes                                                                                                               |
| --------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `page`                      | *(auto page view on init)*    | Fires during initialization when **Auto Page View** is `true`; subsequent page events send user identification only |
| `identify`                  | `ttq.identify()`              | Sets user data; no conversion event fired                                                                           |
| `Order Completed`           | `CompletePayment`             | Multi-product                                                                                                       |
| `Checkout Started`          | `InitiateCheckout`            | Multi-product                                                                                                       |
| `Payment Info Entered`      | `AddPaymentInfo`              | Multi-product                                                                                                       |
| `Product Added`             | `AddToCart`                   | Single-product                                                                                                      |
| `Product Viewed`            | `ViewContent`                 | Single-product                                                                                                      |
| `Product Clicked`           | `ClickButton`                 | Single-product                                                                                                      |
| `Product Added to Wishlist` | `AddToWishlist`               | Single-product                                                                                                      |
| `Products Searched`         | `Search`                      | Single-product                                                                                                      |
| `Signed Up`                 | `CompleteRegistration`        | No product data                                                                                                     |
| `Subscription Created`      | `Subscribe`                   | No product data                                                                                                     |
| *(any other track event)*   | Chord event name passed as-is | See [Custom Events](#)                                                                                              |

# Identify

Sets user identity on the TikTok pixel for enhanced matching. No conversion event is fired.

**TikTok SDK call:** `ttq.identify(userData)`

| TikTok Attribute                        | Chord Source (Priority Order)                                                              | Notes                                                                                                            |
| --------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| `email` or `sha256_email`               | `properties.email` > `context.traits.email` > `traits.email`                               | Routed to `sha256_email` if value is a SHA-256 digest; otherwise sent to `email` and TikTok hashes automatically |
| `phone_number` or `sha256_phone_number` | `properties.phone` > `context.traits.phone` > `traits.phone`                               | Routed to `sha256_phone_number` if value is a SHA-256 digest; otherwise sent to `phone_number` in E.164 format   |
| `external_id`                           | `userId` > `anonymousId`                                                                   |                                                                                                                  |
| `first_name`                            | `properties.first_name` > `context.traits.first_name` > `traits.first_name`                | Lowercased, whitespace removed                                                                                   |
| `last_name`                             | `properties.last_name` > `context.traits.last_name` > `traits.last_name`                   | Lowercased, whitespace removed                                                                                   |
| `city`                                  | `properties.address.city` > `context.traits.address.city`                                  | Lowercased, non-alphanumeric chars removed                                                                       |
| `state`                                 | `properties.address.state` > `context.traits.address.state`                                | Lowercased, non-alphanumeric chars removed                                                                       |
| `country`                               | `properties.address.country` > `context.traits.address.country`                            | Lowercased, non-alphanumeric chars removed                                                                       |
| `zip_code`                              | `properties.address.zipcode` > `context.traits.address.zipcode` > `traits.address.zipcode` | Lowercased, whitespace removed                                                                                   |

Identify is automatically called before every track event if any user data is available.

# PII Handling

TikTok's `track()` event schema does not include PII fields. Email, phone, and name belong exclusively in `ttq.identify()`, where TikTok automatically hashes them client-side using SHA-256 before transmission.

To prevent accidental PII exposure, the following fields are **always stripped** from track event payloads even if they appear in `event.properties` or are written there by a property mapping:

| Field          | Why stripped                |
| -------------- | --------------------------- |
| `email`        | Handled by `ttq.identify()` |
| `phone`        | Handled by `ttq.identify()` |
| `phone_number` | Handled by `ttq.identify()` |
| `first_name`   | Handled by `ttq.identify()` |
| `last_name`    | Handled by `ttq.identify()` |

If you have a property mapping that writes to one of these fields (e.g. `properties.email → properties.email`), the value will still flow to `ttq.identify()` through the normal user data extraction path — it will not appear in the `track()` payload.

# Multi-Product Events (Order Completed, Checkout Started, Payment Info Entered)

**TikTok SDK call:** `ttq.instance(pixelCode).track(eventName, eventProperties, { event_id: messageId })`

| TikTok Attribute | Chord Source (Priority Order)           | Notes                                                   |
| ---------------- | --------------------------------------- | ------------------------------------------------------- |
| `content_type`   | *(hardcoded)* `"product"`               |                                                         |
| `currency`       | `properties.currency`                   | Defaults to `"USD"`                                     |
| `value`          | `properties.value` > `properties.total` | Falls back to sum of `price × quantity` across products |
| `order_id`       | `properties.order_id`                   |                                                         |
| `shop_id`        | `properties.shop_id`                    |                                                         |
| `description`    | `properties.products[0].description`    | From first product                                      |
| `contents`       | `properties.products[]` mapped as below |                                                         |

**Product contents** — each item in `properties.products[]`:

| TikTok Attribute   | Chord Source                                                         |
| ------------------ | -------------------------------------------------------------------- |
| `content_id`       | Configured field from `properties.products[]` > `sku` > `product_id` |
| `content_name`     | `properties.products[].name`                                         |
| `content_category` | `properties.products[].category`                                     |
| `price`            | `properties.products[].price`                                        |
| `quantity`         | `properties.products[].quantity`                                     |
| `brand`            | `properties.products[].brand`                                        |

# Single-Product Events (Product Added, Product Viewed, Product Clicked, Product Added to Wishlist, Products Searched)

Product data is extracted from top-level `properties` (not `properties.products[]`).

**TikTok SDK call:** `ttq.instance(pixelCode).track(eventName, eventProperties, { event_id: messageId })`

| TikTok Attribute | Chord Source (Priority Order)                                | Notes                  |
| ---------------- | ------------------------------------------------------------ | ---------------------- |
| `content_type`   | *(hardcoded)* `"product"`                                    |                        |
| `currency`       | `properties.currency`                                        | Defaults to `"USD"`    |
| `value`          | `properties.value` > `properties.total` > `properties.price` |                        |
| `order_id`       | `properties.cart_id` / `properties.order_id`                 | Omitted if not present |
| `shop_id`        | `properties.shop_id`                                         | Omitted if not present |
| `description`    | `properties.description`                                     |                        |
| `query`          | `properties.query`                                           | Products Searched only |
| `contents`       | Single-element array from top-level `properties`             |                        |

**Single product content:**

| TikTok Attribute   | Chord Source (Priority Order)                                                   |
| ------------------ | ------------------------------------------------------------------------------- |
| `content_id`       | Configured field from `properties` > `properties.sku` > `properties.product_id` |
| `content_name`     | `properties.name`                                                               |
| `content_category` | `properties.category`                                                           |
| `price`            | `properties.price`                                                              |
| `quantity`         | `properties.quantity` — defaults to `1`                                         |
| `brand`            | `properties.brand`                                                              |

# No-Product Events (Signed Up, Subscription Created)

Same event-level attributes as multi-product events above, but `contents` is an empty array.

# Custom Events

Any `track` event that does not match a Chord tracking plan event name is forwarded to TikTok using the Chord event name as-is. This includes events like `Form Submitted`, `Callback Started`, `Download Link Clicked`, and any other custom event names your storefront fires.

**TikTok SDK call:** `ttq.instance(pixelCode).track(eventName, eventProperties, { event_id: messageId })`

The payload uses the same structure as multi-product events — if the event carries `products`, `currency`, `value`, or order data in its properties, those are extracted and forwarded. Custom properties from property mappings are also included.

| TikTok Attribute | Chord Source                                              | Notes                                                       |
| ---------------- | --------------------------------------------------------- | ----------------------------------------------------------- |
| `content_type`   | *(hardcoded)* `"product"`                                 |                                                             |
| `currency`       | `properties.currency`                                     | Defaults to `"USD"`                                         |
| `value`          | `properties.value` > `properties.total`                   | Falls back to sum of `price × quantity` if products present |
| `order_id`       | `properties.order_id`                                     | Omitted if not present                                      |
| `contents`       | `properties.products[]` if present, otherwise empty array |                                                             |

If the TikTok event name you want to fire does not match your Chord event name, use a property mapping in the Hub to rename the event before it reaches this destination.

# Custom Property Forwarding

Configure destination mappings in Hub with `properties.*` destination paths to forward additional event properties alongside the computed schema fields in the `ttq.instance(...).track(...)` payload. Only explicitly-configured non-schema fields are forwarded — nothing flows through automatically.

**How to configure:**

1. Open the destination's **Mappings** tab in Hub.
2. Add a mapping with source path `properties.loyalty_tier` and destination path `properties.loyalty_tier`.
3. On the next event, `loyalty_tier` will appear in the event properties payload sent to TikTok.

**What is excluded:**

- Schema fields already handled by the destination transform (e.g. `currency`, `value`, `order_id`, `contents`) — these flow through the structured transform
- PII fields (`email`, `phone`, `first_name`, `last_name`) — see [PII Handling](#); these are always stripped from track event payloads and handled by `ttq.identify()` instead

When a custom mapping targets a schema field (e.g. `properties.value → properties.value`), the customer-configured value overrides the destination's computed default. This allows schema fields to be sourced from a different event property — for example, mapping `properties.total → properties.value` to use your order total as the conversion value.

# Initialization

The plugin sets up the `ttq` function queue, then loads `https://analytics.tiktok.com/i18n/pixel/events.js`. The partner name is set to `"Chord"`. If **Auto Page View** is `true` (default), an initial page view is fired immediately after initialization.

The plugin manages SDK loading state (`fresh` → `loading` → `loaded`/`failed`) to prevent duplicate script loads. If the script fails to load, subsequent events are silently dropped.

# CSP Requirements

If your site uses a Content Security Policy, allow the following domains:

| Directive     | Domain                         |
| ------------- | ------------------------------ |
| `script-src`  | `https://analytics.tiktok.com` |
| `connect-src` | `https://analytics.tiktok.com` |

***

**Updated 27 May 2026**
