← Back to Blog
How I Implemented Meta CAPI in Django and Recovered 40% of Lost Conversions
# How I Implemented Meta CAPI in Django
After iOS 14+, my client's Facebook ads went from accurately attributing 85% of conversions to barely catching 50%. The browser pixel was getting blocked constantly.
The fix? Meta's Conversion API (CAPI) — server-side event sending that bypasses ad-blockers entirely.
## The Architecture
Here's the high-level flow I implemented:
1. **Browser pixel fires** on page events (ViewContent, AddToCart, etc.)
2. **Django view creates** a `ConversionEvent` model instance simultaneously
3. **Celery task** sends the event to Meta's Graph API asynchronously
4. **Event ID deduplication** ensures Meta counts each conversion exactly once
## The ConversionEvent Model
```python
class ConversionEvent(TimeStampedModel):
event_id = models.CharField(max_length=100, unique=True, default=uuid.uuid4)
event_name = models.CharField(max_length=50, choices=META_EVENT_TYPES)
event_time = models.BigIntegerField()
email_hash = models.CharField(max_length=64, blank=True)
ip_address = models.GenericIPAddressField(null=True, blank=True)
fbc = models.CharField(max_length=200, blank=True)
fbp = models.CharField(max_length=200, blank=True)
status = models.CharField(max_length=20, choices=EVENT_STATUS, default='pending')
```
## Results
After 30 days:
- **Attributed conversions**: +40% recovered
- **Cost per lead**: -35%
- **ROAS**: 2.1x → 3.4x
The key insight: CAPI isn't optional anymore — it's the baseline for any serious Meta advertiser.