Facebook Conversions API (CAPI): Setup Guide and Best Practices for 2025
Step-by-step guide to implementing Meta's Conversions API for accurate Facebook and Instagram ad measurement. Covers setup, event matching, deduplication, and optimization.


Facebook Conversions API (CAPI): Setup Guide and Best Practices for 2025
If you're running Facebook or Instagram ads and still relying solely on the Meta Pixel for conversion tracking, you're likely underreporting conversions by 20–40%. Ad blockers, Safari's ITP, and iOS App Tracking Transparency have all eroded the pixel's effectiveness.
Meta's Conversions API (CAPI) sends conversion data from your server to Meta's servers, bypassing the browser entirely. It's no longer optional—it's the foundation of accurate Meta ad measurement.
Why the Meta Pixel Isn't Enough
The Meta Pixel is a JavaScript tag that fires in the user's browser. Every limitation of client-side tracking applies:
- Ad blockers prevent the pixel from loading for 30–40% of desktop users.
- Safari ITP limits the pixel's cookie to 7 days (or 24 hours), breaking attribution for returning visitors.
- iOS 14.5+ ATT prompts users to opt out of tracking. Opt-out rates are 75–85%, meaning the pixel can't track the majority of iOS users.
- Consent banner rejection prevents the pixel from firing when users decline tracking cookies.
The cumulative impact: Meta's own research shows that advertisers using both the pixel and CAPI see 13% more attributed conversions than those using the pixel alone. In privacy-conscious markets (Europe, certain US states), the gap is even larger.
How the Conversions API Works
CAPI is a server-to-server integration. Instead of relying on the browser to send events to Meta, your server sends them directly:
User Action → Your Server → Meta Conversions API → Meta Ads ManagerYour server sends HTTP POST requests to Meta's Graph API endpoint with event data including the event name, event time, user data parameters (hashed email, phone, etc.), and custom data (value, currency, content IDs).
Meta matches the event to a user in their system using the hashed identifiers you provide. The more identifiers you send, the higher the match rate.
Step-by-Step Setup
Step 1: Generate an Access Token
In Meta Events Manager, navigate to your pixel settings and generate a Conversions API access token. This token authenticates your server's API requests.
Store this token securely—treat it like a password. Use environment variables, never hardcode it.
Step 2: Implement Server-Side Event Collection
Your server needs to capture conversion events and forward them to Meta. Here's a production-ready implementation:
const crypto = require('crypto');
const fetch = require('node-fetch');
class MetaCAPI {
constructor(pixelId, accessToken) {
this.pixelId = pixelId;
this.accessToken = accessToken;
this.endpoint = `https://graph.facebook.com/v18.0/${pixelId}/events`;
}
hashValue(value) {
if (!value) return undefined;
return crypto
.createHash('sha256')
.update(value.toLowerCase().trim())
.digest('hex');
}
async sendEvent(event) {
const payload = {
data: [{
event_name: event.name,
event_time: Math.floor(Date.now() / 1000),
event_id: event.eventId, // For deduplication
event_source_url: event.sourceUrl,
action_source: 'website',
user_data: {
em: this.hashValue(event.email),
ph: this.hashValue(event.phone),
fn: this.hashValue(event.firstName),
ln: this.hashValue(event.lastName),
ct: this.hashValue(event.city),
st: this.hashValue(event.state),
zp: this.hashValue(event.zipCode),
country: this.hashValue(event.country),
external_id: this.hashValue(event.userId),
client_ip_address: event.ipAddress,
client_user_agent: event.userAgent,
fbc: event.fbClickId, // _fbc cookie value
fbp: event.fbBrowserId // _fbp cookie value
},
custom_data: {
value: event.value,
currency: event.currency || 'USD',
content_ids: event.contentIds,
content_type: event.contentType,
order_id: event.orderId
}
}],
access_token: this.accessToken
};
const response = await fetch(this.endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
return response.json();
}
}Step 3: Map Your Events
Map your conversion events to Meta's standard event names:
| Your Event | Meta Event Name | When to Fire |
|---|---|---|
| Page viewed | PageView | Every page load |
| Product viewed | ViewContent | Product detail page |
| Added to cart | AddToCart | Cart addition |
| Checkout started | InitiateCheckout | Checkout page load |
| Purchase completed | Purchase | Order confirmation |
| Lead form submitted | Lead | Form submission |
| Account created | CompleteRegistration | Registration |
| Search performed | Search | Search results page |
Step 4: Implement Event Deduplication
If you're running both the pixel and CAPI (recommended during transition), you'll send the same events twice. Meta deduplicates using the event_id parameter—send the same unique ID from both the pixel and CAPI for each event.
// Generate a unique event ID on the client
const eventId = crypto.randomUUID();
// Send via pixel (client-side)
fbq('track', 'Purchase', { value: 99.99, currency: 'USD' }, { eventID: eventId });
// Send via CAPI (server-side) with the same eventId
capi.sendEvent({
name: 'Purchase',
eventId: eventId, // Must match the pixel event
value: 99.99,
// ... other parameters
});Without deduplication, Meta will count every conversion twice, inflating your reported results.
Step 5: Maximize Event Match Quality
Meta assigns an Event Match Quality (EMQ) score from 1–10 based on how many user parameters you send and how well they match Meta's user database. Higher EMQ means better attribution.
To maximize EMQ:
- Always send hashed email — This is the single highest-impact parameter. Most purchases and leads include an email address.
- Include the _fbc and _fbp cookies — Read these first-party cookies from the user's browser and pass them to CAPI. They contain the Facebook click ID and browser ID that connect the server event to the ad click.
- Add phone number when available — Another high-value match parameter, especially in regions where phone-based identity is common.
- Include IP address and user agent — These enable probabilistic matching when deterministic identifiers aren't available.
- Send first name, last name, city, state, and zip when collected — Each additional parameter incrementally improves matching.
Target an EMQ score of 6 or above. Below 6, your CAPI integration isn't providing much value over the pixel alone.
Testing and Validation
Use the Test Events Tool
Meta Events Manager includes a Test Events tab where you can verify that your CAPI events are arriving correctly. Generate a test event code, include it in your API requests during testing, and verify events appear in real-time.
Validate Deduplication
After enabling both pixel and CAPI, monitor your Events Manager for duplicate events. If you see significantly more events than expected, your deduplication isn't working correctly—check that event_id values match between pixel and CAPI.
Monitor Event Match Quality
Review your EMQ score weekly during the first month of implementation. If it's below your target, audit which user parameters are missing and update your data collection to capture them.
Advanced CAPI Strategies
Offline Conversion Uploads
CAPI isn't limited to website events. You can send offline conversions—in-store purchases, phone orders, CRM conversions—to Meta for attribution:
// Offline conversion upload
await capi.sendEvent({
name: 'Purchase',
eventId: `offline_${orderId}`,
email: customerEmail,
value: orderTotal,
sourceUrl: 'https://yourdomain.com', // Required even for offline events
// Set event_time to when the offline event actually occurred
});This is particularly valuable for businesses with significant offline revenue, as it allows Meta's algorithm to optimize for total business value rather than just online conversions.
Enhanced Conversions for Leads
If you're a B2B company where the real conversion happens days or weeks after the initial lead form submission (when a deal closes in your CRM), use CAPI to send the downstream conversion back to Meta:
- Capture the
fbcandfbpcookie values at the time of lead submission. - Store them in your CRM alongside the lead record.
- When the lead converts to a customer, send a CAPI event with the original cookie values and the new conversion value.
This allows Meta to optimize for customer acquisition, not just lead volume.
Common CAPI Mistakes
Not sending the _fbc cookie. This cookie contains the Facebook click ID. Without it, Meta can't connect the server event to the specific ad click that drove the visit. Always capture and forward it.
Hashing incorrectly. All user data parameters (email, phone, name, etc.) must be lowercase, trimmed of whitespace, and SHA-256 hashed before sending. Common errors: hashing before lowercasing, including whitespace, or double-hashing.
Delayed event sending. CAPI events should be sent within minutes of the user action, not batched and sent hours later. Meta's attribution windows are time-sensitive.
Ignoring the response. Always log and monitor CAPI responses. Meta returns detailed error messages when events are malformed or parameters are invalid. Ignoring errors means silent data loss.
How Audiencelab Simplifies CAPI
Audiencelab handles the full CAPI integration automatically:
- No code required. Our server-side tracking layer captures all standard events and forwards them to Meta's CAPI with full user data parameters.
- Automatic deduplication. Events from both browser and server are deduped transparently.
- EMQ optimization. We automatically enrich events with all available user parameters to maximize match quality.
- Real-time monitoring. Track event delivery, match rates, and any errors in a single dashboard.
Want to improve your Meta ad measurement? Set up CAPI with Audiencelab in under an hour.