Events

A consent event is a partial update to the consent status of a user.
By default, it applies to GDPR regulation, but it can also be associated with other regulations like CPRA and others (See all regulations supported by Didomi).
When a user makes consent choices through your own custom UI, you should create a new consent event on the Didomi platform. The user consent status, for a given regulation, will be automatically updated and the history of consent events will be kept, associated with the user.
The /consents/events endpoint of the API exposes the events managed by Didomi for your organizations. For a full reference of the endpoint and the resources that it returns, visit https://api.didomi.io/docs/.
When a user gives consent to a set of purposes or vendors, create a consent event to register the user choices by calling the POST /consents/events endpoint.
A consent event consists of a set of partial choices, related to a specific regulation, from a user that will be merged into the user consent status. You can also send additional user information like a new ID or custom metadata. When pushing consent events, you do not need to know the prior consent status of the user and the consent information you are pushing will be automatically merged into the user consent status of the Users endpoints.
By default, consent events are stored under GDPR regulation. To register user choices for another regulation, you need to specify it in the request's payload.
Example
A user giving consent to the purpose "purpose_id":
POST /consents/events?organization_id={organization_id}
BODY
{
"user": {
"organization_user_id": "[email protected]",
"metadata": {
"custom_key": "value"
}
},
/**
* regulation is optional
* if regulation is not specified,
* the consent will be stored under GDPR regulation
*/
"regulation": "cpra" // gdpr...
"consents": {
"purposes": [
{
"id": "purpose_id",
"enabled": true
}
]
}
}
You can specify either the user.organization_user_id field with your own organization user ID or a user.id field with the Didomi user ID. If you do not specify any user ID, a random ID will be automatically created for the user.

Proofs

If you are collecting physical proofs of consents from your users (signatures, forms, etc.), you can attach them to the created events. Add your files as base64-encoded data URIs in the proofs property:
POST /consents/events?organization_id={organization_id}
BODY
{
"user": {
"organization_user_id": "[email protected]",
"metadata": {
"custom_key": "value"
}
},
"consents": {
"purposes": [
{
"id": "purpose_id",
"enabled": true
}
]
},
"proofs": [
{
"filename": "proof.png",
"file: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="
}
]
}
Files must be smaller than 10mb and their type must be one of the following formats: PDF, PNG, JPG, GIF, DOCX, DOC, MSG. You can attach a maximum of 5 proofs per event.

Pending events and approval process

By default, created events are confirmed: their status property has the value confirmed. This indicates that the event is valid and was applied to the user consent status.
Didomi supports various approval methods (email confirmation, email approval, etc.) where an event needs to be approved in a separate process before being applied to the user consent status. Such events are considered "pending" as they are created and stored in the API but not applied to the user consent status until the event is approved. Their status property is set to pending_approval.
When an event is updated to become confirmed, the Didomi API will automatically update the user consent status to apply the updated event. Events will be re-applied according to their update or creation date so that the most recent confirmed events will be applied last.

Create pending events

Events are automatically created as pending if you use a validation method or a consent token with a validation method associated.
If you are not using a validation method and want to create pending events yourself, you can do so by specifying pending_approval in the status property:
POST https://api.didomi.io/v1/consents/events?organization_id={organization_id}
{
"status": "pending_approval",
"user": {
"organization_user_id": "{organization_user_id}"
}
}
A pending event must include an organization_user_id. It also requires an event ID in the id property that will be automatically generated if you do not provide it.

Approve pending events

The Didomi API supports three methods for approving pending events.

Approve pending events via validation methods

When a validation method is used, the approval process is entirely managed by the Didomi API through emails or similar methods. The Didomi API will also takes care of updating the event status when the event is approved through the validation method.

Approve pending events via API requests

If you are not using validation methods, you can manage the approval process yourself and approve pending events through API requests.
To approve pending events, update the event and set the status property to confirmed with a PATCH request:
PATCH https://api.didomi.io/v1/consents/events/{event_id}
?organization_id={organization_id}
&organization_user_id={organization_user_id}
{
"status": "confirmed"
}

Approve pending events via an approval URL

When an event is in status pending_approval, an approval URL is added in the validation.approve_url property. Example of an event with an approval URL provided:
{
"user": {
"organization_user_id": "[email protected]",
"metadata": {
"custom_key": "value"
}
},
"consents": {
"purposes": [
{
"id": "purpose_id",
"enabled": true
}
]
},
"status": "pending_approval",
"validation": {
"approve_url": "https://api.privacy-center.org/consents/execute/..."
}
}
This URL can be used to easily approve the event without requiring API authentication and API calls. It is safe to embed in emails, webpages, etc. as links that users can click on to approve the event.
You can attach metadata to the consent event and use it in the email template used to validate the pending consent. As an example, you create a redirect_url in the metadata and use it as an extra parameter to redirect your end-user on a relevant page for your brand after he approves the changes. (See example here)

Delegates

Delegates are third-parties that modify the consents for an end user and that you want to keep track of. They can be an internal team or user that have been given access to the Didomi API. The third-party is a "delegate" who is doing modifications on behalf of the end user. Delegate information is optional and can be added to the event to keep track of the modification and its source for audit purposes.
Provide the delegate property when creating a consent event to indicate that the event was created by a delegate. You can specify the ID and name of the delegate, and use a generic metadata field to keep track of extra information on the delegate.
Example - Tracking an internal employee ID and their department when an event is created
POST /consents/events?organization_id={organization_id}
BODY
{
"user": {
"organization_user_id": "[email protected]",
"metadata": {
"custom_key": "value"
}
},
"consents": {
"purposes": [
{
"id": "purpose_id",
"enabled": true
}
]
},
"delegate": {
"id": "<Internal ID to identify the delegate>",
"name": "<Name of the delegate>",
"metadata": {
// Custom metadata of the delegate
"department_id": "...",
"country": "..."
}
}
}
Delegates can also be used with consent tokens.
You can query consent events for a user by calling the GET /consents/events endpoint.
You must specify either the organization user ID (organization_user_id query-string parameter) or the Didomi user ID (user_id query-string parameter) of the user that you are querying events for.
By default, consent events are registered under GDPR regulation. To query consent events from another regulation, you must specify the regulation with the regulation query-string parameter (See all regulations supported by Didomi).
Example
GET /consents/events
?organization_id={organization_id}
&organization_user_id={organization_user_id}
&regulation=cpra
RESPONSE:
{
"data": [
{
"id": "00b89328-e3d5-4068-b346-8f4fcb4618df",
"user": {
"id": "a3722cd3-f2e4-4451-a564-83f5e8921449",
"metadata": {
...custom user metadata
}
},
"consents": {
"purposes": [
{
"id": "purpose_id",
"enabled": true
}
]
}
}
]
}

Pending events

By default, the GET /consents/events endpoint only returns confirmed events. To get pending events, you must specify a status filter in the query-string parameter.
For instance, to get all confirmed and pending events, you would do:
GET /consents/events
?organization_id={organization_id}
&organization_user_id={organization_user_id}
&status[$in]=confirmed
&status[$in]=pending_approval
RESPONSE:
{
"data": [
{
"id": "00b89328-e3d5-4068-b346-8f4fcb4618df",
"user": {
"id": "a3722cd3-f2e4-4451-a564-83f5e8921449",
"metadata": {
...custom user metadata
}
},
"consents": {
"purposes": [
{
"id": "purpose_id",
"enabled": true
}
]
}
}
]
}

Specific event

You can also query for a specific event by ID by calling GET /consents/events/:id. See the API documentation for more details.
You can delete consents events by calling the DELETE /consents/events endpoint.
When deleting consent events, the user consent status will be automatically re-computed by re-applying the remaining (non-deleted) consent events, for a given regulation.
You must specify either the organization user ID (organization_user_id query-string parameter) or the Didomi user ID (user_id query-string parameter) of the user that you are querying events for.
You must also specify a list of filters as key-value pairs in the query-string parameters to select consent events that should be removed. The key should be a property name from the Event Schema with nested properties path specified with a .. For instance, a custom event metadata field can be specified as metadata.custom_key.
Example
DELETE /consents/events?organization_id={organization_id}&organization_user_id={organization_user_id}&metadata.booking_id={booking ID}
You can also delete a specific event by ID by calling DELETE /consents/events/:id. See the API documentation for more details.

Disable integrations

If you are importing consent events already present in your systems and there is no need for these consents to be forwarded to your integrations, you can add the query parameter $disable_integrations=true to your request to disable such forwarding.

Event Schema

Since 18th of January 2022, Didomi API supports validation of users choices through our Didomi SDK or through your own custom UI. Choices from users are now validated, which means that only existing or previously existing purposes, preferences and preferences values IDs in your organization will be accepted by the API. It ensures that:
  • You always collect the right consent and prevent mistakes
  • Your events/consents are following a proper and structured format
  • You have control over what can be sent to the API
Preferences are now flat, unique and can contain multiple values. They are more readable, easy to access and collecting choices in your integrations should be simplified.
If you subscribed to Didomi after the 18th of January 2022, you are using the Consents API V2.
The full schema of Events is as follows.
Consents API V2
Consents API V1 (Deprecated)
{
/**
* Unique event ID
* Automatically generated by the API if not provided on event creation
*/
id: 'string',
/**
* Creation date of the event
* Automatically generated by the API if not provided on event creation
*/
created_at: 'ISO8601 date',
/**
* Regulation for which the consent is collected
*/
regulation: 'string',
/**
* Consent status of the user
*/
consents: {
purposes: [
{
id: "string",
metadata: {},
/**
* Whether the user has given consent to this purpose or not
* A null value indicates that the user has not made a specific
* choice for the purpose but might have made choices for
* preferences values
*/
enabled: boolean || null,
values: {
[PREFERENCE_ID]: {
/**
* Preference values that the user has made choices for
*/
value: "PREF_VALUE_ID_1,PREF_VALUE_ID_2"
}
}
}
],
/**
* TCF consent string for the user
* (if it was available or generated at the time of consent collection)
*/
tcfcs: null,
/**
* Vendors that the user has made choices for
*/
vendors: {
/**
* List of vendor IDs that the user has given consent to
*/
enabled: ['string', ...],
/**
* List of vendor IDs that the user has denied consent to
*/
disabled: ['string', ...]
}
}
delegate: {
/**
* Unique ID of the delegate
*/
id: 'string',
/**
* Name of the delegate
*/
name: 'string',
/**
* Free-form metadata object
*/
metadata: 'Object'
},
/**
* Domain of the preference center
*
* This is used to know which preference center is this consent linked to.
* For example to send a authenticated link to the preference center on user creation
*/
domain: 'string',
/**
* Free-form metadata object
*/
metadata: {},
/**
* Organization ID
*/
organization_id: 'string',
/**
* IDs of proofs associated with this event
*/
proofs_id: [],
source: {},
/**
* Status of the event
*
* "confirmed" indicates that the event has been validated or was not subject to validation
* "pending_approval" indicates that the event is pending validation
*/
status: 'confirmed|pending_approval',
/**
* User information
*/
user: {
/**
* Didomi user ID
*/
id: 'string',
/**
* Organization user ID
*/
organization_user_id: 'string'
},
/**
* Validation information (if the event was validated)
* `null` if there is no validation
*/
validation: {
/**
* Validation type used for this event
*/
type: 'email|signature|file'
}
}
{
/**
* Unique event ID
* Automatically generated by the API if not provided on event creation
*/
id: 'string',
/**
* Creation date of the event
* Automatically generated by the API if not provided on event creation
*/
created_at: 'ISO8601 date',
/**
* Regulation for which the consent is collected
*/
regulation: 'string',
/**
* Free-form metadata object
*/
metadata: Object,
/**
* User information
*/
user: {
/**
* Didomi user ID
*/
id: 'string',
/**
* Organization user ID
*/
organization_user_id: 'string',
/**
* Free-form metadata object
*/
metadata: Object,
/**
* Two-letter ISO code of the user's country.
* `null` if no value is provided. This property is never set automatically by Didomi.
*/
country: 'string',
/**
* Two-letter ISO country code of the consent event.
* The country of a consent event might differ from the initial
* user's country. This property stores the last seen country from
* the user's consent events.
* Auto-filled for Didomi SDK events.
*/
last_seen_country: 'string'
},
/**
* IDs of proofs associated with this event
*/
proofs_id: [ ... ],
/**
* Delegate that created the event
* `null` if there is no delegate
*/
delegate: {
/**
* Unique ID of the delegate
*/
id: 'string',
/**
* Name of the delegate
*/
name: 'string',
/**
* Free-form metadata object
*/
metadata: Object,
},
/**
* Validation information (if the event was validated)
* `null` if there is no validation
*/
validation: {
/**
* Validation type used for this event
*/
type: 'email|signature|file'
},
/**
* Status of the event
*
* "confirmed" indicates that the event has been validated or was not subject to validation
* "pending_approval" indicates that the event is pending validation
*/
status: 'confirmed|pending_approval',
/**
* Domain of the preference center
*
* This is used to know which preference center is this consent linked to.
* For example to send a authenticated link to the preference center on user creation
*/
domain: 'string'
/**
* Consent status of the user
*/
consents: {
/**
* Channels that the user made choices for
*/
channels: [
{
/**
* Unique channel ID
*/
id: 'string',
/**
* Whether the user has enabled this channel or not
* A null value indicates that the user has not made a specific
* choice for the channel
*/
enabled: boolean | null,
/**
* Free-form metadata object
*/
metadata: Object,
}
],
/**
* Purposes that the user has made choices for
*/
purposes: [
{
/**
* Unique purpose ID
*/
id: 'string',
/**
* Whether the user has given consent to this purpose or not
* A null value indicates that the user has not made a specific
* choice for the purpose but might have made choices for
* preferences or channels
*/
enabled: boolean | null,
/**
* Channels that the user has made choices for
*/
channels: [
{
/**
* Unique channel ID
*/
id: 'string',
/**
* Whether the user has enabled this channel or not
* A null value indicates that the user has not made a specific
* choice for the channel
*/
enabled: boolean | null,
/**
* Free-form metadata object
*/
metadata: Object,
}
],
/**
* Extra preferences expressed for the purpose
*/
preferences: [
{
/**
* Unique preference ID
*/
id: 'string',
/**
* Whether the user has enabled this preference or not
* A null value indicates that the user has not made a specific
* choice for the preference but might have made choices for
* channels
*/
enabled: boolean | null,
/**
* Channels that the user has made choices for
*/
channels: [
{
/**
* Unique channel ID
*/
id: 'string',
/**
* Whether the user has enabled this channel or not
* A null value indicates that the user has not made a specific
* choice for the channel
*/
enabled: boolean | null,
/**
* Free-form metadata object
*/
metadata: Object,
}
],
/**
* Free-form metadata object on the preference
*/
metadata: Object,
}
]
},
...
],
/**
* Vendors that the user has made choices for
*/
vendors: {
/**
* List of vendor IDs that the user has given consent to
*/
enabled: ['string', ...],
/**
* List of vendor IDs that the user has denied consent to
*/
disabled: ['string', ...]
},
/**
* TCF consent string for the user
* (if it was available or generated at the time of consent collection)
*/
tcfcs: 'string'
}
}{