Age-Based Consent Management: Handling Age Verification with Transcend

This guide explains how to use Transcend’s Consent & Preference Management solutions to implement age-based consent rules — such as automatically blocking advertising and data sharing for minors.

Many privacy regulations (COPPA, GDPR, state-level US laws) require organizations to apply stricter consent rules for minors. With Transcend, you can implement age-based consent enforcement across three layers of your stack:

LayerWhat It DoesWhere It Lives
1. Client-Side OverrideIntercepts and blocks network requests & cookies tagged with specific consent purposes (e.g., SaleOfInfo, Advertising)Browser — runs inside airgap.js
2. Preference StoreStores user birth date as metadata, syncs it to the web client for use in client-side logicTranscend backend
3. Downstream SystemsPropagates consent changes to third-party systems (CRMs, ad platforms, CDPs) via workflow triggersTranscend integrations layer

These three layers work together: the Preference Store provides the age data, the client-side override enforces consent rules in real time in the browser, and downstream workflow triggers ensure that the same consent decisions are reflected across your entire data ecosystem.

The first layer of enforcement lives in the browser. Using airgap.js’s override API, you can intercept all pending network requests and cookie mutations and apply custom logic — such as blocking requests tagged with SaleOfInfo or Advertising purposes when the user is a minor.

See the airgap.js API Reference for full override documentation.

  1. airgap.js intercepts every network request and cookie mutation before it executes.
  2. Your override snippet checks whether the current user is a minor.
  3. If the user is a minor and the request is tagged with restricted purposes, the override calls event.deny() to block it.

Place this snippet before the airgap.js script tag, or use the Airgap Prefix approach (see the note below).

const MINOR_RESTRICTED_PURPOSES = ['SaleOfInfo', 'Advertising'];

let _isMinorCached = undefined;
function getMinorStatus() {
  if (_isMinorCached !== undefined) return _isMinorCached;
  const consent = self.airgap?.getConsent?.();
  const birthDate = consent?.metadata?.birthDate;
  if (!birthDate) {
    _isMinorCached = false;
    return false;
  }
  const birth = new Date(birthDate);
  const today = new Date();
  const age = today.getFullYear() - birth.getFullYear();
  const monthDiff = today.getMonth() - birth.getMonth();
  const isMinor = (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birth.getDate()))
    ? age - 1 < 18 : age < 18;
  _isMinorCached = isMinor;
  return isMinor;
}

(self.airgap = { overrides: [], ...self.airgap }).overrides.push({
  override: (event) => {
    if (getMinorStatus() && MINOR_RESTRICTED_PURPOSES.some((p) => event.purposes.has(p))) {
      event.deny();
    }
  }
});

(self.airgap = { cookieOverrides: [], ...self.airgap }).cookieOverrides.push((event) => {
  if (getMinorStatus() && MINOR_RESTRICTED_PURPOSES.some((p) => event.purposes.has(p))) {
    event.deny();
  }
});

Performance note: The getMinorStatus() function is memoized — it calculates the minor status once and caches the result.

ApproachScript TagsMaintenance
Override snippet (DIY)2 scripts per siteYou maintain the snippet
Airgap prefix (managed)1 script per siteTranscend manages it
SourceHow It WorksBest For
Your own databaseYour app sets a global variable (e.g., window.__userBirthDate) on loginOrganizations that already store DOB
Transcend Preference StoreBirth date stored as metadata; read via airgap.getConsent().metadata.birthDateCentralized consent + age data

Transcend’s Preference Store supports a metadata field on each consent record. You can use this to store the user’s birth date alongside their consent preferences.

PUT /v1/preferences

{
  "records": [{
    "partition": "YOUR_PARTITION_ID",
    "timestamp": "2026-01-15T00:00:00Z",
    "identifiers": [{ "name": "email", "value": "user@example.com" }],
    "purposes": [
      { "purpose": "Advertising", "enabled": false },
      { "purpose": "SaleOfInfo", "enabled": false }
    ],
    "metadata": [{ "key": "birthDate", "value": "2010-03" }]
  }]
}
// Set birth date as consent metadata
airgap.setConsentMetadata(event, {
  ...(airgap.getConsent().metadata || {}),
  birthDate: '2010-03'
});

// Sync consent + metadata to Preference Store
airgap.sync();

Privacy Best Practice: Store birth date using month and year only (e.g., "2010-03") rather than the full date.

When a user’s consent changes, Transcend’s workflow triggers automatically push those changes to connected downstream systems. It's common to use a Custom Function to either a) notify downstream systems of a user's minor status or b) update other types of consent on the preference record to be opted out when a minor.

  1. Determine your age data source — your own DB or Transcend Preference Store.
  2. [Optional] Store birth date in Preference Store — use metadata: [{ key: "birthDate", value: "YYYY-MM" }].
  3. Add the client-side override — snippet or airgap prefix.
  4. Define restricted purposes — e.g., SaleOfInfo, Advertising.
  5. [Optional] Connect downstream systems — configure workflow triggers.
  6. Test the implementation — verify blocking for minors, unaffected adults, end-to-end flow.

Transcend has experimental support for automated workflows that trigger when a minor turns 18, automatically updating consent purposes and propagating changes across all three layers. Please reach out to support@transcend.io if you are interested in learning more about this.