Headless WordPress Consent: The Banner Works, the API Ignores It
The headless pitch is clean: WordPress manages content, a modern frontend renders it, APIs feed everything else. Consent fits awkwardly into that picture. The banner lives in the frontend. The cookie lives in the browser. The API, the mobile app, the email platform and the personalisation service live somewhere else entirely, making decisions about the same visitor with no idea a choice was ever made.
This is how organisations end up honestly reporting that consent is respected on the website while a refused visitor is personalised, tracked and emailed through three other pipes. Nobody lied. Nobody integrated. The architecture had a gap exactly where the consent signal needed to cross.
Map every consumer of the data
List what receives WordPress or visitor linked data: the frontend itself, mobile apps calling the same APIs, newsletter and CRM syncs, analytics exports, recommendation engines, ad platforms receiving server side events. For each one, answer a single question in writing: how does this consumer learn that a given visitor refused, and what does it then suppress.
The answers will sort into three piles: consumers that check consent, consumers that assume it, and consumers nobody had thought about since launch. The third pile is the audit finding. Server side event forwarding is a frequent resident, quietly sending conversions to ad platforms for visitors whose browser side tags were correctly blocked.
Carry consent state as data, not as a cookie hope
A cookie read by one frontend is not a consent system. Store the choice against the user record where accounts exist, expose consent state through the API with the content, and require downstream consumers to check it before processing. For anonymous visitors, pass the consent state with any event or sync the moment it is generated, or do not generate it.
Version the state like the banners do: purposes, timestamp, policy version. An API that returns a single boolean consented field has already thrown away the granularity the visitor was offered, and granularity was the legal basis for half the processing downstream. Booleans are where purpose limitation goes to die.
WordPress plugins assume a monolith
Most WordPress consent plugins were built for a world where the same PHP process renders the page and can block a script by dequeueing it. In a headless build they can set a cookie and render a banner through the frontend, but they cannot reach into your app, your API responses, or your server side tagging, because those are no longer WordPress at all.
Evaluate plugins on their API surface, not their banner gallery: webhooks or events on consent change, a documented way to query state server side, and storage you can sync. If the plugin cannot announce a refusal to the rest of your stack, it is a banner with a database, and the remaining integration is yours to build.
Test as a refused visitor, end to end
Create the test that matters: a fresh profile, refuse everything, then walk the whole estate. Browse the site, trigger the app flows you can, sign up for the newsletter, and afterwards inspect what the CRM, the analytics and the ad platforms received. Every artefact that exists about that test visitor is a sentence in your real consent story.
Repeat it after major releases, because headless stacks change at the seams, and the seams are where consent signals cross. The banner will look identical the whole time. Banners always do. The truth of a consent programme lives in the systems the visitor never sees.
Related reading
These earlier guides go deeper on connected questions: Global Privacy Control on a Small Site: Honouring the Signal Without a Legal Department, Consent at the WooCommerce Checkout: Pixels, Payment, and the Order Bump Problem, and Consent for WordPress Contact Forms: The Checkbox Is Not the Whole Job.
Frequently asked questions
Why does headless WordPress break consent handling?
Because consent plugins assume WordPress renders the page and can block scripts directly. In a headless build, rendering, apps and data flows live outside WordPress, so a choice stored as a browser cookie never reaches APIs, mobile apps or server side tools unless you deliberately propagate consent state to each consumer.
What should consent state include when sent through an API?
The purposes granted or refused, the timestamp, and the policy or banner version, attached to the user or passed with each event. A single yes or no boolean loses the granularity the visitor chose and cannot support purpose specific processing downstream. Store it against the account where one exists.
Do server side events need consent checks?
Yes. Server side tagging and conversion forwarding bypass browser controls entirely, so they will happily send data about visitors who refused, unless the server checks consent state before sending. This is one of the most common and least visible consent failures in modern stacks.
How often should headless consent flows be retested?
After any release touching the frontend, API, tag server or CRM sync, and on a regular audit cycle regardless. The failure mode is silent drift at integration seams. A refused visitor end to end test, checking what downstream systems actually received, is the only test that catches it reliably.