Consent
Make aff.js and referalli/browser follow your consent tool: nothing is stored or sent until the visitor allows it.
A referral cookie credits an affiliate, so in the EU and UK it needs the visitor's opt-in (CNIL, ICO, EDPB guidelines 2/2023). The tracking script can read your consent tool (CMP) and wait for it.
What happens before, after and without consent
Visitor's choice | Storage | Visit beacon | Referral |
|---|---|---|---|
No decision yet | Nothing written | None | Kept in memory: |
Granted |
| Sent, with consent evidence | Stored for the cookie window |
Denied or withdrawn | Deleted at once | None | Dropped |
The evidence (which tool, its record id, the TCF or GPP string, the time) is stored with the click. GET /v1/clicks/{id} returns it, and GET /v1/clicks/consent-coverage gives the share of attributed sign-ups that carry it.
Choose a mode
Set it once in Settings → Tracking, or with PUT /v1/org/tracking-consent; the script picks it up within five minutes, with no change to your tag. A tag attribute overrides it for one site.
Mode | Behaviour |
|---|---|
| Uses the first consent tool it finds on the page, in the order below. With none, |
a tool id | Only that tool. Add |
| Waits for your own code: |
| Persist always. Stores before any choice, as the script did before consent support. Use it only where no consent is required. Orgs created before consent support start here, so their tags behave exactly as before until they choose. |
<!-- Follow OneTrust's "Targeting" group, and download only its adapter -->
<script src="https://referalli.com/t/tk_.../aff.js?consent=onetrust" data-consent-category="C0004" async></script>Supported consent tools
auto checks them in this order.
Custom
Define window.referalliConsent() returning true, false or null (no decision), and dispatch window.dispatchEvent(new Event('referalli:consent')) when it changes. Or skip it and push the decision: aff.consent(true | false) (it is idempotent; the latest signal wins). Calls made before the script loads are queued:
<script>window.aff = window.aff || { q: [] }; aff.q.push(['consent', true]);</script>Cookie Munch
Reads CookieMunch.consent after hasResponse, category referrals, falling back to marketing when your site has no referrals category. Evidence: the consent id. Tag: data-consent="cookiemunch".
OneTrust
Reads OnetrustActiveGroups, group C0004 (targeting) by default. An inactive group counts as a denial only once the banner was closed. Evidence: the data-subject id. Tag: data-consent="onetrust".
Cookiebot
Reads Cookiebot.consent.marketing. Evidence: consentID. Tag: data-consent="cookiebot".
Usercentrics
Beta. v2 UC_UI.getServicesBaseInfo() or v3 __ucCmp.getConsentDetails(). Set the category to a service name (add a "Referalli" service) or a category slug; default marketing. Tag: data-consent="usercentrics".
Didomi
Beta. Reads Didomi.getUserStatus(): purpose cookies by default, or a vendor id (c:referalli-…). Tag: data-consent="didomi".
Osano
Beta. Reads Osano.cm.getConsent().MARKETING. Tag: data-consent="osano".
Termly
Beta. Reads Termly.getConsentState().advertising. A returning visitor who declined is kept in memory only (never stored). Tag: data-consent="termly".
TCF
IAB TCF v2.2. Through __tcfapi: purpose 1 (store) plus purpose 7 or 9, or, with data-consent-tcf-vendor="<id>", purpose 1 plus that vendor. Evidence: the TC string. Tag: data-consent="tcf".
GPP
IAB GPP, beta. Through __gpp: the EU section follows the TCF rule; US state sections deny on a sale, sharing or targeted-advertising opt-out. Evidence: the GPP string. Tag: data-consent="gpp".
Google Consent Mode
Version 2. Follows ad_storage (or analytics_storage) from gtag('consent', 'update', …). A denied default with no update yet counts as no decision. Tag: data-consent="gcm".
In your own code
import { createTracker } from 'referalli/browser';
const tracker = await createTracker({ publishableKey: 'tk_...', consent: { mode: 'auto', noCmp: 'memory' } });
tracker.consentMode; // 'onetrust', 'auto' while looking, 'no-cmp', …
tracker.consentEvidence(); // pass to POST /v1/referrals/associate as `consent`Server-side kits take a function that reads your CMP's cookie; on unknown they set no cookie, on denied they delete it:
export const middleware = referalliMiddleware({ consent: (req) => (req.cookies.get('my_cmp')?.value === 'yes' ? 'granted' : 'unknown') });Declarations for your consent tool
/.well-known/forgedeck-embed.json lists the script's storage (referalli_ctx and referally_ctx, cookie and localStorage, category referrals) and origins; GET /v1/embed?token=tk_... gives your org's cookie window and setting.