- The Conversions API (CAPI) sends conversion events to Meta from a server instead of the visitor’s browser, so a blocked or failed Pixel call no longer means a lost event.
- Meta recommends running Pixel and CAPI together and deduplicating with a shared
event_idplus the sameevent_name. - On WordPress there are four realistic routes: Meta’s own plugin, a third-party plugin, server-side GTM, or a forwarding service. None is best for everyone.
- Hash email, phone, names and address fields with SHA-256 after normalizing them. Never hash
client_ip_address,client_user_agent,fbporfbc. - Events must be at most 7 days old, a batch holds up to 1,000 events, and one invalid event rejects the whole batch. Test with
test_event_codebefore going live.
Your ad account says 41 purchases this week. WooCommerce says 58. The gap is rarely a mystery; it is usually the browser. Ad blockers, privacy settings, slow pages and users who close the tab before the Pixel fires all quietly delete conversions that really happened. The Meta Conversions API is the standard fix, and WordPress gives you several ways to wire it up.
This guide covers what CAPI is, the four ways to run it on WordPress with an honest comparison, the parameters that matter, hashing rules, testing, and the limits that trip people up. Everything below comes from Meta’s own developer documentation, which I fetched and checked in October 2026.
What the Conversions API is, and why Pixel-only loses data
The Meta Pixel is JavaScript that runs in the visitor’s browser and reports events such as PageView, Lead and Purchase. The Conversions API is an HTTPS endpoint: your server (or a service acting for it) sends the same kind of event directly to Meta. Meta’s documentation shows the endpoint as https://graph.facebook.com/{API_VERSION}/{PIXEL_ID}/events with an access token, and lists v25.0 as the current version in its using the API guide.
A Pixel-only setup depends on a chain that is easy to break: the page must load, the script must not be blocked, consent tooling must let it run, and the request must leave the browser before the visitor navigates away. A server-side event skips most of that chain. Your server already knows the order was paid, whatever the browser did.
Meta’s best-practices page recommends a redundant setup: send the same events through both Pixel and CAPI so the API captures what the Pixel loses to connectivity problems. Redundant only works if Meta can recognise the pair as one event, which is the job of deduplication.
event_name and event_id match.For the browser-versus-server trade-offs in general, see our client-side vs server-side tracking in WordPress comparison and the explanation of why WordPress analytics data goes missing. I won’t promise a percentage here: how much you recover depends on your audience and your setup, and nobody can honestly quote one for your site.
Four ways to implement CAPI on WordPress
Pick one route per event. Running two server-side senders for the same events is how you end up with duplicates that no event_id can rescue.
1. Meta’s own plugin
The official Meta Pixel for WordPress plugin lists support for the Conversions API, a Facebook Business Extension setup flow, and WooCommerce compatibility. At the time of checking it showed 400,000+ active installs, version 5.2.2, and a 2.7 out of 5 rating. The separate Meta for WooCommerce listing (3.7.6, also 400,000+ installs) emphasises the Pixel and catalog sync, so check its settings screen to confirm what it sends server-side on your version.
It is free and made by the platform you are sending data to. The cost is limited control: if you need custom events, other ad platforms or a delivery log, you will outgrow it.
2. Third-party plugins (PixelYourSite, Conversios)
PixelYourSite describes its Conversions API feature this way: it sends every event twice, once from the browser and once from the server, and Meta matches the pair on event_name and event_id. It says its server events carry match keys such as fbp, fbc, IP and user agent, plus hashed user data, with no Google Tag Manager required. That is the vendor’s description of its own product.
Conversios, in its own Conversios vs PixelYourSite article (dated 4 May 2026), claims server-side CAPI for Meta, TikTok and Snapchat, and says PixelYourSite supports Meta CAPI only. It lists both Pro products at $199 per year for one site, and says PixelYourSite users need $218 to $307 per year of extras to match its scope. These are vendor claims from a competitor’s blog, so verify them against each product’s current pricing page before you buy. PixelYourSite, for its part, also mentions CAPI access through an add-on bundle on its page.
Both run on your WordPress server, so they are quick to start and keep everything in the WordPress admin. The trade-offs are the usual ones for plugins: licence per site, platform coverage that varies by plan, and your hosting taking the extra requests.
3. Server-side Google Tag Manager
You run a tagging server, the browser sends events to it, and a Meta CAPI tag forwards them. It is the most flexible route and the one agencies with GTM skills tend to prefer. It is also the one you have to operate. Google’s Cloud Run setup guide puts a production server at roughly $45 per month and advises at least 2 instances, so budget about $90 per month in Google Cloud costs alone, before any managed-hosting alternative. Our sGTM explainer covers what you are signing up for.
4. A forwarding plugin or API (Traculo)
Here a WordPress plugin sends events to a service that forwards them to ad platforms from its own servers. Traculo works this way: a WordPress plugin and a domain API key, with events forwarded to Meta Conversions API, GA4, Google Ads, LinkedIn, TikTok, Snapchat, Pinterest and Plausible. Each event has a delivery log showing the response from each integration, which is useful when you need to see exactly what Meta answered. Pricing is a free plan with 10,000 events per month and paid plans from $12 per month, with every plan including unlimited domains and integrations (as of October 2026, see the pricing page).
Be clear about what it is not: it is not a hosted GTM server container and does not replace Tag Manager where you rely on custom GTM logic. It also does not remove your need to decide how browser and server events share an event_id.
| Route | Best for | Watch out for |
|---|---|---|
| Meta’s plugin | One site, Meta ads only, no budget | Limited control; check what is sent server-side |
| PixelYourSite / Conversios | WooCommerce shops wanting a configurable plugin | Per-site licence; coverage claims differ by vendor |
| Server-side GTM | Teams already living in GTM | You run and pay for the server |
| Forwarding service (Traculo) | Several platforms from one WordPress setup, agencies with many sites | Not a GTM replacement |
What a CAPI event must contain
Meta’s server event parameters page is the reference. In practice, every website event needs:
-
event_name: a standard event (Purchase,Lead) or a custom name. It is also half of the deduplication key. -
event_time: a Unix timestamp in seconds for when the event actually happened. It must be within 7 days before you send it. Meta states that older events cause the request to fail. -
action_source: where the conversion happened. Valid values areemail,website,app,phone_call,chat,physical_store,system_generated,business_messagingandother. For a WordPress checkout it iswebsite; for a lead you phoned back,phone_callmay be the honest value. -
event_source_url: required for website events, and it should match your verified domain. -
user_data: at least one correctly formatted customer parameter. For website events the best-practices page also asks forclient_user_agent. -
event_id: technically optional, strongly recommended. Meta suggests an order number or transaction ID, as long as the browser and server use the same one.
Add custom_data (currency, value, content IDs) for events like Purchase so that Meta can optimise for value. Our walkthrough of event_id and deduplication goes deeper on the ID choice.
Here is the same request as text you can copy. Replace the placeholder hash with the real digest.
{
"data": [{
"event_name": "Purchase",
"event_time": 1790000000,
"event_id": "order_1042",
"action_source": "website",
"event_source_url": "https://shop.test/thanks/",
"user_data": {
"em": ["<sha256 of normalized email>"],
"client_ip_address": "203.0.113.7",
"client_user_agent": "Mozilla/5.0 ...",
"fbp": "fb.1.1789000000000.1234567890",
"fbc": "fb.1.1789000000000.AbCdEf"
},
"custom_data": { "currency": "USD", "value": 59.00 }
}],
"test_event_code": "TEST12345"
}
Customer information: what is hashed and what is not
This is where most hand-built integrations go wrong. Meta’s customer information parameters page splits fields into two groups.
Normalize, then hash with SHA-256: em (email), ph (phone), fn, ln, db (date of birth), ge (gender), ct, st, zp and country. Normalization comes first and is not optional, because two different spellings of the same value produce two different hashes:
- Email: trim spaces, lowercase.
- Phone: remove symbols and letters, include the country code, no leading zeros.
(650)555-1212becomes16505551212. - Names: lowercase, no punctuation, UTF-8 for special characters.
- City, state, zip: lowercase, no spaces or punctuation. US state is a 2-letter code, US zip is the first 5 digits.
- Country: 2-letter ISO code in lowercase. Meta says to include it even if all your customers share one.
- Date of birth:
YYYYMMDD. Gender:form.
Do not hash: client_ip_address, client_user_agent, fbc and fbp, plus identifiers such as subscription_id, fb_login_id and lead_id. external_id sits in between: Meta recommends hashing it but does not require it.
Meta also publishes a Parameter Builder library with a JavaScript client SDK and server SDKs for PHP, Java, Python, NodeJS and Ruby. It builds fbc and fbp, captures the client IP, and normalizes and hashes customer data. Its caveats are worth keeping: do not modify the cookie values (_fbc is case-sensitive), capture cookies early in the journey rather than only at conversion, and apply normalization and hashing only once, on the client or the server but not both.
A quick PHP sketch for the email case:
$email = strtolower(trim($order->get_billing_email()));
$user_data['em'] = [ hash('sha256', $email) ];
fbp and fbc: the two cookies that carry identity
Per Meta’s docs, fbp is the browser ID stored in the _fbp cookie, formatted fb.{subdomain_index}.{creation_time}.{random_number}. fbc is the click ID stored in _fbc, formatted fb.{subdomain_index}.{creation_time}.{fbclid}, and it exists only if the visitor arrived from a Meta ad click carrying an fbclid parameter.
Both are plain text. The practical rule: read them in the browser, store them with the order or lead (WooCommerce order meta works), and send them with the server event later. A server can’t read a cookie that the visitor’s browser never sent, and a purchase confirmed by a payment webhook has no browser attached to it. Meta also notes that these values can change, so refresh them rather than reusing stale ones.
Timing, batches and what gets rejected
Three limits to design around:
-
Seven days.
event_timeolder than 7 days fails. If your queue retries for a week, expired events will be refused. -
1,000 events per request. The docs allow up to 1,000 events in
data. - All or nothing. Meta states that if any event in a batch is invalid, the entire batch is rejected. One missing field can drop 999 good events. Send small batches or one event at a time unless you validate each event first, and log the response.
Meta also says to send events as they happen, ideally within an hour, in real time or near-real-time batches. Hold-and-flush-at-midnight schemes work against you.
Deduplication in one paragraph
Meta’s deduplication rules match a Pixel eventID to a CAPI event_id, and the Pixel event name to event_name. Events are deduplicated only if the second arrives within 48 hours of the first with that ID. A fallback exists using event_name plus fbp and/or external_id, but it only works for events sent first from the browser and then the server. Use event_id. For how the rules differ across ad platforms, see the dedup rules reference table.
Event Match Quality: your feedback loop
Event Match Quality (EMQ) is a score out of 10 showing how well the customer information on a server event can be matched to a Meta account. Per Meta, it is currently available only for web events. Meta lists email, IP address, names and phone as the recommended extras. The score is a diagnostic, not a goal in itself: add parameters you legitimately hold, in the right format, and look at what changes. Our post on Event Match Quality covers how to read it.
Limited Data Use
The data_processing_options field accepts LDU for Limited Data Use. It requires data_processing_options_country (1 for USA, 0 for geolocation) and, where relevant, data_processing_options_state (1000 for California, 0 for geolocation). Separately, opt_out: true marks an event as used for attribution only. Whether you should use either is a legal question for you and your advisers, not something a plugin can decide. For the consent side, see Consent Mode v2 on WordPress.
Testing with the Test Events tool
- In Events Manager, open your Pixel and go to Test Events. It shows a test code.
- Add that code to your request as
test_event_code, as in the payload above. - Trigger the action (a test order, a form submit) and watch the event arrive, with its source labelled server or browser.
- Check the event shows once when both Pixel and CAPI fire, and look for parameter warnings.
-
Remove
test_event_codebefore production. Meta says it is for testing only.
Meta’s guide also offers a Payload Helper that can send a sample payload straight to Test Events. If you use a forwarding service, its delivery log gives you the same truth from the other side: the exact response Meta returned for each event.
Common failures and how to spot them
-
Events show only as “Server” or only as “Browser”: the
event_idorevent_namediffers between the two. Compare them character for character. - Everything arrives double: two server-side senders, or event IDs generated randomly on each side.
- Whole batches vanish: an invalid event poisoned the batch. Read the response body, not just the HTTP status.
- Low EMQ: no email or phone on the event, wrong normalization before hashing, or hashing done twice.
- Old events dropped: retries past the 7-day window.
Once Meta is solid, the same pattern repeats on other platforms. The follow-ups in this series cover Google Ads offline conversions, LinkedIn and TikTok, Snapchat and Pinterest, and for shops WooCommerce server-side tracking. For the GA4 equivalent, read our GA4 server-side tracking guide and the Measurement Protocol limits cheat sheet.
Frequently asked questions
Do I still need the Meta Pixel if I use the Conversions API?
Meta’s best-practices page recommends sending events through both, so CAPI can capture what the Pixel misses. Pixel-only and CAPI-only setups are possible, but the redundant setup with deduplication is the documented recommendation.
Can the Conversions API send events older than 7 days?
No. event_time must be within 7 days before submission, and Meta states that older events cause the request to fail.
Do I hash the IP address and user agent?
No. client_ip_address and client_user_agent are sent in plain text, along with fbp and fbc. Email, phone, names and address fields are normalized and hashed with SHA-256.
Why did Meta reject my whole request?
Meta rejects the entire batch if any single event in it is invalid. An expired event_time or a malformed field in one event is enough. Send smaller batches and inspect the response.
Is Meta’s WordPress plugin enough?
For one site advertising only on Meta, it may be. If you need other ad platforms, custom events, or a per-event delivery log, one of the other three routes fits better.
Related reading
- Meta CAPI deduplication, event_id explained
- Event Match Quality: what the score means and how to raise it
- Dedup rules and limits on every ad platform
- Google Ads offline conversions for WordPress leads
- WooCommerce server-side tracking
- TikTok, Snapchat and Pinterest Conversions API on WooCommerce
- Server-Side Tracking for WordPress: a beginner’s guide
- Consent Mode v2 on WordPress
If you would rather not maintain payloads and hashing yourself, Traculo’s WordPress plugin forwards events to Meta and other platforms and logs each response. See the integrations page to check whether it fits your setup.