Connecting Contact Form 7 to Meta Conversions API
Contact Form 7 is free, everywhere, and stores nothing by default — which is the whole problem. Meta's pixel loses a large share of conversions to Safari, ad blockers and iOS, and the Conversions API exists because of it. The join between them succeeds or fails on one thing: whether the fbc and fbp values reaches the Contact Form 7 submission before the conversion happens, because Meta can only match a conversion it can tie back to a click it recognizes.
Free30 minutesNo obligation
Specific to this pair
Contact Form 7 leads to Meta CAPI with fbc read from the request
Send Contact Form 7 submissions to Meta as Lead, reading _fbc, _fbp, IP and user agent from the same-domain AJAX request in PHP with hashed email, phone and name. Generate an event_id in the browser at form load, put it in a hidden field, and use it for both pixel and server. Never send the free-text message field.
For Meta, the CF7 submission becomes a Lead event. Because the form posts to your own domain over AJAX, the server already has most of what Meta matches on: the _fbc and _fbp cookies, the visitor's IP address and user agent, all on the incoming request. Read them in PHP alongside the email and phone fields, hash the contact data, and send. That is more matching data than most hosted form tools ever see.
Deduplication is where CF7 setups go wrong. The usual browser setup fires the pixel's Lead on the wpcf7mailsent DOM event; the server sends a Lead from the mail hook; neither knows the other's ID. Generate an event_id in the browser when the form loads, put it in a hidden field, use it for the pixel call, and read the same value from the posted data on the server. Meta then keeps one of the two.
Send only the fields Meta's matching uses (hashed email, phone, name) and never the free-text message box. On a medical, legal or financial practice site, the message field is where visitors describe their situation, and it must not reach an ad platform. If the site belongs to a HIPAA-covered provider, get legal review before sending any Lead from a form on a page about a health service.
Contact Form 7 → Meta · what breaks
Why this join usually fails — Contact Form 7 → Meta
- 01
The fbc and fbp values never reaches Contact Form 7
There is no entries table to write to, so the identifier has to be captured into a hidden field and persisted by whatever you add for storage. Contact Form 7 submits over AJAX, so the page does not reload and anything expecting a navigation event never fires.
- 02
AJAX submission means no page load to hook
Setups that fire a conversion on thank-you-page load simply never fire. Setups that listen for the DOM event miss anyone whose script execution was blocked or deferred.
- 03
Double counting from broken deduplication
Server and browser both fire, the event_id does not match, and Meta counts two purchases. Reported ROAS goes up, the business does not, and it can run for months before anyone reconciles against the store.
- 04
Nothing reconciles afterwards
Events Manager shows received events, the deduplication state and an Event Match Quality score per event. Events arriving is not the test — deduplicated, well-matched events arriving is. Compare Meta's reported purchases against your store's order count for the same window.
Contact Form 7 → Meta · the fix
What working looks like — Contact Form 7 → Meta
The fbc and fbp values on every submission
Conversions arriving in Meta
Events appear in Events Manager with an Event Match Quality score, deduplicated against the pixel, and become usable for optimization and attribution.
Reconciled against the source
Contact Form 7 → Meta · architecture
How Contact Form 7 and Meta actually connect
- 1
Contact Form 7 holds the truth
Out of the box Contact Form 7 emails the submission and keeps no record. Before any attribution work is meaningful, submissions have to be stored somewhere queryable. That is step one and it is not optional.
- 2
Meta Conversions API needs a click to match
Meta matches server events to people using whatever identifiers you send, hashed with SHA-256 where required. There is no single mandatory key, which is why quality varies so much between implementations — a poorly matched event is accepted, reported, and worth much less than it appears.
- 3
The identifier is the bridge
The fbc and fbp values, captured at the visit and carried into the Contact Form 7 submission.
- 4
The event source decides reliability
Fire server-side from PHP. The browser-side wpcf7mailsent DOM event exists and is commonly used, but it depends on the visitor's browser executing correctly and on the AJAX response arriving — the server hook does not.
- 5
Deduplication at the destination
Meta deduplicates on the pair of event_name and event_id. The browser pixel and the server event must send the same event_id for the same conversion, within the deduplication window. Get this wrong and every purchase counts twice — which is by far the most common Conversions API failure and it inflates reported ROAS rather than reducing it.
Contact Form 7 → Meta · normal or broken
Working vs. broken, side by side — Contact Form 7 → Meta
Normal, not a fault
The fbc and fbp values present on the submission
Sent from the wpcf7_mail_sent hook
Deduplicated correctly
Meta deduplicates on the pair of event_name and event_id. The browser pixel and the server event must send the same event_id for the same conversion, within the deduplication window. Get this wrong and every purchase counts twice — which is by far the most common Conversions API failure and it inflates reported ROAS rather than reducing it.
Reconciles with the source
Actually broken
The fbc and fbp values missing on most records
There is no entries table to write to, so the identifier has to be captured into a hidden field and persisted by whatever you add for storage. Contact Form 7 submits over AJAX, so the page does not reload and anything expecting a navigation event never fires.
Sent from the browser
Setups that fire a conversion on thank-you-page load simply never fire. Setups that listen for the DOM event miss anyone whose script execution was blocked or deferred.
Counted twice, or not at all
Server and browser both fire, the event_id does not match, and Meta counts two purchases. Reported ROAS goes up, the business does not, and it can run for months before anyone reconciles against the store.
Nobody has reconciled it
Contact Form 7 → Meta · diagnose
Diagnostic order — Contact Form 7 → Meta
- 01
Count submissions carrying the fbc and fbp values
- 02
Follow one real conversion end to end
- 03
Confirm submissions are being stored at all
If the only record is an email inbox, there is nothing to reconcile and no way to prove any number. Fix storage before touching attribution.
- 04
Read Event Match Quality and the deduplication indicator
In Events Manager, open the event and check both. A low match quality means weak identifiers; a missing deduplication indicator means your event_id pairing is broken.
- 05
Read the match rate, not the success message
Events Manager shows received events, the deduplication state and an Event Match Quality score per event. Events arriving is not the test — deduplicated, well-matched events arriving is. Compare Meta's reported purchases against your store's order count for the same window.
Contact Form 7 → Meta · prove
How it gets proven — Contact Form 7 → Meta
Source of truth
Whatever you configure to persist submissions — an entries plugin, or your own database table. By default there is nothing to reconcile against.
- The fbc and fbp values confirmed present on a live submission.
- Deduplication confirmed in Events Manager on a real purchase, with the browser and server events visibly paired rather than counted twice.
- Stored submissions confirmed to match the email record for the same period, before any attribution claim is made.
Contact Form 7 → Meta · free audit
What we check in the free audit
- Count submissions carrying the fbc and fbp values
- Follow one real conversion end to end
- Confirm submissions are being stored at all
- Read Event Match Quality and the deduplication indicator
- Read the match rate, not the success message
Checked against
Whatever you configure to persist submissions — an entries plugin, or your own database table. By default there is nothing to reconcile against.
Free30 minutesNo obligation
Contact Form 7 → Meta · when not to buy
When you don't need this — Contact Form 7 → Meta
- Measure identifier coverage yourself first — pull your last hundred submissions and count how many carry the fbc and fbp values.
- If you are on Contact Form 7 and serious about attribution, moving to a form plugin that stores entries is often cheaper than working around the one that does not. We will say so rather than bill for the workaround.
- If you are not running Meta ads at meaningful spend, the Conversions API is effort without payoff. It earns its cost when the optimization signal is worth improving.
Contact Form 7 → Meta · what we deliver
What gets built — Contact Form 7 → Meta
Identifier capture into Contact Form 7
Hidden field populated from a first-party cookie, plus a storage layer so the submission and its identifier survive past the email. The wpcf7_before_send_mail hook is where both happen.
Event source: the wpcf7_mail_sent hook
Fire server-side from PHP. The browser-side wpcf7mailsent DOM event exists and is commonly used, but it depends on the visitor's browser executing correctly and on the AJAX response arriving — the server hook does not.
Dispatch to Meta
Server-side events to the Conversions API with the event_id matched to the pixel, action_source set correctly, and customer data hashed before it leaves your infrastructure.
Reversals where they exist
Nothing to reverse. Spam filtering before the send is the equivalent concern.
Written guarantee
95%+ tracking accuracy
Measured against Whatever you configure to persist submissions — an entries plugin, or your own database table. By default there is nothing to reconcile against.. Miss it and we keep working at no cost.
From $400 · See packages
FAQ
Contact Form 7 → Meta questions, answered
Not natively; CF7 has no Meta integration of its own. You send the Lead from a PHP hook on submission or through a server-side GTM container, with a matching event_id from the browser pixel.
The pixel on wpcf7mailsent and the server event are both sending Lead without the same event_id. Pass one ID through a hidden field and use it on both.
Almost always because the fbc and fbp values never reached the Contact Form 7 submission. There is no entries table to write to, so the identifier has to be captured into a hidden field and persisted by whatever you add for storage. Contact Form 7 submits over AJAX, so the page does not reload and anything expecting a navigation event never fires. Measure coverage before debugging the dispatch.
Two things. The _fbc cookie, derived from the fbclid parameter on the landing URL in the format fb.1.<timestamp>.<fbclid>, is the click identifier. The _fbp cookie is the browser identifier. Beyond those, Meta matches on hashed customer information — email, phone, name, city, country — and every additional field raises the Event Match Quality score. Unlike Google, Meta does not need a click ID at all if the customer data is good, but match quality drops noticeably without it.
The wpcf7_mail_sent hook. Fire server-side from PHP. The browser-side wpcf7mailsent DOM event exists and is commonly used, but it depends on the visitor's browser executing correctly and on the AJAX response arriving — the server hook does not.
Events Manager shows received events, the deduplication state and an Event Match Quality score per event. Events arriving is not the test — deduplicated, well-matched events arriving is. Compare Meta's reported purchases against your store's order count for the same window.
More on Contact Form 7 → Meta
- Contact Form 7 + Meta CAPIMeta Conversions API setup for Contact Form 7
- Contact Form 7 → GA4Connecting Contact Form 7 to GA4
- Contact Form 7 → Google AdsConnecting Contact Form 7 to Google Ads
RELATED GUIDES
Where Contact Form 7 → Meta fits in the rest of your tracking
- Meta · Home servicesMeta Ads conversion tracking for home service businesses
- Meta · Law firmsMeta Ads conversion tracking for law firms
- Meta × CRM DealsHow to reconcile Meta Ads against your CRM's closed-won deals
- Meta · Lead magnet → saleHow to track lead magnet to sale for Meta Ads
- Cognito Forms → MetaConnecting Cognito Forms to Meta Conversions API
- Contact Form 7 → X AdsConnecting Contact Form 7 to X Ads
- Law firmsConversion tracking for law firms, without sending case details anywhere
- Formstack → MetaConnecting Formstack to Meta Conversions API
Free · 30 min
Get Contact Form 7 and Meta joined properly
Free30 minutesNo obligation
