Integration · TikTok Events API
Complete purchase signals for an algorithm that rewards them
RoasProof captures the ttclid the moment a TikTok click lands, resolves it to the eventual order, and delivers CompletePayment server-side. Every event is deduplicated against your TikTok pixel and matched with hashed identifiers.
The TikTok Events API is TikTok's server-to-server channel for conversion events. RoasProof captures the ttclid the moment a TikTok click lands, stores it first-party, and sends CompletePayment and other funnel events from the server, deduplicated against your TikTok pixel by a shared event_id and matched with hashed identifiers.
What a RoasProof server event looks like
A CompletePayment event as it leaves our servers for the Events API: click ID restored, identifiers hashed, event ID shared with your pixel.
POST https://business-api.tiktok.com/open_api/v1.3/event/track/
{
"event_source": "web",
"event_source_id": "{pixel_code}",
"data": [{
"event": "CompletePayment",
"event_time": 1781430082,
"event_id": "ord_84213",
"user": {
"email": "9f3d0c52ab…",
"phone": "1b6e21c84f…",
"external_id": "7ac8044190…",
"ttclid": "E.C.P.CrKzqUv…",
"ttp": "9cf2laqOaU…",
"ip": "203.0.113.24",
"user_agent": "Mozilla/5.0 (iPhone; …)"
},
"properties": {
"currency": "EUR",
"value": 184.50,
"order_id": "84213",
"contents": [
{ "content_id": "SKU-2481", "quantity": 1, "price": 129.00 },
{ "content_id": "SKU-1177", "quantity": 1, "price": 55.50 }
]
},
"page": {
"url": "https://store.example/checkout/thank-you"
}
}]
}event_id matches your pixel
Both the pixel's CompletePayment and this server event carry ord_84213, so TikTok pairs them and counts the purchase once, no matter which copy arrives first.
ttclid restored at conversion time
The click ID was captured from the landing URL and stored first-party. When the purchase happens (even weeks later), it's re-attached, so the conversion maps back to the exact ad and campaign.
Hashed to TikTok's spec
email, phone (E.164), and external_id are SHA-256 hashed server-side before transmission. Raw PII never reaches TikTok.
Context that lifts match rate
The buyer's IP, user agent, and the _ttp cookie value (when the pixel set one) ride along, giving TikTok additional keys to match against logged-in users.
ttclid: easy to receive, easy to lose unless you store it
TikTok appends ttclid to your landing URL, and most sessions start inside TikTok's in-app browser, where cookies are short-lived and journeys frequently hop to the real browser. Persistence is the whole game.
Captured on the first pageview
The script reads ttclid from the landing URL before any redirect or navigation can strip it, and stores it first-party against a persistent visitor ID.
Built for in-app browser journeys
When the visitor returns later in Safari, on desktop, or from an email, identity resolution reconnects them to the stored click, so the eventual purchase still carries the ttclid.
The _ttp cookie comes too
Where the TikTok pixel has set its _ttp identifier, we store and forward that as well. That adds one more matching key to every event.
- ttclid
- E.C.P.CrKzqUv…
- ttp
- 9cf2laqOaU…
- utm_campaign
- spark-ads-summer
- landing
- /products/trail-jacket
- referrer
- tiktok.com
- captured
- 2026-06-14 09:41:22 UTC
- attached_to
- order #84213
Pixel and Events API, coexisting by design
TikTok recommends running the pixel and the Events API together and deduplicating by event_id. That's exactly the setup we create.
Same event + event_id: TikTok keeps a single copy, and reported ROAS stops drifting from reality.
Shared IDs, coordinated at fire time
Our on-page script hands the pixel a deterministic event ID derived from the order, and the server event reuses it. The pair is unambiguous.
Keep the pixel for the upper funnel
ViewContent, AddToCart, and InitiateCheckout can stay browser-side where they're cheap and plentiful, while revenue events get the guaranteed server-side path.
No inflated numbers during migration
Because dedup is deterministic from day one, you can turn on server events next to an existing pixel without a week of double-counted purchases polluting optimization.
The identifiers TikTok matches on, and where each comes from
TikTok matches server events to users with hashed contact details, click IDs, and browser context. We populate every field your data allows.
| field | what it is | where we get it |
|---|---|---|
| SHA-256 of the normalized email address | Order or signup email, trimmed and lowercased before hashing | |
| phone | SHA-256 of the phone number in E.164 format | Checkout or lead-form phone, country-normalized |
| external_id | SHA-256 of a stable first-party visitor ID | Set on the first visit and reused across sessions |
| ttclid | TikTok click ID | Captured from the landing URL, stored first-party, restored at conversion |
| ttp | TikTok pixel cookie identifier | Read from the _ttp cookie when the pixel has set one |
| ip / user_agent | The buyer's browsing context | Recorded with the session that produced the conversion, not our server's |
Per-field coverage is visible in the dashboard, so if phone numbers stop arriving from a changed checkout, you find out from a chart instead of a slow bleed in matched conversions. Curious about the click ID itself? See the ttclid glossary entry.
Queued delivery with per-event receipts
Events API requests hit rate limits and transient errors like any API. The queue absorbs them; the dashboard shows you everything.
Store-and-forward
Every event is persisted before delivery and retried with exponential backoff on errors and rate limits. A TikTok outage delays events, but it never deletes them.
Test events before go-live
During setup, events run through TikTok's test mode so you can watch them arrive and dedupe in Events Manager before a single production event is sent.
Per-event delivery status
Each event stores the payload sent and TikTok's response code and message. Failures are diagnosable and replayable, individually or in bulk.
Give TikTok the purchase data it's been missing.
Connect a pixel code and an access token, fire a test event, and confirm the dedup in TikTok Events Manager before going live.