Migrate to derived consent

Read this only if you have an existing integration. If you are starting today, see Tagging a form.

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.

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>
LegacyCurrentNote
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 buttondata-ec-submitThe submitted control is highlighted

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 fieldCurrent field
consentLanguage[].languagedetectedDisclosureDetails.disclosures[].text
disclosures[].keydetectedDisclosureDetails.disclosures[].key
disclosures[].agreeddetectedDisclosureDetails.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