---
title: IAB TCF Support
description: Enable IAB Transparency and Consent Framework (TCF) support in your self-hosted backend.
---
The c15t backend optionally supports [IAB TCF v2.3](https://iabeurope.eu/transparency-consent-framework/), including Global Vendor List (GVL) management and TC String generation.

## CMP Registration

[Inth](https://inth.com), c15t's hosted platform, is IAB TCF certified. If you use Inth instead of self-hosting, the CMP ID is automatically provided to clients — no additional configuration needed.

If you self-host, you need your own CMP registration with IAB Europe and must configure your CMP ID via `iab.cmpId`. Registering your own CMP may also involve IAB Europe fees, so check IAB Europe's current CMP registration terms and pricing before choosing this route. The backend returns this value in the `/init` response so clients use the correct CMP identity in TC Strings.

> ℹ️ **Info:**
> A valid (non-zero) CMP ID is required for IAB TCF compliance. If neither the backend nor the client provides a CMP ID, IAB initialization will fail with an error.
>
> ℹ️ **Info:**
> If you heavily customize or build your own IAB banner or dialog instead of using the default IABConsentBanner and IABConsentDialog components provided by c15t, you cannot use Inth's CMP ID. You must register your own CMP with IAB Europe and configure your CMP ID via iab.cmpId.

## Enable IAB

```ts title="c15t.ts"
import { c15tInstance } from '@c15t/backend';

export const c15t = c15tInstance({
  // ...
  iab: {
    enabled: true,
    cmpId: Number('<YOUR_CMP_ID>'), // replace with your registered CMP ID
    vendorIds: [755, 52, 69],   // only include vendors you use
  },
});
```

The backend fetches the GVL from `https://gvl.inth.com` by default and caches it. The `/init` endpoint returns the filtered GVL and your CMP ID to the frontend, so use the same `iab.cmpId` pattern in every self-hosted configuration.

## Custom GVL Endpoint

Point to your own GVL mirror:

```ts
iab: {
  enabled: true,
  cmpId: Number('<YOUR_CMP_ID>'), // replace with your registered CMP ID
  endpoint: 'https://your-gvl-mirror.com',
  vendorIds: [755, 52, 69],
},
```

## Bundle GVL by Language

Pre-bundle the GVL to avoid runtime fetches:

```ts
import gvlEn from './gvl/en.json';
import gvlDe from './gvl/de.json';

iab: {
  enabled: true,
  cmpId: Number('<YOUR_CMP_ID>'), // replace with your registered CMP ID
  bundled: {
    en: gvlEn,
    de: gvlDe,
  },
},
```

> ℹ️ **Info:**
> Bundling all required GVL translations can significantly increase your deployment size. On serverless environments like Cloudflare Workers — which have strict bundle size limits — this may cause deployments to fail. Consider bundling only the languages you need, or use the GVL endpoint with a cache adapter instead.

## Custom Non-IAB Vendors

Add your own vendors alongside IAB-registered ones:

```ts
iab: {
  enabled: true,
  cmpId: Number('<YOUR_CMP_ID>'), // replace with your registered CMP ID
  vendorIds: [755],
  customVendors: [
    {
      id: 'internal-analytics',
      name: 'Our Analytics Platform',
      privacyPolicyUrl: 'https://example.com/privacy',
      purposes: [1, 8],
    },
  ],
},
```

## TC String

When IAB TCF is enabled, consent records include a `tcString` field — the encoded TC String that can be passed to vendors. The frontend SDKs handle this automatically when using `mode: 'hosted'`.
