> ## Documentation Index
> Fetch the complete documentation index at: https://docs.permutive.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Consent Management

> Handle user consent with the Permutive JavaScript SDK

The Permutive SDK provides consent mechanisms for data controllers to signal user consent status. This page covers how to implement consent handling in your web integration.

<CardGroup cols={3}>
  <Card title="Consent Modes" href="#consent-modes" icon="toggle-on" />

  <Card title="consent() Method" href="#the-consent-method" icon="code" />

  <Card title="Opt Out" href="#opt-out" icon="user-xmark" />
</CardGroup>

## Overview

Permutive operates as a **data processor**, processing personal data on behalf of publishers who act as data controllers. Publishers are responsible for obtaining user consent and signaling that consent to Permutive.

<Info>
  For complete information about Permutive's consent mechanisms, see the [Consent documentation](/governance/consent).
</Info>

## Consent Modes

Permutive provides two consent modes that publishers can configure for their deployment.

### Consent-by-Default

By default, Permutive assumes the data controller has consent to track their users' data. In this configuration mode, the collection of user data starts from the first time Permutive's SDK loads without requiring a consent token.

```html theme={"dark"}
<script>
  !function(e,o,n,i){/* ... */}(window.permutive,"<WORKSPACE_API_KEY>","<WORKSPACE_ID>",{
    // consentRequired defaults to false
  });
</script>
<script async src="https://<ORGANIZATION_ID>.edge.permutive.app/<WORKSPACE_ID>-web.js"></script>

<script>
  // Tracking starts immediately
  permutive.addon('web', {
    page: { type: 'article' }
  });
</script>
```

### Consent-by-Token

As a data controller, you may need to receive consent from the user before tracking data against them.

When `consentRequired: true`, no user data is collected until the data controller has received consent from the user and passed the user's consent token to the Permutive SDK. Once the SDK has been granted consent, it will start collecting user data from this moment on. The user can revoke this consent at any point.

```html theme={"dark"}
<script>
  !function(e,o,n,i){/* ... */}(window.permutive,"<WORKSPACE_API_KEY>","<WORKSPACE_ID>",{
    consentRequired: true
  });
</script>
<script async src="https://<ORGANIZATION_ID>.edge.permutive.app/<WORKSPACE_ID>-web.js"></script>

<script>
  // SDK is loaded but NOT tracking
  // All events are ignored until consent is granted

  permutive.addon('web', {
    page: { type: 'article' }
  });
</script>
```

No user data will be tracked by the SDK until it receives a consent token for the user.

<Warning>
  With `consentRequired: true`, events are **discarded** until consent is granted—they are not queued.
</Warning>

## The consent() Method

### Granting Consent

Once you have obtained consent for the user, pass it to Permutive by calling the SDK `consent` method:

```javascript theme={"dark"}
permutive.consent({ opt_in: true, token: "YOUR_CONSENT_TOKEN_HERE" });
```

From this point on, the SDK will track user event data—or until the user wishes to opt out.

| Parameter | Type    | Description                                  |
| --------- | ------- | -------------------------------------------- |
| `opt_in`  | boolean | Whether user has consented                   |
| `token`   | string  | Consent token (required when `opt_in: true`) |

### About the Consent Token

The consent token can have **any value**. Generally, this is used if an ID gets generated when the user gives consent via a Consent Management Platform to provide some transparency, but the actual value has no meaning to Permutive.

As long as `opt_in` is `true` and the `token` is not null, Permutive considers consent to be given.

```javascript theme={"dark"}
// Example: Using a fixed token value
permutive.consent({ opt_in: true, token: "CONSENT_CAPTURED" });

// Example: Using a CMP-generated token
permutive.consent({ opt_in: true, token: cmp.getConsentId() });
```

<Info>
  Some customers use a fixed value like `"CONSENT_CAPTURED"` for simplicity. Choose whatever approach works best for your consent management workflow.
</Info>

## Opt Out

You may choose or be required to offer users the option to opt out of tracking. All future tracking is then disabled for the user until the point they opt back in.

Whether the SDK is configured in consent-by-default or consent-by-token mode, a user can be opted out by setting the consent `opt_in` field to `false`:

```javascript theme={"dark"}
permutive.consent({ opt_in: false });
```

### What Happens on Opt Out

1. **Tracking stops** - No new events are sent
2. **State reset** - User ID and session cleared
3. **localStorage cleared** - Cohorts and identity data removed
4. **Cookies cleared** - `permutive-id` cookie deleted

### Opt Back In

Users can opt back in by calling `consent()` with `opt_in: true`:

```javascript theme={"dark"}
permutive.consent({ opt_in: true, token: "CONSENT_CAPTURED" });
```

<Warning>
  After opting out and back in, the user receives a new user ID. Their previous behavioral history is not linked to the new profile.
</Warning>

## CMP Integration Examples

### Generic CMP Pattern

```javascript theme={"dark"}
// Check CMP consent status
function handleConsent() {
  if (cmp.hasUserConsented()) {
    permutive.consent({
      opt_in: true,
      token: cmp.getConsentToken() || "CONSENT_CAPTURED"
    });
  } else {
    permutive.consent({ opt_in: false });
  }
}

// Listen for consent changes
cmp.onConsentChange(handleConsent);
```

### OneTrust Example

```javascript theme={"dark"}
function OptanonWrapper() {
  // Check if relevant category is consented
  if (OnetrustActiveGroups.includes('C0002')) {
    permutive.consent({
      opt_in: true,
      token: 'onetrust_consent'
    });
  } else {
    permutive.consent({ opt_in: false });
  }
}
```

### Cookiebot Example

```javascript theme={"dark"}
window.addEventListener('CookiebotOnAccept', function() {
  if (Cookiebot.consent.statistics) {
    permutive.consent({
      opt_in: true,
      token: 'cookiebot_consent'
    });
  }
});

window.addEventListener('CookiebotOnDecline', function() {
  permutive.consent({ opt_in: false });
});
```

## TCF Registration

For customers who must use a consent management platform that relies on the Global Vendor List (GVL), Permutive is registered on the GVL for IAB Europe's Transparency & Consent Framework (TCF).

| Detail          | Value                                                   |
| --------------- | ------------------------------------------------------- |
| **GVL ID**      | 361                                                     |
| **Purpose**     | Purpose 1 (store and/or access information on a device) |
| **TCF Version** | 2.3                                                     |

<Info>
  As a data processor, Permutive primarily relies on consent obtained by the publisher through the consent mechanisms described above (`consent-by-default` or `consent-by-token`). The TCF registration is provided for customers with specific GVL requirements.
</Info>

## Consent State

### Consent Persistence

Consent status is stored in localStorage and persists across sessions. The SDK automatically respects the stored consent state on subsequent page loads.

### Checking Consent Status

```javascript theme={"dark"}
// Consent is stored in localStorage
var consentData = localStorage.getItem('permutive-consent');
if (consentData) {
  var consent = JSON.parse(consentData);
  console.log('Consent status:', consent.opt_in);
}
```

## Troubleshooting

<AccordionGroup>
  <Accordion title="Events not tracking with consentRequired">
    **Problem:** SDK loaded but no events appearing.

    **Solutions:**

    * Verify `consent()` is called with `opt_in: true` and a non-null `token`
    * [Enable debug mode](/sdks/web/javascript-sdk/getting-started/verification#debug-mode) (`?__permutive.loggingEnabled=true`) to see consent status
    * Check localStorage for `permutive-consent` key
  </Accordion>

  <Accordion title="Consent not persisting">
    **Problem:** User must consent on every page load.

    **Solutions:**

    * Check localStorage is not being cleared
    * Verify CMP integration is consistent across pages
    * Ensure consent token is not null
  </Accordion>
</AccordionGroup>

## Related Documentation

<CardGroup cols={2}>
  <Card title="Consent" icon="shield-check" href="/governance/consent">
    Platform consent mechanisms
  </Card>

  <Card title="Initialization" icon="gear" href="/sdks/web/javascript-sdk/getting-started/initialization">
    SDK initialization options
  </Card>
</CardGroup>
