Overview
Spotify Ads primarily uses client-side pixel tracking, with server-side attribution available through promo codes and custom URL tracking.
Client-Side Tracking
Implementation
<script type="text/javascript">
(function(s,p,o,t,i,f,y){s['SpotifyPixelObject']=i;s[i]=s[i]||function(){
(s[i].q=s[i].q||[]).push(arguments)},s[i].l=1*new Date();f=p.createElement(o),
y=p.getElementsByTagName(o)[0];f.async=1;f.src=t;y.parentNode.insertBefore(f,y)
})(window,document,'script','https://pixel.spotify.com/v1/pixel.js','spotify');
spotify('init', 'PIXEL_ID');
spotify('track', 'PageView');
</script>
Advantages
- Easy implementation
- Automatic user tracking
- Real-time attribution
- No server infrastructure needed
Limitations
- Ad blockers can block (20-40%)
- Third-party cookie restrictions
- Privacy compliance required
Server-Side Attribution
Promo Code Tracking
from flask import Flask, request
import time
app = Flask(__name__)
@app.route('/api/promo-code', methods=['POST'])
def track_promo_code():
data = request.json
code = data.get('code', '').upper()
if code.startswith('SPOTIFY'):
# Store attribution
db.attributions.insert_one({
'code': code,
'source': 'spotify_audio_ad',
'timestamp': time.time(),
'user_id': data.get('user_id'),
'order_id': data.get('order_id')
})
return {'status': 'success', 'source': 'spotify'}
return {'status': 'invalid_code'}
Custom URL Tracking
// Server-side Node.js
const express = require('express');
const app = express();
app.get('/spotify-offer', (req, res) => {
const utmSource = req.query.utm_source;
const utmCampaign = req.query.utm_campaign;
if (utmSource === 'spotify') {
// Store attribution
trackSpotifyAttribution({
source: utmSource,
campaign: utmCampaign,
timestamp: Date.now(),
ip: req.ip,
userAgent: req.get('user-agent')
});
}
res.render('landing-page');
});
Advantages
- Bypasses ad blockers
- Privacy-friendly
- Offline conversion tracking
- Full data control
Limitations
- No automatic pixel tracking
- Manual attribution setup required
- Relies on promo codes or custom URLs
Hybrid Approach (Recommended)
Implementation
// Client-side: Track with pixel
spotify('track', 'Purchase', {
value: 99.99,
order_id: 'ORDER_12345'
});
// Also send to server
fetch('/api/spotify/conversion', {
method: 'POST',
body: JSON.stringify({
orderId: 'ORDER_12345',
value: 99.99,
promoCode: getPromoCode()
})
});
# Server-side: Store for attribution
@app.route('/api/spotify/conversion', methods=['POST'])
def track_conversion():
data = request.json
db.conversions.insert_one({
'order_id': data['order_id'],
'value': data['value'],
'promo_code': data.get('promo_code'),
'source': determine_source(data.get('promo_code')),
'timestamp': time.time()
})
return {'status': 'success'}
def determine_source(promo_code):
if promo_code and promo_code.startswith('SPOTIFY'):
return 'spotify_audio_ad'
return 'organic'
Use Case Recommendations
| Scenario | Client-Side | Server-Side | Hybrid |
|---|---|---|---|
| Website conversions | ✓ | ||
| Audio ad attribution | ✓ | ✓ | |
| Promo code tracking | ✓ | ✓ | |
| Offline sales | ✓ | ||
| Real-time tracking | ✓ | ✓ |
Best Practices
- Use client-side pixel for website conversions
- Implement promo codes for audio ad attribution
- Track both pixel and promo codes for hybrid approach
- Use unique promo codes per campaign
- Monitor both attribution methods
- Document attribution logic