# TikTok Pixel with GTM: setup and consent in the EU

**Author:** Piotr Litwa - GTM & Analytics Specialist  
**Published:** 2026-08-21  
**URL:** https://piotrlitwa.com/articles/en/tiktok-pixel-gtm-consent-mode.html  
**Language:** en  
**Keywords:** tiktok pixel gtm, tiktok pixel google tag manager, tiktok pixel consent mode, tiktok events api, tiktok pixel completepayment

---

You set up the TikTok Pixel in GTM with the official TikTok template from the Community Template Gallery, your Pixel ID, and one tag per standard event (`ViewContent`, `AddToCart`, `InitiateCheckout`, `CompletePayment`) carrying `value`, `currency`, and `content_id`. That part takes 20 minutes.

The part that takes longer is consent. **Google Consent Mode v2 doesn't control the TikTok Pixel.** If your banner talks to GTM only through Consent Mode, TikTok is almost certainly firing for users who clicked "Reject all". This guide covers both halves: the build, and the gate you have to add yourself.

> **Key Takeaways**
> - Use the TikTok Pixel template published by TikTok in the GTM Community Template Gallery. Don't paste the base code into a Custom HTML tag.
> - Purchases go through `CompletePayment` with `value`, `currency`, and `content_id`. Without value and currency, value-based optimization has nothing to work with.
> - Consent Mode v2 signals adjust Google tags only. TikTok ignores them, so you need "Require additional consent for tag to fire" with `ad_storage` on every TikTok tag.
> - The pixel writes `_ttp` and `_tt_enable_cookie`. Neither should exist after a user denies consent. That's your 90-second test.
> - If you add the Events API later, send the same `event_id` from browser and server, or TikTok counts every order twice.

## Why TikTok sits outside Consent Mode

[Consent Mode v2](https://piotrlitwa.com/articles/en/consent-mode-v2-guide.html) is a Google protocol. When your CMP sets `ad_storage` to `denied`, Google tags (GA4, Google Ads, Floodlight) read that state and change their own behavior: no cookies, a cookieless ping instead. The tag is built to listen.

TikTok's pixel isn't a Google tag. It doesn't read `gtag('consent', ...)` at all. It has no cookieless mode that GTM can switch on for you. So when GTM fires it, it loads `analytics.tiktok.com`, writes its cookies, and sends the event. Every time.

I'll be blunt: a container where every non-Google tag fires on All Pages, and the only consent logic is the Consent Mode default command, isn't a consent setup. It's a Google setup with a banner on top.

This is the same gap I described for the [LinkedIn Insight Tag in GTM](https://piotrlitwa.com/articles/en/linkedin-insight-tag-gtm.html). TikTok is worse in one way: it tends to get added fast, by a social media freelancer, during a campaign launch, with nobody checking the consent settings.

**Not sure which of your tags ignore consent?** The [Free GTM Audit](https://piotrlitwa.com/checkGTM/) lists every tag in the container and flags the ones with no consent requirement. About 10 minutes, no signup.

## What you need before you open GTM

Four things. Get them first, or you'll be clicking between tabs for an hour.

- **Pixel ID.** In TikTok Ads Manager, go to Tools, then Events, then Web Events. The ID is a string of 20 uppercase letters and digits, something like `C4ABCD1234EFGH5678IJ`.
- **A data layer with ecommerce data.** If your store already pushes GA4 events (`view_item`, `add_to_cart`, `purchase`), you're 80% done. If not, start with the [GA4 data layer guide](https://piotrlitwa.com/articles/en/gtm-data-layer-ga4-guide.html).
- **A CMP that updates consent in GTM.** Cookiebot, CookieYes, Usercentrics, Cookie Banner Pro, any of them, as long as it sets the consent state before tags evaluate.
- **The TikTok Pixel Helper** Chrome extension, for testing.

One decision to make now: does `content_id` in TikTok match the product ID in your catalog feed? If you run Video Shopping Ads or catalog retargeting, it must. A pixel sending SKUs while the feed uses WooCommerce post IDs gives you a 0% match rate and catalog ads that never deliver.

## TikTok Pixel GTM setup, step by step

Here's the base build. It's the boring part and it should stay boring.

1. In GTM, go to **Tags**, then **New**, then **Tag Configuration**, then **Discover more tag types in the Community Template Gallery**.
2. Search for "TikTok Pixel" and pick the one published by TikTok. Check the publisher line. There are lookalikes.
3. Click **Add to workspace** and accept the permissions.
4. Enter your **Pixel ID**.
5. For the base tag, choose the page view event (the template's default) and trigger it on **Initialization - All Pages**, not Consent Initialization.
6. Open **Advanced Settings**, then **Consent Settings**, and set the consent requirement (next section). Don't skip this to "test first". Tests become production.
7. Preview, check with the Pixel Helper, publish.

The template also handles Advanced Matching: you can pass a hashed email or phone number. In the EU, treat that as personal data under the same consent as everything else. I wouldn't turn it on until the consent gate is proven to work.

## The standard events and their parameters

This is where most TikTok setups lose money quietly. The event fires, Ads Manager shows a green dot, and nobody notices the `value` field is empty.

| TikTok event | When it fires | Parameters that matter | Maps from GA4 event |
|---|---|---|---|
| `ViewContent` | Product page view | `content_id`, `content_type`, `value`, `currency` | `view_item` |
| `AddToCart` | Item added to cart | `content_id`, `quantity`, `value`, `currency` | `add_to_cart` |
| `InitiateCheckout` | Checkout started | `contents`, `value`, `currency` | `begin_checkout` |
| `AddPaymentInfo` | Payment method chosen | `value`, `currency` | `add_payment_info` |
| `CompletePayment` | Order confirmed | `contents`, `value`, `currency`, `content_type` | `purchase` |
| `SubmitForm` | Lead form sent | none required | `generate_lead` |

Three rules I apply to every build:

- **`currency` is an ISO code.** `EUR`, `PLN`, `CZK`. Not "€", not "zł". TikTok drops or misreads anything else.
- **`value` is a number.** Not `"1 249,00 zł"` as a string. Format it in the data layer or in a Custom JavaScript variable before it reaches the tag.
- **`content_type` is `product` or `product_group`.** Pick one per site and stick to it.

For `CompletePayment` I map straight from the GA4 `purchase` push. The `contents` array is built from the GA4 `items` array with a small Custom JavaScript variable:

```js
function() {
  var items = {{DLV - ecommerce.items}} || [];
  return items.map(function(item) {
    return {
      content_id: String(item.item_id),
      content_name: item.item_name,
      quantity: Number(item.quantity) || 1,
      price: Number(item.price) || 0
    };
  });
}
```

Then the tag gets `contents` = that variable, `value` = `{{DLV - ecommerce.value}}`, `currency` = `{{DLV - ecommerce.currency}}`. Trigger: a Custom Event trigger on `purchase`. If you've never built a Data Layer Variable, it's Variables, then New, then Data Layer Variable, with the name `ecommerce.items`.

## Gating TikTok for EU consent

There are two clean ways to do it. I use the first one by default.

### Option 1: Require additional consent (my default)

On every TikTok tag, base and events:

1. Open the tag, then **Advanced Settings**, then **Consent Settings**.
2. Select **Require additional consent for tag to fire**.
3. Add `ad_storage`, plus `ad_user_data`, since the pixel sends user-level data to an ad platform.
4. Save, then repeat for every TikTok tag, all of them.

GTM now holds the tag until those consent types are granted. If the user accepts on the second pageview, the tag fires from that point on. If they never accept, it never fires. It works with any CMP that updates GTM consent state, and it's visible in the tag list, which matters when an auditor asks.

### Option 2: Trigger conditions or CMP events

The older approach: your CMP pushes an event like `cookie_consent_marketing`, and you trigger TikTok on that event, or add a condition `Marketing Consent equals granted` to the trigger.

It works. It's also fragile. If the CMP loads slowly, the condition evaluates before consent is known, and depending on how it's written, you either lose the first pageview or fire without consent. Consent timing is where I find most leaks. It's the reason I built the [Universal Consent Adapter](https://piotrlitwa.com/uca/).

TikTok also has its own consent calls (`ttq.holdConsent()`, `ttq.grantConsent()`, `ttq.revokeConsent()`). They're useful on sites without GTM. Inside GTM, I'd rather have one consent mechanism for the whole container than a TikTok-specific one.

### The 90-second test

Configuration proves nothing. Test it:

1. Open the site in a fresh incognito window.
2. Click **Reject all** in the banner.
3. Open DevTools, then **Application**, then **Cookies**, and look for `_ttp` and `_tt_enable_cookie`.
4. In the **Network** tab, filter for `tiktok`. There should be zero requests to `analytics.tiktok.com`.
5. Accept consent, reload, and check that both appear.

If the cookies show up after a rejection, the setup is decorative. The [Consent Mode checklist](https://piotrlitwa.com/articles/en/consent-mode-checklist.html) has the same test for Google tags, so you can run both in one sitting.

## Weronika's store: two problems in one container

Weronika runs a cosmetics store in Kraków, about 620 orders a month, roughly 30% of traffic from TikTok. Her freelancer installed the pixel in March 2026. In June she asked me why TikTok reported 1,010 `CompletePayment` events for a month with 640 actual orders.

The container had two TikTok setups. The freelancer's Custom HTML base code, pasted from Ads Manager, firing on All Pages.

And a newer template tag added by an agency, also firing `CompletePayment` on the thank-you page. Some orders were counted by both. Neither had any consent setting.

The fix took an afternoon:

- Deleted the Custom HTML tag and kept the template.
- Added `ad_storage` and `ad_user_data` as required consent to all five TikTok tags.
- Moved `CompletePayment` from a Page View trigger on `/order-received/` to the `purchase` data layer event, so a refresh of the thank-you page stops sending a second purchase.

July: 655 orders, 431 `CompletePayment` events. Lower than before, and correct.

About 66% of buyers accept marketing cookies on her banner, which matches. Her ROAS in TikTok dropped on paper. Her actual margin didn't change at all. It's a hard conversation, and it's the one an honest setup forces.

## The Events API and event_id deduplication

The TikTok Events API is the server-side half: your server sends conversions directly to TikTok, so ad blockers and Safari's tracking limits don't eat them. Same idea as the [Meta Conversions API](https://piotrlitwa.com/articles/en/meta-conversions-api-setup-guide.html).

Two things matter here.

**Deduplication needs a shared `event_id`.** If the browser pixel and the server both send `CompletePayment` for the same order, TikTok counts it once only if both carry the same `event_id`.

I use the order number, prefixed: `order_48213`. Set it in the template's event ID field and in the server payload. No shared ID, double counting. Guaranteed.

**Server-side doesn't create consent.** If Kamil, a shopper in Gdańsk, rejected marketing cookies, sending his purchase to TikTok from your server instead of his browser is the same processing, just harder to see. Your server-side TikTok tag needs the same consent condition as the browser one. If you're running server-side GTM, pass consent state through to the server container and check it there.

Is the Events API worth it? For stores with real TikTok spend, above maybe €3,000 a month, usually yes. Below that, I'd fix the browser setup first. A clean pixel beats a messy pixel plus a messy server feed.

## Frequently asked questions

**Does Google Consent Mode v2 control the TikTok Pixel?**
No. Consent Mode signals are read by Google tags only. The TikTok Pixel ignores them, so you have to block it in GTM with "Require additional consent for tag to fire" or with consent-based triggers.

**Which TikTok event should I use for purchases?**
Use `CompletePayment` with `value`, `currency`, and `contents` (or `content_id`). Fire it from the `purchase` data layer event, not from a thank-you page URL, so a page refresh doesn't send it twice.

**Should I use the TikTok template or Custom HTML in GTM?**
The template published by TikTok in the Community Template Gallery. It's sandboxed, has fields for every parameter and the event ID, and supports GTM consent settings without extra code. Custom HTML works, but it's harder to audit and easy to duplicate.

**What cookies does the TikTok Pixel set?**
The main first-party ones are `_ttp` and `_tt_enable_cookie`. In the EU both need marketing consent before they're written. If you see them after rejecting consent in incognito, your gate isn't working.

**Do I need the TikTok Events API?**
If TikTok is a meaningful sales channel, yes, because browser tracking loses conversions to ad blockers and browser limits. Send the same `event_id` from browser and server for deduplication, and apply the same consent rules on the server.

**Why does TikTok report more purchases than my store?**
The usual causes are a duplicate pixel (Custom HTML plus template), a purchase tag on a thank-you page that fires on every refresh, or browser and Events API sending the same order without a shared `event_id`. TikTok's attribution windows also count view-through conversions, which your store doesn't.

## Next steps

Open your GTM container and filter tags by "TikTok". Count them. If there's a Custom HTML tag and a template tag, you've found your first problem. If none of them show a consent requirement in the tag list, you've found your second.

Then run the 90-second test. Incognito, Reject all, look for `_ttp`. It tells you more than any dashboard will.

If you'd rather have someone check the whole container, every vendor and not just TikTok, the [Free GTM Audit](https://piotrlitwa.com/checkGTM/) flags tags that fire without consent. And if you want that checked continuously instead of once, that's what [GTM monitoring](https://piotrlitwa.com/services.html#assurance) does, from €390/month, written report, no calls.

---

**Sources and further reading**
- [TikTok Pixel overview](https://ads.tiktok.com/help/article/tiktok-pixel) (TikTok Business Help Center)
- [TikTok Events API](https://ads.tiktok.com/help/article/events-api) (TikTok for Developers)
- [Consent settings in Google Tag Manager](https://support.google.com/tagmanager/answer/10718549) (Google)

---

*Written by [Piotr Litwa](https://piotrlitwa.com/about.html) - independent GTM & Analytics specialist.*
