In this article we will cover the IAB __tcfapi() function with the getTCData command. Your organization can use this command to retrieve end-user consent data for IAB purposes, vendors, legitimate interest, publisher restrictions and more. The IAB has more information about the getTCData API command.
the getTCData
command
The getTCData command can be called with the following example:
getTCData
command
__tcfapi('getTCData', 2, function(tcdata, success) { console.log(tcdata); });
Example implementation
Your organization can call the getTCData command through the browser console or Javascript code on a webpage. The command returns the end-user's consent as a data object.
Once your organization's website has loaded enter this command directly into the browser tools console window and press enter:
__tcfapi('getTCData', 2, (tcdata, success) => {
console.log("show tcdata: ", tcdata)
});
Your organization could also use javascript code similar to the following example to help you utilize the values of specific properties of the consent data object:
<html>
<body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cookie/1.4.1/jquery.cookie.min.js"></script>
<script>
!function(t){var e={};function n(r){if(e[r])return e[r].exports;var o=e[r]={i:r,l:!1,exports:{}};return t[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(r,o,function(e){return t[e]}.bind(null,o));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=3)}([function(t,e,n){var r=n(2);t.exports=!r((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a}))},function(t,e){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,e){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,e,n){n(4),function(){if("function"!=typeof window.__tcfapi){var t,e=[],n=window,r=n.document;!n.__tcfapi&&function t(){var e=!!n.frames.__tcfapiLocator;if(!e)if(r.body){var o=r.createElement("iframe");o.style.cssText="display:none",o.name="__tcfapiLocator",r.body.appendChild(o)}else setTimeout(t,5);return!e}()&&(n.__tcfapi=function(){for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];if(!r.length)return e;if("setGdprApplies"===r[0])r.length>3&&2===parseInt(r[1],10)&&"boolean"==typeof r[3]&&(t=r[3],"function"==typeof r[2]&&r[2]("set",!0));else if("ping"===r[0]){var i={gdprApplies:t,cmpLoaded:!1,apiVersion:"2.0"};"function"==typeof r[2]&&r[2](i,!0)}else e.push(r)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,r={};try{r=e?JSON.parse(t.data):t.data}catch(t){}var o=r.__tcfapiCall;o&&n.__tcfapi(o.command,o.parameter,o.version,(function(n,r){var i={__tcfapiReturn:{returnValue:n,success:r,callId:o.callId}};e&&(i=JSON.stringify(i)),t.source.postMessage(i,"*")}))}),!1))}}()},function(t,e,n){var r=n(0),o=n(5).f,i=Function.prototype,c=i.toString,u=/^s*function ([^ (]*)/;r&&!("name"in i)&&o(i,"name",{configurable:!0,get:function(){try{return c.call(this).match(u)[1]}catch(t){return""}}})},function(t,e,n){var r=n(0),o=n(6),i=n(10),c=n(11),u=Object.defineProperty;e.f=r?u:function(t,e,n){if(i(t),e=c(e,!0),i(n),o)try{return u(t,e,n)}catch(t){}if("get"in n||"set"in n)throw TypeError("Accessors not supported");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){var r=n(0),o=n(2),i=n(7);t.exports=!r&&!o((function(){return 7!=Object.defineProperty(i("div"),"a",{get:function(){return 7}}).a}))},function(t,e,n){var r=n(8),o=n(1),i=r.document,c=o(i)&&o(i.createElement);t.exports=function(t){return c?i.createElement(t):{}}},function(t,e,n){(function(e){var n=function(t){return t&&t.Math==Math&&t};t.exports=n("object"==typeof globalThis&&globalThis)||n("object"==typeof window&&window)||n("object"==typeof self&&self)||n("object"==typeof e&&e)||Function("return this")()}).call(this,n(9))},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){var r=n(1);t.exports=function(t){if(!r(t))throw TypeError(String(t)+" is not an object");return t}},function(t,e,n){var r=n(1);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}}]);
</script>
<script>
window._sp_queue = [];
window._sp_ = {
config: {
accountId: 1732,
propertyHref: 'https://www.visitdenmark.com/',
baseEndpoint: 'https://cdn.privacy-mgmt.com',
ccpa: { },
gdpr: { },
events: {
onMessageReady: function (message_type) {},
onMessageChoiceSelect: function (message_type, choice_id, choice_type_id) {},
onPrivacyManagerAction: function (message_type, pmData) {},
onMessageChoiceError: function (message_type, err) {},
onConsentReady: function (message_type, consentUUID, euconsent) {},
onPMCancel: function (message_type) {},
onMessageReceiveData: function (message_type, data) {},
onSPPMObjectReady: function () {},
onError: function (message_type, errorCode, errorObject, userReset) {}
}
}
}
function create_list(key, list_ids_consent) {
//key - the property the list of ids belong to e.g. purpose ids, vendor ids, legitimate interest ids for publisher or end-user consent
//list_ids_consent - array of ids and consent (boolean) give to each
var list_consented = [];
//get purpose or vendor ids in the array
var ids = Object.keys(list_ids_consent);
//get end-user consent for each id in the array
var consented = Object.values(list_ids_consent);
//make a new list of ids and their end-user consent
for(i in consented) {
a = {};
//insert new id for purpose or vendor
a[key] = ids[i];
//insert consent
a["consented"] = consented[i];
//add to list
list_consented.push(a);
}
return(list_consented);
}
function parse_publisherrestrictions(list_ids_consent) {
//extract publisher restrictions from the TCData object & sub-objects
var list_purposes = [];
//Extract list of publisher purpose ids. Extract list of IAB vendor ids
var purpose_ids = Object.keys(list_ids_consent);
var iab_vendor_ids = Object.values(list_ids_consent);
//the list of publisher restrictions
list_restrictions = ['not allowed', 'consent', 'legitimate interest'];
//for each purpose id, extract the IAB vendor and their restriction
for(i in purpose_ids) {
var list_vendors = [];
var vendor = {}; var a = {};
//list of all IAB vendors for current purpose id
var all_iab_vendors = Object.keys(iab_vendor_ids[i]);
//list of all restrictions for current purpose id
var all_restrictions = Object.values(iab_vendor_ids[i]);
for(j in all_iab_vendors) {
//for each iab vendor obtain its restriction
var iab_vendor = all_iab_vendors[j];
var id_legal_basis = all_restrictions[j];
var restriction = list_restrictions[id_legal_basis];
//add the vendor iab id and restriction to new object
vendor["iab_vendor"] = iab_vendor;
vendor["restriction"] = restriction;
list_vendors.push(vendor);
}
//add purpose id, iab vendors and their restrictions into new list
a["purpose_id"] = purpose_ids[i];
a["vendors"] = list_vendors;
list_purposes.push(a);
}
return(list_purposes);
}
function show_tcdata(success, tcdata) {
// custom code to display the values of tcdata object properties
console.log("tcdata success is " + success);
console.log("tcdata cmpId is " + tcdata.cmpId);
console.log("tcdata cmpStatus is " + tcdata.cmpStatus);
console.log("tcdata cmpVersion is " + tcdata.cmpVersion);
console.log("tcdata eventStatus is " + tcdata.eventStatus);
console.log("tcdata gdprApplies is " + tcdata.gdprApplies);
console.log("tcdata isServiceSpecific is " + tcdata.isServiceSpecific);
console.log("tcdata listenerId is " + tcdata.listenerId);
console.log("tcdata publisherCC is " + tcdata.publisherCC);
console.log("tcdata purposeOneTreatment is " + tcdata.purposeOneTreatment);
console.log("tcdata tcString is " + tcdata.tcString);
console.log("tcdata tcfPolicyVersion is " + tcdata.tcfPolicyVersion);
console.log("tcdata useNonStandardStacks is " + tcdata.useNonStandardStacks);
var publisher_restrictions = parse_publisherrestrictions(tcdata.publisher.restrictions);
console.log("tcdata publisher restriction is " + JSON.stringify(publisher_restrictions));
var publisher_consents = create_list("purpose id", tcdata.publisher.consents);
console.log("tcdata publisher consents is " + JSON.stringify(publisher_consents));
var publisher_legitimateinterests = create_list("purpose id", tcdata.publisher.legitimateInterests);
console.log("tcdata publisher legitimate interest consents is " + JSON.stringify(publisher_legitimateinterests));
var user_consents = create_list("purpose id", tcdata.purpose.consents);
console.log("tcdata user purpose consents is " + JSON.stringify(user_consents));
var user_legitimateinterests = create_list("purpose id", tcdata.purpose.legitimateInterests);
console.log("tcdata user legitimate interest consents is " + JSON.stringify(user_legitimateinterests));
var vendor_consents = create_list("iab_vendor_id", tcdata.vendor.consents);
console.log("tcdata vendor consents is " + JSON.stringify(vendor_consents));
var vendor_legitimateInterests = create_list("iab_vendor_id", tcdata.vendor.legitimateInterests);
console.log("tcdata vendor legitimate interest consents is " + JSON.stringify(vendor_legitimateInterests));
}
__tcfapi('addEventListener', 2, function(tcdata, success) {
if(success) {
if (tcdata.eventStatus === 'useractioncomplete') {
// call custom code when user has made an action
// function to display values of tcdata object properties
show_tcdata(success, tcdata);
} else if (tcdata.eventStatus === 'tcloaded') {
// call custom code when consent string has loaded
// function to display values of tcdata object properties
show_tcdata(success, tcdata);
} else if (tcdata.eventStatus === 'cmpuishown') {
// call code when cmp message is shown
}
}
});
// the standard method of calling getTCData
__tcfapi('getTCData', 2, function(tcdata, success) {
// function to display values of tcdata object properties
show_tcdata(success, tcdata);
});
</script>
<script src='https://cdn.privacy-mgmt.com/unified/wrapperMessagingWithoutDetection.js' async></script>
<!-- Set the link for privacy manager here -->
<footer>
<p>Edit <a onclick="window._sp_.gdpr.loadPrivacyManagerModal(547186, 'purposes')" href="javascript:void(0);">Privacy Settings</a></p>
</footer>
</body>
</html>
Note: The TCData response is an object with information embedded inside other objects. The example functions create_list()
and parse_publisherrestrictions()
extract this information from the TCData object.
Note: This example uses the addEventListener
that allows your organization to listen to specific events e.g. an end-user changes their consent, and automatically perform custom actions in response. The addEventListener
is described in this article.
API response
The response is an end-user's consent data object with the following information:
Attribute | Description |
success |
true if the getTCData API call has been successful |
addtlConsent |
Google Additional Consent allows Google and the IAB Framework to pass end-user consent to Google Ad Technology Providers despite not adhering to the IAB TCF v2 Framework |
cmpId |
CMP id assigned by the IAB |
cmpStatus |
An CMP status that can be stub , loading , loaded , error |
cmpVersion |
The version of the CMP API that is currently supported, e.g. "2.0" |
eventStatus |
The event status which can be: useractioncomplete , tcloaded , cmpuishown |
gdprApplies |
true if GDPR applies to this implementation |
isServiceSpecific |
|
listenerId |
|
publisherCC |
Country code of the country that determines the policy. |
purposeOneTreatment |
Only exists on service-specific TC.
|
tcString |
base64 url-encoded consent string |
tcfPolicyVersion |
Number of the supported TCF version |
useNonStandardStacks |
true if the CMP is using publisher-customized stack descriptions |
publisher object |
A list of publisher consent purposes or legitimate interest purposes the end-user has agreed to or rejected. Click here for more information. |
purpose object |
A list of consent purposes or legitimate interest purposes the end-user has agreed to or rejected. Click here for more information. |
vendor object |
A list of vendors with consent or legitimate interest purposes the end-user has agreed to or rejected. Click here for more information. |
addtlConsent: "1~"
cmpId: 6
cmpStatus: "loaded"
cmpVersion: 1
eventStatus: "tcloaded"
gdprApplies: true
isServiceSpecific: true
listenerId: 0
publisher Object {
consents Object { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true },
legitimateInterests Object { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true },
restrictions Object {
2: { 755:1 },
5: { 755:1 },
6: { 755:1 },
7: { 755:1 },
9: { 109:1, 755:1 },
10: { 755:1 }
}
}
publisherCC: "DE"
purpose Object {
consents Object { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true },
legitimateInterests Object { 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: true, 8: true, 9: true, 10: true }
}
purposeOneTreatment: false
specialFeatureOptins: Object { 1: true, 2: true }
tcString: "CPUW9Z2PUW9Z2AGABCENCCCsAP_AAAPAAAYgF5wAwA2gHTAXmANsAEANoAwyACAvMVABAXmSgBABtAXmUgAgLzCQAQF5joAIC8wA.f4AAAHgAAAAA"
tcfPolicyVersion: 2
useNonStandardStacks: false
vendor Object {
consents Object { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true },
legitimateInterests Object { 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: true, 8: true, 9: true, 10: true }
}
publisher
object
Attribute | Description |
consents object |
This object is a list of key :value pairs where:
|
legitimateInterests object |
This object is a list of key :value pairs where:
|
restrictions object |
This object is a list of Each sub-object is a list of
|
publisher Object {
consents Object { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true },
legitimateInterests Object { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true },
restrictions Object {
2: { 755:1 },
5: { 755:1 },
6: { 755:1 },
7: { 755:1 },
9: { 109:1, 755:1 },
10: { 755:1 }
}
}
purpose
object
Attribute | Description |
consents object |
This object is a list of key :value pairs where:
|
legitimateInterests object |
This object is a list of key :value pairs where:
|
purpose Object {
consents Object { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true },
legitimateInterests Object { 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: true, 8: true, 9: true, 10: true }
}
vendor
object
Attribute | Description |
consents object |
This object is a list of key :value pairs where:
|
legitimateInterests object |
This object is a list of key :value pairs where:
|
vendor Object {
consents Object { 1: true, 2: true, 3: true, 4: true, 5: true, 6: true, 7: true, 8: true, 9: true, 10: true },
legitimateInterests Object { 1: false, 2: false, 3: false, 4: false, 5: false, 6: false, 7: true, 8: true, 9: true, 10: true }
}