Facebook Conversions API
Server-side events to Meta, deduplicated with the browser Pixel.
PixelFox sends conversion events to the Meta Conversions API (Graph v21.0) and - if no
other Pixel is on your page - injects the browser Pixel firing the same eventID, so
Meta deduplicates the pair automatically.
Credentials
| Field | Where to find it |
|---|---|
| Pixel ID | Meta Events Manager → Data sources → select your pixel → the ID under the pixel name. (screenshot placeholder) |
| Access token | Same pixel → Settings tab → Conversions API section → Generate access token. Requires admin access to the pixel's Business Manager. (screenshot placeholder) |
| Test event code (optional) | Same pixel → Test events tab → the TEST#### code shown there. (screenshot placeholder) |
Paste all three under Destinations → Facebook Conversions API in the PixelFox dashboard. The access token is encrypted at rest and never exposed to the browser.
Multiple pixels (route-specific)
Most sites need exactly one pixel — a single pixel lets Meta's algorithm learn from all your traffic, which is Meta's own recommendation. But some businesses run distinct brands, ad accounts or partner departments on one domain. For that, the Meta Pixel tile supports route-specific pixels: each entry pairs a URL pattern with a pixel id (and optionally that pixel's own Conversions API access token).
- On a page whose URL matches a pattern, the matching pixel replaces the main one — first match wins, and exactly one pixel fires per page.
- Patterns match as a case-insensitive substring (
/brand-b/), or as a regex with a~prefix (~^https://store\.com/eu/). - The browser fires via
fbq('trackSingle', …)and the server resolves the pixel from the event's page URL with the same rule, so browser↔serverevent_iddeduplication keeps working per pixel. - A route entry without its own access token sends server events with the main token — use that when both pixels live in the same Business Manager; pixels in a different ad account need their own token.
- Events with no page URL (server-side purchase helpers) go to the main pixel.
Which events are forwarded
Two kinds of event reach Meta:
- Built-in names -
order_placed,product_added_to_cart,product_viewedand friends, emitted by the SDK and the store plugins. These map automatically. - Your own events - anything you defined in the dashboard, e.g.
add_to_cart_click. These map only if you set their conversion.
That second point is the one that catches people out. A definition with no conversion set
is analytics-only: it is captured, counted and stored, but never forwarded - Meta has no
idea what add_to_cart_click means. Open Event definitions and pick a value in the
Conversion column to promote it.
The full vocabulary, and the Meta event each maps to:
| PixelFox conversion | Meta standard event |
|---|---|
view_content | ViewContent |
add_to_cart | AddToCart |
initiate_checkout | InitiateCheckout |
add_payment_info | AddPaymentInfo |
purchase | Purchase |
search | Search |
lead | Lead |
complete_registration | CompleteRegistration |
add_to_wishlist | AddToWishlist |
subscribe | Subscribe |
start_trial | StartTrial |
contact | Contact |
find_location | FindLocation |
schedule | Schedule |
customize_product | CustomizeProduct |
donate | Donate |
submit_application | SubmitApplication |
page_view | PageView |
Purchase needs server-side tracking
Element auto-discovery browses your site anonymously, so it can never see an
order-confirmation page - reaching one requires actually paying. There is no purchase
button to map. Either point a pageview definition at your confirmation URL, or better,
send the purchase from your server (the WooCommerce, Shopify and Laravel integrations
already do). Server-side is immune to ad blockers and to customers closing the tab before
the page renders.
What gets sent
event_id= the SDK event UUID (dedup key),action_source(websitefor the tag; server helpers may pass$action_source=physical_store,system_generated,phone_call,chat,email,app…),event_source_urlon website/app sources (your store root stands in when a server-side event has no page URL, since Meta requires it for website events)event_time, clamped into Meta's 7-day window — an event older than that would make Meta reject the whole batch, so a replayed or clock-skewed event is nudged inside it rather than taking the other events down with ituser_data- every identifier SHA-256 hashed after normalisation:em,ph,fn,ln,ct,st,zp,country,ge,db,external_id. Plus rawfbp/fbc, client IP and user agent, which Meta requires unhashed.custom_data:value,currency(validated as ISO-4217),contents(with per-item quantity and unit price),content_ids,content_name,content_category,order_id;num_itemsonInitiateCheckout, which is the only event Meta defines it for
Every extra user_data field raises Event Match Quality, which is what makes the
server-side event worth more than the browser Pixel it deduplicates against. Pass
customer details on your purchase events wherever you have them - or let a definition's
customer-field selectors read them off the checkout form. Keys the event lacks are filled
from the visitor's match profile (a prior identify(),
the browser session behind a server-side or COD purchase). Phone numbers are completed
to E.164 using the site's home country before hashing.
A Purchase without a value and a valid currency is dropped, with the reason logged: Meta requires both and rejects the entire batch over one bad event. For the same reason, if Meta rejects a batch anyway, PixelFox resends it one event at a time so a single malformed event costs only itself.
If you set data_processing_options on an event it is forwarded verbatim for Limited
Data Use (PixelFox fills in data_processing_options_country/_state as 0, asking Meta
to geolocate, when you send LDU without them). PixelFox never infers it - whether a
visitor is covered is your legal call. opt_out: true on an event marks it for
attribution only, never for optimisation.
Delayed conversions
A conversion confirmed later than it happened - a cash-on-delivery parcel delivered days
after checkout - is sent as a website event with original_event_data carrying the
original event time and order id, so Meta attributes it to the click that caused it
rather than to delivery day. See COD protection.
Testing
A test event code routes events to Events Manager's Test events tab - but Meta still uses them for targeting and measurement, so clear it when you go live. The destination card warns while one is set, and Test connection verifies your credentials by reading the dataset rather than writing a synthetic conversion when no test code is configured.
Verify
The fastest check is Destinations → Facebook Conversions API → Test connection. It sends one synthetic event through the real send path and reports Meta's answer, including the rejection reason if the token is wrong. It is always flagged as a test event, so it cannot pollute your real conversion data.
The destination card also shows live delivery state - how many of the recent batches Meta accepted, and the verbatim error when it refused.
For a full end-to-end check:
- Set the test event code in Signals.
- Open Test events in Events Manager, then trigger a conversion on your site.
- Server events appear within seconds, labeled Server; matching browser events show as Deduplicated.
- Remove the test event code when you're done - events sent with it are not used for ads delivery.