---
title: "TikTok Events API and LinkedIn Conversions API"
description: "Same pattern, different fields TikTok and LinkedIn follow the same server-side pattern as Meta: send conversion events from your server, hash…"
url: https://optimizeall.com/learn/privacy-first-measurement/tiktok-events-api-and-linkedin-capi
updated: 2026-10-05
---

Privacy-First Measurement: Server-Side Tagging, Consent Mode and Conversion APIs · Conversion APIs: Meta, Google, TikTok and LinkedIn · lesson 9 of 14 · 8 min

# TikTok Events API and LinkedIn Conversions API

## Same pattern, different fields

TikTok and LinkedIn follow the same server-side pattern as Meta: send conversion events from your server, hash identifiers, include platform click IDs and browser identifiers, and deduplicate with the browser tag using a shared event ID.

| | **TikTok Events API** | **LinkedIn Conversions API** |
|---|---|---|
| Browser tag | TikTok Pixel | LinkedIn Insight Tag |
| Click ID | `ttclid` (URL), `_ttp` cookie | `li_fat_id` (URL/first-party cookie) |
| Dedup | Same event + `event_id` in Pixel and Events API | `eventId` shared with Insight Tag conversion |
| Identifiers | Hashed email, phone, external_id; IP; user agent | Hashed email (SHA256_EMAIL), LinkedIn first-party tracking UUID, name/company/country as user info |
| Typical use | E-commerce, app, lead gen | B2B leads and CRM stages (online and offline) |
| Setup routes | Partner integrations, server GTM templates, direct API | Partner integrations (e.g., CRM connectors), GTM, direct API |

## TikTok Events API

The Events API endpoint (v1.3 at the time of writing) accepts batches of events with an access token generated in TikTok Events Manager.

```python
import os, time, hashlib, requests

PIXEL_CODE = os.environ["TIKTOK_PIXEL_CODE"]
TOKEN = os.environ["TIKTOK_EVENTS_TOKEN"]
URL = "https://business-api.tiktok.com/open_api/v1.3/event/track/"
sha = lambda v: hashlib.sha256(v.strip().lower().encode()).hexdigest()

def tiktok_purchase(order, req, consent_ads: bool, test_code: str | None = None):
    if not consent_ads:
        return None
    body = {
        "event_source": "web",
        "event_source_id": PIXEL_CODE,
        "data": [{
            "event": "CompletePayment",
            "event_time": int(time.time()),
            "event_id": f"order_{order['id']}",
            "user": {
                "email": sha(order["email"]),
                "phone": sha(order["phone_e164"]),
                "external_id": sha(str(order["customer_id"])),
                "ttclid": req["cookies"].get("ttclid") or req.get("ttclid"),
                "ttp": req["cookies"].get("_ttp"),
                "ip": req["ip"], "user_agent": req["user_agent"],
            },
            "page": {"url": order["thank_you_url"]},
            "properties": {"currency": order["currency"], "value": order["value"],
                           "contents": [{"content_id": i["sku"], "quantity": i["qty"], "price": i["price"]} for i in order["items"]],
                           "content_type": "product"},
        }],
    }
    if test_code:
        body["test_event_code"] = test_code
    r = requests.post(URL, headers={"Access-Token": TOKEN, "Content-Type": "application/json"}, json=body, timeout=10)
    r.raise_for_status()
    data = r.json()
    if data.get("code") != 0:
        raise RuntimeError(f"TikTok Events API error: {data}")
    return data
```

Check the TikTok Events API documentation for the current version, phone normalization rules and supported standard events. Capture `ttclid` from the landing URL and store it (first-party) so the server can send it.

## LinkedIn Conversions API

LinkedIn's API uses versioned REST endpoints. You create a conversion rule in Campaign Manager (or via API), then stream events to `/rest/conversionEvents` with an OAuth access token that has the right permissions.

```python
import os, time, hashlib, requests

TOKEN = os.environ["LINKEDIN_ACCESS_TOKEN"]
LI_VERSION = os.environ.get("LINKEDIN_API_VERSION", "202608")  # YYYYMM; use a currently supported version
RULE_URN = os.environ["LINKEDIN_CONVERSION_RULE_URN"]  # e.g. urn:lla:llaPartnerConversion:123456

def linkedin_sql(lead, stage_value: float, currency="USD", consent_ads=True):
    if not consent_ads:
        return None
    ids = [{"idType": "SHA256_EMAIL", "idValue": hashlib.sha256(lead["email"].strip().lower().encode()).hexdigest()}]
    if lead.get("li_fat_id"):
        ids.append({"idType": "LINKEDIN_FIRST_PARTY_ADS_TRACKING_UUID", "idValue": lead["li_fat_id"]})
    event = {
        "conversion": RULE_URN,
        "conversionHappenedAt": int(time.time() * 1000),  # milliseconds
        "conversionValue": {"currencyCode": currency, "amount": f"{stage_value:.2f}"},
        "user": {"userIds": ids,
                 "userInfo": {"firstName": lead["first_name"], "lastName": lead["last_name"],
                              "companyName": lead.get("company", ""), "countryCode": lead.get("country", "")}},
        "eventId": f"lead_{lead['id']}_sql",
    }
    r = requests.post("https://api.linkedin.com/rest/conversionEvents", json=event, timeout=10,
                      headers={"Authorization": f"Bearer {TOKEN}", "LinkedIn-Version": LI_VERSION,
                               "X-Restli-Protocol-Version": "2.0.0", "Content-Type": "application/json"})
    if r.status_code >= 400:
        raise RuntimeError(f"LinkedIn CAPI error {r.status_code}: {r.text}")
    return r.status_code
```

LinkedIn documents rate limits and batch endpoints; check the Microsoft Learn LinkedIn Marketing API docs for current versions and limits.

## Consent, batching and reliability

Both APIs accept batched events; batch when you process conversions in bulk (for example a nightly CRM sync), and send individually in near real time for web purchases. Build a small outbox table: write each event to the table when the conversion happens, have a worker send it, record the response, and retry with backoff on network errors or rate limiting (HTTP 429). Store the consent state that applied at the time of the conversion and check it before sending. This pattern makes server-side feeds auditable: for any conversion you can show what was sent, when, with what consent, and what the platform replied.

## Worked example: a UK cybersecurity SaaS

The company runs LinkedIn and TikTok (for employer brand and SMB awareness). LinkedIn: Insight Tag for demo requests with eventId; CRM (HubSpot) sends "SQL" and "Opportunity" stages via the Conversions API, stage values from historical close rates. TikTok: Events API for free-trial sign-ups deduplicated with the Pixel. Both honor the CMP's advertising consent. Within a quarter, LinkedIn campaigns optimized toward SQLs instead of raw form fills.

## Pitfalls

- LinkedIn timestamps in seconds instead of milliseconds.
- Unversioned or deprecated LinkedIn API versions.
- Forgetting to capture `ttclid`/`li_fat_id` at landing.
- Different event IDs in browser and server events.

## How to measure success

Events visible in each platform's event diagnostics or conversion tracking pages, dedup working, match rates improving, and qualified-stage conversions steering bidding.

## Video lecture: TikTok Events API and LinkedIn Conversions API

Lecture coming soon · 13 chapters · about 8 minutes. Read the full transcript below.

1. TikTok Events API and LinkedIn CAPI
2. Why it matters
3. The shared pattern
4. TikTok Events API
5. TikTok gotchas
6. Simple example: Dubai HR software (illustrative)
7. LinkedIn Conversions API
8. LinkedIn gotchas
9. Example: UK cybersecurity SaaS (illustrative)
10. Verify
11. Mistakes + try this now
12. Watch me do it: TikTok Events API test (illustrative)
13. Recap and next step

## Lecture transcript

### TikTok Events API and LinkedIn CAPI

Once you've built one conversions API, the next two are mostly a matter of field names. In this lecture you'll learn how TikTok's Events API and LinkedIn's Conversions API follow the same pattern as Meta, the specific fields and gotchas each one has, and how a B2B company can use them to optimize for qualified pipeline instead of raw form fills.

### Why it matters

Why does this matter? Because TikTok and LinkedIn often carry very different parts of your funnel. TikTok frequently drives discovery and impulse purchases, LinkedIn drives slow, high-value B2B pipeline. Both suffer when browser tracking is weak. Here's an analogy. If Meta's Conversions API is learning to drive one car, TikTok and LinkedIn are the same skill in different cars. The pedals and mirrors are in slightly different places, the timestamps are in different units, and the dashboards read differently. But once you know how to drive, switching cars takes an afternoon, not a month.

### The shared pattern

The pattern is the same everywhere. Send events from your server. Hash personal identifiers like email and phone. Include the platform's click ID and browser identifiers. And deduplicate with the browser tag by sharing an event ID. For TikTok, the browser tag is the TikTok Pixel, the click ID is t t c l i d, and the browser cookie is underscore t t p. For LinkedIn, it's the Insight Tag, and the click identifier is l i fat id.

### TikTok Events API

Let's do TikTok first. The Events API endpoint, version one point three at the time of writing, takes an event source of web, your Pixel code as the event source ID, and a list of events. Each event has a name, like complete payment, a timestamp in seconds, an event ID, a user object with hashed email, phone and external ID plus t t c l i d, t t p, IP and user agent, the page URL, and properties like currency, value and contents. The access token goes in a header.

### TikTok gotchas

Two TikTok gotchas. The API can return an HTTP success while the body contains an error code, so check that the response code field equals zero, not just the HTTP status. And capture t t c l i d from the landing URL and store it first-party, because by the time the purchase happens, the parameter is long gone from the address bar. The lesson's Python function handles both.

### Simple example: Dubai HR software (illustrative)

Here's a simple worked example on LinkedIn. A Dubai recruitment software company sends a demo request event when someone books a demo. Two weeks later, sales qualifies the lead. The CRM triggers a LinkedIn Conversions API event for the sales qualified lead rule, with the hashed work email, the first-party tracking ID captured at landing, the company name, the country code, a value based on historical close rates, and a timestamp in milliseconds. The event ID is lead, the lead number, then SQL. LinkedIn attributes it to the campaign that drove the original click, and the campaign starts optimizing toward qualified leads rather than every form fill.

### LinkedIn Conversions API

Now LinkedIn. You create a conversion rule in Campaign Manager, then stream events to the conversion events REST endpoint with an OAuth token. Every request needs a LinkedIn version header, year and month, plus the Rest.li protocol header. Each event references the conversion rule by its URN, has a timestamp in milliseconds, a value with currency, user IDs like the SHA two fifty-six email and the first-party tracking ID, user info like name, company and country, and an event ID for dedup.

### LinkedIn gotchas

LinkedIn's classic mistake is the timestamp. Send seconds instead of milliseconds and your conversion lands in nineteen seventy. The other classic is an unversioned or deprecated API version, which starts failing when LinkedIn retires it. Keep the version in configuration, not code, and check the Microsoft Learn documentation for LinkedIn's current versions and rate limits.

### Example: UK cybersecurity SaaS (illustrative)

Here's an illustrative B2B example. A UK cybersecurity software company runs LinkedIn for pipeline and TikTok for small-business awareness. On LinkedIn, the Insight Tag tracks demo requests with an event ID, and their CRM sends sales-qualified-lead and opportunity stages through the Conversions API, valued by historical close rates. On TikTok, free trial sign-ups go through the Events API, deduplicated with the Pixel. Both respect advertising consent from the consent platform. Within a quarter, LinkedIn campaigns were optimizing for qualified leads, not raw form fills.

### Verify

How do you know it's working? Each platform has an events or conversion diagnostics page. Check events are arriving, deduplication is working, match rates are improving, and your qualified-stage conversions are the ones steering bidding. And as always, keep tokens in environment variables, rotate them, and log errors so failures are visible.

### Mistakes + try this now

Common mistakes with these two APIs. Sending LinkedIn timestamps in seconds. Hard-coding an API version that later gets retired. Trusting TikTok's HTTP status without checking the response code field. Forgetting to capture ttclid or the LinkedIn tracking ID at landing. And using different event IDs in browser and server events. Try this now: pick one of the two platforms and send a single test event from a script in a test account, using the lesson's code. Read the response carefully and confirm the event appears in the platform's test or diagnostics view.

### Watch me do it: TikTok Events API test (illustrative)

Watch me do it. Let's run a first TikTok Events API test for an illustrative Dubai sneaker store. Step one, in TikTok Events Manager I generate an access token for the pixel and copy the test event code. Step two, I store both as environment variables, never in code. Step three, I place a test order with a test t t c l i d in the landing URL. Our landing handler saved it in a first-party cookie, and at checkout the server reads it. Step four, the script sends a complete payment event with event ID order underscore seven seven eight, hashed email and phone, the t t c l i d, IP and user agent, and the value in dirhams. The HTTP status is two hundred, but I print the body: code zero, message OK. Step five, in Test Events, the server event appears alongside the pixel event with the same ID, and TikTok marks the duplicate. Step six, I deliberately send a malformed phone number to see what happens. The body returns a non-zero code with a clear message, and our logger records it. Now I know failures won't be silent.

### Recap and next step

Recap. TikTok and LinkedIn use the same server-side pattern as Meta. For TikTok: Pixel code as source ID, access token header, and check the body code. For LinkedIn: versioned headers, the conversion rule URN, and milliseconds. Capture click IDs at landing. Your next step: pick one of the two, and write the event mapping for your top two conversions, including the event ID source, identifiers, value, and where click IDs are stored.

## Key takeaways

- TikTok and LinkedIn follow the same server-side pattern: hashed IDs, click IDs, browser IDs and shared event IDs for dedup.
- TikTok Events API: event_source_id = Pixel code, Access-Token header, events with event_id and hashed user data.
- LinkedIn Conversions API: versioned REST, conversion rule URN, millisecond timestamps, SHA256_EMAIL and li_fat_id.
- Capture ttclid and li_fat_id at landing and store them first-party.
- Respect advertising consent and check current API versions and limits.

## Try it

Pick TikTok or LinkedIn. Write the event mapping for your top two conversions: event name, event ID source, identifiers, value, and where click IDs are captured and stored.

- [Previous: Google enhanced conversions, offline imports and Data Manager](https://optimizeall.com/learn/privacy-first-measurement/google-enhanced-conversions-and-offline)
- [Next: Data quality: event IDs, deduplication and a tracking plan](https://optimizeall.com/learn/privacy-first-measurement/deduplication-and-data-quality)
- [All lessons of Privacy-First Measurement: Server-Side Tagging, Consent Mode and Conversion APIs](https://optimizeall.com/learn/privacy-first-measurement)
