Diese Seite gibt es auch auf Deutsch.Zur deutschen Version
Skip to content

Setup · Guide

Setting Up Meta Ads Correctly: Pixel, Conversions API & Catalogue for Shopify and Shopware

The complete guide to the Pixel, Conversions API, server-side tracking and product catalogue on Shopify and Shopware – with apps, plugins, consent and the mistakes that burn budget.

By Boaz Lichtenstein Prefer us on Google

Cover image: Setting Up Meta Ads Correctly: Pixel, Conversions API & Catalogue for Shopify and Shopware

Before you put a single euro into Meta Ads, your setup decides whether that budget can work profitably. The best algorithm in the world only optimises as well as the signals it receives – and Meta’s delivery is now so signal-driven that poor data quality doesn’t just distort reporting, it degrades the delivery itself.

This guide is the long version: every route to server-side tracking compared, step by step for Shopify and Shopware, concrete apps and plugins with prices, consent requirements, and a catalogue of the mistakes we keep finding in account checks.

Two things up front, because they are time-critical:

  • On 13 January 2026 Shopify changed the default data-sharing setting for app pixels from “Always on” to “Optimized”. Sharing is paused when Shopify sees no signal from a pixel over a longer period. That needs to be actively reset – see below.
  • Shops without Shopify Plus lose checkout.liquid and “Additional Scripts” on the thank-you and order status page on 26 August 2026. Plus shops were affected on 28 August 2025. If your Purchase tracking still lives there, you lose it on that day.

What changed in 2025 and 2026

If you are following an older setup guide, these points are most likely out of date:

  • The “Pixel” has become a “Dataset”. In Events Manager the Pixel is now one data source inside a Dataset, alongside server, app, offline and messaging events. The ID is the same: your Pixel ID is your Dataset ID. The Pixel itself is not deprecated – fbq works unchanged.
  • There is a one-click CAPI. Since April 2026 you can activate a server-side connection in Events Manager with no server and no developer (“Meta-enabled Conversions API”). Alongside it came an AI enrichment that automatically attaches product and page data to events – and which is enabled for existing ad accounts on an opt-out basis, not opt-in. Check Events Manager to see whether it is running for you.
  • The 8-event limit from Aggregated Event Measurement has disappeared from the interface. There is no manual event prioritisation any more and no domain verification as a prerequisite for it. The mechanism still runs in the background, but advice along the lines of “prioritise your eight events” is moot.
  • The “cookieless future” rationale no longer holds. Google confirmed in April 2025 that Chrome keeps third-party cookies. The real drivers for server-side tracking are different: Safari’s cookie limits, ad blockers, consent loss – and the signal quality Meta’s delivery system needs (see Meta Andromeda).
  • Graph API v25.0 has been current since 18 February 2026. If you build directly against the API you have to move versions several times a year; if you use a plugin, check whether it makes the version configurable.

The four building blocks of a clean setup

Most guides name three. The fourth is not an appendix but part of the setup – without it the whole construction is exposed.

  1. Meta Pixel – captures actions in the browser: page view, ViewContent, AddToCart, InitiateCheckout, Purchase.
  2. Conversions API (CAPI) – reports the same events server-side, independent of the browser. It is not a replacement for the Pixel but the second source.
  3. Product catalogue / feed – the data basis for Advantage+ Shopping, dynamic retargeting and catalogue ads.
  4. Consent – permission that actually works technically. Not a banner that merely stores a tick while the Pixel has long since fired.

Pixel and CAPI have to be cleanly deduplicated. Otherwise Meta counts purchases twice, your ROAS report is worthless and – worse – optimisation runs on the wrong numbers.

Which route fits you?

There is no single correct setup, only one that fits your shop size, developer capacity and number of channels. The rough mapping:

Your situation Recommendation
Shopify, under 500 orders/month, no dev capacity Native integration on “Enhanced”
Shop with no CAPI via platform or app Meta-enabled CAPI (one click)
Shopify, growing, only Meta matters Third-party app
Shopify, several channels (Meta, GA4, TikTok) Server-side GTM
Shopify headless / Hydrogen Custom build, no way around it
Shopware self-hosted Plugin with CAPI
Shopware Cloud (SaaS) App or your own server container
Enterprise, CRM and offline data involved Signals Gateway or a CDP

The five ways to send server-side to Meta

This is the core of the guide. The routes differ less in the result than in effort, cost, and how much control you keep over the data being sent.

Route Effort Running cost Control Own server
Meta-enabled CAPI (one click) Minutes none none no
Platform integration ~1 hour €0–10 low no
Third-party app 1–3 hours €9–50 medium no
Server-side GTM 1–3 days €20–90 high yes
CAPI / Signals Gateway ~1 day cloud cost high yes

1. Meta-enabled CAPI – the one-click route

Since April 2026 Meta will set the server-side connection up itself on request: inside Events Manager, free, no server, no developer. Meta mirrors the events and parameters the Pixel already sends, and deduplicates automatically.

You should know the limits before filing this as solved. It covers web events only – app, offline and CRM data still need a real integration. And it is not configurable: you can select neither events nor parameters. Meta operates the pipe, not you.

Whether this route is ad-blocker resistant is often claimed but remains open. If the collection point stays the browser Pixel, a Meta-operated mirror cannot recover events the browser never sent. Meta does not document the mechanism – don’t rely on it.

Important before you switch it on: this route is meant for shops that have no server-side connection yet. If your platform or app already runs a CAPI – on Shopify that means data sharing set to “Enhanced” or “Maximum” – you end up with two server sources feeding the same dataset. Why that ruins your numbers is covered further down under “The most important warning”. So check in Events Manager first what already arrives server-side today.

Suitable for: small and mid-sized shops with no CAPI at all. The jump from having no server-side connection to having this one is considerably bigger than the jump from here to a perfectly engineered custom solution.

2. Platform integration

The Shopify sales channel or a Shopware plugin. Fast, cheap, sufficient for the standard case – details in the two platform chapters below.

3. Third-party app or plugin

The pragmatic middle route and, for most growing shops, the right answer: multiple pixels, configurable parameters, selectable dedup method, often an event log for debugging. Costs €9–50 a month and one to three hours of setup. Concrete recommendations further down.

4. Server-side GTM

Your own server container that accepts events on your own domain and distributes them from there to Meta, GA4, TikTok and whatever else is needed. The most demanding but cleanest route when several channels are in play: one pipeline instead of five snippets.

Two decisions determine whether the effort pays off.

First: which CAPI tag. There are two to choose from. Meta maintains its own tag template (ConversionsAPI-Tag-for-GoogleTagManager, currently on Graph v25). Alongside it there is the tag from Stape, which offers more control over event mapping – for instance translating GA4 names such as purchase into Purchase automatically. Both work reliably; the Stape tag is more widespread in agency hands.

Second: the domain. This is where the benefit is won or given away. Google’s recommendation is unambiguous – best is a path on the main domain (www.yourshop.com/metrics), second choice a subdomain. Stay on the default *.run.app domain and the container can only set JavaScript cookies, which means Safari’s 7-day cap still applies. You have then paid for server-side tagging without getting the main benefit.

The type of DNS mapping matters too: a subdomain pointed at a third party via CNAME falls under Safari’s countermeasures and is capped as well. Use a same-origin path or a subdomain resolved via A/AAAA record, and set _fbp and _fbc server-side as HTTP cookies.

5. CAPI Gateway and Signals Gateway

Meta’s own stacks – and a common misunderstanding: they do not run at Meta but in your AWS or GCP account. Meta charges nothing for them; you pay the cloud resources.

The actual advantage of the CAPI Gateway is a technical one: it generates the event_id itself and propagates it to both channels. That makes deduplication correct by construction – precisely the point where hand-built setups most often fail.

One capacity trap worth knowing before your first big campaign: default throughput is 1,000 requests per second on AWS EKS, but only 100 requests per second on App Runner and GCP GKE. A Black Friday peak on a 100 rps instance drops events. The value can be raised in the admin interface – beforehand, not during.

Signals Gateway is not a new name for the same thing but the broader product: multiple sources (web, app, CRM, offline) and multiple destinations, not just Meta. Relevant when offline and CRM data are involved. For a pure web shop it is oversized.

Shopify – step by step

Base setup

  1. Install the Facebook & Instagram channel (by Meta) from the App Store.
  2. Connect your business portfolio. Important: the portfolio you select here must be the owner of the Facebook page. This is the most common stumbling block in onboarding.
  3. Set data sharing under Sales channels → Facebook & Instagram → Settings → Data sharing.
  4. Connect the product catalogue – Shopify continuously syncs products, prices, availability and images.
  5. Check in Events Manager that events arrive, and that they arrive via browser and server.

The three data-sharing tiers mean:

Tier What happens
Standard Browser pixel only, blockable by ad blockers
Enhanced Pixel + Conversions API, plus customer data
Maximum Like Enhanced, plus “latest advertising technology”

What Shopify means by “latest advertising technology” on Maximum is documented nowhere. For practical purposes: the solid jump is between Standard and Enhanced – that is where the Conversions API arrives. Whether Maximum adds anything beyond that cannot be verified from the outside.

The channel captures seven events automatically: PageView, ViewContent, Search, AddToCart, InitiateCheckout, AddPaymentInfo and Purchase. Of those, at least the Purchase demonstrably goes out server-side. Which further events actually travel via the CAPI is contradictory across sources – check it for your shop in Events Manager rather than assuming.

The step almost everyone misses in 2026

Since 13 January 2026 app pixels default to “Optimized”: Shopify pauses data sharing when it sees no signal from a pixel over days or weeks. It is intended as a clean-up mechanism for forgotten apps – but it hits active setups too.

Change it under Settings → Customer events, open the affected app pixel, set the mode to “Always on”, save. Since June 2026 there is also an activity log there showing whether and when sharing was paused.

Two clarifications: pure analytics pixels are exempt and stay active. And server-side tracking is not affected by this change – so anyone running the CAPI correctly does not lose the Purchase. That is a good argument for the second source.

Understanding the Web Pixels API

Shopify has been running pixels in a sandbox for some years, and that explains a whole class of problems. Inside the sandbox there is no access to the top frame, no DOM scraping, and therefore no reading email addresses out of the page content.

There are two kinds: app pixels are installed by apps, declare their consent requirements and run in the strict sandbox. Custom pixels you add yourself in the admin – explicitly marked by Shopify as unsupported, with a somewhat looser sandbox.

From this follows the most important practical note for Shopify: “Meta Pixel via GTM” reliably produces poor matching here. A standard tag in the web container cannot read the shop’s real _fbp and _fbc cookies, because it cannot reach them from the sandbox. Automatic Advanced Matching does not work either. Anyone going via GTM has to pass those values through manually – or better, use an app or app pixel built for this environment.

Deadline 26 August 2026

The old routes are switched off or will be:

Affected What ends Date
Plus checkout.liquid + Additional Scripts on thank-you/status page 28.08.2025
Everyone else Additional Scripts on thank-you/status page 26.08.2026

The replacement in both cases is Settings → Customer events. Shopify’s own order of preference: first look for an app that serves the purpose, and only build a custom pixel if none exists.

Headless, Hydrogen, Oxygen

A clear answer: app pixels do not run there. The Web Pixel Manager is not active in Hydrogen storefronts, app pixels are not included automatically, and Shopify has given no date for it. For headless setups that means implementing the Pixel and the CAPI yourself, on the same Dataset ID. Factor that into the decision for headless – it is a genuine cost item, not a detail.

Shopify enforces consent for pixels itself: in regions that require consent (EEA and UK), web pixels only run when the permissions the pixel declares in its configuration are present – by default marketing and analytics. If one is missing, Shopify does not load the pixel.

Technically this hangs on the Customer Privacy API. A pixel can only read consent and listen for changes (visitorConsentCollected), not set it. If you use an external CMP, the decisive question is: does it actually write to the Customer Privacy API – or does it merely hide scripts? Only the former has any effect.

The point to take away here: the CAPI is not covered by this gate. It fires from the server regardless of what the browser decided, as long as your CAPI tool is not consent-aware itself. Get your app vendor to confirm in writing how it handles missing consent.

Shopware – step by step

Establish the version first

Version Status
6.7 Current, since 17.06.2025
6.6 Extended support
6.5 Security support until 28.02.2027
5.x EOL since July 2024

You do not build a new tracking setup on Shopware 5. There are still maintained pixel plugins for it, but without security fixes in the core that is a migration question, not a setup question.

For Shopware 6 two more things matter: with 6.5 jQuery left the storefront – old pixel snippets using $(...) break there. And 6.7 rebuilt the cookie system (more on that below).

Cloud or self-hosted – the decisive difference

This question determines which options are open to you at all: in Shopware Cloud (SaaS) there are no classic plugins and no custom PHP code. Only apps flagged as cloud-capable can be installed. Apps may bring templates, JavaScript and cookies – but cannot execute PHP inside the shop.

For server-side tracking that leaves exactly three routes in the cloud:

  1. An app whose vendor operates the server – the CAPI calls then run on their infrastructure.
  2. Your own sGTM or gateway container on your own infrastructure, independent of shop hosting.
  3. Your own middleware, fed by app webhooks (e.g. “order placed”). This is the clean cloud route when developer capacity is available.

In all three cases an additional processor enters the picture – that belongs in your record of processing activities before it goes live.

Setting up the plugin

  1. Install a vetted Meta plugin with CAPI (selection below).
  2. Enter the Pixel ID (= Dataset ID) and a CAPI access token from Events Manager. Use a system user for the token, not a personal account.
  3. Set the dedup method to event_id + event_name if the plugin gives you the choice. That is the more robust of the two methods.
  4. Check the Graph API version and set it to something current.
  5. Define the content ID source – the setting that later saves or breaks the catalogue. More on that shortly.

Shopware ships its own cookie consent with four groups: technically required, comfort features, marketing, statistics and tracking. The decision lands in the cookie-preference cookie. An additional cookie-config-hash forces renewed consent as soon as the cookie set changes – handy, but easily overlooked when every banner suddenly reappears after a plugin update.

The part that surprises most people: the native tool does not block scripts. It only stores and distributes the preference. Whether a pixel actually waits for consent is up to the individual plugin – which is why the “privacy modes” in the plugin settings are not cosmetic but the actual implementation.

For Shopware 6.7 there is a technical rebuild on top: cookies are now registered via the CookieGroupCollectEvent event; decorating CookieProviderInterface no longer works. Plugins that have not followed suit no longer appear in the banner – and may therefore fire without being asked.

If you use an external CMP (Usercentrics, Cookiebot, CCM19, consentmanager, Klaro), one rule applies: switch the pixel plugin to “external CMP” or manual JavaScript. Leaving both active in parallel – native consent and CMP callback – gets you either double-firing events or none at all.

Exporting the product feed

Shopware handles this through the Product comparison sales channel:

  1. Create the sales channel, set domain, currency, language and customer group.
  2. Use a dynamic product group to define which products belong in the feed.
  3. The Twig template determines how it is exported – CSV or XML.
  4. Enable “include variants” if you advertise variants.
  5. Set the generation interval and run it via the scheduler (which has to be actually running).
  6. The export URL is secured with an access ID and key – that URL is what you enter at Meta as the feed source.

Two things that cost you time if you don’t know them. Whether the template dropdown in your version holds a ready-made Facebook template is version-dependent and reported inconsistently across sources – look in the shop, and if there is none, derive it from the Google Shopping template. And: there is no native snippet for item_group_id. You have to build that yourself, usually from the parent product’s product number.

The catalogue: content IDs are the most common breaking point

Meta’s mandatory catalogue fields are manageable: id, title, description, availability, condition, price (number plus ISO 4217 code), link, image_link, brand. For variants item_group_id is added – the same value across all variants of a product.

The sentence everything hinges on in practice is in Meta’s own docs, and it concerns the id field: for dynamic ads, an item’s id in the feed must match the content ID of the same item in your Pixel exactly. item_group_id only groups variants and is not affected by this.

That is where it breaks over and over. Typical patterns: the Pixel sends an internal UUID while the feed exports the product number. Or the Pixel reports the parent product while the feed exports variants. Or the only difference is upper and lower case.

The rule that fixes this permanently:

  • One identifier for both. On Shopware, product.productNumber is the pragmatic choice.
  • Set content_type correctly: product for single items, product_group for variant parents.
  • Rather than content_ids alone, send contents – with id, quantity and item_price. Only that makes value-based signals at item level possible.
  • If your pixel plugin only knows parent products, export the feed at parent level too. Consistency beats granularity.

You can verify this in Events Manager under “Test events” and via the catalogue diagnostics in Commerce Manager, which flags mismatches explicitly.

When the shop export stops being enough

Everything described so far works with your shop’s native export. That holds as long as you feed one channel in one market. As soon as Google Shopping, Pinterest or marketplaces join in, several countries are involved, or variants have to be grouped cleanly, one feed becomes a set of feeds with differing requirements – and each becomes its own maintenance point.

From there a feed management tool takes over the layer between shop and channel: one normalised data base, a separate output per channel with its own rules, plus quality checks that catch rejections before the channel reports them. In European ecommerce, Channable is the most widespread option here; above it sit platforms like Productsup and managed services like Feedonomics.

Which tier makes sense when, what Channable actually does and where it stops is covered in the feed management guide. For the content ID question from this chapter, one thing holds: a feed tool makes the feed side controllable, the Pixel side remains your shop setup. Both have to point at the same identifier.

Deduplication – how it actually works

Meta knows two methods, and the difference matters in practice.

Method 1 (recommended): two values have to line up – the ID (eventID in the browser, event_id on the server) and the event name (event in the browser, event_name on the server). If only one of them matches, Meta does not deduplicate.

Method 2 (fallback): event_name plus fbp and/or external_id. Weaker, because it depends on the browser event arriving first.

Three things that are almost always told wrongly:

  • The window is 48 hours, counted from when the first event with that event_id is received. The “7 days” doing the rounds is something else: that is how far event_time may lie in the past.
  • Deduplication does not use identity. No email, no phone number, no IP. Only event_name plus a key.
  • Browser-only or server-only setups are not deduplicated at all. Anyone deliberately going server-only has to actually switch the Pixel event off – ignoring it is not enough.

The practical core: generate the ID once, server-side, from something stable, and pass it to the browser.

event_id = "purchase_" + order number

That way a reload of the thank-you page is the same event – not a second purchase. A namespace prefix (purchase_) additionally prevents a later CRM or offline event about the same order from colliding on the same ID.

Measuring signal quality

A setup is not finished when it fires, but when the data is right. Three things you check directly in Events Manager: Event Match Quality, the deduplication rate and the catalogue diagnostics. The last two are quick – the dataset shows the dedup rate under each event, and catalogue diagnostics sit in Commerce Manager and flag rejected items. It is the first value that needs explaining.

Event Match Quality is scored out of 10, and per event type, not once for the whole dataset. Meta publishes no official thresholds. From our practice: below 6 needs action, 7 is workable, on Purchase 8+ is the target.

Sorted by leverage, these parameters do the most:

  1. Hashed email address – the strongest single parameter.
  2. Hashed phone number – almost equivalent at checkout.
  3. external_id – stable, on every event, doubles as a dedup key.
  4. fbc – the click identifier from the ad. The biggest lever on ad traffic and at the same time the value most often missing server-side.
  5. fbp – browser continuity.
  6. IP address and user agent – only useful together, near worthless alone.
  7. Name, city, state, postcode, country – fine tuning.

Worth knowing: events whose only signals are weak combinations such as city, country, postcode, gender and user agent are explicitly rejected by Meta for matching purposes.

For agencies and larger setups the Dataset Quality API is worth it. It delivers more than the interface and can be queried across multiple accounts:

Metric What it shows
Event Match Quality Matching quality per event
Additional Conversions Reported Extra conversions thanks to CAPI
Event Coverage Share of Pixel events with a CAPI counterpart
Deduplication Feedback Share of events carrying a dedup key
Data Freshness Delay between event and receipt

Data freshness is why a nightly cron job is a bad idea: Meta treats the delay as a quality signal and expects events promptly, ideally within an hour.

Getting hashing and identifiers right

Anyone building directly against the API or auditing a setup needs these rules. Customer data goes out as SHA-256, hexadecimal, lower case – and normalisation happens before hashing. This is where the most damage happens quietly: two differently normalised spellings produce two hashes and therefore two people.

Field Normalisation
em Strip spaces, lower case
ph Digits only, with country code, no leading zero
ct Lower case, no spaces (munich)
zp Lower case, no spaces or dashes
country ISO 3166-1 alpha-2, lower case (de)
db YYYYMMDD

So a German mobile number goes from 0151 / 234 567 89 to 4915123456789, and is then hashed.

Never hashed: client_ip_address, client_user_agent, fbp, fbc. Hashing those destroys matching silently – the events arrive, they just don’t match.

The _fbc value is assembled from the click parameter:

_fbc = fb.1.<timestamp in milliseconds>.<fbclid>

Three details that are regularly implemented wrongly: the timestamp is in milliseconds, not seconds. The 1 in the pattern is the subdomain index – building server-side with no cookie present, 1 is the correct value. And the cookie lasts 90 days – set it server-side and only overwrite it when no value exists or the fbclid has changed.

For the external_id the rule is: one stable value per person, hashed, on every event, from browser and server, logged in or not. For guests, a long-lived first-party value from the server. What you must not do is rotate it per session – then it is worthless for matching and for deduplication.

Apps and plugins compared

A word on positioning before the tables: what follows is the tracking layer – the tools that hand events to Meta. It is the cheapest layer of a setup, and it says nothing about how professionally the rest is built. The data side – product data, feeds, channels – is a discipline of its own with its own classes of tooling all the way up to enterprise platforms; see the feed management guide for that. And the server layer scales through the five routes above, from the one-click variant to your own container.

A €10 app is therefore not a poverty statement but a statement about exactly one layer. A cleanly built setup with a server container, Channable on the feed and a lean app for the Pixel connection is more common than one expensive tool trying to be everything at once.

All figures as of July 2026 – prices and compatibilities change, verify before buying. I have deliberately left out ratings; they go stale fastest.

For Shopify

App CAPI Price/month What for
Omega Facebook Pixel & Feed yes $0–46 Solid all-rounder, free tier to test
Trackify yes $0–29 Multiple pixels, cheap
Conversios Multi Pixel & CAPI yes $0–9 Cheapest entry point
Blotout EdgeTag yes from $50 First-party focus
Analyzify yes from $145 Analytics platform
Littledata yes from $199 Analytics + Segment
Elevar yes from $225 Analytics, enterprise
Stape indirect app free Only with your own sGTM container

For context: Elevar, Littledata and Analyzify are analytics platforms first and CAPI tools second. They pay off when you need cross-channel attribution and a clean data layer – not when events just have to reach Meta. For the pure Meta case, Omega or Conversios solve the same job, and the money is better invested in the feed or the server container.

And a detail about Stape that the app listing does not state: the app itself is free but useless without your own server container. That is a separate subscription. Factor it in, or the calculation is wrong.

For Shopware

Plugin Shopware CAPI Price
mediameets Meta Pixel & CAPI 6.4–6.7 yes ~€10/mo or ~€95/yr
Biloba IT Meta Pixel & CAPI 6.1–6.7 yes ~€10/mo or ~€99/yr
ACRIS Meta Pixel & CAPI 6.6–6.7 yes ~€10/mo or ~€99/yr
Biloba Multitracking Pro 6.7 yes Free base + per channel
Stape Conversion Tracking 6.6.x only indirect Free + container

The Biloba plugin ships a CAPI event log, which saves a lot of time when debugging. Multitracking Pro pays off when TikTok, Pinterest or Reddit join Meta – free base, each channel added individually.

Careful with cloud variants: the table above lists plugins for self-hosted shops. Several vendors also offer a cloud-capable app under a very similar name – and that one may be pixel-only without CAPI. mediameets is a case in point: the plugin does the Conversions API, the cloud app does not list it among its features. If you are on the cloud, check the product description explicitly for “Conversions API” rather than inferring the feature set from the vendor name.

What to look for when choosing

Regardless of platform, these are the criteria that count in operation. Is the CAPI genuinely included? Can the dedup method be configured? Is the Graph API version selectable, or does the vendor pin it? Can you choose the content ID source – product number or UUID, parent or variant? Is there a real CMP integration and an event log?

The most important warning in this chapter

Never run two CAPI sources on the same Dataset ID.

If the native integration and an app both send server-side, each generates its own event_id values. They do not match, Meta cannot deduplicate – and counts every purchase twice. The result: inflated Purchase numbers, a ROAS report you cannot trust, and optimisation learning on the wrong values.

This is the most common genuine misconfiguration we find in account checks. If you move to an app: switch data sharing off in the native integration and use the channel only for the catalogue and shop connection.

Not legal advice, but the technical picture from project practice. Assessing your specific setup needs legal counsel.

§ 25 TDDDG requires consent before anything is stored on or read from the end device. For tracking cookies that means: beforehand, actively, not pre-ticked.

The most important misconception first: “server-side means consent-free” is wrong. Two independent reasons. First, _fbp and _fbc are still written to and read from the device – where the event is processed afterwards changes nothing about that. Second, transmitting personal data to Meta for advertising purposes needs a legal basis anyway, and for cross-context ad targeting that is in practice consent.

From this follows the technical consequence that is implemented far too rarely: because the CAPI runs server-side, browser consent does not stop it automatically. The gate has to sit where the sending happens – in the server container or the backend. A cookie banner that only blocks front-end scripts does not hold the CAPI back.

Three further clarifications:

  • Meta has no “Consent Mode”. The term comes from third parties. What exists is the command pair on the Pixel: fbq('consent', 'revoke') before init, and fbq('consent', 'grant') after consent. Before that the Pixel loads but sets no cookies and sends no events.
  • Limited Data Use (LDU) is not a GDPR tool. The flag is built for individual US states. The correct behaviour on missing consent in the EU is not LDU but: send nothing at all.
  • Advanced Matching needs cover. Hashing is not anonymisation. The fields you transmit must be covered by the consent and named in your privacy policy.

And a classic from audits: unhashed personal data sent to Meta. Plain-text email addresses in the user_data object are technically accepted by Meta – legally you have created a transmission nobody covered. Normalisation and hashing belong on the server, not in the browser.

Pitfalls – what breaks real setups

Data

  • test_event_code in production. Everything lands in test events and never reaches reporting or optimisation. Put it behind an environment variable, never hard-code it.
  • value with a comma as decimal separator. 1.234,56 is not a number Meta can read. Full stop as the decimal separator, no thousands separators, currency as an ISO 4217 code.
  • event_time older than 7 days. Silently discarded. Timestamps in the future are a classic too – usually milliseconds instead of seconds, or a wrong time zone.
  • Wrong action_source. website for a CRM upload is simply untrue and affects attribution. And event_source_url is mandatory for web events.
  • Weak identifiers only. City, country, postcode and user agent alone are not enough – Meta discards such events for matching.

Duplicates

  • Two Pixel snippets on the page. Theme plus app plus GTM. That already doubles in the browser, and CAPI deduplication does not help against it.
  • event_id generated independently on client and server. Two random UUIDs never match. Generate once, pass it on.
  • event_name in the wrong case. purchase instead of Purchase. Case matters. With GA4 mapping, add_to_cart has to become AddToCart.
  • Purchase fires on a thank-you page reload. The fix is the event_id derived from the order number.
  • Retry runs after more than 48 hours. A retry job with the same event_id outside the window counts as a new conversion.

Infrastructure

  • sGTM on the default *.run.app domain. Sets JavaScript cookies only, so Safari’s 7-day cap applies – the main benefit is gone.
  • Custom domain via CNAME. Also falls under Safari’s countermeasures. Use a same-origin path or an A/AAAA subdomain and set the cookies server-side.
  • Checkout on a different domain. _fbp and _fbc do not carry across domain boundaries. Then external_id and hashed email are the only continuity – that has to be planned for, not discovered afterwards.
  • Poorly managed access tokens. System user rather than a personal token, and never in the web container or in client code.

Refunds – the blind spot

The Conversions API has no Refund event. Negative Purchase values and custom refund events do not appear in the standard views and do not move delivery.

This is not a detail but a structural limit: your Meta revenue is gross, your P&L is net. In categories with high cancellation or return rates that means, first, moving the net view into BI or GA4, and second, considering sending the Purchase on payment capture rather than on order creation.

Myths that cost you money

  • “Server-side is ad-blocker proof.” Only the second hop is. If the path from the browser to your collector is blocked, the event is gone. Genuinely immune are only pure server setups firing from the order webhook – no browser involved there.
  • “CAPI replaces the Pixel.” Deduplication needs two sources, and only the browser can mint fbp. Meta’s own recommendation is to run both redundantly.
  • “AEM limits us to 8 events.” Prioritisation and the limit have disappeared from the interface. Anyone still planning event prioritisation is working from an outdated playbook.
  • “Hashing makes the data anonymous.” It does not. A hash is a pseudonym, not an anonymisation technique.

Checklist

  • Pixel installed, firing on all relevant standard events
  • Conversions API active – on one route, not two
  • event_id generated server-side, identical in the browser
  • Deduplication rate checked in Events Manager
  • Event Match Quality above 7, on Purchase heading for 8
  • Hashed email and phone number are being transmitted
  • external_id stable, on every event
  • fbc captured from the click and set server-side
  • Shopify: app pixel on "Always on" instead of "Optimized"
  • Shopify: tracking migrated out of Additional Scripts (deadline 26.08.2026)
  • Shopware: plugin privacy mode matches the CMP in use
  • Catalogue synced, no rejected items
  • Content IDs of events and feed match exactly
  • Consent gate also applies server-side, not just in the front end
  • test_event_code removed in production

If you want to have your existing setup double-checked: that’s exactly what we do in the free account check – including three concrete quick wins. For a compact introduction to the topic, see the article on setting up the Meta Pixel and CAPI, and which events you should be optimising for at all is covered in the guide to optimisation goals. You can read how we manage Meta Ads overall on our page about the Meta Ads agency.

FAQ

Frequently asked questions

Do I absolutely need the Conversions API if I already have a Pixel?

Yes. Browser signals get lost – to ad blockers, to Safari's cookie limits, to missing consent. The Conversions API (CAPI) reports the same events server-side and closes that gap. Meta itself states that accounts with a CAPI setup for web events see on average 17.8% lower cost per result than accounts without. Important: CAPI does not replace the Pixel, it complements it – deduplication needs both sources.

Is the native Shopify integration enough for Meta?

For getting started, yes. The Facebook & Instagram channel sets up the Pixel, CAPI and catalogue at a basic level, and on the "Enhanced" or "Maximum" tier at least the Purchase goes out server-side. The limits: one Pixel ID only, no control over parameters, no Event Match Quality view inside the shop, and no support for headless storefronts. Anyone who needs multiple Pixels, custom parameters or EMQ above 8 moves to an app or their own server container.

Is it true that server-side tracking needs no consent?

No – this is the single most common misconception on the topic. Two reasons. First, the `_fbp` and `_fbc` cookies are still written to and read from the device, so § 25 TDDDG applies regardless of where the event is processed afterwards. Second, transmitting personal data to Meta for advertising purposes needs a legal basis anyway. In practice this means: because the CAPI runs server-side, browser consent does not stop it automatically. The gate has to sit in the server container or backend.

How long is Meta's deduplication window?

48 hours, counted from when the first event with a given `event_id` is received. The frequently quoted "7 days" is something else: that is how far `event_time` may lie in the past. Anyone sending events from a nightly or weekly batch and pairing them with real-time browser events blows the window – and Meta counts twice.

What is a realistic Event Match Quality score?

Meta publishes no official thresholds. From practice: below 6 needs action, 7 is workable, 8 or more on Purchase is the target. The biggest jump comes from hashed email address and phone number, then a stable `external_id` and the `fbc` value from the ad click. IP address and user agent alone are not enough – Meta rejects events whose only signals are weak combinations such as city, country, postcode and user agent.

Can I report refunds and cancellations back to Meta?

Practically no – the Conversions API has no Refund event. Negative Purchase values or custom refund events do not appear in the standard reports and do not move delivery. The consequence: your Meta revenue is gross, your P&L is net. Net figures belong in BI or GA4. With a high cancellation rate it pays to send the Purchase on payment capture rather than on order creation.

Free account check

We apply exactly this know-how to your setup – in 30 minutes we analyse your account and show you 3 concrete quick wins.