Deployment Strategy
- Preferred: Google Tag Manager with Reddit Pixel base code and event-specific tags for standard and custom events.
- Enforce consent mode integration with your CMP (OneTrust, Cookiebot, Osano) to respect user privacy choices before pixel fires.
- Use GTM variables for environment-specific pixel IDs and test event codes to avoid mixing dev/staging data with production.
- Consider Conversions API for server-side redundancy and privacy-compliant tracking, especially for high-value events like purchases and registrations.
Tag Manager Deployment
- Create a base Reddit Pixel tag in GTM that fires on all pages with your pixel ID.
- Build separate event tags for each standard event (Purchase, SignUp, Lead, ViewContent, AddToCart) triggered by dataLayer pushes or page-specific rules.
- Bind pixel ID, advanced matching data (hashed email, external_id), and consent state to GTM variables per environment.
- Use GTM Preview mode to validate pixel firing, event parameters, and consent signal integration before publishing.
- Test advanced matching parameters in Events Manager Test Events to confirm they are properly hashed and formatted.
GTM Base Pixel Tag
Tag Configuration:
- Tag Type: Custom HTML
- Fires On: All Pages
- Tag Name: Reddit Pixel - Base Code
HTML Template:
<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}}', {
optOut: false,
useDecimalCurrencyValues: true
});
rdt('track', 'PageView');
</script>
GTM Variables:
{{Reddit Pixel ID}}- Configured per environment (dev, staging, production)- Different pixel IDs for each environment to separate testing data
GTM Event Tags
Purchase Event Tag:
<script>
rdt('track', 'Purchase', {
value: {{Transaction Value}},
currency: '{{Transaction Currency}}',
transactionId: '{{Transaction ID}}',
itemCount: {{Item Count}}
});
</script>
Trigger: Custom Event = purchase or Page Path matches /order-confirmation
SignUp Event Tag:
<script>
rdt('track', 'SignUp');
</script>
Trigger: Form Submission or Custom Event = signup
Lead Event Tag:
<script>
rdt('track', 'Lead');
</script>
Trigger: Form Submission on lead gen pages
Direct Embed or Hard-Coded Scripts
- If GTM is not available, place the Reddit Pixel base code in the document
<head>section with async loading. - Add
rdt('init', 'PIXEL_ID')followed byrdt('track', 'PageView')immediately after the base code. - For event tracking, call
rdt('track', 'EventName', {parameters})on user actions (button clicks, form submissions, page loads). - Keep pixel IDs environment-aware via server-rendered variables or feature flags so staging never sends data to production pixels.
- Implement consent checks before initializing the pixel to comply with GDPR and CCPA requirements.
Base Pixel Code
Place in <head> tag 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', 'a2_XXXXXXXXXX', {
optOut: false,
useDecimalCurrencyValues: true
});
rdt('track', 'PageView');
</script>
<!-- End Reddit Pixel Code -->
Replace a2_XXXXXXXXXX with your actual Reddit Pixel ID from Events Manager.
Event Tracking Examples
Purchase Event on Order Confirmation:
<script>
rdt('track', 'Purchase', {
value: 149.99,
currency: 'USD',
transactionId: 'ORDER_12345',
itemCount: 3
});
</script>
SignUp Event on Registration:
<script>
rdt('track', 'SignUp');
</script>
Lead Event on Form Submission:
<script>
document.getElementById('lead-form').addEventListener('submit', function(e) {
rdt('track', 'Lead');
});
</script>
Dynamic Product View:
<script>
rdt('track', 'ViewContent', {
value: <%= product.price %>,
currency: 'USD',
itemCount: 1
});
</script>
Mobile & App SDKs
Reddit Ads doesn't provide native mobile SDKs. For mobile app tracking, use Mobile Measurement Partners (MMPs):
Supported MMPs
- AppsFlyer - Full Reddit integration with attribution
- Adjust - App install and in-app event tracking
- Kochava - Cross-device attribution
- Branch - Deep linking with Reddit campaign data
- Singular - Unified mobile app attribution
MMP Integration Steps
- Create account with supported MMP (e.g., AppsFlyer, Adjust)
- Integrate MMP SDK in your iOS/Android app
- Add Reddit as an integrated partner in MMP dashboard
- Configure postback URLs for Reddit attribution
- Map in-app events to Reddit conversion events
- Test attribution with test campaigns
- Verify events appearing in Reddit Ads reporting
AppsFlyer Example
iOS Integration:
import AppsFlyerLib
// Initialize AppsFlyer
AppsFlyerLib.shared().appsFlyerDevKey = "YOUR_DEV_KEY"
AppsFlyerLib.shared().appleAppID = "YOUR_APPLE_ID"
AppsFlyerLib.shared().delegate = self
AppsFlyerLib.shared().start()
// Track purchase event
AppsFlyerLib.shared().logEvent(
AFEventPurchase,
withValues: [
AFEventParamRevenue: 99.99,
AFEventParamCurrency: "USD",
AFEventParamQuantity: 1
]
)
Android Integration:
import com.appsflyer.AppsFlyerLib;
// Initialize AppsFlyer
AppsFlyerLib.getInstance().init("YOUR_DEV_KEY", conversionListener, this);
AppsFlyerLib.getInstance().start(this);
// Track purchase event
Map<String, Object> eventValues = new HashMap<>();
eventValues.put(AFInAppEventParameterRevenue, 99.99);
eventValues.put(AFInAppEventParameterCurrency, "USD");
eventValues.put(AFInAppEventParameterQuantity, 1);
AppsFlyerLib.getInstance().logEvent(
getApplicationContext(),
AFInAppEventType.PURCHASE,
eventValues
);
Server-Side Collection (Conversions API)
- Deploy Conversions API endpoints on your backend to send server-side events for high-value conversions (purchases, leads, registrations).
- Use the same event names as the pixel to enable Reddit's deduplication logic (match on event_id).
- Send hashed user data (email, external_id) for improved event attribution and match quality.
- Implement retry logic, error logging, and monitoring for CAPI requests to surface failed events quickly.
- Test server events in Events Manager before enabling production traffic.
CAPI Endpoint Setup
Generate Access Token:
- Log in to Reddit Ads Manager
- Navigate to Events Manager
- Select your pixel
- Go to Settings > Conversions API
- Generate access token
- Securely store token in environment variables
CAPI Request Example
Node.js Implementation:
const axios = require('axios');
const crypto = require('crypto');
function hashSHA256(value) {
return crypto.createHash('sha256')
.update(value.toLowerCase().trim())
.digest('hex');
}
async function sendRedditConversion(eventData) {
const payload = {
events: [{
event_at: new Date().toISOString(),
event_type: {
tracking_type: 'Purchase'
},
user: {
email: hashSHA256(eventData.email),
external_id: eventData.userId
},
event_metadata: {
item_count: eventData.itemCount,
products: eventData.products,
value: eventData.value,
currency: eventData.currency,
conversion_id: eventData.orderId
}
}]
};
try {
const response = await axios.post(
`https://ads-api.reddit.com/api/v2.0/conversions/events/${ADVERTISER_ID}`,
payload,
{
headers: {
'Authorization': `Bearer ${REDDIT_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
}
);
console.log('Reddit CAPI success:', response.data);
return response.data;
} catch (error) {
console.error('Reddit CAPI error:', error.response?.data || error.message);
throw error;
}
}
// Usage example
sendRedditConversion({
email: 'customer@example.com',
userId: 'user_123',
itemCount: 2,
products: [{ id: 'SKU_001' }, { id: 'SKU_002' }],
value: 149.99,
currency: 'USD',
orderId: 'ORDER_12345'
});
Python Implementation:
import requests
import hashlib
from datetime import datetime
def hash_sha256(value):
return hashlib.sha256(value.lower().strip().encode()).hexdigest()
def send_reddit_conversion(event_data):
payload = {
"events": [{
"event_at": datetime.utcnow().isoformat() + "Z",
"event_type": {
"tracking_type": "Purchase"
},
"user": {
"email": hash_sha256(event_data['email']),
"external_id": event_data['user_id']
},
"event_metadata": {
"item_count": event_data['item_count'],
"value": event_data['value'],
"currency": event_data['currency'],
"conversion_id": event_data['order_id']
}
}]
}
headers = {
"Authorization": f"Bearer {REDDIT_ACCESS_TOKEN}",
"Content-Type": "application/json"
}
response = requests.post(
f"https://ads-api.reddit.com/api/v2.0/conversions/events/{ADVERTISER_ID}",
json=payload,
headers=headers
)
if response.status_code == 200:
print("Reddit CAPI success:", response.json())
else:
print("Reddit CAPI error:", response.status_code, response.text)
return response
# Usage
send_reddit_conversion({
'email': 'customer@example.com',
'user_id': 'user_123',
'item_count': 2,
'value': 149.99,
'currency': 'USD',
'order_id': 'ORDER_12345'
})
Event Deduplication
When using both Pixel and CAPI, ensure deduplication:
Browser-side (Pixel):
const eventId = 'ORDER_12345_' + Date.now();
rdt('track', 'Purchase', {
value: 149.99,
currency: 'USD',
transactionId: 'ORDER_12345',
eventId: eventId // Unique identifier
});
// Send eventId to server for CAPI
Server-side (CAPI):
// Use same eventId from pixel
event_metadata: {
conversion_id: 'ORDER_12345',
event_id: eventId // Match pixel event
}
Consent Management Integration
OneTrust Example
// Wait for consent before initializing pixel
function OptanonWrapper() {
if (OnetrustActiveGroups.includes('C0002')) {
// Advertising cookies approved
rdt('init', 'PIXEL_ID');
rdt('track', 'PageView');
}
}
Cookiebot Example
window.addEventListener('CookiebotOnAccept', function (e) {
if (Cookiebot.consent.marketing) {
rdt('init', 'PIXEL_ID');
rdt('track', 'PageView');
}
});
Custom Consent
// Check custom consent flag
if (localStorage.getItem('marketing_consent') === 'true') {
rdt('init', 'PIXEL_ID');
rdt('track', 'PageView');
}
Validation Checklist
- Reddit Pixel loads on all pages without JavaScript errors
- PageView event fires automatically on page load
- Conversion events fire on correct user actions
- Event parameters match tracking plan requirements
- Events appear in Events Manager within 30 minutes
- Pixel ID correct for environment (dev/staging/production)
- Consent management integration working correctly
- Advanced matching data properly hashed (if implemented)
- CAPI events sending successfully (if implemented)
- Event deduplication working between pixel and CAPI
- Cross-browser testing completed (Chrome, Firefox, Safari, Edge)
- Mobile responsive testing completed
Configuration Recommendations
Advanced Matching: Enable advanced matching with hashed email (rdt('init', 'PIXEL_ID', { email: 'hashed_email' })) if your site collects email at checkout or signup. This improves match rates by 20-40% and enables better attribution for logged-in users. Always SHA-256 hash before sending.
CAPI Events: Implement server-side CAPI for high-value conversion events (purchases, leads, signups) where losing events to ad blockers directly impacts campaign optimization. Keep the client-side pixel for behavioral events (PageView, ViewContent) where some data loss is acceptable.
Event Deduplication: Use matching event_id values between pixel and CAPI events for the same conversion. Generate a unique ID per conversion (e.g., order ID for purchases) and pass it in both implementations. Reddit deduplicates based on matching event_id + event_name within a 48-hour window.
Standard vs. Custom Events: Use Reddit's standard events (Purchase, Lead, SignUp, AddToCart, ViewContent) whenever possible — they unlock pre-built audience segments and optimization goals. Only create custom events for actions that don't map to any standard event.
Monitoring: Check Events Manager weekly for pixel health alerts. Set up conversion volume alerts in Reddit Ads if event volume drops below expected thresholds, which could indicate pixel breakage.