Create and publish a multi-regulation consent notice

This tutorial will walk you through the steps necessary to create a multi-regulation notice, modify its configuration, and publish it.
Please be aware that requests for multi-regulation notices specify the v:"2" header value; don't forget to include this in your API requests to the /widgets/notices and /widgets/notices/configs endpoints!
To create a consent notice, send a POST /widgets/notices request with the name of the notice to create and the ID of the organization that the notice belongs to:
Node.js
HTTP
1
const bent = require("bent");
2
const organizationId = "didomi";
3
const headers = {
4
Authorization: `Bearer ${token}`,
5
v: "2",
6
};
7
8
const client = {
9
post: bent(
10
"POST",
11
"https://api.didomi.io/v1",
12
"json",
13
headers,
14
201
15
),
16
};
17
18
(async () => {
19
console.log(`Creating a notice for organization ${organizationId} ...`);
20
21
const notice = await client.post("/widgets/notices", {
22
organization_id: organizationId,
23
name: "My consent notice",
24
});
25
26
console.log(`Notice with ID ${notice.id} created!`);
27
})();
curl --request POST 'https://api.didomi.io/v1/widgets/notices' \
--header 'Authorization: Bearer <TOKEN>' \
--header 'v: 2' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "My consent notice",
"organization_id": "didomi"
}'
The API will return a response similar to:
{
"name": "My consent notice",
"archived_at": null,
"organization_id": "didomi",
"id": "7wmRYUH6",
"created_at": "2021-03-27T08:38:10.831Z",
"updated_at": "2021-03-27T08:38:10.831Z",
"version": 0
}

Modify the notice's draft multi-regulation configuration

The API automatically created a draft configuration when a notice was created. To update the notice configuration, you must first get the ID of the draft configuration and then modify that draft configuration.

Get the ID of the draft configuration

To get the ID of the draft configuration, get the list of all configurations:
Node.js
HTTP
1
const bent = require("bent");
2
const noticeId = "QdA3yxfi";
3
const BASE_URL = "https://api.didomi.io/v1";
4
5
const headers = {
6
Authorization: `Bearer ${token}`,
7
v: "2",
8
};
9
10
const client = {
11
get: bent("GET", BASE_URL, "json", headers),
12
patch: bent("PATCH", BASE_URL, "json", headers),
13
post: bent("POST", BASE_URL, "json", headers, 201),
14
};
15
16
(async () => {
17
console.log("Getting the latest draft config ...");
18
19
// Get the Configuration related to our notice with deployed_at as NULL.
20
const {
21
data: [draftConfiguration],
22
} = await client.get(
23
`/widgets/notices/configs?notice_id=${noticeId}&deployed_at=null`
24
);
25
26
console.log(
27
`A default notice has ${draftConfiguration.regulation_configurations.length} Regulation-Configurations`
28
);
29
// prints: A default notice has 3 Regulation-Configurations
30
31
console.log(
32
`A default notice has ${
33
draftConfiguration.regulation_configurations.filter(
34
(rc) => rc.regulation_id === "gdpr"
35
).length
36
} GDPR related Regulation-Configurations`
37
);
38
// prints: A default notice has 3 GDPR related Regulation-Configurations
39
40
const defaultGdprConfigurations =
41
draftConfiguration.regulation_configurations.filter(
42
(rc) => rc.regulation_id === "gdpr" && rc.is_default_regulation_config
43
);
44
45
console.log(
46
`A regulation should only have 1 default configuration hence our Configuration is ${
47
defaultGdprConfigurations.length === 1 ? "valid" : "invalid"
48
}!`
49
);
50
// prints: A regulation should only have 1 default Regulation-Configuration hence our Configuration is valid!
51
52
const italyOverride = draftConfiguration.regulation_configurations.find(
53
(rc) =>
54
rc.regulation_id === "gdpr" &&
55
!rc.is_default_regulation_config &&
56
rc.geo_locations.length === 1 &&
57
rc.geo_locations[0] === "IT"
58
);
59
60
const franceOverride = draftConfiguration.regulation_configurations.find(
61
(rc) =>
62
rc.regulation_id === "gdpr" &&
63
!rc.is_default_regulation_config &&
64
rc.geo_locations.length === 1 &&
65
rc.geo_locations[0] === "FR"
66
);
67
68
if (italyOverride && franceOverride) {
69
console.log(
70
"A default notice has overrides set up for France and Italy to comply with local requirements."
71
);
72
} else {
73
throw new Error("Something went wrong :(");
74
}
75
})();
1
curl -X GET \
2
'https://api.didomi.io/v1/widgets/notices/configs?notice_id=<NOTICE_ID>&deployed_at=null' \
3
-H 'Authorization: Bearer <AUTH_TOKEN>' \
4
-H 'v: 2'
5
6
{
7
"total": 1,
8
"limit": 100,
9
"skip": 0,
10
"data": [
11
{
12
"custom_json": {},
13
"config": {
14
"user": {
15
"bots": {
16
"consentRequired": false
17
}
18
},
19
"notice": {
20
"position": "bottom",
21
"showDataProcessing": true
22
},
23
"languages": {
24
"default": "en",
25
"enabled": [
26
"en",
27
"fr"
28
]
29
}
30
},
31
"default": false,
32
"platform": "web",
33
"targets": [],
34
"text_mode": "approved",
35
"text_id": "LZJ3VTcz",
36
"full_atp": true,
37
"enable_ignore_consent_before": false,
38
"ignore_consent_before": null,
39
"negative_action": "button",
40
"negative_action_link": false,
41
"negative_action_link_format": "cross",
42
"negative_action_button": false,
43
"disagree_button_style": "primary",
44
"country": null,
45
"notice_deny_applies_to_li": true,
46
"preferences_deny_applies_to_li": true,
47
"consent_duration": 12,
48
"consent_duration_unit": "months",
49
"denied_consent_duration": 12,
50
"denied_consent_duration_unit": "months",
51
"denied_consent_duration_custom": false,
52
"cross_device_enabled": false,
53
"cross_device_timeout": 3000,
54
"gcm_enabled": false,
55
"gcm_set_default_status": true,
56
"gcm_data_layer_name": null,
57
"gcm_analytics_default_status": false,
58
"gcm_ads_default_status": false,
59
"gcm_functionality_default_status": true,
60
"gcm_personalization_default_status": true,
61
"gcm_security_default_status": true,
62
"template_id": null,
63
"regulation_configurations": [
64
{
65
"id": "HfEYXa4L",
66
"regulation_id": "gdpr",
67
"is_default_regulation_config": true,
68
"geo_locations": [
69
"AD",
70
"AT",
71
"BE",
72
"BG",
73
"CY",
74
"CZ",
75
"DE",
76
"DK",
77
"EE",
78
"ES",
79
"FI",
80
"FR",
81
"GF",
82
"GG",
83
"GI",
84
"GP",
85
"GR",
86
"HR",
87
"HU",
88
"IE",
89
"IS",
90
"IT",
91
"JE",
92
"LI",
93
"LT",
94
"LU",
95
"LV",
96
"MC",
97
"MF",
98
"MQ",
99
"MT",
100
"NL",
101
"NO",
102
"PL",
103
"PT",
104
"RE",
105
"RO",
106
"SE",
107
"SI",
108
"SK",
109
"SM",
110
"VA",
111
"YT"
112
],
113
"regulation_settings": {},
114
"config": {
115
"app": {
116
"vendors": {
117
"iab": {
118
"all": false,
119
"stacks": {
120
"auto": true
121
},
122
"enabled": true,
123
"version": 2
124
},
125
"include": [
126
"googleana-4TXnJigR",
127
"google"
128
]
129
}
130
},
131
"preferences": {
132
"categories": [
133
{
134
"type": "purpose",
135
"purposeId": "cookies"
136
},
137
{
138
"type": "purpose",
139
"purposeId": "measure_content_performance"
140
},
141
{
142
"type": "purpose",
143
"purposeId": "create_ads_profile"
144
},
145
{
146
"type": "purpose",
147
"purposeId": "create_content_profile"
148
},
149
{
150
"type": "purpose",
151
"purposeId": "improve_products"
152
},
153
{
154
"type": "purpose",
155
"purposeId": "market_research"
156
},
157
{
158
"type": "purpose",
159
"purposeId": "measure_ad_performance"
160
},
161
{
162
"type": "purpose",
163
"purposeId": "select_basic_ads"
164
},
165
{
166
"type": "purpose",
167
"purposeId": "select_personalized_ads"
168
},
169
{
170
"type": "purpose",
171
"purposeId": "select_personalized_content"
172
}
173
]
174
}
175
},
176
"disabled_at": null,
177
"created_at": "2023-03-23T08:47:32.558Z",
178
"updated_at": "2023-03-23T08:47:32.558Z",
179
"enable_ignore_consent_before": null,
180
"disagree_button_style": null,
181
"consent_duration": null,
182
"consent_duration_unit": null,
183
"denied_consent_duration": null,
184
"denied_consent_duration_unit": null,
185
"denied_consent_duration_custom": null,
186
"gcm_enabled": true,
187
"gcm_set_default_status": null,
188
"gcm_analytics_default_status": null,
189
"gcm_ads_default_status": null,
190
"gcm_functionality_default_status": null,
191
"gcm_personalization_default_status": null,
192
"gcm_security_default_status": null,
193
"negative_action_link_format": null,
194
"notice_deny_applies_to_li": null,
195
"preferences_deny_applies_to_li": null,
196
"version": 0,
197
"negative_action_link": null,
198
"negative_action_button": null,
199
"gcm_data_layer_name": null,
200
"full_atp": null,
201
"notice_config_id": "g4xH3ypQ",
202
"organization_id": "didomi"
203
},
204
{
205
"id": "m33TZCqY",
206
"regulation_id": "gdpr",
207
"is_default_regulation_config": false,
208
"geo_locations": [
209
"IT"
210
],
211
"regulation_settings": {},
212
"config": {},
213
"disabled_at": null,
214
"created_at": "2023-03-23T08:47:32.558Z",
215
"updated_at": "2023-03-23T08:47:32.558Z",
216
"enable_ignore_consent_before": null,
217
"disagree_button_style": null,
218
"consent_duration": null,
219
"consent_duration_unit": null,
220
"denied_consent_duration": null,
221
"denied_consent_duration_unit": null,
222
"denied_consent_duration_custom": null,
223
"gcm_enabled": null,
224
"gcm_set_default_status": null,
225
"gcm_analytics_default_status": null,
226
"gcm_ads_default_status": null,
227
"gcm_functionality_default_status": null,
228
"gcm_personalization_default_status": null,
229
"gcm_security_default_status": null,
230
"negative_action_link_format": "cross",
231
"notice_deny_applies_to_li": null,
232
"preferences_deny_applies_to_li": null,
233
"version": 0,
234
"negative_action_link": true,
235
"negative_action_button": false,
236
"gcm_data_layer_name": null,
237
"full_atp": null,
238
"notice_config_id": "g4xH3ypQ",
239
"organization_id": "didomi"
240
},
241
{
242
"id": "G72tRBmY",
243
"regulation_id": "gdpr",
244
"is_default_regulation_config": false,
245
"geo_locations": [
246
"FR"
247
],
248
"regulation_settings": {},
249
"config": {},
250
"disabled_at": null,
251
"created_at": "2023-03-23T08:47:32.558Z",
252
"updated_at": "2023-03-23T08:47:32.558Z",
253
"enable_ignore_consent_before": null,
254
"disagree_button_style": null,
255
"consent_duration": null,
256
"consent_duration_unit": null,
257
"denied_consent_duration": null,
258
"denied_consent_duration_unit": null,
259
"denied_consent_duration_custom": null,
260
"gcm_enabled": null,
261
"gcm_set_default_status": null,
262
"gcm_analytics_default_status": null,
263
"gcm_ads_default_status": null,
264
"gcm_functionality_default_status": null,
265
"gcm_personalization_default_status": null,
266
"gcm_security_default_status": null,
267
"negative_action_link_format": "text",
268
"notice_deny_applies_to_li": null,
269
"preferences_deny_applies_to_li": null,
270
"version": 0,
271
"negative_action_link": false,
272
"negative_action_button": true,
273
"gcm_data_layer_name": null,
274
"full_atp": null,
275
"notice_config_id": "g4xH3ypQ",
276
"organization_id": "didomi"
277
}
278
],
279
"secure_cookies": false,
280
"notice_id": "FDPhA7fP",
281
"organization_id": "didomi",
282
"deployed_by": null,
283
"deployed_by_type": null,
284
"deployed_by_name": null,
285
"deployed_at": null,
286
"id": "g4xH3ypQ",
287
"created_at": "2023-03-23T08:47:32.529Z",
288
"updated_at": "2023-03-23T08:47:32.529Z",
289
"version": 0,
290
"deployed_metadata": {}
291
}
292
]
293
}
The configuration is called "draft" because its deployed_at field is null which indicates that this configuration has not been published before and can be modified.
As we are working with a newly created notice in this tutorial, we can assume that it has a single associated configuration and that it is a draft. If you are working with an existing notice that might have been published before and would have multiple configurations, read our documentation to find the current draft documentation.

Modify the draft configuration

To modify the draft configuration, send a PATCH request with the updated configuration. In this example, we change the cross-regulation defaults for consent duration to 12 months and include CPRA as a targeted regulation for California, United States.
Node.js
HTTP
1
const bent = require("bent");
2
const organizationId = "<organizationId>";
3
const noticeId = "<noticeId>";
4
const BASE_URL = "https://api.didomi.io/v1";
5
const token = "<token>>"; // Get a token by authenticating in the API (https://developers.didomi.io/api/introduction/authentication)
6
7
const headers = {
8
Authorization: `Bearer ${token}`,
9
v: "2",
10
};
11
12
const client = {
13
get: bent("GET", BASE_URL, "json", headers),
14
patch: bent("PATCH", BASE_URL, "json", headers),
15
post: bent("POST", BASE_URL, "json", headers, 201),
16
};
17
18
(async () => {
19
console.log("Getting the latest draft config ...");
20
21
let {
22
data: [draftConfiguration],
23
} = await client.get(
24
`/widgets/notices/configs?notice_id=${noticeId}&deployed_at=null`
25
);
26
console.log("Patching consent duration to 6 months");
27
28
draftConfiguration = await client.patch(
29
`/widgets/notices/configs/${draftConfiguration.id}`,
30
{
31
consent_duration: 6,
32
consent_duration_unit: "months",
33
}
34
);
35
36
console.log(
37
`The configuration has a consent duration of ${draftConfiguration.consent_duration} ${draftConfiguration.consent_duration_unit}`
38
);
39
// prints: The configuration has a consent duration of 6 months
40
41
console.log("Enabling CPRA for California, United States");
42
43
draftConfiguration.regulation_configurations.push({
44
regulation_id: "cpra",
45
is_default_regulation_config: true,
46
geo_locations: ["US_CA"],
47
});
48
49
draftConfiguration = await client.patch(
50
`/widgets/notices/configs/${draftConfiguration.id}`,
51
draftConfiguration
52
);
53
54
// Check enabled regulations.
55
const enabledRegulations = draftConfiguration.regulation_configurations
56
.filter((rc) => rc.is_default_regulation_config)
57
.map((rc) => rc.regulation_id);
58
59
console.log(
60
`The configuration has the following regulations enabled: ${enabledRegulations.join(
61
", "
62
)}`
63
);
64
// prints: The configuration has the following regulations enabled: gdpr, cpra
65
66
// Set IAB vendor 100mercis and tappx-Vzy7mget on CPRA configuration.
67
let cpraConfiguration = draftConfiguration.regulation_configurations.find(
68
(rc) => rc.is_default_regulation_config && rc.regulation_id === "cpra"
69
);
70
71
cpraConfiguration.config.app = {
72
vendors: {
73
include: ["100mercis", "tappx-Vzy7mget"],
74
},
75
};
76
77
draftConfiguration = await client.patch(
78
`/widgets/notices/configs/${draftConfiguration.id}`,
79
draftConfiguration
80
);
81
82
cpraConfiguration = draftConfiguration.regulation_configurations.find(
83
(rc) => rc.is_default_regulation_config && rc.regulation_id === "cpra"
84
);
85
86
console.log(
87
`CPRA has the following vendors set: ${cpraConfiguration.config.app.vendors.include.join(
88
", "
89
)}`
90
);
91
// prints: CPRA has the following vendors set: 100mercis, tappx-Vzy7mget
92
})();
curl --request PATCH 'https://api.didomi.io/widgets/notices/configs/Lz97gCd6' \
--header 'Authorization: Bearer <TOKEN>' \
--header 'v: 2' \
--header 'Content-Type: application/json' \
--data-raw '{
"consent_duration": 12,
"consent_duration_unit": "months",
"regulation_configurations": [
{
"regulation_id": "cpra",
"geo_locations": ["US_CA"],
"is_default_regulation_config": true
}
]
}'
{
"custom_json": {},
"config": {
"user": {
"bots": {
"consentRequired": false
}
},
"notice": {
"position": "bottom",
"showDataProcessing": true
},
"languages": {
"default": "en",
"enabled": [
"en",
"fr"
]
}
},
"default": false,
"platform": "web",
"targets": [],
"text_mode": "approved",
"text_id": "LZJ3VTcz",
"full_atp": true,
"enable_ignore_consent_before": false,
"ignore_consent_before": null,
"negative_action": "button",
"negative_action_link": false,
"negative_action_link_format": "cross",
"negative_action_button": false,
"disagree_button_style": "primary",
"country": null,
"notice_deny_applies_to_li": true,
"preferences_deny_applies_to_li": true,
"consent_duration": 12,
"consent_duration_unit": "months",
"denied_consent_duration": 12,
"denied_consent_duration_unit": "months",
"denied_consent_duration_custom": false,
"cross_device_enabled": false,
"cross_device_timeout": 3000,
"gcm_enabled": false,
"gcm_set_default_status": true,
"gcm_data_layer_name": null,
"gcm_analytics_default_status": false,
"gcm_ads_default_status": false,
"gcm_functionality_default_status": true,
"gcm_personalization_default_status": true,
"gcm_security_default_status": true,
"template_id": null,
"regulation_configurations": [
{
"id": "R4hZbHwe",
"regulation_id": "gdpr",
"is_default_regulation_config": true,
"geo_locations": [
"AD",
"AT",
"BE",
"BG",
"CY",
"CZ",
"DE",
"DK",
"EE",
"ES",
"FI",
"FR",
"GF",
"GG",
"GI",
"GP",
"GR",
"HR",
"HU",
"IE",
"IS",
"IT",
"JE",
"LI",
"LT",
"LU",
"LV",
"MC",
"MF",
"MQ",
"MT",
"NL",
"NO",
"PL",
"PT",
"RE",
"RO",
"SE",
"SI",
"SK",
"SM",
"VA",
"YT"
],
"regulation_settings": {},
"config": {
"app": {
"vendors": {
"iab": {
"all": false,
"stacks": {
"auto": true
},
"enabled": true,
"version": 2
},
"include": [
"googleana-4TXnJigR",
"google"
]
}
},
"preferences": {
"categories": [
{
"type": "purpose",
"purposeId": "cookies"
},
{
"type": "purpose",
"purposeId": "measure_content_performance"
},
{
"type": "purpose",
"purposeId": "create_ads_profile"
},
{
"type": "purpose",
"purposeId": "create_content_profile"
},
{
"type": "purpose",
"purposeId": "improve_products"
},
{
"type": "purpose",
"purposeId": "market_research"
},
{
"type": "purpose",
"purposeId": "measure_ad_performance"
},
{
"type": "purpose",
"purposeId": "select_basic_ads"
},
{
"type": "purpose",
"purposeId": "select_personalized_ads"
},
{
"type": "purpose",
"purposeId": "select_personalized_content"
}
]
}
},
"disabled_at": null,
"created_at": "2023-03-24T11:09:45.725Z",
"updated_at": "2023-03-24T11:09:45.725Z",
"enable_ignore_consent_before": null,
"disagree_button_style": null,
"consent_duration": null,
"consent_duration_unit": null,
"denied_consent_duration": null,
"denied_consent_duration_unit": null,
"denied_consent_duration_custom": null,
"gcm_enabled": true,
"gcm_set_default_status": null,
"gcm_analytics_default_status": null,
"gcm_ads_default_status": null,
"gcm_functionality_default_status": null,
"gcm_personalization_default_status": null,
"gcm_security_default_status": null,
"negative_action_link_format": null,
"notice_deny_applies_to_li": null,
"preferences_deny_applies_to_li": null,
"version": 0,
"negative_action_link": null,
"negative_action_button": null,
"gcm_data_layer_name": null,
"full_atp": null,
"notice_config_id": "Lz97gCd6",
"organization_id": "didomi"
},
{
"id": "XTF4F6da",
"regulation_id": "gdpr",
"is_default_regulation_config": false,
"geo_locations": [
"IT"
],
"regulation_settings": {},
"config": {},
"disabled_at": null,
"created_at": "2023-03-24T11:09:45.725Z",
"updated_at": "2023-03-24T11:09:45.725Z",
"enable_ignore_consent_before": null,
"disagree_button_style": null,
"consent_duration": null,
"consent_duration_unit": null,
"denied_consent_duration": null,
"denied_consent_duration_unit": null,
"denied_consent_duration_custom": null,
"gcm_enabled": null,
"gcm_set_default_status": null,
"gcm_analytics_default_status": null,
"gcm_ads_default_status": null,
"gcm_functionality_default_status": null,
"gcm_personalization_default_status": null,
"gcm_security_default_status": null,
"negative_action_link_format": "cross",
"notice_deny_applies_to_li": null,
"preferences_deny_applies_to_li": null,
"version": 0,
"negative_action_link": true,
"negative_action_button": false,
"gcm_data_layer_name": null,
"full_atp": null,
"notice_config_id": "Lz97gCd6",
"organization_id": "jonathan-thai-didomi"
},
{
"id": "iPqJpaDC",
"regulation_id": "gdpr",
"is_default_regulation_config": false,
"geo_locations": [
"FR"
],
"regulation_settings": {},
"config": {},
"disabled_at": null,
"created_at": "2023-03-24T11:09:45.725Z",
"updated_at": "2023-03-24T11:09:45.725Z",
"enable_ignore_consent_before": null,
"disagree_button_style": null,
"consent_duration": null,
"consent_duration_unit": null,
"denied_consent_duration": null,
"denied_consent_duration_unit": null,
"denied_consent_duration_custom": null,
"gcm_enabled": null,
"gcm_set_default_status": null,
"gcm_analytics_default_status": null,
"gcm_ads_default_status": null,
"gcm_functionality_default_status": null,
"gcm_personalization_default_status": null,
"gcm_security_default_status": null,
"negative_action_link_format": "text",
"notice_deny_applies_to_li": null,
"preferences_deny_applies_to_li": null,
"version": 0,
"negative_action_link": false,
"negative_action_button": true,
"gcm_data_layer_name": null,
"full_atp": null,
"notice_config_id": "Lz97gCd6",