---
title: Consent Models
description: How c15t determines consent behavior based on legal jurisdiction.
---
c15t supports four consent models that control how consent defaults, banner visibility, and category gating behave:

|Model|Philosophy|Banner|Categories default to|
|--|--|--|--|
|`opt-in`|Explicit consent required|Blocking banner|`false` (except `necessary`)|
|`opt-out`|Processing allowed by default|Non-blocking notice|`true` (all granted)|
|`iab`|IAB TCF 2.3 for programmatic ads|TCF banner|Managed by TCF framework|
|`null`|No regulation detected|No banner|`true` (all auto-granted)|

There are two ways c15t determines which model applies:

1. **Policy packs** (recommended) — you explicitly set the model per region in a `PolicyConfig`. This gives you full control over which regions get which model. See [Policy Packs](/docs/frameworks/react/concepts/policy-packs).

2. **Automatic jurisdiction mapping** (legacy default) — when no policy pack is configured, c15t detects the visitor's jurisdiction via geolocation and maps it to a model using the table below. This still works but gives you less control over categories, UI, and scope.

> ℹ️ **Info:**
> When using policy packs, the consent.model field in each policy directly sets the model — the automatic jurisdiction mapping is bypassed for that request.

Read the current consent model from the hook:

```tsx
import { useConsentManager } from '@c15t/react';

function ConsentStatus() {
  const { model, policy } = useConsentManager();

  return (
    <p>
      Current consent model: {model ?? 'detecting...'}
      {policy && ` (from policy: ${policy.id})`}
    </p>
  );
}
```

## The Four Models

### Opt-in

The strictest consent model, used for GDPR and similar regulations that require explicit, affirmative consent before any non-essential data processing occurs. All consent categories except `necessary` default to `false`. A consent banner must be shown before any tracking scripts load.

Applies to: EU (GDPR), UK (UK GDPR), Switzerland, Brazil (LGPD), Japan (APPI), South Korea (PIPA), Quebec (Law 25). Also the fallback for unknown jurisdiction codes.

### Opt-out

Used for CCPA-style regulations where data processing is permitted by default until the user exercises their right to opt out. All consent categories default to `true`. A blocking banner is not required — the typical pattern is a non-intrusive notice or footer link.

Applies to: California (CCPA), Canada (PIPEDA), Australia.

When the policy has `consent.gpc: true`, the browser's Global Privacy Control signal (`Sec-GPC: 1` or `navigator.globalPrivacyControl`) is respected — `marketing` and `measurement` are denied while other categories remain granted. The built-in California presets enable this by default. See [Policy Packs — GPC](/docs/frameworks/react/concepts/policy-packs#gpc) for details.

### IAB

IAB Transparency and Consent Framework (TCF) 2.3 mode for programmatic advertising compliance. Only activates when two conditions are met: the jurisdiction is `GDPR` or `UK_GDPR`, and `iab.enabled` is `true` in your configuration.

When active, IAB mode generates TC strings, registers the `__tcfapi` CMP API, and works with the Global Vendor List (GVL) for machine-readable consent signals. If `iab.enabled` is not set, GDPR jurisdictions fall back to standard opt-in.

### null

Returned when no jurisdiction is detected (`NONE` or `null`). No banner is displayed. On first visit, all categories are auto-granted.

## Jurisdiction Mapping

When no policy pack is configured, c15t maps jurisdictions to models automatically:

|Jurisdiction Code|Region|Consent Model|
|--|--|--|
|`GDPR`|European Union|opt-in|
|`UK_GDPR`|United Kingdom|opt-in|
|`CH`|Switzerland|opt-in|
|`BR`|Brazil (LGPD)|opt-in|
|`APPI`|Japan|opt-in|
|`PIPA`|South Korea|opt-in|
|`PIPEDA`|Canada (excl. Quebec)|opt-out|
|`QC_LAW25`|Quebec, Canada|opt-in|
|`CCPA`|California, USA|opt-out|
|`AU`|Australia|opt-out|
|`NONE`|No jurisdiction|null|
|*(unknown)*|Any other|opt-in|

**IAB override:** If `iab.enabled: true` and the jurisdiction is `GDPR` or `UK_GDPR`, the model becomes `'iab'` instead of `'opt-in'`. This override only applies to those two jurisdictions.

> ℹ️ **Info:**
> With policy packs, you set the model explicitly per policy — the automatic mapping above is only used as a fallback when no policy pack is configured, or for non-policy-pack features like auto-granting in opt-out jurisdictions.

Override the detected jurisdiction for testing:

```tsx
import { useConsentManager } from '@c15t/react';

function JurisdictionTester() {
  const { setOverrides } = useConsentManager();

  return (
    <div>
      <button onClick={() => setOverrides({ country: 'DE' })}>
        Test as EU visitor
      </button>
      <button onClick={() => setOverrides({ country: 'US', region: 'CA' })}>
        Test as California visitor
      </button>
    </div>
  );
}
```

> ℹ️ **Info:**
> For full control over which model applies where — plus UI customization, category scoping, and re-prompting — see Policy Packs.
