TikTok Events API
Datafly Signal delivers events to TikTok server-to-server using the TikTok Events API, replacing the client-side TikTok Pixel.
Why route TikTok through Datafly Signal
- Conversions survive ad blockers and tracking prevention. A browser tag served from an advertising domain is blocked outright for part of your traffic, and Safari’s ITP shortens the cookies it can set. Signal sends the event from your own server, so the conversions TikTok optimises against are not filtered by the browser.
- Email, phone number and user id are hashed before leaving your infrastructure. Signal normalises (trim and lowercase) and applies SHA-256 inside your own deployment, so TikTok receives match keys rather than raw personal data.
- Client IP and user agent are carried in the payload. Both are taken from the original visitor request rather than your server, which is what TikTok needs to attribute the event to the right session.
- Click identifiers are captured and replayed. Signal stores
ttclidfirst-party at collection time and attaches them to the conversion later, so attribution survives even when the original landing cookie has expired. - Delivery is batched, rate-limited, and retried. Signal buffers to Kafka, respects the TikTok rate limit, and retries on 429 or transient failure rather than dropping the event.
- Presets for Retail, Travel, Automotive and Media. The mapping starts from a working configuration for your vertical instead of a blank field map.
- One consent decision governs every destination. TikTok is gated by the same consent state as the rest of your stack, so a withdrawal applies everywhere at once.
- No vendor tag on the page. Removing it removes its page weight and its independent access to your visitors.
Prerequisites
Before configuring TikTok in Signal, you need:
- A TikTok for Business / TikTok Ads Manager account with admin or Events Manager permissions
- A TikTok Pixel (Web Event Source)
- An Events API access token for that Pixel
Get your TikTok credentials
- Sign in to TikTok Ads Manager.
- Go to Assets → Events → Web Events and select your Pixel (or click Set up Web Events to create one).
- The Pixel Code (e.g.
CXXXXXXXXXXXXXXXXX) is shown on the Pixel overview page. - Open the Pixel’s Settings → Events API and click Generate access token. Copy the token immediately.
See TikTok’s Events API documentation for full details.
Configure the integration in Signal
- In the Management UI, go to Integrations → Add Integration.
- Select TikTok from the catalogue.
- Give the integration a name (for your reference).
- Choose a preset (Retail, Travel, Automotive, Media or Insurance).
- Fill in the required fields:
| Field | Required | Description |
|---|---|---|
pixel_code | Yes | TikTok Pixel Code from Ads Manager. |
access_token | Yes | Events API access token. |
test_event_code | No | Test event code for validation. |
- Choose which pipeline(s) this integration should run on.
- Select consent categories (defaults to marketing).
- Click Save.
Presets and event mapping
contents (TikTok’s shape: content_id, content_name, content_category, brand, price, quantity) comes from your items[] (canonical), else the legacy products[], else a single flat item_id / product_id (automotive: then the legacy vehicle_id), with content_type product. search_string and query are search_term, else the legacy query; order_id is transaction_id, else order_id; value is value (the total including tax and shipping, as the event specs define it), else the legacy revenue. CompletePayment is sent only with a currency.
The request’s event_source is web unless you set event_source on the integration (app, offline, crm); app events are reported as web for now (#1581). Every request is batched in data[] with event_source_id (your pixel code).
Retail preset (ecommerce)
Full retail funnel for the TikTok Events API: Pageview, Search (search_string and query), ViewContent, AddToWishlist, AddToCart, InitiateCheckout, AddPaymentInfo, CompletePayment (currency required, order ID) and Lead. contents (content_id, content_name, content_category, brand, price, quantity) come from items[], else the legacy products[], else a flat item. Email and phone are normalised SHA-256 hashes, the user ID a SHA-256 hash.
| Signal event | TikTok event | Fields the preset sets |
|---|---|---|
page | Pageview | global fields only. |
search | Search | contents, search_string, query, value, currency, content_type. |
view_item | ViewContent | contents, value, currency, content_type. |
add_to_wishlist | AddToWishlist | contents, value, currency, content_type. |
add_to_cart | AddToCart | contents, quantity, price, value, currency, content_type. |
begin_checkout | InitiateCheckout | contents, value, currency, content_type. |
add_payment_info | AddPaymentInfo | contents, value, currency, content_type. |
purchase | CompletePayment | contents, order_id, value, currency, content_type. Sent only when properties.currency is set. |
generate_lead | Lead | description, value, currency. |
Travel preset (travel)
Travel funnel for the TikTok Events API: searches, listing views and saves, booking start, payment and completed booking (CompletePayment), leads; contents from items[].
| Signal event | TikTok event | Fields the preset sets |
|---|---|---|
page | Pageview | global fields only. |
destination_searched | Search | search_string, query, value, currency. |
listing_viewed | ViewContent | contents, value, currency, content_type. |
listing_saved | AddToWishlist | contents, value, currency, content_type. |
booking_started | InitiateCheckout | contents, value, currency, content_type. |
add_payment_info | AddPaymentInfo | contents, value, currency, content_type. |
booking_completed | CompletePayment | contents, order_id, value, currency, content_type. Sent only when properties.currency is set. |
generate_lead | Lead | description, value, currency. |
Automotive preset (automotive)
Vehicle marketing funnel for the TikTok Events API: Search, ViewContent, AddToWishlist, Download, SubmitForm, Lead, Contact and Subscribe; contents from items[] or the flat item_id.
| Signal event | TikTok event | Fields the preset sets |
|---|---|---|
page | Pageview | global fields only. |
vehicle_searched | Search | search_string, query, make, model, body_type, fuel_type. |
vehicle_viewed | ViewContent | contents, brand, content_name, value, currency, content_category, content_type. |
vehicle_compared | ViewContent | contents, content_type. |
vehicle_saved | AddToWishlist | contents, brand, content_name, value, currency, content_type. |
brochure_downloaded | Download | content_id, make, model. |
finance_quote_requested | SubmitForm | contents, value, currency, content_type. |
trade_in_valued | SubmitForm | value, currency. |
test_drive_booked | Lead | contents, dealer_id, make, model, content_type. |
dealer_contacted | Contact | contents, dealer_id, enquiry_type, content_type. |
service_appointment_booked | Subscribe | dealer_id, service_type, value, currency. |
Media preset (media)
Media and subscription funnel for the TikTok Events API: content views, subscriptions, leads and registrations.
| Signal event | TikTok event | Fields the preset sets |
|---|---|---|
page | Pageview | global fields only. |
content_viewed | ViewContent | content_id, content_name, content_category. |
subscription_started | Subscribe | content_name, value, currency. |
generate_lead | Contact | description, value, currency. |
sign_up | CompleteRegistration | description. |
Insurance preset (insurance)
Insurance funnel per the insurance event spec’s TikTok mapping: quote requests and leads as SubmitForm, policy views as ViewContent, checkout and payment, policy purchase and renewal as CompletePayment (policy number as order_id, currency required), the quote journey as custom events. Email and phone are sent only as normalised SHA-256 hashes; contents come from items[].
| Signal event | TikTok event | Fields the preset sets |
|---|---|---|
page | Pageview | global fields only. |
view_item_list | ViewContent | contents, value, currency, content_type. |
select_item | ClickButton | contents, value, currency, content_type. |
search | Search | search_string, query. |
view_search_results | Search | search_string, query. |
view_item | ViewContent | contents, value, currency, content_type. |
quote_started | QuoteStarted | value, currency, content_category, quote_id. |
get_quote | GetQuote | value, currency, content_category, quote_id. |
quote_requested | SubmitForm | value, currency, content_category, quote_id. |
quote_received | QuoteReceived | value, currency, content_category, quote_id. |
quote_completed | QuoteCompleted | value, currency, content_category, quote_id. |
generate_lead | SubmitForm | value, currency, content_category, quote_id. |
lead_submitted | SubmitForm | value, currency, content_category, quote_id. |
contact_requested | Contact | value, currency, content_category, quote_id. |
add_to_cart | AddToCart | contents, value, currency, content_type. |
begin_checkout | InitiateCheckout | contents, value, currency, content_type. |
add_payment_info | AddPaymentInfo | contents, value, currency, content_type. |
purchase | CompletePayment | contents, value, currency, order_id, content_type. Sent only when properties.currency is set. |
policy_purchased | CompletePayment | contents, value, currency, order_id, content_type. Sent only when properties.currency is set. |
policy_renewed | CompletePayment | contents, value, currency, order_id, content_type. Sent only when properties.currency is set. |
sign_up | CompleteRegistration | global fields only. |
Example: purchase
A Retail purchase from a known visitor, as Signal sends it to POST https://business-api.tiktok.com/open_api/v1.3/event/track/:
{
"data": [
{
"event": "CompletePayment",
"event_id": "evt-spec-0001",
"event_time": 1790155800,
"page": {
"referrer": "https://www.google.com/",
"url": "https://shop.example.co.uk/checkout?gclid=g-123"
},
"properties": {
"content_type": "product",
"contents": [
{
"brand": "BMW",
"content_category": "SUV",
"content_id": "STK-7421",
"content_name": "BMW X3 xDrive30e",
"price": 49995,
"quantity": 1
}
],
"currency": "GBP",
"event_source": "web",
"order_id": "ORD-10042",
"value": 49995
},
"user": {
"email": "86e0b9e56c17cc4d12387e1949b85053fbe73bc3ce5a1188713a9d300cc6133d",
"external_id": "40ba61f5c6b64e4f3f389c4b7a244f2b176115cbf452d1d81cf9bf70ebdf739d",
"ip": "203.0.113.7",
"locale": "en-GB",
"phone_number": "a8acc3a90a7b4e4dc65e93db9240ed26523050ef754d63b75b5161de76781436",
"ttclid": "tt-123",
"user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 Version/18.0 Safari/605.1.15"
}
}
],
"event_source": "web"
}Identity
Signal sends these identity signals to TikTok, subject to consent and availability:
| Signal | Field | Notes |
|---|---|---|
user.email | Normalised SHA-256 (trimmed, lower-cased) | |
| Phone | user.phone_number | Normalised SHA-256 of the E.164 number |
| External ID | user.external_id | SHA-256 of your user ID |
| Click ID | user.ttclid | From the ttclid URL parameter |
| Browser ID | user.ttp | First-party TikTok browser ID |
| IP address | user.ip | The visitor’s request |
| User agent | user.user_agent | The visitor’s request |
| Locale | user.locale | The visitor’s locale |
TikTok only matches on email and phone, so they are never sent in plain text. See Personal data by integration.
Consent
This integration is gated on the marketing canonical consent category. Events without marketing consent are not delivered.
Verify it’s working
- Paste a test event code from TikTok Ads Manager into the integration’s
test_event_codefield. - In the Management UI, open Pipelines → your pipeline → Live Events and trigger a test event.
- The event appears in Signal’s live feed and in TikTok’s Test event tab within seconds.
- Clear the
test_event_codeonce validated.
Troubleshooting
Events aren’t appearing in TikTok.
- Confirm the integration is enabled on the pipeline.
- Confirm marketing consent is granted.
- Inspect the delivery response —
code: 40001/40100indicate auth issues (regenerate the token).
code: 40002. The pixel code is invalid — verify the value in TikTok Ads Manager.