Vendor · engineers · marketers
ttq plus Events API, ISO time on the server
Copying a Meta CAPI client and pointing it at TikTok is how you send ten-digit seconds into an ISO field. The 200 will be fine. The event time will not.
Browser pipe
ttq in the page. Loader and collect requests hit analytics.tiktok.com. sdkid is the Pixel ID. lib is expected to be ttq. TikTok documents JS events and parameters, not this wire format, so vendor/tiktok is ecosystem_reference scoped to what Events Manager generates. Copy the base code. Two ttq inits are two PageViews. Network filter: analytics.tiktok.com. The pack page /packs/tiktok/ is the loader table.
Store ttclid from the landing URL the same way you store fbclid. Without it, Events API matching leans on hashed PII and IP/UA. Do not fire CompletePayment on the product page. Standard events and pixel id as TikTok documents them. Ad blockers still punch the browser pipe. That is why the Events API exists.
pixellint validate url @tiktok-pixel.txt --rulepack vendor/tiktok
Events API pipe
S2S track and batch go to business-api.tiktok.com /pixel/track and /pixel/batch. pixel_code is required (the Pixel ID from Events Manager). event is required per conversion (CompletePayment, ViewContent, and the documented web names). timestamp is ISO 8601; an epoch number is stamped as arrival time: vendor.tiktok-events-api.body.timestamp.invalid. Yesterday's purchases then train today's campaign.
context.user.email, phone_number, and external_id are SHA-256 hex. context.ip and context.user_agent are plaintext. A hashed IP is hashed_plaintext_field. properties.currency, when present, is ISO 4217. The track call posts one event at the root. The batch call posts the same object under batch, with pixel_code on the envelope. Pack page: /packs/tiktok-events-api/.
{
"pixel_code": "XXXXXXXXXXXXXXXXXX",
"event": "CompletePayment",
"event_id": "T12345",
"timestamp": "2026-08-21T18:04:00Z",
"context": {
"ip": "203.0.113.10",
"user_agent": "Mozilla/5.0",
"user": { "email": "64CHARHEXDIGEST", "phone_number": "64CHARHEXDIGEST" }
},
"properties": { "value": 19.99, "currency": "USD" }
}
event_id on both pipes
Share event_id with ttq. Same idea as Meta, same field name on the server, different clock. Event names must match TikTok's list, not Meta's PascalCase by accident. CompletePayment is not Purchase. If the pixel mints a UUID and the worker mints another, TikTok counts two CompletePayment events. Mint once (order id is fine if unique per event type), persist it, replay it on retries.
The pack match is /pixel/track and /pixel/batch. A different Events API envelope (a later open_api event/track path) is a different shape. This pack does not contract it. Pointing the wrong client at the wrong path looks like missing pixel_code and a 200 you cannot debug from the status line.
ISO clock, not Unix seconds
TikTok Events API timestamp is ISO 8601, such as 2026-08-21T18:04:00Z. Meta event_time is 10-digit seconds. Pinterest event_time is 10-digit seconds. Amplitude and LinkedIn are 13-digit milliseconds. PostHog and Segment want ISO too. The Meta helper that divides Date.now() by 1000 is the wrong type here. An epoch in the ISO field is accepted and then treated as arrival.
Store the order time as an instant. Serialize ISO at the TikTok edge. Serialize seconds at the Meta edge. Do not share one timestamp column without conversion. Omit timestamp and you get received-at, which is wrong for a queue that drains on Monday.
pixellint validate json @tiktok-events.json --rulepack vendor/tiktok-events-api
Independence
Pixellint is not affiliated with TikTok. Treat Events Manager as source of truth for pixel ids, and the published Events API doc as source of truth for JSON. The browser pack is ecosystem evidence for the loader URL. The Events API pack is official_vendor. Both pipes, hashed PII, plaintext IP and UA, shared event_id, ISO on the server.
You can launch on pixel-only. You cannot call it the recommended Events API setup until diagnostics show the server hit with the same event_id the pixel sent. pixellint validate json --rulepack vendor/tiktok-events-api on a fixture before you drain a queue.
Check the artifact
Paste the pixel URL or JSON body into the
playground. Same engine as
pixellint validate. Nothing leaves the tab.