You're running LinkedIn ads, Meta ads, maybe Google or TikTok campaigns. You've installed the pixel. You're seeing some conversions in the dashboard. But the numbers don't match what your backend actually processed. Some conversions are missing – eaten by ad blockers, iOS restrictions, or the visitor closing the tab before the pixel fires.
This is the problem conversion APIs solve. Instead of relying on a browser pixel alone, you send conversion events directly from your server to the ad platform. The data arrives regardless of what the visitor's browser did or didn't do.
Why the pixel isn't enough
Browser-based pixels have three problems in 2026:
- Ad blockers. Roughly 30–40% of desktop users block tracking scripts. Your pixel never loads, so the conversion is never reported.
- Cookie restrictions. Safari's ITP, Firefox ETP, and Chrome's evolving Privacy Sandbox all limit third-party cookies. Click IDs expire faster, attribution windows shrink.
- Page unloads. A visitor completes a purchase, the "thank you" page starts loading, and they close the tab. The pixel never fires. Your ad platform thinks the ad didn't work.
Server-side conversion APIs bypass all three. Your server sees the completed action and reports it directly.
How conversion APIs work
The pattern is the same across platforms:
- Capture the click ID – when someone clicks your ad, the platform appends a parameter to the URL (
fbclidfor Meta,li_fat_idfor LinkedIn,gclidfor Google,ttclidfor TikTok). Your landing page stores this value – typically in a first-party cookie or your session store. - Record the conversion server-side – when the conversion happens (purchase, signup, form submission), your backend has the click ID and the user's email.
- Send the event to the platform's API – POST the conversion data, including the click ID and a hashed email, to the platform's endpoint. The platform matches it to the original ad click.
Platform-by-platform examples
LinkedIn Conversions API
LinkedIn CAPI requires an access token with rw_conversions scope, your ad account ID, and a conversion rule ID (created in LinkedIn Campaign Manager).
curl -X POST "https://api.linkedin.com/rest/conversionEvents" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "LinkedIn-Version: 202603" \
-H "Content-Type: application/json" \
-d '{
"conversion": "urn:lla:llaPartnerConversion:YOUR_RULE_ID",
"conversionHappenedAt": 1711756800000,
"user": {
"userIds": [{
"idType": "SHA256_EMAIL",
"idValue": "a]8f5f167...hashed"
}],
"userInfo": {
"firstName": "Jane",
"lastName": "Doe"
}
},
"eventId": "evt-unique-123"
}'
Key details: Timestamps are in milliseconds. Email must be SHA256-hashed and lowercased before hashing. The eventId field enables deduplication – send the same ID twice and LinkedIn ignores the duplicate.
Meta Conversions API
Meta CAPI sends events to a specific pixel ID. You need a system user token with ads_management permission.
curl -X POST "https://graph.facebook.com/v19.0/YOUR_PIXEL_ID/events" \
-H "Content-Type: application/json" \
-d '{
"data": [{
"event_name": "Purchase",
"event_time": 1711756800,
"action_source": "website",
"event_source_url": "https://example.com/checkout/success",
"user_data": {
"em": ["a8f5f167...hashed"],
"fbc": "fb.1.1711756700.ABCdef123"
},
"custom_data": {
"currency": "GBP",
"value": 49.99
}
}],
"access_token": "YOUR_TOKEN"
}'
Key details: Timestamps are in seconds (not milliseconds). The fbc parameter is the click ID stored from the fbclid URL parameter – format is fb.{version}.{timestamp}.{fbclid}. Hash emails with SHA256 after lowercasing and trimming whitespace.
Google Ads offline conversions
Google uses the gclid click ID. You upload conversions via the Google Ads API or the simpler Measurement Protocol.
# Google Ads API – upload click conversion
curl -X POST "https://googleads.googleapis.com/v17/customers/YOUR_CUSTOMER_ID:uploadClickConversions" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "developer-token: YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"conversions": [{
"gclid": "CjwKCAjw...",
"conversionAction": "customers/123/conversionActions/456",
"conversionDateTime": "2026-03-30 10:00:00+00:00",
"conversionValue": 49.99,
"currencyCode": "GBP"
}]
}'
Key details: The gclid must be captured on your landing page and stored alongside the user's session. Conversions can be uploaded up to 90 days after the click. DateTime format is yyyy-MM-dd HH:mm:ss+TZ.
TikTok Events API
TikTok's Events API works similarly to Meta's, posting events against a pixel ID.
curl -X POST "https://business-api.tiktok.com/open_api/v1.3/event/track/" \
-H "Access-Token: YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"pixel_code": "YOUR_PIXEL_CODE",
"event": "CompletePayment",
"event_id": "evt-unique-456",
"timestamp": "2026-03-30T10:00:00+00:00",
"user": {
"email": "a8f5f167...hashed",
"ttclid": "E.C.P.abc123..."
},
"properties": {
"currency": "GBP",
"value": 49.99
}
}'
Key details: ttclid is captured from the URL parameter. event_id is used for deduplication with the browser pixel. Hash email with SHA256.
What to send and when
| Platform | Click ID parameter | Timestamp format | Hashing | Dedup field |
|---|---|---|---|---|
li_fat_id | Milliseconds | SHA256 | eventId | |
| Meta | fbclid | Seconds | SHA256 | event_id |
| Google Ads | gclid | DateTime string | Not required | orderId |
| TikTok | ttclid | ISO 8601 | SHA256 | event_id |
Common mistakes
- Not capturing click IDs on the landing page. The conversion API is useless without the original click ID. Store
fbclid,gclid,li_fat_id, andttclidin a first-party cookie the moment someone lands on your site. - Hashing before lowercasing. Every platform requires the email to be lowercased and trimmed before hashing.
SHA256("Jane@Example.com")andSHA256("jane@example.com")produce completely different hashes. - Sending duplicate events without dedup IDs. If you send the same purchase twice – once from the pixel and once from the API – without a shared event ID, the platform counts it twice. Always set the deduplication field.
- Wrong timestamp formats. LinkedIn uses milliseconds. Meta uses seconds. Google uses a formatted DateTime string. TikTok uses ISO 8601. Mix them up and events silently fail or get rejected.
- Testing in production. Use test event codes (Meta's
test_event_code, LinkedIn's test mode, Google's validation endpoint) before going live. Test conversions pollute your reporting and can't be deleted.
Verifying it works
Each platform provides tools to check if your events are arriving:
- Meta: Events Manager → Test Events tab. Use a
test_event_codeto see events arrive in real time without affecting production data. - LinkedIn: Campaign Manager → Conversions → check the event count and match rate. It can take up to 48 hours for events to appear.
- Google Ads: The upload response includes a
partial_failure_errorfield. Check it. No errors doesn't mean thegclidmatched – it means the format was valid. - TikTok: Events Manager → Event Debugging. Similar to Meta's test events tool.
Combining CAPI with your analytics
Conversion APIs tell the ad platform what happened. Your web analytics tool – like Grandma Knows – tells you what the visitor did before and after. The two complement each other:
- UTM parameters track where visitors came from in your analytics.
- Conversion goals track the same events in your dashboard – page visits, button clicks, scroll depth milestones.
- The conversion API reports those events back to the ad platform for attribution and bid optimisation.
The best setup uses all three: UTMs for campaign tracking in analytics, goals for measuring what matters on your site, and CAPI for closing the loop with the ad platform.
Grandma's take: The pixel watches the front door. The conversion API watches the back door. If you're spending money on ads, you need both – because Grandma didn't raise you to waste your advertising budget on guesswork.