How Consent Works
How PixelsCleared detects and forwards consent signals from your website to destination platforms.
Overview
PixelsCleared never sends tracking data without consent. The consent signal flows from your visitor's consent tool through the widget, into the gateway, and onward to each destination platform with platform-specific consent fields attached.
This happens automatically. You do not need to configure consent forwarding separately for each destination.
The Consent Flow
Visitor loads page
|
Consent banner appears (Cookiebot, OneTrust, etc.)
|
Visitor accepts or rejects
|
Widget reads consent cookie / API signal
|
Widget attaches _consent_meta to each event
|
Gateway receives event, validates consent server-side
|
No consent --> Event dropped (logged as "blocked")
Consent granted --> Scrubber + forwarder apply rules
|
Forwarder translates _consent_meta into platform-specific fields
|
Meta CAPI: opt_out / LDU applied
GA4: consent.ad_user_data / ad_personalization set
Webhook: X-Consent-Granted header included
Step 1: Consent Provider Sets a Cookie
When a visitor accepts or rejects your consent banner, the consent management platform (CMP) writes a first-party cookie on your domain. This is a standard first-party cookie, readable by any script on the page.
PixelsCleared never sets its own consent cookie. It reads the one your CMP already writes.
Step 2: Widget Reads the Cookie
The pixelscleared.js script polls for consent cookies every second for up to 10 seconds after page load. It checks for cookies from Cookiebot, OneTrust, CookieYes, Complianz, GDPR Cookie Compliance, and several generic formats.
If no cookie is found, it also checks for platform APIs like window.__tcfapi (IAB TCF v2) and window.Shopify.customerPrivacy.
If no consent signal is detected within 10 seconds, the widget stays idle. No events are collected or sent.
Step 3: Widget Sends Consent Meta With Each Event
Once consent is detected, the widget attaches a structured _consent_meta object to every event it sends to the gateway:
{
"event": "Lead",
"consent": true,
"_consent_meta": {
"granted": true,
"source": "cookiebot",
"categories": {
"marketing": true,
"analytics": true
}
}
}
The source field identifies which CMP was detected. The categories object breaks consent down by type. This structure is preserved through the scrubbing engine (it is not treated as a sensitive field).
Step 4: Gateway Validates Consent
The gateway performs its own server-side consent check on every incoming event. This is a second line of defense in case the widget is bypassed or tampered with.
consent: true+ valid_consent_meta-- event is processed and forwardedconsent: false-- event is dropped immediately, logged withblocked_reason: "consent_denied"- Missing consent field -- event is dropped, logged with
blocked_reason: "no_consent"
Blocked events appear in the Gateway > Events table with their blocked reason. They are counted in your event totals but never reach any destination.
Step 5: Forwarder Applies Platform-Specific Consent Fields
Each destination connector translates the _consent_meta categories into the consent fields required by that platform:
| Platform | What Changes Based on Consent |
|---|---|
| Meta CAPI | Marketing granted: normal forwarding. Marketing denied: opt_out: true. Unknown: data_processing_options: ["LDU"] |
| GA4 | Marketing granted: consent.ad_user_data: "granted". Marketing denied: consent.ad_user_data: "denied" |
| Webhook | X-Consent-Granted: true/false header + _consent_meta in body |
| TikTok, LinkedIn, others | Server-side gating only (these platforms have no consent fields in their server-to-server APIs) |
See the Meta LDU and GA4 Consent Mode articles for details on how each platform's consent signals are applied.
When Consent Is Unknown
If the widget cannot determine consent (no cookie found, no API signal, no manual call), it takes a conservative approach:
- The widget stays idle and sends no events
- If an old widget version sends
consent: truewithout_consent_meta, the gateway synthesizes{ granted: true }with no categories - Forwarders apply conservative defaults: Meta gets Limited Data Use mode, GA4 gets
"denied"consent signals
This ensures that ambiguous consent states never result in unrestricted data forwarding.
When Consent Changes
- Visitor accepts after initial reject -- widget begins sending new events immediately. Previously discarded events are not retried.
- Visitor withdraws consent -- widget stops sending immediately and clears its local state. Any events in flight that arrive at the gateway with a now-invalid consent signal are dropped server-side.
- Visitor changes categories -- the next event sent by the widget will carry the updated
_consent_meta. The gateway uses the consent state attached to each individual event, not a cached session state.