vendor/tiktok-events-api · vendor documented
TikTok Events API timestamp is ISO 8601
Server-to-server track and batch on business-api.tiktok.com. pixel_code is the Pixel ID. event is the conversion name. timestamp is ISO 8601; an epoch number is stamped as the arrival time instead.
context.user.email, phone_number, and external_id are SHA-256 hex. context.ip and context.user_agent are sent unhashed. CompletePayment and PlaceAnOrder need properties.value and properties.currency. An event with no hashed identifier and no IP warns.
timestamp is ISO 8601, not epoch
An epoch number is accepted and then ignored in favor of arrival time. Backfills look like they happened just now.
What this pack matches
Rules
Codes are stable. A finding in CI, MCP, or the playground lands on the same id.
| Field | Required | What it checks | Rule ids | Source |
|---|---|---|---|---|
pixel_code |
required | It is the Pixel ID from Events Manager. TikTok documents it as required on both the single-event track call and the batch call. Fix: Set `pixel_code` to the Pixel ID shown in Events Manager. | vendor.tiktok-events-api.body.pixel_code.missingvendor.tiktok-events-api.body.pixel_code.empty |
docs |
batch |
optional | The batch endpoint posts events under `batch`. The track endpoint posts a single event at the root instead. | docs | |
event |
required | It is the conversion event name. TikTok documents it as required on every track payload. Fix: Set `event` to a documented web event name, such as `CompletePayment` or `ViewContent`. | vendor.tiktok-events-api.body.event.missingvendor.tiktok-events-api.body.event.empty |
docs |
event_id |
optional | It identifies the event for deduplication against the browser pixel. TikTok documents it as required when the same conversion is sent from both. Fix: Send the same `event_id` the Pixel fired, so the pair collapses to one conversion. | vendor.tiktok-events-api.body.event_id.empty |
docs |
timestamp |
optional | TikTok documents the event time as an ISO 8601 timestamp. An epoch number is not that format, and TikTok then stamps the event with the time it arrived. Fix: Send an ISO 8601 timestamp, such as `2026-07-26T06:00:00Z`. | vendor.tiktok-events-api.body.timestamp.emptyvendor.tiktok-events-api.body.timestamp.invalid |
docs |
context.ip |
optional | It is the visitor's public IP address, sent unhashed. Fix: Send the browser's public IP, not a SHA-256 digest and not your server's address. | vendor.tiktok-events-api.body.context.ip.empty |
docs |
context.user_agent |
optional | It is the visitor's user agent, sent unhashed. Fix: Send the browser's user agent string, not a digest. | vendor.tiktok-events-api.body.context.user_agent.empty |
docs |
context.ad.callback |
optional | It is the TikTok Click ID (`ttclid`) from the landing URL. TikTok documents it as unhashed on `context.ad.callback`. Fix: Copy `ttclid` from the landing URL into `context.ad.callback`, or drop the empty pair. | vendor.tiktok-events-api.body.context.ad.callback.empty |
docs |
context.page.url |
optional | It is the page URL when the event happened. TikTok documents it on `context.page`. Fix: Send an absolute URL in `context.page.url`, including the scheme. | vendor.tiktok-events-api.body.context.page.url.emptyvendor.tiktok-events-api.body.context.page.url.invalid |
docs |
context.page.referrer |
optional | It is the page referrer. TikTok documents it on `context.page`. Fix: Send an absolute referrer URL, or drop the empty pair. | vendor.tiktok-events-api.body.context.page.referrer.emptyvendor.tiktok-events-api.body.context.page.referrer.invalid |
docs |
context.user.email |
optional | Email must be SHA-256 hashed on the client side before it is sent. Fix: Trim and lowercase the address, hash it with SHA-256, and send the hex digest. | vendor.tiktok-events-api.body.context.user.email.emptyvendor.tiktok-events-api.body.context.user.email.invalid |
docs |
context.user.phone_number |
optional | Phone must be SHA-256 hashed on the client side before it is sent. Fix: Normalize the number, hash it with SHA-256, and send the hex digest. | vendor.tiktok-events-api.body.context.user.phone_number.emptyvendor.tiktok-events-api.body.context.user.phone_number.invalid |
docs |
context.user.external_id |
optional | Advertiser-side identifiers must be SHA-256 hashed on the client side. Fix: Hash the identifier with SHA-256 and send the hex digest. | vendor.tiktok-events-api.body.context.user.external_id.emptyvendor.tiktok-events-api.body.context.user.external_id.invalid |
docs |
context.user.ttp |
optional | It is the first-party `_ttp` cookie. TikTok documents it as unhashed on `context.user.ttp`. Fix: Read `_ttp` under your domain into `context.user.ttp`, or drop the empty pair. | vendor.tiktok-events-api.body.context.user.ttp.empty |
docs |
properties.currency |
optional | It is an ISO 4217 currency code. Fix: Use the three-letter code, such as `USD`. | vendor.tiktok-events-api.body.properties.currency.emptyvendor.tiktok-events-api.body.properties.currency.invalid |
docs |
properties.value |
optional | It is the total value of the order or items, not the unit price. | docs | |
properties.contents[].content_id |
optional | It is the product item ID on a contents row. TikTok's Events API SDK documents `content_id` on each `PixelContent` object, not on `properties`. Fix: Set `properties.contents[].content_id` to the catalog item ID, or drop the empty pair. | vendor.tiktok-events-api.body.properties.contents[].content_id.empty |
docs |
properties.contents[].content_type |
optional | It is how the row maps to the catalog. TikTok's Events API SDK documents `product` or `product_group` on each contents object. Fix: Set `properties.contents[].content_type` to `product` or `product_group`. Do not put `content_type` on `properties`. | vendor.tiktok-events-api.body.properties.contents[].content_type.emptyvendor.tiktok-events-api.body.properties.contents[].content_type.invalid |
docs |
properties.contents[].quantity |
optional | It is the item count on a contents row. TikTok's Events API SDK documents `quantity` as a number. Fix: Send `properties.contents[].quantity` as a number, such as `2`. | vendor.tiktok-events-api.body.properties.contents[].quantity.emptyvendor.tiktok-events-api.body.properties.contents[].quantity.invalid |
docs |
properties.contents[].price |
optional | It is the unit price of one item. TikTok's Events API SDK documents `price` as the single-item price, not the order total. Fix: Send `properties.contents[].price` as a number, such as `10`. Put the order total in `properties.value`. | vendor.tiktok-events-api.body.properties.contents[].price.emptyvendor.tiktok-events-api.body.properties.contents[].price.invalid |
docs |
properties.contents[].content_name |
optional | It is the name of the page or product on a contents row. TikTok's Events API SDK documents `content_name` on each `PixelContent` object. Fix: Set `properties.contents[].content_name` to the page or product name, or drop the empty pair. | vendor.tiktok-events-api.body.properties.contents[].content_name.empty |
docs |
properties.contents[].content_category |
optional | It is the category of the page or product on a contents row. TikTok's Events API SDK documents `content_category` on each `PixelContent` object. Fix: Set `properties.contents[].content_category` to the category, or drop the empty pair. | vendor.tiktok-events-api.body.properties.contents[].content_category.empty |
docs |
properties.contents[].status |
optional | It is the status of an order, item, or service on a contents row. TikTok's Events API SDK documents `status` as a string with no enumerated values. Fix: Set `properties.contents[].status` to the order or item status, or drop the empty pair. | vendor.tiktok-events-api.body.properties.contents[].status.empty |
docs |
body.unhashed_email |
required | A field carries what looks like a raw email address. TikTok requires customer email to be SHA-256 hashed on the client side. Fix: Trim the address, lowercase it, hash it with SHA-256, and send the hex digest. | vendor.tiktok-events-api.body.unhashed_email |
docs |
body.hashed_plaintext_field |
required | This field looks like a SHA-256 digest, but TikTok documents `context.ip`, `context.user_agent`, `context.ad.callback`, and `context.user.ttp` as unhashed. Fix: Send the raw IP address, user agent, click ID, or `_ttp` cookie. Hashing it makes the event unmatchable. | vendor.tiktok-events-api.body.hashed_plaintext_field |
docs |
body.user_needs_an_identifier |
recommended | The event has no user identifier. TikTok documents hashed email, phone, external_id, the `_ttp` cookie, click ID, or IP as the match keys that attach the conversion to a person. Fix: Send hashed `context.user.email`, `phone_number`, or `external_id`, or unhashed `context.user.ttp`, `context.ad.callback`, or `context.ip`. | vendor.tiktok-events-api.body.user_needs_an_identifier |
docs |
body.complete_payment_requires_value_and_currency |
required | A `CompletePayment` or `PlaceAnOrder` event is missing `properties.value` or `properties.currency`. TikTok documents both on those revenue events. Fix: Set `properties.value` to the order total and `properties.currency` to a three-letter ISO 4217 code. | vendor.tiktok-events-api.body.complete_payment_requires_value_and_currency |
docs |
Validate a payload
pixellint validate json @payload.json --rulepack vendor/tiktok-events-api
Try this failing payload in the playground. TikTok Events API with epoch timestamp.
{"pixel_code":"XXXXXX","event":"ViewContent","timestamp":1770000000,"context":{"user":{"email":"a85e9ca18f34935ab9b0381b25bfad2455444112b0149270fd88e3da172fe196"}}}
cargo install pixellint
·
npm install pixellint