Reddit Ads Event Tracking
Overview
Reddit Ads uses the Reddit Pixel and Conversions API (CAPI) for conversion tracking and audience building. The pixel enables website tracking for standard and custom events, while CAPI provides server-side tracking for improved accuracy and privacy compliance. Together, they enable comprehensive measurement across the customer journey.
Standard Events
Reddit supports predefined events for common conversion types:
Conversion Events
- Purchase - Completed transaction
- Lead - Lead form submission
- SignUp - Account registration
- AddToCart - Product added to cart
- AddToWishlist - Product added to wishlist
- ViewContent - Key content page view
- Search - Site search performed
- PageVisit - General page view
Engagement Events
- Custom - Business-specific custom events
Installing the Reddit Pixel
Base Pixel Code
Install the base pixel on all pages:
<!-- Reddit Pixel Base Code -->
<script>
!function(w,d){if(!w.rdt){var p=w.rdt=function(){p.sendEvent?p.sendEvent.apply(p,arguments):p.callQueue.push(arguments)};p.callQueue=[];var t=d.createElement("script");t.src="https://www.redditstatic.com/ads/pixel.js",t.async=!0;var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(t,s)}}(window,document);
rdt('init','PIXEL_ID');
rdt('track', 'PageVisit');
</script>
Replace PIXEL_ID with your Reddit Pixel ID from the Reddit Ads dashboard.
Noscript Fallback
Add noscript tag for users without JavaScript:
<noscript>
<img src="https://alb.reddit.com/snoo.gif?q=CAAHAAABAAoACgAAAA&s=PIXEL_ID" style="display:none" width="1" height="1" alt=""/>
</noscript>
Custom Events
Creating Custom Conversions
Track business-specific actions:
// Custom event with parameters
rdt('track', 'Custom', {
customEventName: 'VideoComplete',
value: 0,
currency: 'USD'
});
// Newsletter signup
rdt('track', 'Custom', {
customEventName: 'NewsletterSignup',
value: 5.00,
currency: 'USD'
});
// Content download
rdt('track', 'Custom', {
customEventName: 'WhitepaperDownload',
value: 25.00,
currency: 'USD'
});
Event Parameters
Customize tracking with additional data:
rdt('track', 'Lead', {
value: 50.00,
currency: 'USD',
transactionId: 'LEAD_12345',
// Custom parameters
leadType: 'demo_request',
source: 'pricing_page'
});
Ecommerce Events
Purchase Tracking
Complete purchase implementation:
// Purchase event with full details
rdt('track', 'Purchase', {
value: 149.99,
currency: 'USD',
transactionId: 'ORDER_12345',
itemCount: 3,
// Product details (optional)
products: [
{
id: 'SKU_001',
name: 'Product Name',
category: 'Electronics',
price: 99.99,
quantity: 1
},
{
id: 'SKU_002',
name: 'Accessory',
category: 'Accessories',
price: 25.00,
quantity: 2
}
]
});
Add to Cart
Track cart additions:
rdt('track', 'AddToCart', {
value: 99.99,
currency: 'USD',
itemCount: 1,
products: [
{
id: 'SKU_001',
name: 'Product Name',
category: 'Electronics',
price: 99.99
}
]
});
View Content
Track product or content page views:
rdt('track', 'ViewContent', {
value: 0,
currency: 'USD',
products: [
{
id: 'SKU_001',
name: 'Product Name',
category: 'Electronics'
}
]
});
Complete Funnel Example
// 1. Page View (automatic with base pixel)
rdt('track', 'PageVisit');
// 2. Product View
rdt('track', 'ViewContent', {
products: [{ id: 'SKU_001', name: 'Widget Pro' }]
});
// 3. Add to Cart
rdt('track', 'AddToCart', {
value: 99.99,
currency: 'USD',
products: [{ id: 'SKU_001', name: 'Widget Pro', quantity: 1 }]
});
// 4. Initiate Checkout (Custom)
rdt('track', 'Custom', {
customEventName: 'InitiateCheckout',
value: 99.99,
currency: 'USD'
});
// 5. Purchase
rdt('track', 'Purchase', {
value: 99.99,
currency: 'USD',
transactionId: 'ORDER_12345'
});
Conversion Tracking
Implementation Methods
1. Reddit Pixel (JavaScript)
Standard client-side implementation:
<script>
!function(w,d){if(!w.rdt){var p=w.rdt=function(){p.sendEvent?p.sendEvent.apply(p,arguments):p.callQueue.push(arguments)};p.callQueue=[];var t=d.createElement("script");t.src="https://www.redditstatic.com/ads/pixel.js",t.async=!0;var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(t,s)}}(window,document);
rdt('init','PIXEL_ID');
rdt('track', 'PageVisit');
</script>
2. Google Tag Manager
Deploy via GTM with Custom HTML tag:
<script>
!function(w,d){if(!w.rdt){var p=w.rdt=function(){p.sendEvent?p.sendEvent.apply(p,arguments):p.callQueue.push(arguments)};p.callQueue=[];var t=d.createElement("script");t.src="https://www.redditstatic.com/ads/pixel.js",t.async=!0;var s=d.getElementsByTagName("script")[0];s.parentNode.insertBefore(t,s)}}(window,document);
rdt('init','{{Reddit Pixel ID}}');
rdt('track', 'PageVisit');
</script>
Event tracking via GTM:
Create separate Custom HTML tags for each event:
<script>
rdt('track', 'Purchase', {
value: {{DL - Order Total}},
currency: 'USD',
transactionId: '{{DL - Order ID}}'
});
</script>
3. Reddit Conversions API (CAPI)
Server-side tracking for improved accuracy:
import requests
import hashlib
import time
def hash_value(value):
"""SHA256 hash for user data"""
return hashlib.sha256(value.lower().strip().encode()).hexdigest()
def send_reddit_conversion(event_data):
url = "https://ads-api.reddit.com/api/v2.0/conversions/events/PIXEL_ID"
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
payload = {
"events": [{
"event_at": int(time.time() * 1000), # Milliseconds
"event_type": {
"tracking_type": "Purchase"
},
"event_metadata": {
"currency": "USD",
"value_decimal": 99.99,
"item_count": 1,
"conversion_id": "ORDER_12345"
},
"user": {
"email": hash_value("user@example.com"),
"external_id": hash_value("USER_123"),
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"click_id": "reddit_click_id" # From URL parameter
}
}]
}
response = requests.post(url, headers=headers, json=payload)
return response.json()
Enhanced Match (User Data)
Improve match rates with hashed user data:
// Initialize with user data
rdt('init', 'PIXEL_ID', {
email: 'user@example.com', // Will be hashed automatically
externalId: 'USER_123'
});
// Track conversion with enhanced match
rdt('track', 'Purchase', {
value: 99.99,
currency: 'USD',
transactionId: 'ORDER_12345'
});
Manual hashing:
// SHA256 hash function
async function sha256(message) {
const msgBuffer = new TextEncoder().encode(message.toLowerCase().trim());
const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);
const hashArray = Array.from(new Uint8Array(hashBuffer));
return hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
}
// Initialize with pre-hashed data
const hashedEmail = await sha256('user@example.com');
rdt('init', 'PIXEL_ID', {
email: hashedEmail,
optOut: false,
useDecimalCurrencyValues: true
});
Offline Conversions
CAPI for Offline Events
Upload offline conversions via Conversions API:
import requests
import time
def upload_offline_conversion(conversion_data):
url = "https://ads-api.reddit.com/api/v2.0/conversions/events/PIXEL_ID"
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json"
}
payload = {
"events": [{
"event_at": conversion_data['timestamp'],
"event_type": {
"tracking_type": "Purchase"
},
"event_metadata": {
"currency": "USD",
"value_decimal": conversion_data['value'],
"conversion_id": conversion_data['order_id']
},
"user": {
"email": hash_value(conversion_data['email']),
"click_id": conversion_data.get('click_id')
}
}]
}
return requests.post(url, headers=headers, json=payload)
Click ID Capture
Capture Reddit click ID for offline attribution:
// Capture click_id from URL
function getRedditClickId() {
const params = new URLSearchParams(window.location.search);
return params.get('rdt_cid');
}
// Store for later use
const clickId = getRedditClickId();
if (clickId) {
localStorage.setItem('reddit_click_id', clickId);
// Also send to your server with form submissions
}
Attribution
Attribution Windows
Reddit offers configurable attribution windows:
| Window Type | Default | Range |
|---|---|---|
| Post-click | 28 days | 1-28 days |
| Post-view | 1 day | 1-7 days |
Configure in Reddit Ads Manager under Pixel settings.
Attribution Models
Last-touch attribution:
- Credit goes to last Reddit ad interaction before conversion
- Standard model for direct response campaigns
Multi-touch consideration:
- Reddit often influences consideration phase
- Use longer click windows for high-consideration products
- Compare Reddit-attributed vs. assisted conversions
Audience Building
Create Audiences from Events
Build retargeting audiences based on pixel events:
// Track for audience building
rdt('track', 'PageVisit'); // All visitors
rdt('track', 'ViewContent', { products: [{ id: 'SKU_001' }] }); // Product viewers
rdt('track', 'AddToCart'); // Cart abandoners
rdt('track', 'Purchase'); // Customers (for exclusion)
Audience examples:
- All site visitors (PageVisit)
- Product page visitors (ViewContent)
- Cart abandoners (AddToCart without Purchase)
- Past purchasers (Purchase - for exclusion or upsell)
Debugging & Validation
Reddit Pixel Helper
Chrome extension for validation:
- Install Reddit Pixel Helper from Chrome Web Store
- Navigate to your website
- Click extension icon to see:
- Pixel detected status
- Events firing
- Event parameters
- Error messages
Browser Developer Tools
Manual verification:
// Console check
if (typeof rdt === 'function') {
console.log('Reddit Pixel loaded');
} else {
console.error('Reddit Pixel not found');
}
// Check call queue
console.log(window.rdt.callQueue);
Network Tab Verification
- Open DevTools > Network tab
- Filter for "reddit" or "alb.reddit.com"
- Trigger conversion action
- Verify request fires with correct parameters
Reddit Ads Dashboard
Check pixel health in Reddit Ads:
- Navigate to Events Manager
- Select your pixel
- Review:
- Last activity timestamp
- Event volume by type
- Match rate (with enhanced match)
- Any error notifications
Test Events
Send test conversions:
// Test purchase
rdt('track', 'Purchase', {
value: 1.00,
currency: 'USD',
transactionId: 'TEST_' + Date.now()
});
Verify in Events Manager within 20-30 minutes.
Best Practices
Implementation
- Install pixel on all pages for comprehensive audience building
- Use enhanced match with hashed email for improved attribution
- Implement CAPI alongside pixel for redundancy and accuracy
- Capture click_id for offline conversion attribution
- Test thoroughly before launching campaigns
Event Strategy
- Track full funnel from PageVisit to Purchase
- Use consistent transaction IDs for deduplication
- Pass accurate values for ROAS calculation
- Create custom events for business-specific actions
- Build audiences from all meaningful interactions
Privacy & Compliance
- Respect user consent before firing pixels
- Use server-side tracking where client-side blocked
- Hash all PII before sending to Reddit
- Update privacy policy to disclose Reddit tracking
- Implement consent mode for GDPR/CCPA compliance
Optimization
- Use conversion events for campaign optimization
- Create exclusion audiences from converters
- Build lookalikes from high-value customers
- Monitor conversion rates by subreddit
- Test different attribution windows for your sales cycle