Skip to main content
Skip table of contents

"Integrated Model" - Utiq & CMP APIs

This page purpose is to guide you what technical steps you will need to make, if you want to go for “Integrated Model”.

Prerequisites to use “Integrated Model”

Make sure you meet the minimum Utiq standards for using the “Integrated Model” by reviewing Option A: Integrated consent model

Configurations in CMP console

For the integration you will need to do some configurations on your CMP.

Please follow the principles and steps as described on Configuration in CMP console.

Adding a new vendor and/or new purpose might trigger a reconsent for your property's end Users.

Ensure the buttons are always visible

Add CMP CSS to allow scrollbar, so that buttons are always visible

#id { max-height: 300px; overflow-y: scroll; }

Change #id with your CMP's respective text element id

Technical Implementation

On top of the CMP configurations, there are the following technical integration actions that need to be done.

For any technical questions, you can reach out to our Customer Success team at csm@utiq.com

Code

Please implement the following code to be executed after your CMP code has completed.

Follow the below code examples, to combine the required actions, as described above.

General Snippet

General snippet

Last update: October 2025

General Utiq integration snippet

JS
// Call 'handleConsentChange' when CMP consent changes
// Use 'onConsentUpdateFinished' event to receive signals of consent change from Utiq
// Get utiqPurposeConsent and utiqVendorConsent from the CMP
// If the website’s CMP is not listing any other vendors (and only listing the purposes), the utiqVendorConsent parameter can be omitted

window.Utiq ||= {};
window.Utiq.queue ||= [];

// If the CMP has own listeners or on-ready functions, they should wrap the Utiq.queue.push, otherwise use a delay (setTimeout) to make sure the CMP was initialized
window.cmpOnReady((cmp) => {
  // Otherwise call Utiq.queue.push directly
  window.Utiq.queue.push(() => {
    if (!window.Utiq.API.getUtiqConsentStatus()) {
      // handleConsentChange option 1: If the CMP and Utiq consents are different, synchronize
      window.Utiq.API.handleConsentChange(
        cmp.utiqPurposeConsent === true && cmp.utiqVendorConsent !== false,
      );
      // handleConsentChange option 2: If the consent change was triggered from the user action, pass syncConsentOnAccept parameter
      window.Utiq.API.handleConsentChange(
        cmp.utiqPurposeConsent === true && cmp.utiqVendorConsent !== false,
        {
          syncConsentOnAccept: true, // syncConsentOnAccept flag should be only set to true when the consent is explicitly accepted
        },
      );
    }

    // onConsentUpdateFinished option 1: listener can be defined in the queue
    window.Utiq.API.addEventListener(
      'onConsentUpdateFinished',
      ({ isConsentGranted }) => {
        // Update Utiq purpose AND vendor in CMP if consents are different (use isConsentGranted)
      },
    );
  });
});

window.Utiq ||= {};
window.Utiq.config = {
  CMP: 'none', // Needed for Utiq SDK to *not* show Utiq Separate Pop-up
  customizationOptions: {
    // Customization for Utiq UI elements
    buttons: {
      bodyColor: '#ff0066',
      textColor: '#000000',
      radius: 5,
    },
    contentTextColor: '#000000',
  },
  listeners: {
    // onConsentUpdateFinished option 2: Alternatively listener can be defined in the config
    onConsentUpdateFinished: ({ isConsentGranted }) => {
      // Update Utiq purpose AND vendor in CMP if consents are different (use isConsentGranted)
    },
  },
};
(() => {
  const s = document.createElement('script');
  s.type = 'text/javascript';
  s.src = 'https://utiq.example.com/utiqLoader.js';
  s.async = true;
  document.head.appendChild(s);
})();

For window.Utiq.API.handleConsentChange(utiqPurposeConsent === true && utiqVendorConsent !== false);, if the website’s CMP is not listing any other vendors (and only listing the purposes), the utiqVendorConsent parameter can be omitted.

Using up to ES5 JavaScript Version (Google Tag Manager)

The code can be integrated using a Tag Manager. Bellow an example using Google Tag Manager, where you need to put the code in <script></script> and change the arrow function (() => { to (function () { to comply with ES5 JavaScript.

JS
<script>
  // Call 'handleConsentChange' when CMP Consent changes
  // Get utiqPurposeConsent and utiqVendorConsent from the CMP
  // If the website’s CMP is not listing any other vendors (and only listing the purposes), the utiqVendorConsent parameter can be omitted
  window.Utiq.API.handleConsentChange(utiqPurposeConsent === true && utiqVendorConsent !== false); // example variables
  
  // Check if Utiq Consent was revoked from Manage Utiq page
  window.Utiq ||= {};
  window.Utiq.queue ||= [];
  
  window.Utiq.queue.push(() => {
    if (!window.Utiq.API.getUtiqConsentStatus()) {
      // Turn Utiq purpose AND vendor to false on CMP if needed
    }
  });
  
  // Set 'none' on window.Utiq.config.CMP
  // Set 'onConsentUpdateFinished' listener for the consent syncronization
  window.Utiq ||= {};
  window.Utiq.config = {
    CMP: 'none', // Needed for Utiq SDK to *not* show Utiq Separate Pop-up
    customizationOptions: { // Needed for consent revocation pop-up in Manage Utiq
      buttons: {
        bodyColor: '#ff0066',
        textColor: '#000000',
        radius: 5,
      },
      contentTextColor: '#000000'
    },
    listeners: {
      onConsentUpdateFinished: ({ isConsentGranted }) => {
        setTimeout(() => {
          if (!isConsentGranted) {
            // Turn Utiq purpose AND vendor to false on CMP if needed
          }
        }, 250);
      }
    }
  };
  (function () {
    const s = document.createElement("script")
    s.type = 'text/javascript';
    s.src = "https://utiq.example.com/utiqLoader.js"
    s.async = true;
    document.head.appendChild(s)
  })();
</script>

Below are some hyperlinks for above event listeners and APIs, just for further information of their purpose.

Full code per CMP vendor

Below are full codes to use, based on your CMP vendor, including their APIs.

Please note that:

  • [INSERT UTIQ CUSTOM PURPOSE] → add the parameter setup in your CMP for the Utiq custom purpose

  • [INSERT UTIQ CUSTOM VENDOR] → add the parameter setup in your CMP for the Utiq custom vendor

CMP vendors:

Didomi

Didomi

Last update: October 2025 (check vendor documentation)

Complete Didomi integration snippet

JS
/* ID strings */
const utiqPurposeId = '[INSERT UTIQ CUSTOM PURPOSE]';
const utiqVendorId = 'c:' + '[INSERT UTIQ CUSTOM VENDOR]'; // (if used)

const isConsentGranted = (Didomi) => {
  const purposeConsent = Didomi.getUserConsentStatusForPurpose(utiqPurposeId);
  const vendorConsent = Didomi.getUserConsentStatusForVendor(utiqVendorId);

  if (Didomi.getCurrentUserStatus().consent_string === null) {
    return undefined;
  }
  if (purposeConsent === false && vendorConsent === false) {
    return false;
  } else if (purposeConsent === true && vendorConsent !== false) {
    return true;
  }
  return false;
};

const updateConsent = (Didomi, consent) => {
  const didomiIsCmpConsentGranted = isConsentGranted(Didomi);
  const transaction = Didomi.openTransaction();
  if (consent === false && didomiIsCmpConsentGranted === true) {
    transaction.disablePurpose(utiqPurposeId);
    transaction.disableVendor(utiqVendorId);
    transaction.commit();
  } else if (consent === true && didomiIsCmpConsentGranted === false) {
    transaction.enablePurpose(utiqPurposeId);
    transaction.enableVendor(utiqVendorId);
    transaction.commit();
  } else if (consent === undefined && didomiIsCmpConsentGranted !== undefined) {
    window.Utiq?.API?.handleConsentChange(didomiIsCmpConsentGranted);
  }
};

/* Initialize required namespaces */
window.Utiq ||= {};
window.Utiq.queue ||= [];
window.didomiOnReady ||= [];
window.didomiEventListeners ||= [];

window.didomiOnReady.push((Didomi) => {
  window.didomiEventListeners.push({
    event: 'consent.changed',
    listener(context) {
      window.Utiq.queue.push(() => {
        const didomiConsent = isConsentGranted(Didomi);
        if (context?.action === 'click' && didomiConsent) {
          window.Utiq.API.handleConsentChange(didomiConsent, {
            syncConsentOnAccept: true, // syncConsentOnAccept flag should be only set to true when the consent is explicitly accepted
          });
        } else {
          window.Utiq.API.handleConsentChange(didomiConsent);
        }
      });
    },
  });
  window.Utiq.queue.push(() => {
    window.Utiq.API.addEventListener(
      'onConsentUpdateFinished',
      ({ isConsentGranted }) => {
        updateConsent(Didomi, isConsentGranted);
      },
    );
    try {
      updateConsent(Didomi, window.Utiq.API.getUtiqConsentStatus());
    } catch (err) {
      console.error(
        `getUtiqConsentStatus API call failed. Reason: ${err.message}`,
      );
    }
  });
});

window.Utiq.config = {
  CMP: 'none',
};
(() => {
  const a = document.createElement('script');
  a.type = 'text/javascript';
  a.src = '/utiqLoader.js';
  document.head.appendChild(a);
})();

Function to open 2nd layer

CODE
Didomi.preferences.show()
OneTrust and CookiePro

OneTrust and CookiePro

Last update: October 2025 (check vendor documentation)

Complete OneTrust integration snippet

JS
/* ID strings */
const utiqPurposeId = '[INSERT UTIQ CUSTOM PURPOSE]';
const utiqVendorId = '[INSERT UTIQ CUSTOM VENDOR]'; // (if used)

const isUserConsentGranted = () => {
  if (!window.Optanon?.IsAlertBoxClosed?.()) {
    return undefined;
  }
  if (
    typeof window.OptanonActiveGroups !== 'string' ||
    window.OptanonActiveGroups === ''
  )
    return undefined;

  return (
    window.OptanonActiveGroups.indexOf(utiqPurposeId) !== -1 &&
    window.OptanonActiveGroups.indexOf(utiqVendorId) !== -1
  );
};

const updateConsent = (isUtiqConsentGranted) => {
  setTimeout(() => {
    const optanonIsCmpConsentGranted = isUserConsentGranted();

    if (isUtiqConsentGranted === false && optanonIsCmpConsentGranted === true) {
      window.Optanon?.UpdateConsent('Category', `${utiqPurposeId}:0`);
      window.Optanon?.UpdateConsent('General Vendor', `${utiqVendorId}:0`);
    } else if (
      isUtiqConsentGranted === true &&
      optanonIsCmpConsentGranted === false
    ) {
      window.Optanon?.UpdateConsent('Category', `${utiqPurposeId}:1`);
      window.Optanon?.UpdateConsent('General Vendor', `${utiqVendorId}:1`);
    } else if (
      isUtiqConsentGranted === undefined &&
      optanonIsCmpConsentGranted !== undefined
    ) {
      window.Utiq?.API?.handleConsentChange(optanonIsCmpConsentGranted);
    }
  }, 250);
};

window.Utiq ||= {};
window.Utiq.queue ||= [];
window.Utiq.queue.push(() => {
  window.addEventListener('consent.onetrust', () => {
    const optanonConsent = isUserConsentGranted();
    if (
      window.Utiq.API.getUtiqConsentStatus() === undefined ||
      optanonConsent !== undefined
    ) {
      window.Utiq.API.handleConsentChange(optanonConsent, {
        syncConsentOnAccept: Boolean(optanonConsent), // syncConsentOnAccept flag should be only set to true when the consent is explicitly accepted
      });
    }
  });
  updateConsent(window.Utiq.API.getUtiqConsentStatus());
  window.Utiq.listeners ||= {};
  window.Utiq.listeners.onConsentUpdateFinished ||= [];
  window.Utiq.listeners.onConsentUpdateFinished.push(({ isConsentGranted }) => {
    updateConsent(isConsentGranted);
  });
});

window.Utiq ||= {};
window.Utiq.config = {
  CMP: 'none',
};
(() => {
  const a = document.createElement('script');
  a.type = 'text/javascript';
  a.src = '/utiqLoader.js';
  document.head.appendChild(a);
})();

Function to open 2nd layer

CODE
window.Optanon.ToggleInfoDisplay()
iubenda

iubenda

Last update: October 2025 (check vendor documentation)

Complete Iubenda integration snippet

JS
/* Initialize required namespaces */
const iubendaPurposeId = '[INSERT UTIQ CUSTOM PURPOSE]';
var _iub = _iub || [];
window.Utiq ||= [];
window.Utiq.queue ||= [];

let isFirstLoad = true;

const isConsentGranted = () => {
  const preferences = _iub.cs?.api?.getPreferences();
  if (preferences === undefined) return undefined;
  return typeof preferences.purposes?.[iubendaPurposeId] === 'boolean'
    ? preferences.purposes?.[iubendaPurposeId]
    : undefined;
};

_iub.csConfiguration.callback = {
  onPreferenceExpressed(context) {
    if (!isFirstLoad) {
      const preferences = _iub.cs?.api?.getPreferences();
      window.Utiq.queue.push(() => {
        window.Utiq?.API?.handleConsentChange(
          preferences?.purposes.[iubendaPurposeId] === true,
          {
            syncConsentOnAccept: Boolean(context.gppString), // syncConsentOnAccept flag should be only set to true when the consent is explicitly accepted
          },
        );
      });
    }
  },
};

const updateConsent = (consent) => {
  const iubendaIsCmpConsentGranted = isConsentGranted();
  setTimeout(() => {
    if (consent === false && iubendaIsCmpConsentGranted === true) {
      _iub.cs?.api?.setPreferences({
        purposes: {
          [iubendaPurposeId]: false,
        },
      });
    } else if (consent === true && iubendaIsCmpConsentGranted === false) {
      _iub.cs?.api?.setPreferences({
        purposes: {
          [iubendaPurposeId]: true,
        },
      });
    } else if (
      consent === undefined &&
      iubendaIsCmpConsentGranted !== undefined
    ) {
      window.Utiq?.API?.handleConsentChange(iubendaIsCmpConsentGranted);
    }
    isFirstLoad = false;
  }, 250);
};

setTimeout(() => {
  window.Utiq.queue.push(() => {
    try {
      const utiqConsent = window.Utiq.API.getUtiqConsentStatus();
      if (utiqConsent !== null) {
        updateConsent(utiqConsent);
      } else {
        const iubendaIsCmpConsentGranted = isConsentGranted();
        if (iubendaIsCmpConsentGranted !== undefined) {
          window.Utiq.API.handleConsentChange(iubendaIsCmpConsentGranted);
        }
      }
    } catch (err) {
      console.error(
        `getUtiqConsentStatus API call failed. Reason: ${err.message}`,
      );
      const iubendaIsCmpConsentGranted = isConsentGranted();
      if (iubendaIsCmpConsentGranted !== undefined) {
        window.Utiq.API.handleConsentChange(iubendaIsCmpConsentGranted);
      }
    }
    window.Utiq.API.addEventListener(
      'onConsentUpdateFinished',
      ({ isConsentGranted }) => {
        updateConsent(isConsentGranted);
      },
    );
  });
}, 250);

window.Utiq.config = {
  CMP: 'none',
};
(() => {
  const a = document.createElement('script');
  a.type = 'text/javascript';
  a.src = '/utiqLoader.js';
  document.head.appendChild(a);
})();

Function to open 2nd layer

CODE
_iub.cs.api.openPreferences()
Sourcepoint

Sourcepoint

Last update: November 2025 (check vendor documentation)

Sourcepoint full code to use

JS
/* ID strings */
const utiqPurposeId = '[INSERT UTIQ CUSTOM PURPOSE]';
const utiqVendorId = '[INSERT UTIQ CUSTOM VENDOR]';

/* Initialize required namespaces */
window.Utiq ||= {};
window.Utiq.API ||= {};
window.Utiq.queue ||= [];
window._sp_ ||= [];
window._sp_.API ||= [];
window._sp_queue ||= [];

const getConsentUUID = () => {
  const match = document.cookie.match(/(?:^|;\s*)consentUUID=([^;]+)/);
  return match ? decodeURIComponent(match[1]) : null;
}

/* Function provided by Sourcepoint team to remove a single purpose and vendor */
const deleteCustomConsent = async ({
    siteId,
    vendors = [],
    categories = [],
    legIntCategories = [],
  }) => {
    const consentUUID = getConsentUUID();
    if (!consentUUID) {
      console.error('Consent UUID cookie not found');
      return;
    }

    const url = `https://cdn.privacy-mgmt.com/consent/tcfv2/consent/v3/custom/${encodeURIComponent(
      siteId,
    )}?consentUUID=${encodeURIComponent(consentUUID)}`;

    const body = JSON.stringify({
      vendors,
      categories,
      legIntCategories,
    });

    try {
      const response = await fetch(url, {
        method: 'DELETE',
        headers: {
          'Content-Type': 'application/json',
        },
        body,
      });

      if (!response.ok) {
        const errorText = await response.text();
        throw new Error(
          `Request failed: ${response.status} ${response.statusText}\n${errorText}`,
        );
      }

      const result = await response.json().catch(() => ({}));
      console.log('Deleted successfully:', result);
      return result;
    } catch (error) {
      console.error('Error deleting custom consent data:', error);
    }
  };

/* Function to get purpose and vendor consents */
const getConsents = async({
  siteId,
  vendorId,
  purposeId,
}) => {
  const consentUUID = getConsentUUID();
  if (!consentUUID) {
    console.log('Consent UUID cookie not found');
    return {
      vendorConsent: undefined,
      purposeConsent: undefined,
    };
  }

  const url = `https://cdn.privacy-mgmt.com/consent/tcfv2/consent/v3/${encodeURIComponent(
    siteId,
  )}?consentUUID=${consentUUID}&separateLegIntVendors=true`;

  try {
    const response = await fetch(url, {
      method: 'GET',
      headers: {
        'Content-Type': 'application/json',
      },
    });

    if (!response.ok) {
      const errorText = await response.text();
      throw new Error(
        `Request failed: ${response.status} ${response.statusText}\n${errorText}`,
      );
    }

    const result = await response.json().catch(() => ({}));
    console.log('Get consents response success');

    return {
      vendorConsent: result.vendors.includes(vendorId),
      purposeConsent: result.categories.includes(purposeId),
    };
  } catch (error) {
    console.error('Error getting consent data:', error);
  }
};

/* End of the function provided by Sourcepoint team */

const isCmpConsentGranted = () => {
  return new Promise(async (resolve) => {
    await __tcfapi('getCustomVendorConsents', 2, async function (data) {
      const { vendorConsent, purposeConsent } =
        await getConsents({
          siteId: window._sp_.metricData.propertyId,
          utiqVendorId,
          utiqPurposeId,
        });
      if (data.newUser) {
        resolve(undefined);
      } else if (purposeConsent === true && vendorConsent !== false) {
        resolve(true);
      } else {
        resolve(false);
      }
    });
  });
};

const updateConsent = async (consent) => {
  const sourcepointIsCmpConsentGranted = await isCmpConsentGranted();
  if (consent === false && sourcepointIsCmpConsentGranted) {
    deleteCustomConsent({
      siteId: window._sp_.metricData.propertyId,
      vendors: [utiqVendorId],
      categories: [utiqPurposeId],
      legIntCategories: [],
    });
  } else if (consent === true && sourcepointIsCmpConsentGranted === false) {
    __tcfapi(
      'postCustomConsent',
      2,
      function () {},
      [utiqVendorId],
      [utiqPurposeId],
      [],
    );
  } else if (
    consent === undefined &&
    sourcepointIsCmpConsentGranted !== undefined
  ) {
    window.Utiq.API.handleConsentChange(sourcepointIsCmpConsentGranted);
  }
};

window._sp_queue.push(() => {
  window.Utiq.queue.push(() => {
    window._sp_.addEventListener('onPrivacyManagerAction', () =>
      window._sp_.addEventListener('onConsentReady', async () => {
        window.Utiq.API.handleConsentChange(await isCmpConsentGranted());
      }),
    );
    window._sp_.addEventListener('onMessageChoiceSelect', () =>
      window._sp_.addEventListener('onConsentReady', async () => {
        window.Utiq.API.handleConsentChange(await isCmpConsentGranted(), {
          syncConsentOnAccept: true, // syncConsentOnAccept flag should be only set to true when the consent is explicitly accepted
        });
      }),
    );

    try {
      updateConsent(window.Utiq.API.getUtiqConsentStatus());
    } catch (err) {
      console.error(
        `getUtiqConsentStatus API call failed. Reason: ${err.message}`,
      );
    }
    window.Utiq.API.addEventListener(
      'onConsentUpdateFinished',
      ({ isConsentGranted }) => {
        updateConsent(isConsentGranted);
      },
    );
  });
});

window.Utiq.config = {
  CMP: 'none',
};

(() => {
  const a = document.createElement('script');
  a.type = 'text/javascript';
  a.src = '/utiqLoader.js';
  document.head.appendChild(a);
})();

Function to open 2nd layer

JS
window._sp_.gdpr.loadPrivacyManagerModal([INSERT]);
Usercentrics

Usercentrics

Last update: October 2025 (check vendor documentation)

Complete Usercentrics integration snippet

JS
/* Initialize required namespaces */
window.Utiq ||= {};
window.Utiq.API ||= {};
window.Utiq.queue ||= [];

/* Provide Utiq service name */
const UTIQ_SERVICE_NAME = '[INSERT UTIQ SERVICE CUSTOM NAME]';

let isFirstLoad = true;

/* Usercentrics APIs handler */
const ucApiHandler = {
  hasCmpV3: () => typeof window.__ucCmp !== 'undefined',
  hasUiApi: () =>
    typeof window.UC_UI?.isInitialized === 'function' &&
    window.UC_UI.isInitialized(),
  async getServiceInfo() {
    try {
      if (ucApiHandler.hasCmpV3()) {
        return (await window.__ucCmp.getServicesBaseInfo()).find(
          (service) => service.name === UTIQ_SERVICE_NAME,
        );
      } else if (ucApiHandler.hasUiApi()) {
        return (await window.UC_UI.getServicesBaseInfo()).find(
          (service) => service.name === UTIQ_SERVICE_NAME,
        );
      } else {
        return undefined;
      }
    } catch (err) {
      console.error('getServiceId failed:', err);
      return undefined;
    }
  },
  async getConsentInfo() {
    try {
      if (ucApiHandler.hasCmpV3()) {
        return Object.values(
          (await window.__ucCmp.getConsentDetails())?.services,
        ).find((serviceInfo) => serviceInfo?.name === UTIQ_SERVICE_NAME)
          ?.consent;
      } else if (ucApiHandler.hasUiApi()) {
        return (await window.UC_UI.getServicesBaseInfo()).find(
          (service) => service.name === UTIQ_SERVICE_NAME,
        )?.consent;
      } else {
        return undefined;
      }
    } catch (err) {
      console.error('getServiceId failed:', err);
      return undefined;
    }
  },
  async getConsentStatus() {
    try {
      const consentInfo = await ucApiHandler.getConsentInfo();
      if (ucApiHandler.hasCmpV3()) {
        return consentInfo?.type === 'EXPLICIT'
          ? consentInfo?.given
          : undefined;
      } else if (ucApiHandler.hasUiApi()) {
        const consentHistory =
          consentInfo?.history?.[consentInfo.history.length - 1];
        return consentHistory?.type === 'explicit'
          ? consentHistory?.status
          : undefined;
      } else {
        return undefined;
      }
    } catch (err) {
      console.error('getConsentStatus failed:', err);
      return undefined;
    }
  },
  async updateConsent(newConsentValue) {
    try {
      const serviceId = (await this.getServiceInfo())?.id;
      if (this.hasCmpV3()) {
        await window.__ucCmp.updateServicesConsents([
          {
            id: serviceId,
            consent: newConsentValue,
          },
        ]);
        window.__ucCmp.saveConsents();
      } else if (this.hasUiApi()) {
        if (newConsentValue === false) {
          await window.UC_UI.rejectService(serviceId);
        } else if (newConsentValue === true) {
          await window.UC_UI.acceptService(serviceId);
        }
      } else {
        throw Error(
          'Neither V2 nor V2 usercentrics APIs were available when updating the consent',
        );
      }
    } catch (err) {
      console.error('updateConsent failed:', err);
    }
  },
};

const updateConsent = async (newConsentValue) => {
  const cmpConsentGranted = await ucApiHandler.getConsentStatus();

  if (newConsentValue === undefined && cmpConsentGranted !== undefined) {
    try {
      window.Utiq?.API?.handleConsentChange(cmpConsentGranted);
    } catch (err) {
      console.error(`handleConsentChange failed: ${err?.message}`);
    }
    isFirstLoad = false;
    return;
  } else if (
    (cmpConsentGranted === true || cmpConsentGranted === false) &&
    newConsentValue !== cmpConsentGranted
  ) {
    try {
      await ucApiHandler.updateConsent(newConsentValue);
    } catch (err) {
      console.error('Error updating Usercentrics consent:', err);
    } finally {
      isFirstLoad = false;
    }
    return;
  }

  isFirstLoad = false;
};

window.addEventListener('ucEvent', async function (e) {
  if (e.detail && e.detail.event === 'consent_status') {
    /* Avoid interatcion on first load */
    if (e.detail.action === 'onInitialPageLoad' || isFirstLoad) {
      return;
    }
    const utiqServiceConsent = await ucApiHandler.getConsentStatus();
    let utiqConsent =
      utiqServiceConsent !== undefined
        ? utiqServiceConsent
        : e.detail[UTIQ_SERVICE_NAME];

    window.Utiq.queue.push(() => {
      try {
        if (
          e.detail.action === 'onAcceptAllServices' ||
          (e.detail.action === 'onUpdateServices' && utiqConsent)
        ) {
          window.Utiq?.API?.handleConsentChange(utiqConsent, {
            syncConsentOnAccept: true, // syncConsentOnAccept flag should be only set to true when the consent is explicitly accepted
          });
        } else {
          window.Utiq?.API?.handleConsentChange(utiqConsent);
        }
      } catch (err) {
        console.error(
          `handleConsentChange API call failed. Reason: ${err.message}`,
        );
      }
    });
  }
});

window.addEventListener('UC_UI_INITIALIZED', function (_event) {
  window.Utiq.queue.push(async () => {
    try {
      const utiqConsentStatus =
        typeof window.Utiq?.API?.getUtiqConsentStatus === 'function'
          ? window.Utiq.API.getUtiqConsentStatus()
          : await ucApiHandler.getConsentStatus();

      updateConsent(utiqConsentStatus);
    } catch (err) {
      console.error(
        `getUtiqConsentStatus API call failed. Reason: ${err.message}`,
      );
    }

    window.Utiq.API.addEventListener(
      'onConsentUpdateFinished',
      ({ isConsentGranted }) => {
        updateConsent(isConsentGranted);
      },
    );
  });
});

window.Utiq.config = {
  CMP: 'none',
};
(() => {
  const a = document.createElement('script');
  a.type = 'text/javascript';
  a.src = '/utiqLoader.js';
  document.head.appendChild(a);
})();

Function to open 2nd layer

Usercentrics V3:

CODE
await window.__ucCmp.showSecondLayer()

Usercentrics V2:

CODE
await window.UC_UI.showSecondLayer()

(For 1. Option C: Consent or Pay Model only) Correct configuration of consent/accept and pay/reject functions

The CMP must be configured to ensure that Utiq calls are only triggered if user consents to the activation of Utiq technology. In particular:

  • Utiq technology must be off by default.

  • Utiq technology must not be enabled if a user specifically:

    • selects the “pay” option

    • rejects consent to the use of Utiq technology (rejects Utiq custom purpose and/or Utiq custom vendor)

    • makes an overall rejection of all non-essential cookies and other tracking technologies

    • withdraws Utiq consent (from the main CMP, Manage Utiq footer and consenthub) or withdraws all consents (i.e. including Utiq)

    • if the user, after having accepted, decides to “pay/subscribe”

To reject Utiq consent, please implement the following code to be executed:

JS
window.Utiq.API.handleConsentChange(false);

For testing purposes, please:

  • provide us a mock “subscription” account for testing; or 

  • provide us a confirmation/recording about your payment journeys behaviour (see above)

Testing

To validate the integration, you will need to run the “Utiq Integrated Model” test cases.

JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.