Skip to content

Building your own CMP

The Usercentrics SDK allows you to build a fully compliant CMP of your own. For this, we have provided an API that provides all the data and action delegates needed.

Be aware that there are implementation differences between each legal framework, due to divergent legal requirements.

General Data Protection Regulation (GDPR)

The European Union's General Data Protection Regulation applies to any business in the EU as well as organizations outside the EU that collect, process and store information on EU citizens, as well as non-citizens residing in the EU.

To get you started, we have provided a compliance checklist to help you understand the requirements of a GDPR CMP.

Data Source

UsercentricsCore.isReady { status in

    let data = UsercentricsCore.shared.getCMPData()
    let settings = data.settings
    let services = data.services
    let categories = data.categories

} onFailure: { error in
    // Handle non-localized error
}
Usercentrics.isReady({

    val data = Usercentrics.instance.getCMPData()
    val settings = data.settings
    val services = data.services
    val categories = data.categories

}, { error ->
    // Handle non-localized error
})

Matching Categories and Services

You may match services to categories with category.slug == service.categorySlug.

Content Mapping

To help you navigate our Data Source, please see the following content mapping tables:

CMP Component SDK Property
1. Title settings.labels.firstLayerTitle
2. Description settings.bannerMessage
3. Short Description settings.bannerMobileDescription
4. Read More settings.labels.btnBannerReadMore
5. Privacy Policy Text settings.labels.privacyPolicyLinkText
6. Privacy Policy URL settings.privacyPolicyUrl
7. Imprint Text settings.labels.imprintLinkText
8. Imprint URL settings.imprintUrl
9. Language Selected settings.language
10. Languages Available settings.languagesAvailable
11. Categories Tab settings.secondLayer.tabsCategoriesLabel
12. Services Tab settings.secondLayer.tabsServicesLabel
13. Accept All settings.labels.btnAcceptAll
14. Deny All settings.labels.btnDeny
15. Save Services settings.labels.btnSave
Category Component SDK Property
16. Category Name category.label
17. Category Description category.description
Services Component SDK Property
18. Service Name service.dataProcessor
19. Service Description Title settings.labels.descriptionOfService
20. Service Description service.descriptionOfService
21. Processing Company Title settings.labels.processingCompanyTitle
22. Processing Company service.nameOfProcessingCompany + service.addressOfProcessingCompany
23. Data Purposes Title settings.labels.dataPurposes
24. Data Purposes Description settings.labels.dataPurposesInfo
25. Data Purposes service.dataPurposesList
26. Technologies Used Title settings.labels.technologiesUsed
27. Technologies Used Description settings.labels.technologiesUsedInfo
28. Technologies Used service.technologyUsed
29. Data Collected Title settings.labels.dataCollectedList
30. Data Collected Description settings.labels.dataCollectedListInfo
31. Data Collected service.dataCollectedList
32. Legal Bases Title settings.labels.legalBasisList
33. Legal Bases Description settings.labels.legalBasisInfo
34. Legal Bases service.legalBasisList
35. Processing Location Title settings.labels.locationOfProcessing
36. Processing Location service.locationOfProcessing
37. Retention Period Title settings.labels.retentionPeriod
38. Retention Period service.retentionPeriodDescription
39. Third Country Distribution Title settings.labels.transferToThirdCountries
40. Third Country Distribution service.thirdCountryTransfer
41. Data Recipients Title settings.labels.dataRecipientsList
42. Data Recipients service.dataRecipientsList
43. Privacy Policy Title settings.labels.policyOf
44. Privacy Policy service.privacyPolicyURL
45. Cookie Policy Title settings.labels.cookiePolicyInfo
46. Cookie Policy service.cookiePolicyURL
47. Opt Out Link Title settings.labels.optOut
48. Opt Out Link service.optOutUrl
49. History Title settings.labels.history
51. History service.consent.history
52. History Consent Given settings.labels.yes
53. History Consent Not Given settings.labels.no
54. History Explicit Consent settings.labels.explicit
55. History Implicit Consent settings.labels.implicit
56. Controller ID status.controllerId (isReady)

Action Delegates

In order to collect consent, we have provided the following 3 functions:

Accept All

let consents = UsercentricsCore.shared.acceptAll(consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.acceptAll(consentType = <UsercentricsConsentType>)

Deny All

let consents = UsercentricsCore.shared.denyAll(consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.denyAll(consentType = <UsercentricsConsentType>)

Save

For granular selection, you may pass specific sets of consent with an array of decisions:

let consents = UsercentricsCore.shared.saveDecisions(decisions: <[UserDecision]>, consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.saveDecisions(decisions = <[UserDecision]>, consentType = <UsercentricsConsentType>)

Consent Type

The consent type should be based on if a customer made an explicit action to provide consent, or not. Implicit can be used if the user ignores or skips the CMP. We highly recommend you only use implicit together with the denyAll() method, which will accept only essential services.

The Interactive Advertising Bureau, (IAB Europe) has created the GDPR Transparency and Consent Framework (TCF 2.0) to support publishers, technology vendors and advertisers in being compliant with EU’s GDPR and ePrivacy Directive.

Be aware that a validation process with the IAB is required, in order to become a licensed TCF 2.0 CMP provider.

IAB Data Source

UsercentricsCore.isReady { status in

    // CMP Data
    let data = UsercentricsCore.shared.getCMPData()
    let settings = data.settings
    let tcfSettings = settings.tcf2

    // TCF Data
    let tcfData = UsercentricsCore.shared.getTCFData()
    let purposes = tcfData.purposes
    let specialPurposes = tcfData.specialPurposes
    let features = tcfData.features
    let specialFeatures = tcfData.specialFeatures
    let stacks = tcfData.stacks
    let vendors = tcfData.vendors

    // TCString
    let tcString = UsercentricsCore.shared.getTCString()

} onFailure: { error in
    // Handle non-localized error
}
Usercentrics.isReady({

    // CMP Data
    val data = Usercentrics.instance.getCMPData()
    val settings = data.settings
    val tcfSettings = settings.tcf2

    // TCF Data
    val tcfData = Usercentrics.instance.getTCFData()
    val purposes = tcfData.purposes
    val specialPurposes = tcfData.specialPurposes
    val features = tcfData.features
    val specialFeatures = tcfData.specialFeatures
    val stacks = tcfData.stacks
    val vendors = tcfData.vendors

    // Non-TCF Data - if you have services not included in IAB
    val services = data.services
    val categories = data.categories

    // TCString
    val tcString = Usercentrics.instance.getTCString()

}, { error ->
    // Handle non-localized error
})

Non-IAB Data Source

UsercentricsCore.isReady { status in

    let data = UsercentricsCore.shared.getCMPData()
    let settings = data.settings
    let services = data.services
    let categories = data.categories

} onFailure: { error in
    // Handle non-localized error
}
Usercentrics.isReady({

    val data = Usercentrics.instance.getCMPData()
    val settings = data.settings
    val services = data.services
    val categories = data.categories

}, { error ->
    // Handle non-localized error
})

Matching Categories and Services

You may match services to categories with category.slug == service.categorySlug.

Content Mapping

First Layer SDK Property
1. First layer title tcf2.firstLayerTitle
2. First layer description tcf2.firstLayerDescription
3. First layer additional Info tcf2.firstLayerAdditionalInfo
4. First layer resurface note tcf2.firstLayerNoteResurface
5. Vendorlist link title tcf2.linksVendorListLinkLabel
6. Manage settings link title tcf2.linksManageSettingsLabel
7. Label purposes tcf2.labelsPurposes
8. Label features tcf2.labelsFeatures
Second Layer SDK Property
1. Second layer title tcf2.secondLayerTitle
2. Second layer description tcf2.secondLayerDescription
3. Purposes tab tcf2.tabsPurposeLabel
4. Vendors tab tcf2.tabsVendorsLabel
5. Vendors who are part of TCF tcf2.labelsIabVendors
6. Vendors who are NOT part of TCF tcf2.labelsNonIabVendors
7. Non IAB purposes tcf2.labelsNonIabPurposes
Buttons SDK Property
1. Accept all button title tcf2.buttonsAcceptAllLabel
2. Deny all button title tcf2.buttonsDenyAllLabel
3. Save button title tcf2.buttonsSaveLabel
General SDK Property
1. Language Selected settings.language
2. Languages Available settings.languagesAvailable
3. Privacy Policy Text settings.labels.privacyPolicyLinkText
4. Privacy Policy URL settings.privacyPolicyUrl
5. Imprint Text settings.labels.imprintLinkText
6. Imprint URL settings.imprintUrl
Toggles SDK Property
1. Toggle consent label tcf2.togglesConsentToggleLabel
2. Toggle legitimate interest label tcf2.togglesLegIntToggleLabel
Vendors SDK Property
1. Label title vendor.name
2. Purpose label tcf2.vendorPurpose
3. Purpose Name vendor.purposes[n].[findByPurposeId].name
4. Legitimate interest purpose label tcf2.vendorLegitimateInterestPurposes
5. Legitimate Interest Purpose name vendor.legitimateInterestPurposes[n].[findByPurposeId].name
6. Special purpose label tcf2.vendorSpecialPurposes
7. Special purpose name vendor.specialPurposes[n].[findByPurposeId].name
8. Feature label tcf2.vendorFeatures
9. Feature name vendor.features[n].[findByPurposeId].name
10. Special Feature label tcf2.vendorSpecialFeatures
11. Special Feature name vendor.specialFeatures[n].[findByPurposeId].name
12. Cookie refresh value vendor.cookieRefresh
13. Cookie Age value vendor.cookieMaxAgeSeconds
14. Cookie storage value vendor.usesCookie
15. Non-cookie storage value vendor.usesNonCookieAccess
Purposes SDK Property
1. Label title purpose.name
2. Legitimate interest consent purpose.legitimateInterestConsent
3. Legal Description purpose.descriptionLegal
4. Purpose Description purpose.purposeDescription
5. Consent purpose.consent
Special Purposes SDK Property
1. Label title specialPurpose.name
2. Legal Description specialPurpose.descriptionLegal
3. Purpose Description purpose.purposeDescription
Features SDK Property
1. Label title feature.name
2. Legitimate interest consent feature.legitimateInterestConsent
3. Legal Description feature.descriptionLegal
Special Features SDK Property
1. Label title specialFeature.name
2. Consent specialFeature.consent
3. Description specialFeature.purposeDescription
4. Legal Description specialFeature.descriptionLegal
Stacks SDK Property
1. Label title stack.name
3. Description stack.description
3. Purposes stack.purposeIds
4. Special Features stack.specialFeatureIds

Set CMP ID

When building your own TCF 2.0 CMP, it is required to have your CMP UI design certified by the IAB. Once certified, you will need to provide your CMP ID as follows:

UsercentricsCore.shared.setCMPId(id: <ID>)
Usercentrics.instance.setCMPId(<ID>)

Action Delegates

In order to collect consent, we have provided the following 3 functions:

Accept All

let consents = UsercentricsCore.shared.acceptAllForTCF(fromLayer: <TCFDecisionUILayer>, consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.acceptAllForTCF(fromLayer = <TCFDecisionUILayer>, consentType = <UsercentricsConsentType>)

Deny All

let consents = UsercentricsCore.shared.denyAllForTCF(fromLayer: <TCFDecisionUILayer>, consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.denyAllForTCF(fromLayer = <TCFDecisionUILayer>, consentType = <UsercentricsConsentType>)

Save

For granular selection, you may pass specific sets of consent with an array of TCFUserDecisions.

let consents = UsercentricsCore.shared.saveDecisionsForTCF(tcfDecisions: <[TCFUserDecisions]>, 
                                                           fromLayer: <TCFDecisionUILayer>,
                                                           serviceDecisions: <[UserDecision]>,
                                                           consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.saveDecisionsForTCF(
    tcfDecisions = <[TCFUserDecisions]>, 
    fromLayer = TCFDecisionUILayer.FIRST_LAYER,
    serviceDecisions = <[UserDecision]>, 
    consentType = <UsercentricsConsentType>
)

TCF 2.0 Decision Layer

Depending on your design, you might have 1 or 2 layers for collecting consent. It is required by the IAB, that you specify in which layer the consent was collected. For this, you may pass the corresponding enum value from TCF_DECISION_UI_LAYER.

Consent Type

The consent type should be based on if a customer made an explicit action to provide consent, or not. Implicit can be used if the user ignores or skips the CMP. We highly recommend you only use implicit together with the denyAllForTCF() method, which will accept only essential services.

California Consumer Privacy Act (CCPA)

The California Consumer Privacy Act of 2018 (CCPA) gives consumers more control over the personal information that businesses collect about them and provide guidance on how to implement the law. This landmark law secures new privacy rights for California consumers, including:

  • The right to know about the personal information a business collects about them and how it is used and shared;
  • The right to delete personal information collected from them (with some exceptions);
  • The right to opt-out of the sale of their personal information; and
  • The right to non-discrimination for exercising their CCPA rights.

Businesses are required to give consumers certain notices explaining their privacy practices. The CCPA applies to many businesses, including data brokers.

Data Source

UsercentricsCore.isReady { status in

    let data = UsercentricsCore.shared.getCMPData()
    let settings = data.settings
    let services = data.services
    let categories = data.categories

} onFailure: { error in
    // Handle non-localized error
}
Usercentrics.isReady({

    val data = Usercentrics.instance.getCMPData()
    val settings = data.settings
    val services = data.services
    val categories = data.categories

}, { error ->
    // Handle non-localized error
})

Matching Categories and Services

You may match services to categories with category.slug == service.categorySlug.

Content Mapping

CMP Component SDK Property
1. Title ccpa.firstLayerTitle
2. Description ccpa.appFirstLayerDescription
3. Short Description ccpa.firstLayerMobileDescription
4. Read More settings.labels.btnBannerReadMore
5. Privacy Policy Text settings.labels.privacyPolicyLinkText
6. Privacy Policy URL settings.privacyPolicyUrl
7. Imprint Text settings.labels.imprintLinkText
8. Imprint URL settings.imprintUrl
9. Language Selected settings.language
10. Languages Available settings.languagesAvailable
11. Categories Tab settings.secondLayer.tabsCategoriesLabel
12. Services Tab settings.secondLayer.tabsServicesLabel
13. Do not sell my info label ccpa.optOutNoticeLabel
14. Save button ccpa.btnSave
Category Component SDK Property
16. Category Name category.label
17. Category Description category.description
Services Component SDK Property
18. Service Name service.dataProcessor
19. Service Description Title settings.labels.descriptionOfService
20. Service Description service.descriptionOfService
21. Processing Company Title settings.labels.processingCompanyTitle
22. Processing Company service.nameOfProcessingCompany + service.addressOfProcessingCompany
23. Data Purposes Title settings.labels.dataPurposes
24. Data Purposes Description settings.labels.dataPurposesInfo
25. Data Purposes service.dataPurposesList
26. Technologies Used Title settings.labels.technologiesUsed
27. Technologies Used Description settings.labels.technologiesUsedInfo
28. Technologies Used service.technologyUsed
29. Data Collected Title settings.labels.dataCollectedList
30. Data Collected Description settings.labels.dataCollectedListInfo
31. Data Collected service.dataCollectedList
32. Legal Bases Title settings.labels.legalBasisList
33. Legal Bases Description settings.labels.legalBasisInfo
34. Legal Bases service.legalBasisList
35. Processing Location Title settings.labels.locationOfProcessing
36. Processing Location service.locationOfProcessing
37. Retention Period Title settings.labels.retentionPeriod
38. Retention Period service.retentionPeriodDescription
39. Third Country Distribution Title settings.labels.transferToThirdCountries
40. Third Country Distribution service.thirdCountryTransfer
41. Data Recipients Title settings.labels.dataRecipientsList
42. Data Recipients service.dataRecipientsList
43. Privacy Policy Title settings.labels.policyOf
44. Privacy Policy service.privacyPolicyURL
45. Cookie Policy Title settings.labels.cookiePolicyInfo
46. Cookie Policy service.cookiePolicyURL
47. Opt Out Link Title settings.labels.optOut
48. Opt Out Link service.optOutUrl
49. History Title settings.labels.history
51. History service.consent.history
52. History Consent Given settings.labels.yes
53. History Consent Not Given settings.labels.no
54. History Explicit Consent settings.labels.explicit
55. History Implicit Consent settings.labels.implicit
56. Controller ID status.controllerId (isReady)

Action Delegates

CCPA is a global opted out framework. This means:

  • Consent is a boolean, no granular consent of services.
  • The consent is given by default and the user has to explicitly opt-out.

To collect consent for CCPA, we offer one simplified method:

let ccpaConsents = UsercentricsCore.shared.saveOptOutForCCPA(isOptedOut: <Bool>, consentType: <UsercentricsConsentType>)
val ccpaConsents = Usercentrics.instance.saveOptOutForCCPA(isOptedOut = <Bool>, consentType = <UsercentricsConsentType>)

Consent Type

The consent type should be based on if a customer made an explicit action to provide consent, or not. Implicit can be used if the user ignores or skips the CMP.

Brazil’s Lei Geral de Proteção de Dados (LGPD)

LGPD applies to any business or organization that processes the personal data of people in Brazil, regardless of where that business or organization itself might be located. So, if your company has any customers or clients in Brazil, you should begin preparing for LGPD compliance.

If you are already GDPR compliant, then you have already done the bulk of the work necessary to comply with LGPD. It is only necessary that you set the appropaite Legal Basis for all your services.

Data Source

UsercentricsCore.isReady { status in

    let data = UsercentricsCore.shared.getCMPData()
    let settings = data.settings
    let services = data.services
    let categories = data.categories

} onFailure: { error in
    // Handle non-localized error
}
Usercentrics.isReady({

    val data = Usercentrics.instance.getCMPData()
    val settings = data.settings
    val services = data.services
    val categories = data.categories

}, { error ->
    // Handle non-localized error
})

Matching Categories and Services

You may match services to categories with category.slug == service.categorySlug.

Content Mapping

CMP Component SDK Property
1. Title settings.labels.firstLayerTitle
2. Description settings.bannerMessage
3. Short Description settings.bannerMobileDescription
4. Read More settings.labels.btnBannerReadMore
5. Privacy Policy Text settings.labels.privacyPolicyLinkText
6. Privacy Policy URL settings.privacyPolicyUrl
7. Imprint Text settings.labels.imprintLinkText
8. Imprint URL settings.imprintUrl
9. Language Selected settings.language
10. Languages Available settings.languagesAvailable
11. Categories Tab settings.secondLayer.tabsCategoriesLabel
12. Services Tab settings.secondLayer.tabsServicesLabel
13. Accept All settings.labels.btnAcceptAll
14. Deny All settings.labels.btnDeny
15. Save Services settings.labels.btnSave
Category Component SDK Property
16. Category Name category.label
17. Category Description category.description
Services Component SDK Property
18. Service Name service.dataProcessor
19. Service Description Title settings.labels.descriptionOfService
20. Service Description service.descriptionOfService
21. Processing Company Title settings.labels.processingCompanyTitle
22. Processing Company service.nameOfProcessingCompany + service.addressOfProcessingCompany
23. Data Purposes Title settings.labels.dataPurposes
24. Data Purposes Description settings.labels.dataPurposesInfo
25. Data Purposes service.dataPurposesList
26. Technologies Used Title settings.labels.technologiesUsed
27. Technologies Used Description settings.labels.technologiesUsedInfo
28. Technologies Used service.technologyUsed
29. Data Collected Title settings.labels.dataCollectedList
30. Data Collected Description settings.labels.dataCollectedListInfo
31. Data Collected service.dataCollectedList
32. Legal Bases Title settings.labels.legalBasisList
33. Legal Bases Description settings.labels.legalBasisInfo
34. Legal Bases service.legalBasisList
35. Processing Location Title settings.labels.locationOfProcessing
36. Processing Location service.locationOfProcessing
37. Retention Period Title settings.labels.retentionPeriod
38. Retention Period service.retentionPeriodDescription
39. Third Country Distribution Title settings.labels.transferToThirdCountries
40. Third Country Distribution service.thirdCountryTransfer
41. Data Recipients Title settings.labels.dataRecipientsList
42. Data Recipients service.dataRecipientsList
43. Privacy Policy Title settings.labels.policyOf
44. Privacy Policy service.privacyPolicyURL
45. Cookie Policy Title settings.labels.cookiePolicyInfo
46. Cookie Policy service.cookiePolicyURL
47. Opt Out Link Title settings.labels.optOut
48. Opt Out Link service.optOutUrl
49. History Title settings.labels.history
51. History service.consent.history
52. History Consent Given settings.labels.yes
53. History Consent Not Given settings.labels.no
54. History Explicit Consent settings.labels.explicit
55. History Implicit Consent settings.labels.implicit
56. Controller ID status.controllerId (isReady)

Action Delegates

In order to collect consent, we have provided the following 3 functions:

Accept All

let consents = UsercentricsCore.shared.acceptAll(consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.acceptAll(consentType = <UsercentricsConsentType>)

Deny All

let consents = UsercentricsCore.shared.denyAll(consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.denyAll(consentType = <UsercentricsConsentType>)

Save

For granular selection, you may pass specific sets of consent with an array of decisions:

let consents = UsercentricsCore.shared.saveDecisions(decisions: <[UserDecision]>, consentType: <UsercentricsConsentType>)
val consents = Usercentrics.instance.saveDecisions(decisions = <[UserDecision]>, consentType = <UsercentricsConsentType>)

Consent Type

The consent type should be based on if a customer made an explicit action to provide consent, or not. Implicit can be used if the user ignores or skips the CMP. We highly recommend you only use implicit together with the denyAll() method, which will accept only essential services.