> ## Documentation Index
> Fetch the complete documentation index at: https://developer.onetrust.com/llms.txt
> Use this file to discover all available pages before exploring further.

# IAB TCF Developer Guide

> 📘 Note
>
> As of September 2021, the global scope will no longer be supported per the recent TCF Policy and Technical Specifications. To view the formal notification, please refer to the [IAB Europe PDF Notification](https://iabeurope.eu/wp-content/uploads/2021/06/TCF_V-CMP_comms_DeprecationOfGlobalScopeSupportInTCF_220621_IABEurope.pdf) and [IAB Europe PDF Notification Update](https://iabeurope.eu/wp-content/uploads/2021/07/TCF_V-CMP_comms_UpdateTIMING-DeprecationOfGlobalScopeSupportInTCF_300621_IABEurope.pdf).

## Required API Commands

All CMPs must support four required API commands:

* `getTCData`
* `ping`
* `addEventListener`
* `removeEventListener`

The TCF API 2.3 function takes the general form:

```javascript
__tcfapi(command, version, callback, parameter)
```

## getTCData

> 📘 Note
>
> getTCData is deprecated in TCF v2.2. Instead add an 'addEventListener' and use its callback function to access the tcData object.

| Argument Name | Type      | Optional | Value                                       |
| ------------- | --------- | -------- | ------------------------------------------- |
| command       | string    | No       | getTCData                                   |
| verson        | number    | No       | 2                                           |
| callback      | function  | No       | `function(tcData: TCData, sucess: boolean)` |
| parameter     | int array | Yes      | vendorIDs                                   |

#### Example:

```javascript
__tcfapi('getTCData', 2, (tcData, success) => {

  if(success) {

    // do something with tcData

  } else {

    // do something else

  }

}, [1,2,3]);
```

This will return [TCData](https://my.onetrust.com/s/article/UUID-3aac21bc-6881-3c64-c9af-511b3f16ead0?topicId=0TO1Q000000ssJGWAY#UUID-3aac21bc-6881-3c64-c9af-511b3f16ead0_section-idm4646117370228831658176670062).

## ping

| Argument Name | Type     | Value                          |
| ------------- | -------- | ------------------------------ |
| command       | string   | ping                           |
| version       | number   | 2                              |
| callback      | function | `function(PingReturn: object)` |

#### Example:

```javascript
__tcfapi('ping', 2, (pingReturn) => {
  // do something with pingReturn
});
```

## addEventListener

| Argument Name | Type     | Value                                        |
| ------------- | -------- | -------------------------------------------- |
| command       | string   | addEventListener                             |
| version       | number   | 2                                            |
| callback      | function | `function(tcData: TCData, success: boolean)` |

#### Example:

```javascript
const callback = (tcData, success) => {

  if(success && tcData.eventStatus === 'tcloaded') {

		// do something with tcData.tcString
		// remove the ourself to not get called more than once
		
		__tcfapi('removeEventListener', 2, (success) => {

			if(success) {
				// oh good...
			}
		}, callback);

  } else {
    // do something else
  }
	
}

__tcfapi('addEventListener', 2, callback);
```

| eventStatus        | Description                                                                                                                                                                   |
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| tcloaded           | The CMP is loaded and prepared to sent a TC string.                                                                                                                           |
| cmpuishown         | The TC string is available and has rendered 'Transparency'. The CMP will create TC string will contain the vendors' Legitimate Interest and the consent signals set to false. |
| useractioncomplete | The user has confirmed or re-confirmed their consent choices and the CMP will respond with the corresponding TC string.                                                       |

## removeEventListener

| Argument Name | Type     | Value                                               |
| ------------- | -------- | --------------------------------------------------- |
| command       | string   | removeEventListener                                 |
| version       | number   | 2                                                   |
| callback      | function | `function(success: boolean)`                        |
| parameter     | function | previously registered callback (`addEventListener`) |

**For example**, see `addEventListener`. The callback will be `false` if the listener could not be removed. This may happen, for instance, if a listener corresponding to `listenerId` is not found.

<br />

## Optional API Commands

### getInAppTCData

| Argument Name | Type     | Value                                                  |
| ------------- | -------- | ------------------------------------------------------ |
| command       | string   | `getInAppTCData`                                       |
| version       | number   | 2                                                      |
| callback      | function | `function(inAppTCData: InAppTCData, success: boolean)` |

#### Example:

```javascript
__tcfapi('getInAppTCData', 2, (inAppTCData, success) => {
  if(success) {
    // do something with inAppTCData
  } else {
    // do something else
  }
});
```

### getVendorList

| Argument Name | Type          | Optional | Value                                               |
| ------------- | ------------- | -------- | --------------------------------------------------- |
| command       | string        | No       | getVendorList                                       |
| version       | number        | No       | 2                                                   |
| callback      | function      | No       | `function(gvl: GlovalVendorList, success: boolean)` |
| parameter     | int or string | Yes      | vendorListVersion                                   |

#### Example:

```javascript
__tcfapi('getVendorList', 2, (gvl, success) => {

  if(success) {
    // do something with gvl
  } else {
    // do something else
  }
}, 'LATEST');
```

<br />

## Returned Objects

### TCData

```json
TCData = {
  tcString: 'base64url-encoded TC string with segments',
  tcfPolicyVersion: 2,
  cmpId:1000,
  cmpVersion: 1000,
  gdprApplies: Boolean | undefined,
  eventStatus: String,
  cmpStatus: 'string',
  listenerId: Number | undefined,
  isServiceSpecific: Boolean,
  useNonStandardStacks: Boolean,
  publisherCC: 'Two-letter ISO 3166-1 alpha-2 code',
  purposeOneTreatment: Boolean,
  outOfBand: {
    allowedVendors: {
      '[vendor id]': Boolean
    },
    discloseVendors: {
      '[vendor id]': Boolean
    }
  },
  purpose: {
    consents: {
      '[purpose id]': Boolean
    },
   legitimateInterests: {
      '[purpose id]': Boolean
    }
  },
  vendor: {
    consents: {
      '[vendor id]': Boolean
    },
    legitimateInterests: {
      '[vendor id]': Boolean
    }
  },
  specialFeatureOptins: {
      '[special feature id]': Boolean
  },
  publisher: {
    consents: {
      '[purpose id]': Boolean
    },
    legitimateInterests: {
      '[purpose id]': Boolean
    },
    customPurpose: {
      consents: {
        '[purpose id]': Boolean
      },
      legitimateInterests: {
        '[purpose id]': Boolean
      },
    },
    restrictions: {
      '[purpose id]': {
        '[vendor id]': 1
      }
    }
  }
}
```

[block:parameters]
{
  "data": {
    "h-0": "Value",
    "h-1": "Description",
    "0-0": "gdprApplies",
    "0-1": "_ `true` - GDPR Applies <br> _ `false` - GDPR Does not apply <br> \\* `undefined` - unknown whether GDPR Applies",
    "1-0": "eventStatus",
    "1-1": "See `addEventListener` command",
    "2-0": "cmpStatus",
    "2-1": "See **Ping Status Codes** in following table.",
    "3-0": "listenerId",
    "3-1": "_ If this TCData is sent to the callback of addEventListener: number, the unique ID assigned by the CMP to the listener function registered via addEventListener. <br> _ Others: undefined",
    "4-0": "isServiceSpecific",
    "4-1": "_ `true` - if using a service-specific or publisher-specific TC String <br> _ `false` - if using a global TC String",
    "5-0": "useNonStandardStacks",
    "5-1": "_ `true` - CMP is using publisher-customized stack descriptions <br> _ `false` - CMP is NOT using publisher-customized stack descriptions",
    "6-0": "publisherCC",
    "6-1": "Country code of the country that determines the policy.",
    "7-0": "purposeOneTreatment",
    "7-1": "Only exists on service-specific TC. <br> _ `true` - Purpose 1 not disclosed at all. CMPs use PublisherCC to indicate the publisher's country of establishment to help Vendors determine whether the vendor requires Purpose 1 consent. <br> _ `false` - There is no special Purpose 1 treatment status. Purpose 1 was disclosed normally (consent) as expected by TCF Policy.",
    "8-0": "outOfBand",
    "8-1": "Only exists on global-scope TC.",
    "9-0": "allowedVendors",
    "9-1": "_ `true` - Vendor is allowed to use an Out-of-Band Legal Basis <br> _ `false` - Vendor is NOT allowed to use an Out-of-Band Legal Basis",
    "10-0": "discloseVendors",
    "10-1": "_ `true` - Vendor has been disclosed to the user <br> _ `false` - Vendor has NOT been disclosed to the user",
    "11-0": "purpose",
    "11-1": "**consents** <br> _ `true` - Consent <br> _ `false` - No Consent <br><br> **legitimateInterests** <br> _ `true` - Legitimate Interest Established <br> _ `false` - No Legitimate Interest Established",
    "12-0": "vendor",
    "12-1": "**consents** <br> _ `true` - Consent <br> _ `false` - No Consent <br><br> **legitimateInterests** <br> _ `true` - Legitimate Interest Established <br> _ `false` - No Legitimate Interest Established",
    "13-0": "specialFeatureOptins",
    "13-1": "_ `true` - Special Feature Opted Into <br> _ `false` - Special Feature NOT Opted Into",
    "14-0": "publisher",
    "14-1": "**consents** <br> _ `true` - Consent <br> _ `false` - No Consent <br><br> **legitimateInterests** <br> _ `true` - Legitimate Interest Established <br> _ `false` - No Legitimate Interest Established <br><br> **customPurpose:** <br><br> **consents** <br> _ `true` - Consent <br> _ `false` - No Consent <br><br> **legitimateInterests** <br> _ `true` - Legitimate Interest Established <br> _ `false` - No Legitimate Interest Established <br><br> **restrictions** <br> `'[purposeId]'`: <br> _ `0` - Not Allowed <br> _ `1` - Require Consent <br> \\* `2` - Require Legitimate Interest <br><br> `'[vendor id]'`: 1"
  },
  "cols": 2,
  "rows": 15,
  "align": [
    null,
    null
  ]
}
[/block]

### InAppTCData

```json
InAppTCData = {
  tcString: 'base64url-encoded TC string with segments',
  tcfPolicyVersion: 2,
  cmpId:1000,
  cmpVersion: 1000,
  gdprApplies: 1,
  eventStatus: 'string',
  isServiceSpecific: 1,
  useNonStandardStacks: 1,
  publisherCC: 'Two-letter ISO 3166-1 alpha-2 code',
  purposeOneTreatment: 1,
  purpose: {
    consents: '01010 -- Purpose bitfield'
    legitimateInterests: '01010 -- Purpose bitfield'
  },
  vendor: {
    consents: '01010 -- Vendor bitfield',
    legitimateInterests: '01010 -- Vendor bitfield'
  },
  specialFeatureOptins: '01010 -- Special Feature bitfield',
  publisher: {
    consents: '01010 -- Purpose bitfield',
    legitimateInterests: '01010 -- Purpose bitfield',
    customPurpose: {
      consents: '01010 -- Purpose bitfield',
      legitimateInterests: '01010 -- Purpose bitfield'
    },
    restrictions: {
      '[purpose id]': '01201221'
    }
  }
}
```

[block:parameters]
{
  "data": {
    "h-0": "Value",
    "h-1": "Description",
    "0-0": "gdprApplies",
    "0-1": "_ `1` - GDPR Applies <br> _ `0` - GDPR Does not apply <br> \\* `undefined` - unknown whether GDPR applies",
    "1-0": "eventStatus",
    "1-1": "See `addEventListener`",
    "2-0": "isServiceSpecific",
    "2-1": "_ `1` - If using a service-specific or publisher-specific TC String. <br> _ `0` - If using a global TC String.",
    "3-0": "useNonStandardStacks",
    "3-1": "_ `1` - CMP is using publisher-customized stack descriptions. <br> _ `0` - CMP is NOT using publisher-customized stack descriptions.",
    "4-0": "publisherCC",
    "4-1": "Country code of the country that determines the policy.",
    "5-0": "purposeOneTreatment",
    "5-1": "_ `1` - Purpose 1 not disclosed at all. CMPs use PublisherCC to indicate the publisher's country of establishment to help vVendors determine whether the vendor requires Purpose 1 consent. <br> _ `0` - There is no special Purpose 1 treatment status. Purpose 1 was disclosed normally (consent) as expected by TCF Policy.",
    "6-0": "purpose",
    "6-1": "**consents** <br> _ `true` - Consent <br> _ `false` - No Consent <br><br> **legitimateInterests** <br> _ `true` - Legitimate Interest Established <br> _ `false` - No Legitimate Interest Established",
    "7-0": "vendor",
    "7-1": "**consents** <br> _ `true` - Consent <br> _ `false` - No Consent <br><br> **legitimateInterests** <br> _ `true` - Legitimate Interest Established <br> _ `false` - No Legitimate Interest Established",
    "8-0": "specialFeatureOptins",
    "8-1": "_ `true` - Special Feature Opted Into <br> _ `false` - Special Feature NOT Opted Into",
    "9-0": "publisher",
    "9-1": "**consents** <br> _ `true` - Consent <br> _ `false` - No Consent <br><br> **legitimateInterests** <br> _ `true` - Legitimate Interest Established <br> _ `false` - No Legitimate Interest Established <br><br> **customPurpose:** <br><br> **consents** <br> _ `true` - Consent <br> _ `false` - No Consent <br><br> **legitimateInterests** <br> _ `true` - Legitimate Interest Established <br> _ `false` - No Legitimate Interest Established <br><br> **restrictions** <br> `'[purposeId]'`: <br> _ `0` - Not Allowed <br> _ `1` - Require Consent <br> \\* `2` - Require Legitimate Interest"
  },
  "cols": 2,
  "rows": 10,
  "align": [
    null,
    null
  ]
}
[/block]

### PingReturn

```json
PingReturn = {
  gdprApplies: Boolean | undefined,
  cmpLoaded: Boolean,
  cmpStatus: String,
  displayStatus: String,
  apiVersion: String,
  cmpVersion: Number | undefined,
  cmpId: Number | undefined,
  gvlVersion: Number | undefined,
  tcfPolicyVersion: Number | undefined
};
```

[block:parameters]
{
  "data": {
    "h-0": "Value",
    "h-1": "Description",
    "0-0": "gdprApplies",
    "0-1": "_ `true` - GDPR Applies <br> _ `false` - GDPR Does not apply <br> _ `undefined` - unknown whether GDPR Applies <br><br> _ see the section: \"What does the gdprApplies value mean?\"",
    "1-0": "cmpLoaded",
    "1-1": "_ `true` - CMP main script is loaded <br> _ `false` - still running stub",
    "2-0": "cmpStatus",
    "2-1": "_ `stub`: CMP not yet loaded – stub still in place. <br> _ `loading`: CMP is loading. <br> _ `loaded`: CMP has loaded. <br> _ `error`: CMP is in an error state. A CMP shall not respond to any other API requests if this cmpStatus is present. A CMP may set this status if, for any reason, it is unable to perform the operations in compliance with the TCF.",
    "3-0": "displayStatus",
    "3-1": "_ `visible`: The user interface is displayed. <br> _ `hidden`: The user interface is not being displayed. <br> \\* `disabled`: The user interface will not be displayed. This will be returned when GDPR does not apply or the TC string does not need renewal.",
    "4-0": "apiVersion",
    "4-1": "Version of the CMP API that is supported, e.g. \"2.3\".",
    "5-0": "cmpVersion",
    "5-1": "CMPs own/internal version that is currently running. It is undefined if still the stub",
    "6-0": "cmpId",
    "6-1": "IAB assigned CMP ID. It is undefined if the stub is still in place.",
    "7-0": "gvlVersion",
    "7-1": "Version of the GVL currently loaded by the CMP. It is undefined if the stub is still in place.",
    "8-0": "tcfPolicyVersion",
    "8-1": "Number of the supported TCF version. It is undefined if the stub is still in place."
  },
  "cols": 2,
  "rows": 9,
  "align": [
    null,
    null
  ]
}
[/block]