> ## Content Index
> Fetch the complete content index at: https://www.livain.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# My scheduled Meta CAPI consent audit found a missing cookie banner, not a tracking bug
- URL: https://www.livain.com/blog/my-scheduled-consent-audit-found-a-missing-cookie-banner/
- Published: 2026-09-07T07:00:00.000Z
- Updated: 2026-09-07T06:59:59.000Z
- Description: A weekly Claude Code routine flagged one market at 0% of orders reaching Meta. The consent banner had never rendered there at all — so the pixel fired on every visitor with no way to refuse.
- Author: Remco Livain
- Tags: Analytics, Privacy, Marketing Tech, E-commerce, AI Automation

One of my scheduled Claude Code routines runs a weekly Meta Conversions API consent audit across four storefronts — how many orders were billable, how many actually reached the ad platform, and why the rest didn't. It landed on Tuesday with a line that looked like a tracking bug. One market, one order, zero events reaching the ad platform. A hundred per cent of that market's revenue missing from the numbers the ads optimise on.

The obvious move is to go and fix the reporting pipeline. I have written that fix before. It takes an afternoon and it feels productive.

I went looking for why the event was skipped instead, and the answer turned out to be much worse than a broken pipeline.

### The skip was correct

The server only forwards a purchase to the ad platform if it can find a consent signal saying the customer agreed to it. In three of the four storefronts for this home and living brand, the report showed real refusals — a cookie recording that a human had looked at a banner and said no. That is the system working. Nothing to fix.

The fourth market showed something different. Not a refusal. Not a corrupted value. Nothing at all. No consent signal had ever reached the server, for any visitor, ever.

So I did what I have learned to do instead of reading the plugin list: I fingerprinted the HTML the site actually serves. The three healthy markets load a consent script, carry a couple of hundred references to the banner in their markup, and set a cookie the checkout can read. The fourth loads a stylesheet for a cookie banner and nothing else. No script. No banner markup. Not on the homepage, not on the cart. The only consent-related strings in the page were in our own snippet — code reading a cookie that nothing on that site was ever going to write.

The consent plugin was installed. It was listed as active. It rendered nothing. This is the same failure shape I keep meeting: [the thing is present and the thing is inert](https://www.livain.com/blog/no-login-to-the-tag-manager/), and the inventory can't tell the difference.

### The real finding was in the other direction

Here is the part that made me stop caring about the missing revenue figure.

If no banner renders, nobody is asked. And if nobody is asked, nothing blocks the scripts that a banner is supposed to gate. The base advertising pixel on that storefront was firing on every page load. The ad platform's tag was initialising unconditionally. The blocker that would normally hold them until consent arrives was part of the plugin that never ran.

So the store was not under-tracking its customers. It was tracking every single visitor in that country, with two large advertising platforms, with no banner on screen and no way to refuse. The pipeline that skipped the purchase event was the only part of the stack behaving lawfully.

> The report told me a market was invisible. What it had actually found was a market that could not say no.

That inverts the whole ticket. A missing conversion is a performance problem you schedule for next sprint. Setting tracking cookies without consent is the thing the Dutch regulator has been sending warning letters about — it [opened a large-scale inspection of cookie banners](https://www.autoriteitpersoonsgegevens.nl/actueel/ap-pakt-misleidende-cookiebanners-aan?ref=livain.com) after consumer complaints, and its position on tracking without free, informed, unambiguous consent is not ambiguous. Running *no* banner is not a clever way around a rule about banner design.

### Server-side is not a loophole

There is a persistent belief that moving conversion tracking to the server puts it outside the consent regime, because the browser is no longer the one talking to the platform. It doesn't. The platform's own [Conversions API documentation](https://developers.facebook.com/docs/marketing-api/conversions-api/?ref=livain.com) is a data-sharing interface, not an exemption; the identifiers you send are hashed customer data, and hashing is pseudonymisation, not anonymisation. Practitioners tracking the case law have [been flagging exactly this](https://flexyconsent.com/blog/meta-pixel-facebook-conversions-api-consent-guide/?ref=livain.com) as courts award damages for embedding those tools without a legal basis.

Which is why the one fix I refused to make was the fix that would have closed the ticket fastest. You can make the missing-events number go to zero this afternoon by sending the events regardless of consent. The report would look healthy. The ads would optimise better. And every one of those events would be a decision made on someone's behalf.

The skip stays. The banner gets built.

### What I actually changed about how I run these checks

Three things, and none of them are about consent specifically.

First, when an automated report flags a market, extend the window before you diagnose. Four storefronts with low order volume means every percentage in that report is a small-n number. One order at zero per cent looks catastrophic and means almost nothing on its own. The thirty-day view was what separated "genuine refusals, honoured correctly" from "no signal has ever existed here".

Second, distinguish an empty value from a negative one. A refusal and an absence look identical in a summary table and mean opposite things. I now record *why* an event was skipped, not just that it was — and that single extra field is what turned a vague gap into a one-hour diagnosis. It is the same discipline as [refusing to let a system fail silently](https://www.livain.com/blog/everything-returned-200/).

Third, and this is the one I keep relearning about agentic workflows: the routine found the problem, and then it stopped. It did not deploy a banner to a live store in a country it had never seen, because that changes what every visitor sees and carries legal weight. Automation is very good at noticing. It should be deliberately bad at acting on the things a person needs to decide — the same reason I [refused to ship a countdown that wasn't counting down to anything](https://www.livain.com/blog/the-design-asked-for-a-countdown/).

The report was built to protect ad performance. It found a compliance hole instead. That is not the report failing at its job. That is what happens when you point an honest instrument at a system nobody has looked at in a while.

### Sources & further reading

**External**  
[Autoriteit Persoonsgegevens — AP pakt misleidende cookiebanners aan](https://www.autoriteitpersoonsgegevens.nl/actueel/ap-pakt-misleidende-cookiebanners-aan?ref=livain.com)  
[Meta for Developers — Conversions API documentation](https://developers.facebook.com/docs/marketing-api/conversions-api/?ref=livain.com)  
[Meta Pixel and Conversions API: the GDPR and CCPA consent implementation guide](https://flexyconsent.com/blog/meta-pixel-facebook-conversions-api-consent-guide/?ref=livain.com)

**Related posts**  
[No login to the tag manager](https://www.livain.com/blog/no-login-to-the-tag-manager/)  
[Everything returned 200](https://www.livain.com/blog/everything-returned-200/)  
[The design asked for a countdown](https://www.livain.com/blog/the-design-asked-for-a-countdown/)