TikTok Events API: How to Set Up Server-Side Conversions
A GTM-free walkthrough of the TikTok Events API: prerequisites, access tokens, required fields, hashing rules, event_id deduplication, testing in Events Manager, and how to choose between direct API, server GTM, and a platform toggle.
In short
TikTok Events API setup means sending conversion events from your server straight to TikTok's endpoint instead of relying only on the browser pixel. You need a TikTok pixel ID, an access token from Events Manager, correctly hashed user identifiers, and a shared event_id so TikTok can deduplicate server events against pixel events. This guide covers all of it without Google Tag Manager.
What is the TikTok Events API?
The TikTok Events API is a server-to-server interface that lets you report website, app, offline, and CRM events directly to TikTok. Events are sent as JSON to https://business-api.tiktok.com/open_api/v1.3/event/track/ with an access token in the request header. Because the call comes from your server, it is not affected by ad blockers, Safari's tracking prevention, or a user closing the tab before the pixel fires.
It is TikTok's equivalent of Meta's Conversions API and GA4's Measurement Protocol. If you already run server-side conversions for either of those, the concepts transfer almost one-to-one. If you are new to the pattern, our server-side conversion tracking guide explains why browser-only tracking undercounts and what a first-party event stream fixes.
What changed in Events API 2.0
Events API 2.0 consolidated what used to be three separate endpoints (web, app, offline) into the single event/track endpoint above. The request now carries an event_source field that tells TikTok what kind of event it is and an event_source_id that identifies the dataset:
| event_source | What it covers | event_source_id |
|---|---|---|
| web | Website events, measured by a pixel | Pixel code (pixel ID) |
| app | Mobile app events | TikTok App ID |
| offline | In-store or other physical conversions | Offline Event Set ID |
| crm | Lead status events from a CRM | CRM Event Set ID |
For a website integration you will use event_source "web" and your pixel ID. Existing event parameters and logic carried over, so older integrations on the web-specific endpoint still work, but new builds should target event/track directly.
TikTok Events API vs TikTok Pixel: do I need both?
Yes. TikTok's own guidance, repeated across every vendor integration we checked, is to run the pixel and the Events API together with deduplication turned on. The two channels collect different signals, and neither one alone gives TikTok everything it needs to match a conversion to an ad click.
| TikTok Pixel (browser) | Events API (server) | |
|---|---|---|
| Runs in | The visitor's browser | Your backend or a tracking platform |
| Blocked by | Ad blockers, ITP, consent tools, early tab close | Nothing on the client; only your own outages |
| Captures automatically | ttclid from the landing URL, _ttp cookie, user agent | Only what you pass explicitly |
| Best at | Page-level events and setting first-party cookies | Purchases, leads, and anything confirmed server-side |
| Weakness | Loses a share of conversions on iOS and blocked browsers | Needs the pixel's cookies and click ID to match well |
The practical split: let the pixel handle PageView and ViewContent, and send the events that cost you money (Purchase, Lead, CompleteRegistration) from both channels with the same event_id. TikTok keeps one copy and you keep the higher match rate.
What do you need before you start?
You need four things: a TikTok for Business account with access to the ad account, a pixel (TikTok now calls these datasets) in Events Manager, an Events API access token, and a server that can make HTTPS requests. Here is how to get the pieces you may not have yet.
- 1Open TikTok Ads Manager, then Tools > Events. If the ad account sits inside a Business Center, confirm your Business Center role includes access to the ad account, or the token button will be missing.
- 2Create a pixel if you do not have one, or open the existing pixel from the datasets overview. Copy the pixel ID. This is your event_source_id.
- 3Open the pixel's Settings tab and scroll to the Events API section. Click Generate Access Token. Copy it immediately; it is only shown once and disappears when you refresh.
- 4Store the token in a secrets manager or server environment variable. Never place it in client-side JavaScript, a public repository, or a GTM web container.
- 5Install the TikTok Pixel base code on every page (or confirm it is already there). You can check what a page actually loads with the free Tracking Pixel Inspector.
That is the whole prerequisite list. No approval process, no app review, and no separate server-side GTM container is required unless you choose that route.
Which fields does a TikTok Events API event require?
Each request is a JSON body with event_source, event_source_id, and a data array of one or more events. Every event needs an event name, a Unix timestamp in seconds, an event_id for deduplication, and a user object with at least one matching key. Purchase-type events also need value and currency in properties.
| Field | Where | Required? | Notes |
|---|---|---|---|
| event_source | Top level | Yes | "web" for website events |
| event_source_id | Top level | Yes | Your pixel ID |
| event | data[] | Yes | Standard event name, case-sensitive |
| event_time | data[] | Yes | Unix seconds, not milliseconds |
| event_id | data[] | Strongly recommended | Same value on pixel and server for dedup |
| user.email | data[].user | One matching key needed | SHA-256 of lowercase, trimmed email |
| user.phone | data[].user | One matching key needed | SHA-256 of E.164 number |
| user.external_id | data[].user | Optional | SHA-256 of your own user ID |
| user.ttclid | data[].user | Optional, high value | Click ID from the landing URL |
| user.ttp | data[].user | Optional, high value | Value of the _ttp cookie set by the pixel |
| user.ip / user.user_agent | data[].user | Optional | Sent raw, not hashed |
| properties.value / currency | data[].properties | Yes for purchases | Number plus ISO 4217 code |
| properties.contents[] | data[].properties | Recommended | content_id, content_type, price, quantity |
| page.url | data[].page | Recommended | Page where the event happened |
| test_event_code | Top level | Testing only | Remove before going live |
You can batch multiple events in one data array. Vendor connectors expose batch sizes of up to 1,000 events per call. Be careful with large batches: TikTok rejects the whole request if any single event fails validation, so validate before you batch.
Standard event names
Use TikTok's standard names, spelled exactly. The common web set is ViewContent, AddToCart, InitiateCheckout, AddPaymentInfo, CompletePayment, CompleteRegistration, SubmitForm, Subscribe, Contact, Search, Download, and ClickButton. TikTok has since added Purchase and Lead as preferred names for the payment and form events; Events Manager shows which names your dataset currently supports. A misspelled or non-standard name returns a success code and then never appears in reporting, which is one of the quietest failure modes in the whole setup.
How do I hash email and phone for the TikTok Events API?
Normalize first, then hash with SHA-256, then send the lowercase hex digest. TikTok matches hashes against its own normalized hashes, so a value hashed in the wrong format silently matches nothing. Not every identifier is hashed, which trips up a lot of first integrations.
| Identifier | Normalization | Hash? |
|---|---|---|
| Trim whitespace, lowercase | SHA-256 | |
| phone | E.164: + country code, digits only, no spaces or dashes | SHA-256 |
| external_id | Your stable user ID as a string | SHA-256 |
| ttclid | Exact value from the landing URL query string | No |
| ttp | Exact value of the _ttp cookie | No |
| ip | Client IP as seen by your server | No |
| user_agent | Full browser user agent string | No |
Two operational tips. First, capture ttclid on the first page load and persist it in a first-party cookie or your session store, because a redirect chain or a stripped query string later in the funnel will lose it. Second, hash on the server, not in the browser. If you are pushing hashed values from client JavaScript you have already lost the resilience the Events API was supposed to add.
How does TikTok deduplicate Pixel and Events API events?
TikTok treats two events as duplicates when they share the same event_source_id (pixel ID), the same event name, and the same event_id. When that happens it keeps the first event received and discards later copies that arrive within 48 hours. Within the first five minutes it goes one step further and merges any extra data from the later event into the first one.
- Match keys: pixel ID + event name + event_id. All three must match. A Purchase and a CompletePayment with the same event_id are not duplicates.
- Merge window: duplicates received within 5 minutes are merged, so a server event with a hashed email can enrich a pixel event that only had the cookie.
- Dedup window: duplicates received within 48 hours are dropped. After that, a repeated event_id counts again.
- Winner: the first event received is kept. If your server call fires before the pixel, the server event is the one that survives.
The practical rule is to mint one ID per user action and pass it to both channels. Order IDs work well for purchases because they already exist and are unique. For non-transactional events, generate a UUID when the action happens and reuse it. Do not let each channel invent its own ID; that is the single most common cause of doubled conversion counts. Events Manager surfaces a mismatched event_id warning when the two channels are not lining up.
How to send a purchase event to TikTok from your server
Send the purchase from the code path that confirms the order, not from the thank-you page. That way the event fires even if the customer never sees the confirmation screen. The sequence below works for any backend language.
- 1On landing, read ttclid from the URL and store it with the session. Read the _ttp cookie the pixel sets. Both will be needed at checkout.
- 2When the order is confirmed, build the user object: SHA-256 of the lowercase email, SHA-256 of the E.164 phone, the stored ttclid and ttp, plus the client IP and user agent from the checkout request.
- 3Build properties: value as a number, currency as a three-letter ISO code, and a contents array with content_id, content_type ("product"), price, and quantity for each line item.
- 4Set event to your dataset's purchase event name, event_time to the current Unix time in seconds, and event_id to the order ID.
- 5POST the JSON to https://business-api.tiktok.com/open_api/v1.3/event/track/ with the header Access-Token set to your token and Content-Type application/json. Include a test_event_code while testing.
- 6Fire the pixel's purchase event on the confirmation page with the same event name and the same event_id (the order ID).
- 7Check the response. A code of 0 means accepted. Log any other code with the message, retry transient failures with backoff, and never retry with a new event_id.
If your checkout is on a hosted platform where you cannot run server code, this is where a platform destination or a server-side tag manager earns its keep. The next section compares the options.
Direct API vs server GTM vs platform toggle: which setup path should you use?
There are three realistic ways to get events to TikTok's endpoint. The right one depends on who maintains it, how many destinations you send to, and whether you already own a first-party event stream.
| Path | How it works | Best for | Trade-offs |
|---|---|---|---|
| Direct API | Your backend calls event/track | Custom stacks with engineering time | Full control; you own hashing, dedup, retries, and monitoring |
| Server-side GTM | Web GTM forwards to a server container running TikTok's tag template | Teams already invested in sGTM | Two containers plus hosting to maintain; every destination is another tag |
| Platform destination toggle | A tracking platform collects the event stream and forwards to TikTok | Marketers and agencies who want one pipeline for Meta, GA4, and TikTok | Less low-level control; you depend on the platform's field mapping |
On the server GTM route, TikTok publishes an official server-side tag template, and hosts such as Stape and TAGGRS package it with a server container. As of September 2026, TAGGRS lists a free tier up to 10,000 requests per month and a Basic plan at €22 per month for 750,000 requests. Stape also sells a standalone TikTok Events API Gateway that skips GTM entirely, listed at $10 per month per pixel with a 7-day trial. Shopify-focused tools take a third approach: Elevar (sold as Audiense Online as of September 2026) installs as a Shopify app with plans starting at $225 per month for 2,000 orders as of September 2026, with an API for other platforms on higher tiers. Enterprise tag managers such as Tealium offer TikTok connectors but do not publish pricing.
The platform-toggle path is the one EndFrame takes. Its tracking snippet collects the visit and action stream, and each server-side destination (Meta Conversions API, GA4 Measurement Protocol, TikTok Events API, custom webhooks) is a switch in the dashboard rather than a separate container. Hashing of identifiers and browser-to-server event-ID deduplication are handled in the pipeline, so the same conversion goal can feed all three ad platforms without three integrations.
How do I test the Events API and fix 'events received but no conversions'?
Test with the Test Events tab in Events Manager first, then check Ads Manager after real traffic. The two tools answer different questions: Test Events tells you the payload arrived and parsed, while Ads Manager tells you whether TikTok could attribute it. A green light in Events Manager does not guarantee a conversion in reporting.
- 1In Events Manager, open your pixel, go to Test Events, and copy the test code. Put it in test_event_code on your server requests.
- 2Trigger a real conversion on a test order. Server events appear in the Test Events feed, often within a minute; purchase events can take a few minutes. Pageviews do not appear in Test Events, only in Overview.
- 3Expand each event and confirm the fields you meant to send actually arrived: event_id, hashed email or phone, ttclid, value, and currency.
- 4Trigger the same action with the pixel firing and confirm both events show the same event_id and event name. If Events Manager shows the mismatched event_id warning, your two channels are generating different IDs.
- 5Check the pixel's Event Quality or match-quality view. If ttclid coverage is near zero, the click ID is being lost between landing and checkout.
- 6Remove test_event_code before deploying. TikTok does not store live events that carry a test code.
- 7After a day of live traffic, compare Events Manager event counts with Ads Manager conversions. Large gaps point to matching or attribution-window problems, not delivery problems.
When events are received but conversions stay at zero, work through the usual suspects in order: a non-standard event name, email or phone hashed before normalization, phone numbers without a country code, missing ttclid and ttp, event_time in milliseconds instead of seconds, or conversions that happened outside the attribution window. Each of these returns a success code and produces nothing in reporting.
Attribution windows: why TikTok's numbers differ from your own
TikTok Ads Manager only counts a conversion when the matched user clicked or viewed an ad inside the attribution window you chose. As of September 2026, TikTok lets you pick click-through windows of 1, 7, 14, or 28 days and view-through windows of off, 1, or 7 days, with 7-day click and 1-day view as the default. Anything outside those windows is not a TikTok conversion, no matter how cleanly your server sent it.
Your first-party numbers will differ for three reasons. First, view-through attribution credits conversions from people who never clicked, which your UTM-based reporting cannot see. Second, TikTok reports conversions on the click or view date in some views and the conversion date in others, so daily totals shift. Third, TikTok counts the event only if it matched a user; your own store counts every order. The right response is to keep both numbers and treat the gap as a diagnostic, not to force them to agree. A tool that stores the raw visit, action, and conversion chain lets you see exactly which orders TikTok could not match and why. Clean UTM discipline helps too; see how to fix UTM parameters if your source breakdowns are already messy.
Where EndFrame fits
EndFrame is a first-party attribution and conversion tracking platform, and TikTok Events API is one of its built-in server-side destinations. You add the EndFrame snippet to your domain, define a conversion goal by event match or URL match, and switch on the TikTok destination in the dashboard alongside Meta, GA4, and custom webhooks. EndFrame hashes identifiers and deduplicates browser and server events by event ID, and it stores the raw visit to action to conversion chain so you can audit which conversions reached TikTok and with which parameters.
It is a fit for performance teams and agencies that run spend on more than one platform and would rather maintain one event stream than one integration per network. It is not a replacement for TikTok's Shopify channel app if that already covers your store, and it does not add multi-touch modeling on top of TikTok's reporting. If you want to see how much of your current tracking is browser-only before deciding, run the free Website Tracking Audit against your domain. Server-side conversions to TikTok are included on the Starter plan; details are on the pricing page.
The bottom line
TikTok Events API setup is a small amount of work with a few unforgiving details. Get the token from Events Manager, use standard event names, normalize before you hash, keep ttclid and the _ttp cookie alive through the funnel, and send one event_id per action to both the pixel and the server. Test with a test code, then judge success in Ads Manager, not just Events Manager. Whether you write the integration yourself, run it through a server GTM container, or flip a destination toggle in a platform like EndFrame, those same rules decide whether TikTok can attribute the conversions you are paying for.
Frequently asked questions
Can I run the TikTok Events API without the TikTok Pixel?
Technically yes: the Events API accepts events from any server without a pixel on the page. In practice you should keep the pixel. It sets the _ttp cookie and captures ttclid on landing, and both are among the strongest matching signals TikTok has. Run both, share one event_id per action, and let TikTok deduplicate.
Is the TikTok Events API free to use?
TikTok does not charge for the Events API itself. You need a TikTok for Business account, a pixel (dataset) in Events Manager, and an access token. Costs come from whatever you use to send events: developer time for a direct integration, a server GTM host, or a tracking platform with a TikTok destination.
Does the TikTok Events API work on Shopify?
Yes. TikTok's own Shopify channel app sends browser and server events for you, and several third-party Shopify apps do the same. If you sell on a platform without a native app, or run lead-gen sites, a direct integration, a server GTM tag, or a platform destination like EndFrame's TikTok toggle covers the gap.
How long does TikTok keep an event_id for deduplication?
Per TikTok's rules as relayed in vendor documentation, duplicates arriving within five minutes are merged into the first event, and any duplicate with the same pixel ID, event name, and event_id received within 48 hours is discarded. The first event received is the one kept, so send identical IDs from the browser and the server.
Why does Events Manager show my server events but Ads Manager shows no conversions?
Receipt and attribution are different steps. Events Manager confirms the payload arrived. Ads Manager only counts a conversion when the event matches a TikTok user inside your attribution window. Missing ttclid, wrongly normalized hashes, a non-standard event name, or a conversion outside the window all produce received-but-unattributed events.
Sources
- 1.Adobe Experience Platform: TikTok web events API extension overview
- 2.Elevar docs: What is the mismatched event_id warning in TikTok?
- 3.Commanders Act: TikTok Events API destination reference
- 4.MetaRouter: TikTok Events API 2.0 integration
- 5.Hightouch: TikTok destination documentation
- 6.Elevar docs: How to generate a TikTok access token
- 7.Stape: TikTok Events API Gateway
- 8.TAGGRS pricing
- 9.Audiense Online (Elevar) pricing
- 10.NestScale: TikTok attribution window
Try EndFrame
Recover the conversions iOS and ad blockers hide.
EndFrame collects events first-party and forwards conversions server-side to Meta, GA4, TikTok, and webhooks with event-ID deduplication — then shows the result in real time, with the visit-to-conversion path you can audit.
No credit card required