Overview
LinkedIn Ads offers two primary approaches for conversion tracking: client-side using the Insight Tag and server-side using the Conversion API. This guide helps you understand the differences, benefits, trade-offs, and implementation approaches for each method.
Client-Side Tracking (Insight Tag)
How It Works
The Insight Tag is a JavaScript snippet that:
- Loads in user's browser
- Sets first-party cookies
- Captures page views and events
- Sends data to LinkedIn's servers
- Attributes conversions to ads
Data Flow:
User's Browser → Insight Tag (JavaScript) → LinkedIn Servers → Campaign Manager
Advantages
1. Easy Implementation
<!-- Simple tag installation -->
<script type="text/javascript">
_linkedin_partner_id = "1234567";
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(_linkedin_partner_id);
</script>
<script type="text/javascript">
(function(l) {
if (!l){window.lintrk = function(a,b){window.lintrk.q.push([a,b])};
window.lintrk.q=[]}
var s = document.getElementsByTagName("script")[0];
var b = document.createElement("script");
b.type = "text/javascript";b.async = true;
b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
s.parentNode.insertBefore(b, s);})(window.lintrk);
</script>
No backend development required.
2. Automatic Attribution
LinkedIn handles:
3. Rich Data Collection
Captures:
- Page views (automatic)
- User behavior
- Site demographics
- Engagement metrics
- Session data
4. Website Retargeting
Enables:
- Retargeting audiences
- URL-based segments
- Behavioral targeting
- Lookalike audiences
5. No Server Infrastructure
- Runs entirely client-side
- No API credentials needed
- No server maintenance
- Instant updates from LinkedIn
Disadvantages
1. Browser Dependencies
Requires:
- JavaScript enabled
- Cookies enabled
- Page fully loaded
- No blocking extensions
Fails When:
- JavaScript disabled
- AdBlockers active
- Network issues prevent tag load
- Page abandonment before tag fires
2. Privacy Limitations
Increasingly Affected By:
- Browser privacy features (ITP, ETP)
- Cookie restrictions
- GDPR/CCPA requirements
- User consent requirements
- Third-party cookie deprecation
Impact:
- Reduced match rates
- Attribution gaps
- Incomplete tracking
- Data loss
3. Client-Side Vulnerabilities
Challenges:
- Users can inspect/manipulate
- Browser console access
- Tag can be blocked
- No guaranteed firing
- Timing dependencies
4. Limited Control
- Can't track without page load
- Dependent on frontend changes
- Difficult offline conversions
- No backend-only events
Server-Side Tracking (Conversion API)
How It Works
Server-to-server API calls:
- User completes action
- Your server detects event
- Server calls LinkedIn API
- LinkedIn records conversion
- Attributes to campaigns
Data Flow:
User Action → Your Server → LinkedIn Conversion API → Campaign Manager
API Endpoint
POST https://api.linkedin.com/v2/conversions
Advantages
1. Reliable Tracking
- Not dependent on browser
- No JavaScript required
- Immune to ad blockers
- Guaranteed delivery (with retries)
- Works offline or server-side only
2. Privacy Compliant
- First-party data only
- No browser cookies required
- Better GDPR/CCPA compliance
- Server-controlled data sharing
- Reduced client-side tracking
3. Complete Control
- Track any backend event
- Flexible timing
- Retry logic
- Data validation
- Custom attribution
4. Enhanced Security
- API credentials server-side
- No client-side exposure
- Validated data
- Encrypted transmission
- Audit trails
5. Offline Conversions
Track events that occur:
- In-person (retail, events)
- Via phone calls
- Through offline channels
- Days/weeks after initial interaction
Disadvantages
1. Complex Implementation
Requires:
- Backend development
- API integration
- Authentication setup
- Error handling
- Testing infrastructure
2. No Automatic Attribution
You Must Provide:
- User identifier (email hash)
- Conversion timestamp
- Attribution data
- Click ID (if available)
LinkedIn can't automatically:
- Track clicks
- Set cookies
- Identify users
- Handle view-through attribution
3. Limited Retargeting
- No page view data
- Can't build URL-based audiences
- No automatic demographic insights
- Manual audience uploads required
4. Development Resources
Ongoing Needs:
- Server maintenance
- API monitoring
- Error handling
- Credential management
- Version updates
5. Delayed Attribution
- Must match email to LinkedIn member
- Lower match rates than cookie-based
- Requires user identification
- Hash matching limitations
Comparison Table
| Aspect | Client-Side (Insight Tag) | Server-Side (API) |
|---|---|---|
| Implementation | Easy, JavaScript snippet | Complex, API integration |
| Attribution | Automatic | Manual |
| Browser Required | Yes | No |
| JavaScript Required | Yes | No |
| Cookie Required | Yes | No |
| Ad Blocker Proof | No | Yes |
| Privacy Impact | Higher | Lower |
| Match Rate | Higher (cookie-based) | Lower (email-based) |
| Retargeting | Full support | Limited |
| Website Demographics | Yes | No |
| Offline Conversions | No | Yes |
| Development Effort | Minimal | Significant |
| Reliability | Browser-dependent | Server-controlled |
| Data Control | Limited | Complete |
| Real-Time Tracking | Yes | Yes (with implementation) |
Server-Side Implementation
Prerequisites
Required:
- LinkedIn Campaign Manager account
- LinkedIn Marketing API access
- OAuth 2.0 credentials
- Server infrastructure
- Development resources
Step 1: API Access
Get Access:
- Register application at LinkedIn Developers
- Request marketing API permissions
- Generate OAuth 2.0 credentials
- Obtain access token
Required Permissions:
w_member_socialrw_adsr_ads_reporting
Step 2: Conversion Tracking Setup
Create Conversion (if not exists):
POST https://api.linkedin.com/v2/conversions
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
{
"account": "urn:li:sponsoredAccount:123456",
"name": "Purchase",
"type": "PURCHASE",
"attributionType": "LAST_TOUCH_BY_CAMPAIGN",
"postClickAttributionWindowSize": 30,
"viewThroughAttributionWindowSize": 7
}
Response includes Conversion ID:
{
"id": "urn:li:conversion:987654"
}
Step 3: Track Conversions
API Call Structure:
POST https://api.linkedin.com/v2/conversionEvents
Authorization: Bearer {ACCESS_TOKEN}
Content-Type: application/json
{
"conversion": "urn:li:conversion:987654",
"conversionHappenedAt": 1699564800000,
"user": {
"userIds": [
{
"idType": "SHA256_EMAIL",
"idValue": "hash_of_user_email"
}
]
},
"conversionValue": {
"currencyCode": "USD",
"amount": "99.99"
},
"eventId": "unique_event_id_12345"
}
Step 4: Implementation Examples
Node.js Example
const axios = require('axios');
const crypto = require('crypto');
async function trackLinkedInConversion(userEmail, conversionValue) {
// Hash email
const hashedEmail = crypto
.createHash('sha256')
.update(userEmail.toLowerCase().trim())
.digest('hex');
// Prepare conversion event
const conversionEvent = {
conversion: 'urn:li:conversion:987654',
conversionHappenedAt: Date.now(),
user: {
userIds: [
{
idType: 'SHA256_EMAIL',
idValue: hashedEmail
}
]
},
conversionValue: {
currencyCode: 'USD',
amount: conversionValue.toString()
},
eventId: `order_${Date.now()}_${Math.random()}`
};
try {
const response = await axios.post(
'https://api.linkedin.com/v2/conversionEvents',
conversionEvent,
{
headers: {
'Authorization': `Bearer ${process.env.LINKEDIN_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
}
);
console.log('Conversion tracked:', response.data);
return response.data;
} catch (error) {
console.error('Error tracking conversion:', error.response?.data || error.message);
throw error;
}
}
// Usage
trackLinkedInConversion('user@example.com', 99.99);
Python Example
import hashlib
import time
import requests
import os
def track_linkedin_conversion(user_email, conversion_value):
# Hash email
hashed_email = hashlib.sha256(
user_email.lower().strip().encode()
).hexdigest()
# Prepare conversion event
conversion_event = {
'conversion': 'urn:li:conversion:987654',
'conversionHappenedAt': int(time.time() * 1000),
'user': {
'userIds': [
{
'idType': 'SHA256_EMAIL',
'idValue': hashed_email
}
]
},
'conversionValue': {
'currencyCode': 'USD',
'amount': str(conversion_value)
},
'eventId': f'order_{int(time.time())}_{hash(user_email)}'
}
# Make API call
response = requests.post(
'https://api.linkedin.com/v2/conversionEvents',
json=conversion_event,
headers={
'Authorization': f'Bearer {os.getenv("LINKEDIN_ACCESS_TOKEN")}',
'Content-Type': 'application/json'
}
)
if response.status_code == 201:
print('Conversion tracked successfully')
return response.json()
else:
print(f'Error: {response.status_code} - {response.text}')
raise Exception('Failed to track conversion')
# Usage
track_linkedin_conversion('user@example.com', 99.99)
PHP Example
<?php
function trackLinkedInConversion($userEmail, $conversionValue) {
// Hash email
$hashedEmail = hash('sha256', strtolower(trim($userEmail)));
// Prepare conversion event
$conversionEvent = [
'conversion' => 'urn:li:conversion:987654',
'conversionHappenedAt' => time() * 1000,
'user' => [
'userIds' => [
[
'idType' => 'SHA256_EMAIL',
'idValue' => $hashedEmail
]
]
],
'conversionValue' => [
'currencyCode' => 'USD',
'amount' => strval($conversionValue)
],
'eventId' => 'order_' . time() . '_' . uniqid()
];
// Make API call
$ch = curl_init('https://api.linkedin.com/v2/conversionEvents');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($conversionEvent));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . getenv('LINKEDIN_ACCESS_TOKEN'),
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($statusCode === 201) {
echo 'Conversion tracked successfully';
return json_decode($response, true);
} else {
throw new Exception('Failed to track conversion: ' . $response);
}
}
// Usage
trackLinkedInConversion('user@example.com', 99.99);
?>
Hybrid Approach (Recommended)
Best of Both Worlds
Use Client-Side For:
- Page view tracking
- Website retargeting audiences
- Demographic insights
- Automatic attribution
- View-through conversions
Use Server-Side For:
- High-value conversions
- Offline conversions
- Backend-only events
- Compliance requirements
- Guaranteed tracking
Implementation
Step 1: Install Insight Tag
Standard client-side implementation for retargeting and attribution.
Step 2: Server-Side for Critical Conversions
When high-value conversion occurs server-side:
// Server-side (Node.js example)
app.post('/checkout/complete', async (req, res) => {
const order = req.body;
// Process order
await processOrder(order);
// Track to LinkedIn via API
await trackLinkedInConversion(order.email, order.total);
// Return success
res.json({ success: true });
});
Step 3: Client-Side as Backup
On confirmation page:
<script>
// Client-side tracking as backup/supplement
window.lintrk('track', {
conversion_id: 987654,
value: {{ order.total }},
currency: 'USD'
});
</script>
Step 4: Deduplication
LinkedIn's backend handles deduplication when:
- Same conversion ID
- Same user (matched via email or cookie)
- Similar timestamp
- Uses eventId for server-side
Use unique eventId:
eventId: `order_${orderId}_${timestamp}`
LinkedIn deduplicates based on eventId within 24 hours.
When to Choose Each Approach
Client-Side Only
Best For:
- Small to medium businesses
- Limited development resources
- Standard e-commerce
- Retargeting-focused campaigns
- Quick implementation needed
Examples:
Server-Side Only
Best For:
- Enterprise applications
- Strict privacy requirements
- Offline conversions
- Complex attribution needs
- High-value transactions
Examples:
Hybrid Approach
Best For:
- Large businesses
- Comprehensive tracking
- Multiple conversion types
- Advanced marketing
- Compliance + performance
Examples:
- Enterprise SaaS
- Large e-commerce
- Multi-channel businesses
- Financial services
- Healthcare (HIPAA compliance)
Best Practices
Client-Side
- Install on all pages - Comprehensive tracking
- Use tag manager - GTM for flexibility
- Test thoroughly - Verify before launch
- Monitor tag health - Regular checks
- Respect privacy - Implement consent management
Server-Side
- Secure credentials - Environment variables, never hardcode
- Hash emails properly - SHA256, lowercase, trimmed
- Implement retries - Handle API failures
- Unique event IDs - Prevent duplicates
- Log conversions - Audit trail for debugging
Hybrid
- Clear separation - Document which events use which method
- Consistent IDs - Use same conversion IDs when appropriate
- Deduplication strategy - Understand LinkedIn's handling
- Monitor both sources - Verify data consistency
- Fallback logic - Server-side backup for critical events
Troubleshooting
Client-Side Issues
Tag not loading:
- Check JavaScript console errors
- Verify tag code correct
- Ensure no ad blockers
- Confirm page fully loads
Conversions not tracking:
- Verify Insight Tag on conversion page
- Check conversion_id correct
- Confirm lintrk function available
- Review Network tab for requests
Server-Side Issues
API authentication errors:
- Verify access token valid
- Check token not expired
- Confirm proper permissions
- Regenerate if needed
Conversion not attributed:
- Verify email hash correct
- Check match rate (typically 40-60%)
- Confirm conversion URN correct
- Review eventId for uniqueness
Rate limiting:
- Implement exponential backoff
- Batch requests when possible
- Monitor rate limit headers
- Distribute load
Monitoring and Analytics
Client-Side Monitoring
Campaign Manager:
- Tag health dashboard
- Detected domains
- Recent activity
- Conversion counts
- UTM parameter tracking
- Conversion correlation
- Cross-platform analysis
Server-Side Monitoring
Application Logs:
logger.info('LinkedIn conversion tracked', {
eventId: event.eventId,
conversionId: event.conversion,
value: event.conversionValue.amount,
timestamp: event.conversionHappenedAt
});
Error Tracking:
try {
await trackLinkedInConversion(email, value);
} catch (error) {
errorLogger.error('LinkedIn API error', {
error: error.message,
statusCode: error.response?.status,
email: hashEmail(email) // Log hash, not actual email
});
}
Metrics to Track:
- API success rate
- Response times
- Match rates
- Error types
- Conversion volume
Future Considerations
Privacy Evolution
Trends:
- Increased cookie restrictions
- Third-party cookie deprecation
- Stricter privacy laws
- User consent requirements
Impact:
- Server-side becomes more important
- First-party data focus
- API tracking advantages grow
- Hybrid approaches essential
LinkedIn Platform Updates
Stay informed:
- API version changes
- New features
- Deprecation notices
- Best practice updates
Next Steps
- Evaluate needs - Determine best approach for your business
- Plan implementation - Client-side, server-side, or hybrid
- Develop solution - Code and test thoroughly
- Monitor performance - Track success and errors
- Iterate and optimize - Refine based on results
Additional Resources
- Install Insight Tag - Client-side setup
- Event Tracking - Conversion implementation
- LinkedIn Marketing API Docs - Official API documentation
- Integrations Guide - CRM and platform integrations