Meta Conversions API
Credentials
- business.facebook.com → Events Manager → select your data set (pixel).
- Settings → section Conversions API → Set up manually → Generate access token.
- Note the pixel id (data set id) shown in the same place.
PUT /v1/projects/{project}/destinations/meta
{
"enabled": true,
"mode": "test",
"transport": "direct",
"settings": { "pixelId": "1234567890123456", "apiVersion": "v26.0", "testEventCode": "TEST12345" },
"secrets": { "accessToken": "EAAB…" }
}With "transport": "composio" and an adConnectionId, events go through Composio's
METAADS_SEND_CONVERSION_EVENTS using the Meta ad connection – no separate token is stored. The
connection's token must have access to the pixel.
What is sent
POST https://graph.facebook.com/{apiVersion}/{pixelId}/events with one event per conversion:
| Field | Value |
|---|---|
event_name | the definition's Meta eventName |
event_time | conversion time (Unix seconds) |
event_id | the conversion's event id (deduplication with the browser pixel) |
action_source | chat for whatsapp_manual; website for quiz/booking/event/goal/lead conversions with a user agent; otherwise system_generated |
event_source_url | the page of the conversion (only with action_source: website) |
user_data.em, ph, fn, ln, external_id, country | SHA-256 hashes, normalized per Meta's rules |
user_data.client_ip_address, client_user_agent | request context, when your server passed it |
user_data.fbc | the _fbc cookie, or built from the session's fbclid (fb.1.<ms>.<fbclid>) |
user_data.fbp | the _fbp cookie (only after consent, or passed by your server) |
custom_data.value, currency | from the conversion or definition, when the value is above 0 |
An event needs at least one match key (em, ph, external_id, fbc, fbp or IP); otherwise the
status is skipped ("no customer identifiers"). Meta accepts events up to 7 days old; older
conversions are skipped (3x keeps one hour of margin).
Deduplication with the browser pixel
If you also fire the pixel in the browser, pass the same event name and the same id
(eventID in fbq('track', 'Lead', {}, { eventID })) as the conversion's eventId. Meta then
counts one conversion. In the browser, x3.conversion(definition, { eventId }) takes your id (or
resolves with the generated one); from your server pass eventId to conversions.create.
Testing
- Events Manager → Test events → copy the test code into
settings.testEventCode. - Set the destination
modetotest(orlivewith the test code – events then still land in Test events). POST /v1/projects/{project}/destinations/meta/testor trigger a real conversion.- Check that the event appears as Server and – when the pixel fired – as deduplicated.
- Remove the test code and set
mode: "live".
Typical errors
| Error | Meaning |
|---|---|
190 Invalid OAuth access token | token revoked or expired – generate a new one |
100 Invalid parameter with event_time | conversion older than 7 days |
2804050 … test_event_code | the test code no longer exists – remove it |