Overview
The Trade Desk supports both client-side (Universal Pixel JavaScript) and server-side (Conversion API / S2S) tracking methods. Each approach has distinct advantages and use cases. A hybrid implementation combining both methods provides the most comprehensive and resilient measurement solution.
Client-Side Tracking (Universal Pixel)
How It Works
The Universal Pixel is a JavaScript tag that loads in the user's browser and sends events directly to TTD's servers. It automatically captures browser context, user behavior, and attribution data.
Implementation
<!-- Universal Pixel Client-Side -->
<script>
!function(t,r,a,c,k){
t[c]=t[c]||function(){(t[c].q=t[c].q||[]).push(arguments)};
var s=r.createElement(a),d=r.getElementsByTagName(a)[0];
s.async=1;s.src=k;d.parentNode.insertBefore(s,d);
}(window,document,'script','ttd','https://js.adsrvr.org/up_loader.1.1.0.js');
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'purchase',
value: 199.99,
currency: 'USD',
order_id: 'ORD123456'
});
</script>
Advantages
- Automatic Data Collection: Captures browser data (user agent, IP, referrer) automatically
- Easy Implementation: Simple JavaScript tag deployment via GTM or direct embed
- Rich Behavioral Data: Tracks page views, scrolling, time on page, and engagement
- Cookie-Based Attribution: Automatic user identification via cookies
- Real-Time Events: Immediate event transmission on user action
- No Server Infrastructure: No backend development required
Disadvantages
- Ad Blockers: Browser extensions and privacy tools can block pixel
- JavaScript Required: Won't fire if JavaScript is disabled
- Browser Restrictions: ITP (Safari), ETP (Firefox) limit cookie persistence
- Client Performance: Adds JavaScript load to page (minimal but measurable)
- Data Loss: Network issues or page navigation can prevent pixel from firing
- Privacy Constraints: GDPR/CCPA consent requirements may block tracking
Best Use Cases
- Standard website conversion tracking
- E-commerce product views and cart tracking
- Lead generation forms and user interactions
- Audience building based on page views and behavior
- Environments where server-side integration isn't feasible
Server-Side Tracking (Conversion API)
How It Works
The Conversion API (S2S) sends event data directly from your server to TTD's servers via HTTP POST requests. This bypasses the user's browser entirely, providing resilient and privacy-durable measurement.
Implementation
// Node.js example
const axios = require('axios');
async function sendTTDConversion(orderData) {
try {
const response = await axios.post('https://insight.adsrvr.org/track/up', {
adv: 'YOUR_ADVERTISER_ID',
upid: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'purchase',
value: orderData.total,
currency: 'USD',
order_id: orderData.id,
items: orderData.items,
// User data for attribution
td_uid: orderData.uid2Token, // UID2 token
ip: orderData.userIP,
user_agent: orderData.userAgent,
// Custom parameters
td2: orderData.customerTier,
td3: orderData.campaignSource
}, {
headers: {
'Content-Type': 'application/json'
}
});
console.log('TTD conversion sent:', response.status);
} catch (error) {
console.error('TTD conversion failed:', error.message);
}
}
// After order processing
app.post('/checkout/complete', async (req, res) => {
const order = await processOrder(req.body);
// Send conversion to TTD server-side
await sendTTDConversion({
total: order.total,
id: order.id,
items: order.items,
uid2Token: req.session.uid2Token,
userIP: req.ip,
userAgent: req.headers['user-agent'],
customerTier: req.user.tier
});
res.json({ success: true });
});
Python Example
import requests
import hashlib
def send_ttd_conversion(order_data):
url = 'https://insight.adsrvr.org/track/up'
payload = {
'adv': 'YOUR_ADVERTISER_ID',
'upid': 'YOUR_UNIVERSAL_PIXEL_ID',
'event_name': 'purchase',
'value': order_data['total'],
'currency': 'USD',
'order_id': order_data['id'],
'items': order_data['items'],
'td_uid': order_data.get('uid2_token'),
'ip': order_data['user_ip'],
'user_agent': order_data['user_agent'],
'td2': order_data.get('customer_tier')
}
try:
response = requests.post(url, json=payload)
print(f'TTD conversion sent: {response.status_code}')
except Exception as e:
print(f'TTD conversion failed: {str(e)}')
Advantages
- Ad Blocker Resistant: Bypasses browser-based blocking entirely
- Reliable Data Transmission: No dependency on client-side JavaScript or cookies
- Privacy Durable: Works in ITP/ETP environments and cookieless contexts
- Server Data Enrichment: Include backend data (customer LTV, offline events)
- Deduplication Control: Prevent duplicate conversions with order_id
- PII Hashing: Securely hash PII server-side before transmission
- Guaranteed Delivery: Retry logic and error handling on server
Disadvantages
- Development Required: Backend integration and API development needed
- Attribution Complexity: Must pass user identifiers (UID2, TDID, IP/UA)
- No Automatic Behavioral Data: Won't capture page views or engagement
- Infrastructure Costs: Server resources and monitoring required
- Debugging Harder: Less visibility than client-side browser tools
Best Use Cases
- E-commerce checkout and purchase conversions
- Offline conversions (phone orders, in-store purchases)
- CRM-based lead scoring and qualification events
- Subscription renewals and recurring revenue
- High-value transactions requiring guaranteed tracking
- Mobile app conversions (native apps without webviews)
Hybrid Approach (Recommended)
Implementation Strategy
Combine client-side and server-side tracking for maximum coverage:
Client-Side: Track behavioral events and initial conversions
// Browser - Universal Pixel
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'begin_checkout',
value: 249.99,
currency: 'USD'
});
Server-Side: Confirm conversions and add enriched data
// Server - Conversion API
await axios.post('https://insight.adsrvr.org/track/up', {
adv: 'YOUR_ADVERTISER_ID',
upid: 'YOUR_UNIVERSAL_PIXEL_ID',
event_name: 'purchase',
value: 249.99,
currency: 'USD',
order_id: 'ORD123456', // Deduplication key
td_uid: uid2Token,
td2: 'returning_customer',
td3: 'lifetime_value_high'
});
Deduplication
Use order_id to prevent duplicate conversion counting:
// Both client and server send same order_id
// TTD deduplicates automatically based on order_id
// Client-side
ttd.universal({
event_name: 'purchase',
order_id: 'ORD123456',
value: 249.99
});
// Server-side (backup)
axios.post('https://insight.adsrvr.org/track/up', {
event_name: 'purchase',
order_id: 'ORD123456', // Same ID - TTD deduplicates
value: 249.99
});
Comparison Matrix
| Feature | Client-Side | Server-Side | Hybrid |
|---|---|---|---|
| Implementation Complexity | Low | Medium | Medium |
| Ad Blocker Resistance | No | Yes | Yes |
| Behavioral Tracking | Yes | No | Yes |
| Privacy Durability | Limited | High | High |
| Data Enrichment | Limited | Full | Full |
| Attribution Accuracy | Good | Excellent | Excellent |
| Page View Tracking | Yes | No | Yes |
| Offline Conversions | No | Yes | Yes |
| Mobile App Support | Limited | Yes | Yes |
| Development Required | Minimal | Significant | Significant |
UID2 Integration
Client-Side UID2
// Generate UID2 token client-side
const uid2Token = await UID2.getToken(emailHash);
// Pass to Universal Pixel
ttd.universal({
advertiser_id: 'YOUR_ADVERTISER_ID',
td1: 'YOUR_UNIVERSAL_PIXEL_ID',
uid2_token: uid2Token,
event_name: 'page_view'
});
Server-Side UID2
// Generate UID2 token server-side
const uid2Token = await generateUID2Token(userEmail);
// Send to Conversion API
await axios.post('https://insight.adsrvr.org/track/up', {
adv: 'YOUR_ADVERTISER_ID',
upid: 'YOUR_UNIVERSAL_PIXEL_ID',
td_uid: uid2Token, // Server-side UID2
event_name: 'purchase',
value: 299.99,
order_id: 'ORD789456'
});
Best Practices
Client-Side
- Deploy via GTM for easier management and testing
- Implement consent management for GDPR/CCPA compliance
- Test with Chrome DevTools and TTD Pixel Helper
- Use descriptive event names that match business goals
- Monitor pixel health with automated alerts
Server-Side
- Always include user identifiers (UID2, IP, user agent) for attribution
- Implement retry logic for failed API calls
- Use order_id for deduplication with client-side events
- Hash PII (email, phone) server-side before transmission
- Monitor API error rates and latency
- Test in staging environment before production deployment
Hybrid
- Use client-side for behavioral events (page views, cart adds)
- Use server-side for conversion events (purchase, subscription)
- Implement order_id deduplication across both methods
- Enrich server-side events with CRM data not available client-side
- Monitor both pixel and API tracking in TTD reporting
- Regular audit of tracking coverage and data quality
Migration Path
Phase 1: Client-Side Only
- Deploy Universal Pixel via GTM
- Test and validate conversion tracking
- Build audience and attribution baseline
Phase 2: Add Server-Side for Conversions
- Implement Conversion API for purchase events
- Use order_id deduplication
- Validate server-side conversions in reporting
Phase 3: Full Hybrid Implementation
- Expand server-side to offline conversions
- Integrate UID2 for cookieless identity
- Optimize attribution with enriched server data
- Monitor and compare client vs server event volume