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.

JS
// 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);
    }
  }
};
(() => {
  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.

APIs for CMP vendors

Below is a list of APIs you can call, based on your CMP vendor, and full codes to use.

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 check on CMP vendor documentation:

Where to add it

API

Before appending utiqLoader.js

On comment(s)

JS
// Call 'handleConsentChange' when CMP Consent changes
JS
window.didomiOnReady ||= [];
window.didomiOnReady.push((Didomi) => {
  window.didomiEventListeners ||= [];
  window.didomiEventListeners.push({
    event: 'consent.changed',
    listener() {
      const utiqPurposeConsent = Didomi.getUserConsentStatusForPurpose([INSERT UTIQ CUSTOM PURPOSE]);
      const utiqVendorConsent = Didomi.getUserConsentStatusForVendor([INSERT UTIQ CUSTOM VENDOR]);
      window.Utiq.queue.push(() => {
        try {
          window.Utiq.API.handleConsentChange(utiqPurposeConsent === true && utiqVendorConsent !== false);
        } catch (err) {
          console.error(
            `handleConsentChange API call failed. Reason: ${err.message}`,
          );
        }
      });
    },
  });
});

On load and in onConsentUpdateFinished Utiq’s event listener if Utiq consent is false

On comment(s)

JS
// Turn Utiq purpose AND vendor to false on CMP if needed
JS
const transaction = Didomi.openTransaction();
transaction.disablePurpose([INSERT UTIQ CUSTOM PURPOSE]);
transaction.disableVendor([INSERT UTIQ CUSTOM VENDOR]);
transaction.commit();

Function to open 2nd layer

JS
Didomi.preferences.show()

Putting it all together - full code to use

JS
// Set your CMP configuration for Utiq purpose & vendor (if used)
const cmpUtiqPurposeId = "[INSERT UTIQ CUSTOM PURPOSE]";
const cmpUtiqVendorId = "[INSERT UTIQ CUSTOM VENDOR]"; // (if used)

// 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.didomiOnReady ||= [];
window.didomiOnReady.push((Didomi) => {
  window.didomiEventListeners ||= [];
  window.didomiEventListeners.push({
    event: 'consent.changed',
    listener() {
      const utiqPurposeConsent = Didomi.getUserConsentStatusForPurpose([INSERT UTIQ CUSTOM PURPOSE]);
      const utiqVendorConsent = Didomi.getUserConsentStatusForVendor([INSERT UTIQ CUSTOM VENDOR]);
      window.Utiq.queue.push(() => {
        try {
          window.Utiq.API.handleConsentChange(utiqPurposeConsent === true && utiqVendorConsent !== false);
        } catch (err) {
          console.error(
            `handleConsentChange API call failed. Reason: ${err.message}`,
          );
        }
      });
    },
  });
});

// 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
    const transaction = Didomi.openTransaction();
    transaction.disablePurpose(cmpUtiqPurposeId);
    transaction.disableVendor(cmpUtiqVendorId);
    transaction.commit();
  }
});

// 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
          const transaction = Didomi.openTransaction();
          transaction.disablePurpose(cmpUtiqPurposeId);
          transaction.disableVendor(cmpUtiqVendorId);
          transaction.commit();
        }
      }, 250);
    }
  }
};
(() => {
  const s = document.createElement("script")
  s.type = 'text/javascript';
  s.src = "https://utiq.example.com/utiqLoader.js"
  s.async = true;
  document.head.appendChild(s)
})();
OneTrust and CookiePro

OneTrust and CookiePro

Last check on CMP vendor documentation:

Where to add it

API

Before appending utiqLoader.js

On comment(s)

JS
// Call 'handleConsentChange' when CMP Consent changes
JS
window.Utiq ||= {};
window.Utiq.queue ||= [];
window.Utiq.queue.push(() => {
  window.addEventListener('consent.onetrust', () => {
    let utiqPurposeConsent = null;
    if (OptanonActiveGroups) {
      utiqPurposeConsent = OptanonActiveGroups.indexOf('[INSERT UTIQ CUSTOM PURPOSE]') !== -1;
    }
    try {
      window.Utiq.API.handleConsentChange(utiqPurposeConsent);
    } catch (err) {
      console.error(
        `handleConsentChange API call failed. Reason: ${err.message}`,
      );
    }
  });
});

On load and in onConsentUpdateFinished Utiq’s event listener if Utiq consent is false

On comment(s)

JS
// Turn Utiq purpose AND vendor to false on CMP if needed
JS
window.Optanon.UpdateConsent('Category', '[INSERT UTIQ CUSTOM PURPOSE]:0');

Function to open 2nd layer

JS
window.Optanon.ToggleInfoDisplay()

Putting it all together - full code to use

JS
// Set your CMP configuration for Utiq purpose & vendor (if used)
const cmpUtiqPurposeId = "[INSERT UTIQ CUSTOM PURPOSE]";
const cmpUtiqVendorId = "[INSERT UTIQ CUSTOM VENDOR]"; // (if used)

// 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 ||= {};
window.Utiq.queue ||= [];
window.Utiq.queue.push(() => {
  window.addEventListener('consent.onetrust', () => {
    let utiqPurposeConsent = null;
    if (OptanonActiveGroups) {
      utiqPurposeConsent = OptanonActiveGroups.indexOf(cmpUtiqPurposeId) !== -1;
    }
    try {
      window.Utiq.API.handleConsentChange(utiqPurposeConsent);
    } catch (err) {
      console.error(
        `handleConsentChange API call failed. Reason: ${err.message}`,
      );
    }
  });
});

// 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
    window.Optanon.UpdateConsent('Category', cmpUtiqPurposeId+':0');
  }
});

// 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
          window.Optanon.UpdateConsent('Category', cmpUtiqPurposeId+':0');
        }
      }, 250);
    }
  }
};
(() => {
  const s = document.createElement("script")
  s.type = 'text/javascript';
  s.src = "https://utiq.example.com/utiqLoader.js"
  s.async = true;
  document.head.appendChild(s)
})();
iubenda

iubenda

Last check on CMP vendor documentation:

Where to add it

API

Before appending utiqLoader.js

On comment(s)

JS
// Call 'handleConsentChange' when CMP Consent changes
JS
_iub.csConfiguration.callback = {
  onPreferenceExpressed() {
    const preferences = _iub.cs?.api?.getPreferences();
    window.Utiq.API.handleConsentChange(preferences?.purposes.[INSERT UTIQ CUSTOM PURPOSE] === true && preferences?.vendors.[INSERT UTIQ CUSTOM VENDOR] !== false);
  },
};

On load and in onConsentUpdateFinished Utiq’s event listener if Utiq consent is false

On comment(s)

JS
// Turn Utiq purpose AND vendor to false on CMP if needed
JS
_iub.cs?.api?.setPreferences({
  purposes: {
    [INSERT UTIQ CUSTOM PURPOSE]: false,
  },
  vendors: {
    [INSERT UTIQ CUSTOM VENDOR]: false,
  },
});

Function to open 2nd layer

JS
_iub.cs.api.openPreferences()

Putting it all together - full code to use

JS
// Set your CMP configuration for Utiq purpose & vendor (if used)
const cmpUtiqPurposeId = "[INSERT UTIQ CUSTOM PURPOSE]";
const cmpUtiqVendorId = "[INSERT UTIQ CUSTOM VENDOR]"; // (if used)

// 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
_iub.csConfiguration.callback = {
  onPreferenceExpressed() {
    const preferences = _iub.cs?.api?.getPreferences();
    window.Utiq.API.handleConsentChange(preferences?.purposes.cmpUtiqPurposeId === true && preferences?.vendors.cmpUtiqVendorId !== false);
  },
};

// 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
    _iub.cs?.api?.setPreferences({
      purposes: {
        cmpUtiqPurposeId: false,
      },
      vendors: {
        cmpUtiqVendorId: false,
      },
    });
  }
});

// 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
          _iub.cs?.api?.setPreferences({
            purposes: {
              cmpUtiqPurposeId: false,
            },
            vendors: {
              cmpUtiqVendorId: false,
            },
          });
        }
      }, 250);
    }
  }
};
(() => {
  const s = document.createElement("script")
  s.type = 'text/javascript';
  s.src = "https://utiq.example.com/utiqLoader.js"
  s.async = true;
  document.head.appendChild(s)
})();
Sourcepoint

Sourcepoint

Last check on CMP vendor documentation:

Where to add it

API

Before appending utiqLoader.js

On comment(s)

JS
// Call 'handleConsentChange' when CMP Consent changes
JS
setTimeout(() => {
  const isConsentGranted = await __tcfapi('getCustomVendorConsents', 2, function (data) {
    purposeIds = data.consentedPurposes.map((item) => item._id);
    vendorIds = data.consentedVendors.map((item) => item._id);
    utiqPurposeConsent = purposeIds.includes('[INSERT UTIQ CUSTOM PURPOSE]');
    utiqVendorConsent = vendorIds.includes('[INSERT UTIQ CUSTOM VENDOR]');
    if (utiqPurposeConsent === true && utiqVendorConsent !== false) {
      resolve(true);
    } else {
      resolve(false);
    }
  });
  try {
    window.Utiq.API.handleConsentChange(isConsentGranted);
  } catch (err) {
    console.error(
      `handleConsentChange API call failed. Reason: ${err.message}`,
    );
  }
}, 250);

On load and in onConsentUpdateFinished Utiq’s event listener if Utiq consent is false

On comment(s)

JS
// Turn Utiq purpose AND vendor to false on CMP if needed
JS
let purposeIds = [];
let vendorIds = [];
await __tcfapi('getCustomVendorConsents', 2, function (data) {
  purposeIds = data.consentedPurposes.map((item) => item._id);
  vendorIds = data.consentedVendors.map((item) => item._id);
});
__tcfapi('postRejectAll', 2, function () {
  __tcfapi(
    'postCustomConsent',
    2,
    function () {},
    vendorIds.filter((item) => item !== '[INSERT UTIQ CUSTOM VENDOR]'),
    purposeIds.filter((item) => item !== '[INSERT UTIQ CUSTOM PURPOSE]'),
    [],
  );
});

Function to open 2nd layer

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

Putting it all together - full code to use

JS
// Set your CMP configuration for Utiq purpose & vendor (if used)
const cmpUtiqPurposeId = "[INSERT UTIQ CUSTOM PURPOSE]";
const cmpUtiqVendorId = "[INSERT UTIQ CUSTOM VENDOR]"; // (if used)

// 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
setTimeout(() => {
  const isConsentGranted = await __tcfapi('getCustomVendorConsents', 2, function (data) {
    purposeIds = data.consentedPurposes.map((item) => item._id);
    vendorIds = data.consentedVendors.map((item) => item._id);
    utiqPurposeConsent = purposeIds.includes('cmpUtiqPurposeId');
    utiqVendorConsent = vendorIds.includes('cmpUtiqVendorId');
    if (utiqPurposeConsent === true && utiqVendorConsent !== false) {
      resolve(true);
    } else {
      resolve(false);
    }
  });
  try {
    window.Utiq.API.handleConsentChange(isConsentGranted);
  } catch (err) {
    console.error(
      `handleConsentChange API call failed. Reason: ${err.message}`,
    );
  }
}, 250);

// 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
    let purposeIds = [];
    let vendorIds = [];
    await __tcfapi('getCustomVendorConsents', 2, function (data) {
      purposeIds = data.consentedPurposes.map((item) => item._id);
      vendorIds = data.consentedVendors.map((item) => item._id);
    });
    __tcfapi('postRejectAll', 2, function () {
      __tcfapi(
        'postCustomConsent',
        2,
        function () {},
        vendorIds.filter((item) => item !== cmpUtiqPurposeId),
        purposeIds.filter((item) => item !== cmpUtiqVendorId),
        [],
      );
    });
  }
});

// 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
          let purposeIds = [];
          let vendorIds = [];
          await __tcfapi('getCustomVendorConsents', 2, function (data) {
            purposeIds = data.consentedPurposes.map((item) => item._id);
            vendorIds = data.consentedVendors.map((item) => item._id);
          });
          __tcfapi('postRejectAll', 2, function () {
            __tcfapi(
              'postCustomConsent',
              2,
              function () {},
              vendorIds.filter((item) => item !== cmpUtiqPurposeId),
              purposeIds.filter((item) => item !== cmpUtiqVendorId),
              [],
            );
          });
        }
      }, 250);
    }
  }
};
(() => {
  const s = document.createElement("script")
  s.type = 'text/javascript';
  s.src = "https://utiq.example.com/utiqLoader.js"
  s.async = true;
  document.head.appendChild(s)
})();

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.