Get started

ExpressConsent captures proof of what a user saw and agreed to at the moment they consent, so you can stand behind every lead you generate or buy.

How it works

When a user submits a form they consented on, you call captureCDR(). ExpressConsent saves a screenshot of exactly what the user saw at that moment, together with the signer details (IP address, location, timestamp) and any data you attach. All of it is sealed into a Certified Digital Record (CDR) and stored for five years.

From there a CDR is yours to use: pull it up instantly in the dashboard or over the API, hand it to a lead buyer, and have everything you need to stand behind the lead in one place.

Building with an AI assistant?

The fastest way to integrate is to let your AI coding assistant do it. We publish a complete, copy-paste context prompt that contains the full ExpressConsent documentation: SDK setup, every captureCDR() option, the server-to-server API, webhooks, and the rules for capturing high-quality evidence.

Paste it into your assistant at the start of a conversation and ask it to wire up your forms. It will write correct integration code and answer your questions without you explaining the system from scratch.

Get plugged into your site

A working integration is two steps: add the SDK to your page, then capture a CDR when a user submits. Everything below is the complete picture; the captureCDR() reference has the full spec for each option.

1. Add the SDK to your page

Put this script tag in your <head>. Replace YOUR_CID with the CID from your organization settings in the dashboard.

html
<!-- async is recommended: it keeps the SDK off your page's critical
     path and it is ready well before any form submit. -->
<script
  src="https://sdk.expressconsent.com/sdk/v1/sdk.js"
  data-ec-cid="YOUR_CID"
  async
></script>

2. Capture evidence on submit

Call captureCDR() from inside your form’s submit handler and await it before the page navigates. Awaiting keeps the page alive during capture, confirms the evidence was saved, and gives you back the cdrId and a shareUrl you can pass straight to a lead buyer.

javascript
form.addEventListener("submit", async (event) => {
  event.preventDefault();

  // Read form values synchronously BEFORE the first await.
  const phone = form.phone.value;

  try {
    // captureCDR() must be the first await, calling anything async before it
    // breaks the link to the user-triggered submission.
    // autoShare: true generates a share URL in the same call. Store this with your lead if handing off to a leader buyer.
    const { cdrId, shareUrl } = await window.ExpressConsent.captureCDR({
      autoShare: true,
      custom: { phoneNumber: phone },
    });

    // Store cdrId and shareUrl with the lead to your backend.
    // Pass shareUrl to the buyer so they can access the evidence.
    await saveLead({ phone, cdrId, shareUrl });
  } catch (err) {
    // Log it and let the submit proceed — never block submission on a capture failure.
    console.error("Capture failed:", err);
  }

  form.submit();
});

Capture every view the user consented on

Call captureCDR() at each moment that matters. If a user gives consent on more than one screen, or entered information on a previous page that you want visible alongside the consent, capture each one. When several captures happen in the same browser session, ExpressConsent automatically combines them into a single Package CDR so the whole flow reads as one comprehensive record of what the user saw.

See Sessions & Package CDRs for how sessions group captures.

Label your consent elements

Add a few attributes to the consent parts of your page: the disclosure language, the checkbox (if you have one), and the submit button. This lets ExpressConsent enrich the CDR with stronger evidence of what the user actually did.

html
<!-- The disclosure language the user is agreeing to. -->
<p data-ec-disclosure>
  By submitting, you agree to be contacted at the number provided,
  including by automated technology.
</p>

<!-- The consent checkbox, if you have one. -->
<input type="checkbox" data-ec-consent-checkbox />

<!-- The button the user submits with. -->
<button type="submit" data-ec-submit>Submit</button>

With these in place, ExpressConsent reads whether the checkbox was checked, confirms the user submitted, and captures the disclosure text so the record is searchable. If you sell leads, this also lets a buyer filter on what they require, such as a disclosure that names their company. The verifiable consent section covers the tags in full.

Generating leads for a buyer?

The example above already includes autoShare: true, so you get a shareUrl back in the same call. Keep it with the rest of the lead data and pass it to your buyer; they open it with their API key to receive the CDR. See Sharing with lead buyers for the full handoff.

Next