Conversions API
Send server-side conversion events to Meta
Conversions API
Send offline conversion events (deal closed, lead qualified, trial converted) back to Meta via the Graph API events endpoint. Zernio uses the Meta Ads account you already connected, no additional OAuth, no pixel-scoped CAPI token to paste. PII is SHA-256 hashed server-side per Meta's spec before anything leaves your server.
Discover available pixels
const { data } = await zernio.ads.listConversionDestinations({
path: { accountId: 'ACCOUNT_ID' },
});data = client.ads.list_conversion_destinations(account_id="ACCOUNT_ID")curl "https://zernio.com/api/v1/accounts/ACCOUNT_ID/conversion-destinations" \
-H "Authorization: Bearer YOUR_API_KEY"Returns every pixel accessible to the connected ad accounts. Use the returned id as destinationId on the send call.
Send a conversion event
const result = await zernio.ads.sendConversions({ body: {
accountId: 'ACCOUNT_ID',
destinationId: '1729525464415281', // pixel ID
events: [{
eventName: 'Lead',
eventTime: Math.floor(Date.now() / 1000),
eventId: 'order_abc_123', // dedup key, must match pixel event if dual-tracking
value: 42.50,
currency: 'USD',
actionSource: 'crm',
user: {
email: 'customer@example.com',
phone: '+14155551234',
firstName: 'Jane',
lastName: 'Doe',
country: 'US',
},
}],
}});result = client.ads.send_conversions(
account_id="ACCOUNT_ID",
destination_id="1729525464415281",
events=[{
"eventName": "Lead",
"eventTime": int(time.time()),
"eventId": "order_abc_123",
"value": 42.50,
"currency": "USD",
"actionSource": "crm",
"user": {
"email": "customer@example.com",
"phone": "+14155551234",
"firstName": "Jane",
"lastName": "Doe",
"country": "US",
},
}],
)curl -X POST "https://zernio.com/api/v1/ads/conversions" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"accountId": "ACCOUNT_ID",
"destinationId": "1729525464415281",
"events": [{
"eventName": "Lead",
"eventTime": 1744732800,
"eventId": "order_abc_123",
"value": 42.50,
"currency": "USD",
"actionSource": "crm",
"user": {
"email": "customer@example.com",
"phone": "+14155551234",
"firstName": "Jane",
"lastName": "Doe",
"country": "US"
}
}]
}'Match keys
The more identifiers you send on user, the higher Meta's Event Match Quality. All are normalized and SHA-256 hashed server-side per Meta's spec (you send plaintext); ipAddress, userAgent, fbc, and fbp are sent unhashed per Meta's requirement. Supported keys:
- Contact:
email,phone,firstName,lastName - Location / demographic:
country,city,state,zip,dob(YYYYMMDD),gender(form) - Identifiers:
externalId(your stable user/device id),ipAddress,userAgent - Click IDs (under
user.clickIds):fbc(from thefbclidURL param),fbp(the_fbpcookie)
The highest-signal web keys are fbc, fbp, externalId, ipAddress, and userAgent, send them whenever you capture them at first touch.
Standard event names
Purchase, Lead, CompleteRegistration, AddToCart, InitiateCheckout, AddPaymentInfo, Subscribe, StartTrial, ViewContent, Search, Contact, SubmitApplication, Schedule. Custom event names are accepted too.
Test mode
Pass testCode: "TEST12345" at the request root to route events to the Test Events tab in Meta Events Manager without affecting production pixel data.
Deduplication
Pass a stable eventId on every event. Meta dedupes against your pixel within a 48-hour window when eventId matches. Missing or inconsistent eventId between pixel and CAPI double-counts conversions, the #1 cause of inflated reports.
Batching
Up to 1,000 events per request (Zernio chunks larger batches automatically). Meta rejects the entire batch if any event is malformed, the response includes failures[] with per-event error detail and a traceId you can look up in Meta support.
Event Match Quality
Read Event Match Quality (EMQ) and pixel-to-CAPI coverage back from Meta without opening Events Manager. Pass the pixel/dataset destinationId and you get, per event, the composite EMQ score (0-10), per-match-key coverage, and the event coverage rate (how well your CAPI events dedupe against the pixel).
const { data } = await zernio.ads.getConversionsQuality({
query: { accountId: 'ACCOUNT_ID', destinationId: '1729525464415281' },
});data = client.ads.get_conversions_quality(
account_id="ACCOUNT_ID",
destination_id="1729525464415281",
)curl "https://zernio.com/api/v1/ads/conversions/quality?accountId=ACCOUNT_ID&destinationId=1729525464415281" \
-H "Authorization: Bearer YOUR_API_KEY"{
"platform": "metaads",
"rows": [
{
"eventName": "Purchase",
"compositeScore": 6.2,
"matchKeys": [{ "identifier": "email", "coveragePercentage": 80 }],
"eventCoveragePercentage": 75
}
]
}Web events only (a Meta limitation, app and offline EMQ aren't exposed by the API). Uses the connected Meta Ads account, no extra permission.