One script tag. Zero dependencies, ~30 KB, bilingual and RTL-correct, themed to your brand. It renders the banner, records decisions with receipts, gates your tracking scripts, and hosts the subject's rights UI.
It will not load until you allow your origin under API keys → Widget origins. Widget CORS is a per-organization allowlist.
PDPL guarantees baked into the UI
- Consent-basis purposes are unchecked by default, always — a pre-ticked box is not consent.
- Non-consent bases (contract, legal obligation, legitimate interest) render as informational rows, not checkboxes — you don't ask for what you don't need to ask for.
- Saving is an explicit visible action; closing with Esc records nothing (dismissal ≠ consent).
- After deciding, the subject sees their own receipt_id with a public verify link — the receipt is theirs too.
Gating trackers until consent
Mark the tag inert; the widget activates it only after its purpose is granted — and on withdrawal it stays off at the next load:
Google Consent Mode v2
With googleConsentMode: true the widget signals gtag defaults as denied before any Google tag runs, maps purpose decisions to ad_storage / analytics_storage / ad_user_data / ad_personalization, and re-signals on withdrawal. Override the mapping per purpose with consentModeMap.
State queries
Theming
Set brand color, radius and logo once in the dashboard (Branding) — banner, hosted policy page and rights pages all follow. Host-page CSS variables win if you need per-site control:
The rights center in the widget
See Privacy center & rights — embedded mode (your backend mints a subject token) and anonymous mode (localStorage record, plus "add your phone/email" claim that upgrades it) are both handled by the same ConsentProof.openPrivacyCenter().