Skip to main content

Guides

IAB backend configuration

Configure an IAB policy

IAB support needs both an IAB policy in the manifest and the client IAB add-on. The server options alone do not install a TCF UI or generate a TC String in the browser.

c15t-backend.config.ts
import { defineConfig, policyRulePresets } from '@c15t/backend';
import { createMemoryCacheAdapter } from '@c15t/backend/cache';

const url = process.env.DATABASE_URL;
if (!url) throw new Error('Set DATABASE_URL');

export default defineConfig({
	database: { dialect: 'postgres', url },
	trustedOrigins: ['https://app.example.com'],
	manifest: {
		policyRules: [policyRulePresets.europeIab()],
		iab: { enabled: true },
	},
	// The matched IAB rule asks for a list; this says where it comes from and
	// which vendors it may name.
	gvl: { cache: createMemoryCacheAdapter(), vendorIds: [3, 7, 41] },
});

Set manifest.iab.cmpId to the CMP ID your deployment is entitled to use. IAB Europe assigns one when a company registers as a CMP (register.consensu.org/CMP); publishers using a registered CMP do not need their own. Every TC String names the CMP that wrote it, so a copied or placeholder ID attributes your users' consent records to another provider and is not a staging-only shortcut.

Left unset, /init returns no CMP ID and the browser add-on does not mount, so nothing writes a TC String. Set to a value outside the encodable range, an integer from 2 to 4095, and @c15t/iab throws instead of encoding a string that names no registered CMP.

Review the policy's location coverage and add other reviewed regional rules as needed.

Understand the two GVL settings

manifest.iab publishes IAB metadata and a GVL endpoint to clients that resolve the manifest themselves. gvl controls how the backend loads the list when /init resolves a matched IAB rule. Setting one does not configure the other. Both endpoints default to https://gvl.inth.app; if you run a different compatible endpoint, set manifest.iab.endpoint and gvl.endpoint.

Adding a gvl block turns on list loading. Every /init that matches an IAB rule then carries the list. Set gvl.enabled: false to keep the block but serve the list from somewhere else. If your rules resolve as IAB and there is no gvl block, the backend serves no list and prints a warning at startup.

gvl.vendorIds is the most the backend will serve. It never fetches a wider list to fill gaps, and it filters whatever the upstream returns, so a vendor outside the list never reaches a client. Leave vendorIds out to serve every vendor in the published list.

A client can ask for fewer vendors by listing the ones it ships on each init request:

curl -i 'http://localhost:3000/api/c15t/init' \
  -H 'x-c15t-country: DE' \
  -H 'x-c15t-vendors: 8, 46, 153'

For a matched IAB policy, the gvl in the response is the intersection of that header and gvl.vendorIds, so the header can narrow the list but never widen it. A missing or unreadable header gets the configured list, and a header with more than 500 IDs is ignored. The backend narrows the list after its cache lookup, so different app scopes do not add upstream fetches.

Use a cache adapter to reuse fetched lists. gvl.ttlMs defaults to one day. A failed upstream fetch or an invalid document gives a null GVL instead of failing /init. Check how your client handles that before you deploy.

Check the IAB setup

  1. Request /manifest and confirm it lists the IAB rule and IAB metadata.
  2. Call /init with a location the rule covers, such as the curl request above. The policy model is iab and the response has a gvl field. A client that bundles no vendor list gets the list only from this response, so a missing gvl means that client has no vendors to disclose.
  3. Call /init with a location outside the rule. The ordinary consent flow applies and the response has no list.
  4. Send x-c15t-vendors and confirm the gvl names only those vendors that gvl.vendorIds also allows.

Connect the browser with the IAB add-on guide, and keep a persistent link to vendor and purpose choices. A preset and a served GVL are configuration; they do not prove your site meets the TCF rules.