# Migrate to derived consent

Read this only if you have an existing integration. If you are starting today, see [Tagging a form](https://app.expressconsent.com/docs/tags).

## What changed

Previously, you told the SDK what the user agreed to by passing `disclosures: { key: boolean }` to `captureCDR()`. ExpressConsent stored those client-reported values.

Now you tag the disclosure, consent checkbox, and submit button in your HTML. ExpressConsent derives the consent facts from the captured page and produces a `consentMechanism` for each disclosure.

> **Info: The legacy path is still supported**
>
> `disclosures` and `triggerEvent` are still accepted, although `triggerEvent`
> is ignored. Existing webhook and API fields continue to work.

If your systems read `consentLanguage` or `disclosures`, complete Step 3 before deploying the page changes.

## Step 1: Swap your HTML tags

Replace the legacy text and checkbox attributes with the current disclosure model.

### Before

```html
<p data-ec-consent-text="tcpa">
  By submitting, you agree to be contacted at the number provided.
</p>
<input type="checkbox" data-ec-consent-checkbox="tcpa" />
<button type="submit">Submit</button>
```

### After

```html
<p data-ec-disclosure="tcpa">
  By submitting, you agree to be contacted at the number provided.
</p>
<input type="checkbox" data-ec-consent-checkbox data-ec-consent-for="tcpa" />
<button type="submit" data-ec-submit>Submit</button>
```

| Legacy | Current | Note |
|---|---|---|
| `data-ec-consent-text="tcpa"` | `data-ec-disclosure="tcpa"` | The value becomes the disclosure `key` |
| `data-ec-consent-checkbox="tcpa"` | `data-ec-consent-checkbox data-ec-consent-for="tcpa"` | The binding moves to `data-ec-consent-for` |
| Untagged submit button | `data-ec-submit` | The submitted control is highlighted |

> **Warning: A single data-ec-disclosure turns the legacy detector off for the whole page**
>
> Convert every disclosure on a page in one change. A partial conversion stops
> the remaining legacy disclosures from producing `consentLanguage`.

Responsive layouts sometimes render mobile and desktop copies of the same disclosure. Ensure only one tagged copy is present in the captured page. Each tagged element becomes a separate entry.

## Step 2: Remove legacy captureCDR() parameters

Once the page is tagged, remove `disclosures` and `triggerEvent`.

### Before

```javascript
await window.ExpressConsent.captureCDR({
  disclosures: {
    tcpa: tcpaCheckbox.checked,
  },
  triggerEvent: event,
  custom: { phoneNumber: phone },
});
```

### After

```javascript
await window.ExpressConsent.captureCDR({
  custom: { phoneNumber: phone },
});
```

## Step 3: Update the payload you read

Webhooks and API responses now use `detectedDisclosureDetails`.

| Legacy field | Current field |
|---|---|
| `consentLanguage[].language` | `detectedDisclosureDetails.disclosures[].text` |
| `disclosures[].key` | `detectedDisclosureDetails.disclosures[].key` |
| `disclosures[].agreed` | `detectedDisclosureDetails.disclosures[].consentMechanism` |

`consentMechanism` is `checkbox`, `button_submission`, or `none_detected`. It is not a boolean.

```javascript
const derived = event.detectedDisclosureDetails?.disclosures?.[0];
const consentMechanism = derived?.consentMechanism;
const language = derived?.text;
```

An SDK upgrade can add `detectedDisclosureDetails` to a legacy page with an empty `disclosures` array. Check `disclosures.length`, not only whether the object exists. During migration, fall back to `consentLanguage` and `disclosures` when the derived array is empty.

## Next

- [Tagging a form](https://app.expressconsent.com/docs/tags): Mark the disclosure, the checkbox, and the submit control so a record carries structured consent facts.
- [The cdr.completed event](https://app.expressconsent.com/docs/webhooks/cdr-completed): Every field on the webhook payload, when each one is present, and what it means.
- [CDR endpoints](https://app.expressconsent.com/docs/reference/api/cdrs): List your domains, page through records, read one record in full, and collect a record.
