User choices
User choices provide a solution to:
  • Store user choices and enforce them by design / default on your daily marketing activities on the mediarithmics platform.
  • Answer audit requirements related to user consents.
These user choices are offered as an addition to, and not as a replacement for, the existing compliance software used by our clients.
They can be integrated with any market CMP (even automatically integrated if the CMP is IAB registered) but are not registered IAB CMP as we do not provide a user interface (website popup) to capture user choices.
This feature is offered to all mediarithmics clients as a way to improve their compliance with the GDPR.
User choices are not:
  • A guaranty for GDPR compliance. The data controller shall make sure that the legal basis used for processing consent expression is valid, and that user consents contain enough information to prove its validity and processing activities are rightfully associated with data sources and operations on the platform.
  • A front-end solution. Integration with front-end CMP must be considered.
  • A choice "hub" to share choices with third parties (not yet). Integration with front-end CMP must be considered.

Why you need user choices

The General Data Protection Regulation has granted data controllers with new obligations and responsibilities.
At the center of them is Transparency: the obligation to inform users about the processing activities they are conducting with their personal data.
To lawfully process personal data, controllers may sometimes have the obligation to:
  • Ask the user if he consents to the processing of his personal data
  • Offer the possibility to object to the processing of his personal data
  • (And of course) to enforce those user choices.
As a data processor, we must provide services that allow our clients to legally process personal data, therefore that comply with the hereabove requirements.
Moreover, the GDPR requires that data protection principles should be taken into account by design and by default in any organisation, technical solution, project, etc. involved in the processing of personal data

GDPR Article 6: "Lawfulness of processing"

  1. 1.
    Processing shall be lawful only if and to the extent that at least one of the following applies:
    a. The data subject has given consent to the processing of his or her personal data for one or more specific purposes.
    b. Processing is necessary for the performance of a contract to which the data subject is party or in order to take steps at the request of the data subject prior to entering into a contract;
    c. Processing is necessary for compliance with a legal obligation to which the controller is subject;
    d. Processing is necessary in order to protect the vital interests of the data subject or of another natural person;
    e. Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the controller;
    f. Processing is necessary for the purposes of the legitimate interests pursued by the controller or by a third party, except where such interests are overridden by the
    interests or fundamental rights and freedoms of the data subject which require protection of personal data, in particular where the data subject is a child.

GDPR Article 7: "Conditions for consent"

  1. 1.
    Where processing is based on consent, the controller shall be able to demonstrate that the data subject has consented to processing of his or her personal data.
  2. 2.
    The data subject shall have the right to withdraw his or her consent at any time. The withdrawal of consent shall not affect the lawfulness of processing based on consent
    before its withdrawal. Prior to giving consent, the data subject shall be informed thereof. It shall be as easy to withdraw as to give consent

GDPR Article 21: "Right to object"

  1. 1.
    The data subject shall have the right to object, on grounds relating to his or her particular situation, at any time to processing of personal data concerning him or her which
    is based on point (e) or (f) of Article 6(1), including profiling based on those provisions. The controller shall no longer process the personal data unless the controller
    demonstrates compelling legitimate grounds for the processing which override the interests, rights and freedoms of the data subject or for the establishment, exercise or
    defence of legal claims.
  2. 2.
    Where personal data are processed for direct marketing purposes, the data subject shall have the right to object at any time to processing of personal data concerning him
    or her for such marketing, which includes profiling to the extent that it is related to such direct marketing.
  3. 3.
    Where the data subject objects to processing for direct marketing purposes, the personal data shall no longer be processed for such purposes.
  4. 4.
    At the latest at the time of the first communication with the data subject, the right referred to in paragraphs 1 and 2 shall be explicitly brought to the attention of the data
    subject and shall be presented clearly and separately from any other information

GDPR Article 25: "Data protection by design and by default"

  1. 1.
    Taking into account the state of the art, the cost of implementation and the nature, scope, context and purposes of processing as well as the risks of varying likelihood and
    severity for rights and freedoms of natural persons posed by the processing, the controller shall, both at the time of the determination of the means for processing and at
    the time of the processing itself, implement appropriate technical and organisational measures, such as pseudonymisation, which are designed to implement dataprotection principles, such as data minimisation, in an effective manner and to integrate the necessary safeguards into the processing in order to meet the requirements of
    this Regulation and protect the rights of data subjects.
  2. 2.
    The controller shall implement appropriate technical and organisational measures for ensuring that, by default, only personal data which are necessary for each specific
    purpose of the processing are processed. That obligation applies to the amount of personal data collected, the extent of their processing, the period of their storage and
    their accessibility. In particular, such measures shall ensure that by default personal data are not made accessible without the individual’s intervention to an indefinite
    number of natural persons.

How it works

You have some preliminary legal steps to ensure before using the platform to store user choices:
  1. 1.
    Define your data processing activities (purpose, legal basis,...)
  2. 2.
    If you use consent as a legal basis, define what information you must collect to prove a valid consent (ie consent string with metadata, privacy policy version, website code version, ...)
  3. 3.
    Identify your choice sources (front-end CMP, settings in logged-in environment, CRM files, ...)
You perform the following steps:
  1. 1.
    Register processing activities in the platform (either by API or by going in the navigator, in your organisation settings) representing what you expect to do with the data and its legal basis.
  2. 2.
    Record user choices as events in user activities in the different locations where the user is supposed to acknowledge the usage that is done with its data. Those choices and their history will be stored on the platform for each user
  3. 3.
    Implement privacy walls by linking your channels, compartments and segments with the relevant processing activities. Privacy walls on channels and compartments prevent the platform from storing data it shouldn't. Privacy walls on segments prevent users from being in a segment if they shouldn't.
Processing activities and user choices

Processing activities

Processing activities are an object representing what you expect to do with the data. The data includes the following values:
Field
Type
Description
Id
String
Defined by the platform.
The processing primary ID on mediarithmics platform.
Can be used to identify a processing in an authenticated environment.
name
String
A descriptive name to display on the user interface.
purpose
String
The explained purpose of your processing. This must be consistent with the information you provided to your users
legal_basis
Enum
The legal basis of your processing. Its value has impacts on the ability to use the processing in user choices.
Can only be set when creating a processing activity, cannot be modified later.
technical_name
String
External ID for the processing to be used by authenticated API only
token
String
External ID for the processing, to be used when capturing choices from a website using the JavaScript Tag.
community_id
String
Processing entries are defined at the community level
archived
Boolean
To de-activate and hide a processing.
No new user choice can be attached to archived processing and it will not be displayed in the UI.
1
[
2
{
3
"id": "1",
4
"community_id": "1125",
5
"name": "Analytics",
6
"purpose": "Collecting navigation events to
7
build aggregated reports on site usage (pages
8
views etc.)",
9
"legal_basis": "LEGITIMATE_INTEREST",
10
"technical_name": "mics-analytics-processing",
11
"token": "mics-analytics-processing",
12
"archived": false
13
},
14
{
15
"id": "2",
16
"community_id": "1125",
17
"name": "Targeted advertising",
18
"purpose": "Collecting navigation events to
19
perform user profiling and broadcast targeted
20
advertising",
21
"legal_basis": "CONSENT",
22
"technical_name": "mics-advertisingprocessing",
23
"token": "mics-advertising-processing",
24
"archived": false
25
}
26
]
Copied!
The legal basis is important metadata that will have an impact when defining if a user should consent or object and on the rules applied in privacy walls.
The data subject has given consent to the processing of his or her personal data for one or more specific purposes
  • Associated user choices can have an acceptance value of true or false
  • Data processing in the platform will be allowed if the user has a user choice and its value is true
  • Data processing in the platform will be blocked if the user has no user choice or if its value is false

CONTRACTUAL_PERFORMANCE

“Processing is necessary for the performance of a contract to which the data subject is party or in order to take steps at the request of the data subject prior to entering into a contract
  • No associated user choice is stored
  • Data processing in the platform is always allowed
“Processing is necessary for compliance with a legal obligation to which the controller is subject
  • No associated user choice is stored
  • Data processing in the platform is always allowed

PUBLIC_INTEREST_OR_EXERCISE_OF_OFFICIAL_AUTHORITY

“Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the controller
  • The user can only object to this processing: the associated user choices can only have an acceptance value of false
  • Data processing in the platform will be allowed if the user has no user choice
  • Data processing in the platform will be blocked if the user has a user choice and if its value is false

LEGITIMATE_INTEREST

“Processing is necessary for the purposes of the legitimate interests pursued by the controller or by a third party, except where such interests are overridden by the interests or fundamental rights and freedoms of the data subject which require protection of personal data, in particular where the data subject is a child. Shall not apply to processing carried out by public authorities in the performance of their tasks.
  • The user can only object to this processing: the associated user choices can only have an acceptance value of false
  • Data processing in the platform will be allowed if the user has no user choice
  • Data processing in the platform will be blocked if the user has a user choice and if its value is false
The legal basis VITAL_INTERESTS is not allowed as it is not pertinent in our context. GDPR Verbatim: "Processing is necessary in order to protect the vital interests of the data subject or of another natural person"
post
https://api.mediarithmics.com
/v1/processings
Create a processing
1
// Sample payload
2
{
3
"id":"",
4
"community_id":"<your_community_id>",
5
"name": "Testing",
6
"purpose": "Test the delete",
7
"legal_basis": "CONSENT",
8
"technical_name": "me-testing-delete-processing",
9
"token": "me-testing-delete-processing"
10
}
Copied!
get
https://api.mediarithmics.com
/v1/processings?community_id=:communityId
List the processings
put
https://api.mediarithmics.com
/v1/processings/:processingId
Update a processing
1
// Sample payload
2
{
3
"id":"",
4
"community_id":"<your_community_id>",
5
"name": "Testing",
6
"purpose": "Collecting navigation events to perform R&D tests ONLY. Test Update.",
7
"legal_basis": "CONSENT",
8
"technical_name": "me-testing-delete-processing",
9
"token": "me-testing-delete-processing"
10
}
Copied!
delete
https://api.mediarithmics.com
/v1/processings/:processingId?community_id=:communityId
Delete a processing

User choices

User choices represent the choices a user makes for each of your processing activities.
Each time a user makes a choice, you send it to the platform as user event with the $set_user_choice name and a set of metadata. It will then be computed and stored. You can also create choices via API.
Here are the fields of a user choice object :
1
{
2
"$processing_id":1004",
3
"$choice_ts": 1561622248000,
4
"$choice_acceptance_value": true,
5
"$creation_ts": 1561622248000,
6
"$channel_id": "1234",
7
"$choice_source_id": "1001",
8
"$user_agent_id": "vec:123456789",
9
"$compartment_id": "1234",
10
"$user_account_id": "123456789",
11
"$email_hash": {
12
"$hash": "a1b2c3d4e5",
13
"$email": "[email protected]"
14
},
15
"custom_property_1": "custom_value_1",
16
"custom_property_2": "custom_value_2"
17
}
Copied!
Field
Type
Description
$processing_id
String
The ID of the associated processing activity.
Mandatory via API. Automatically set with $set_user_choice events from the $processing_token property
$choice_ts
Timestamp
Timestamp at which the choice has been given by the user.
Mandatory via API. Automatically set with $set_user_choice events from the $ts property
$choice_acceptance_value
Boolean
Choice acceptance value
Mandatory via API. Automatically set with $set_user_choice events from the $choice_acceptance_value property
$creation_ts
Timestamp
System field. Creation timestamp of the user choice
Forbidden modification (via API or event). Automatically defined at the user choice creation.
$channel_id
String
Channel on which the choice has been collected
Optional via API. Automatically set with $set_user_choice events from the activity origin.
$choice_source_id
String
Source of the choice
Optional via API. Automatically set with $set_user_choice events from the $choice_source_token property. Allowing a choice update will depend on the source weight (see below).
$user_agent_id User Identifier
String
The identifier of the user device as provided by the user id mapping service. ex: vec:89090939434
<code></code>
  • If choice defined by a $set_user_choice event (pixel or /user_activities API): we copy the identifiers from the activity origin (after interpreting those within events if pixel)
  • If choice defined by /user_choices API, we consider those in the request payload. If no identifier is defined in the request payload, we copy those in the URL
$user_account_id
User Identifier with $compartment_id
String
The user account id of the user.
  • If choice defined by a $set_user_choice event (pixel or /user_activities API): we copy the identifiers from the activity origin (after interpreting those within events if pixel)
  • If choice defined by /user_choices API, we consider those in the request payload. If no identifier is defined in the request payload, we copy those in the URL
$compartment_id
User Identifier with $user_account_id
Integer
The ID of the compartment associated with this activity.
  • If choice defined by a $set_user_choice event (pixel or /user_activities API): we copy the identifiers from the activity origin (after interpreting those within events if pixel)
  • If choice defined by /user_choices API, we consider those in the request payload. If no identifier is defined in the request payload, we copy those in the URL
$email_hash
Email Hash Object (Optional)
The email hash object { “$hash”:…, “$email”:…}.
  • If choice defined by a $set_user_choice event (pixel or /user_activities API): we copy the identifiers from the activity origin (after interpreting those within events if pixel)
    • If choice defined by /user_choices API, we consider those in the request payload. If no identifier is defined in the request payload, we copy those in the URL
[any custom property]
String
Custom properties
Optional via API. Automatically set with $set_user_choices events from the events custom properties

Registering user choices

You have different ways to capture user choices, each corresponding to different use cases.

Via user activities

The platform detects the $set_user_choice events and creates a user choice using some fields of the user activity.
You can use the different methods of ingesting user activities to ingest your user choices.
User choice fields mapping form user activities

With Website tracking

Use the real-time user tracking to push a $set_user_choice event. No authentication is required.
This method is used to capture front-end CMP signals and choices the user may do in their user settings.
Please note that those events will go through the processing pipeline before being stored as a user choice. You must ensure no activity analyzers is removing them during that process.
Here is a sample code to include in your mediarithmics snippet :
1
// Function to be triggered when the user made a choice
2
// Could be triggered by the front-end CMP
3
// or in the user settings page
4
function triggetSetUserChoice(value){
5
// Include the mediarithmics snippet if not already included
6
...
7
mics.init("mycorm");
8
9
// Create the consent event metadata
10
var userConsent = {
11
// The token of the associated processing activity
12
$processing_token: "mics-advertising-processing"
13
// The acceptance value
14
$choice_acceptance_value: value
15
// Any custom property
16
mycustomproperty: "hello there"
17
}
18
19
// Push the event
20
mics.push("$set_user_choice",userConsent);
21
}
Copied!
This code will result in a user activity after processing :
1
// Sample result user activity with a $set_user_choice event
2
{
3
"$type": "SITE_VISIT",
4
"$session_status": "CLOSED_SESSION",
5
"$ttl": 0,
6
"$user_account_id": null,
7
"$email_hash": null,
8
"$user_agent_id": "vec:123456789",
9
"$origin": null,
10
"$location": null,
11
"$unique_key": "bfff1e50-15d0-11ea-bc21-d5761024f5d0",
12
"$error_analyzer_id": null,
13
"$ts": 1575379690677,
14
"$session_duration": 3,
15
"$topics": {},
16
"$site_id": "3407,
17
...
18
"$events": [
19
{
20
"$ts": 1575379693722,
21
"$event_name": "$set_user_choice",
22
"$properties": {
23
"$processing_token": "mics-advertising-processing",
24
"$choice_acceptance_value": true,
25
"mycustomproperty": "hello there",
26
"$url": "https://www.mediarithmics.com/fr-fr"
27
}
28
},
29
{
30
"$ts": 1575379690677,
31
"$event_name": "Page View",
32
"$properties": {
33
"$url": "https://www.mediarithmics.com/fr-fr",
34
"$referrer": "",
35
"level0": "fr-fr"
36
}
37
}
38
]
39
}
Copied!

API creation of user activities with $set_user_choice events

Use the Tracking API to create an already well-formatted user activity. The platform will then create a user choice exactly as it did in the website tracking section.
This method is used when you want to achieve real-time tracking but can't use the mediarithmics JavaScript Tag. In mobile applications for example.
Please note that those events will go through the processing pipeline before being stored as a user choice. You must ensure no activity analyzers is removing them during that process.
1
// Sample user activity to add using the tracking API
2
{
3
"$user_account_id":"<your_user_account_id>",
4
"$compartment_id":<your_compartement_id>,
5
"$type":"<your_activity_type (ex: SITE_VISIT)",
6
"$site_id": "<your_site_id>",
7
"$session_status":"NO_SESSION",
8
"$ts":<a_timestamp (ex:1572947762)>,
9
"$events": [
10
{
11
"$event_name":"$set_user_choice",
12
"$ts":<a_timestamp (ex:1572948120)>,
13
"$properties":{
14
"$processing_token": "<your_processing_token>", // Mandatory
15
"$choice_acceptance_value":<true/false>, // Mandatory
16
"<your_custom_field>" : "<your_custom field_value>"
17
}
18
}
19
]
20
}
Copied!

Document import

Use the document import feature to bulk create user activities with $set_user_choice events from external sources (CRM files, server-side CMPs, ...).
This method is used when you want to bulk import user choices from external sources via files.
Please note that those events will not go through the processing pipeline before being stored as a user choice. You must ensure they are already formatted.
1
// Sample user activity to add using the document import API
2
{
3
"$user_account_id":"<your_user_account_id>",
4
"$compartment_id":<your_compartement_id>,
5
"$type":"<your_activity_type (ex: SITE_VISIT)",
6
"$site_id": "<your_site_id>",
7
"$session_status":"NO_SESSION",
8
"$ts":<a_timestamp (ex:1572947762)>,
9
"$events": [
10
{
11
"$event_name":"$set_user_choice",
12
"$ts":<a_timestamp (ex:1572948120)>,
13
"$properties":{
14
"$processing_token": "<your_processing_token>", // Mandatory
15
"$choice_acceptance_value":<true/false>, // Mandatory
16
"<your_custom_field>" : "<your_custom field_value>"
17
}
18
}
19
]
20
}
Copied!

Via API

put
https://api.mediarithmics.com
/v1/datamarts/:datamartId/user_points/:userSelector/user_choices/processing_id=:processingId
Create/Update user choices
1
// Sample payload
2
{
3
"$choice_ts": "<a_timestamp (ex:1573135588140)>", // Mandatory
4
"$choice_acceptance_value":<true/false>, // Mandatory
5
"<your_custom_field>" : "<your_custom field_value> // Optional
6
}
Copied!
get
https://api.mediarithmics.com
/v1/datamarts/:datamartId/user_points/:userSelector/user_choices/processing_id=:processingId
List user choices
get
https://api.mediarithmics.com
/v1/datamarts/:datamartId/user_points/:userSelector/user_choices/processing_id=:processingId/change_log
User choices history

Privacy walls

User choices can be used to automatically allow or block the processing of personal data for a given user, based on his choices.
They can be created at different levels :
  • On UPSERT of user activities of type SITE_VISIT and APP_VISIT. To achieve this, you link a list of processing activities to a channel. The upsert of data will be allowed for a user if he has allowed at least one of the selected processing activities. User activities of types TOUCH, EMAIL and DISPLAY_AD are not covered yet.
  • On UPSERT of user profiles. This is done by linking a list of processing activities to a compartment. The upsert of data will be allowed for a user if he has allowed at least one of the selected processing activities.
  • On segments computation. The linkage is done at the segment level by selecting a list of processing activities. The user will be allowed in the segment if he has allowed all the selected processing activities.
On the navigator, go to the settings of the object you wish to link to a list of processing activities and you'll have an option displayed.
For upserted data (user activities, user profiles and user segments of type USER_LIST), the decision to upsert or drop is taken just before saving it into the datamart. In the case of user activities, the decision takes into account the presence of a $set_user_choice event in the activity. If a user changes his choices, new data upserts will be blocked but already captured data is kept and follows the standard cleaning rules.
For USER_QUERY segments, the segment query is automatically updated with conditions on the user choices to include only users with compatible choices. If a user changes his choices, the user will exit the segment as he doesn't match the query anymore?

User points merge

Like other data, choices are taken into account when two user points are merging. However, user choices updates do not trigger merges.
For a given processing, user choices changelogs are merged like user activities in the timeline. Regarding the active values, the one with the latest $creation_ts is kept active on the user point survivor, the other one being added to the change log.
Example 1 of user point merge
Example 2 of user point merge

User choices in the schema

User choices and their custom properties should be declared in the schema for the feature to work.
Any property can be indexed and the following four properties should be indexed: processing_id, choice_ts, creation_ts and choice_acceptance_value.
As the other properties (standard or custom) are expected to be used mostly to prove the validity of a given choice, it might not be required to index them.
1
# User choices in the schema
2
type UserPoint @TreeIndexRoot(index:"USER_INDEX") {
3
id:ID!
4
5
activity_events:[ActivityEvent!]!
6
choices:[UserChoice!]!
7
}
8
type UserChoice {
9
id:ID!
10
processing_id: String! @TreeIndex(index:"USER_INDEX")
11
choice_acceptance_value:Boolean! @TreeIndex(index:"USER_INDEX")
12
choice_ts: Timestamp! @TreeIndex(index:"USER_INDEX")
13
creation_ts: Timestamp! @TreeIndex(index:"USER_INDEX")
14
channel_id: String
15
user_agent_id: String
16
email_hash: String
17
compartment_id: String
18
user_account_id: String
19
custom_field: String @Property(path: "custom_field")
20
}
Copied!
Here are examples of OTQL queries that can be built :
1
// Listing all processings and their available values
2
SELECT {
3
processing_id @map {
4
choice_acceptance_value @map
5
}
6
}
7
FROM UserChoice
8
9
// Count the number of users who accepted a processing
10
SELECT @count {}
11
FROM UserPoint
12
WHERE choices {
13
processing_id = "1001"
14
AND choice_acceptance_value = true
15
}
16
17
// Choice-based segments
18
SELECT {id}
19
FROM UserPoint
20
WHERE [segment_query_conditions]
21
AND choices {
22
processing_id = "1001"
23
AND choice_acceptance_value = true
24
}
Copied!

Choice sources

You should ask your mediarithmics contact to activate this feature for you if needed
When a new choice comes to overwrite an existing choice on the same processing, it may be needed to establish a priority based on the choice source. For instance:
  • User choices in a logged-in environment VS front-end CMP popup
  • Direct exercise of rights toward the data processor VS CMP cache on the browser
  • ...
Therefore we have added an optional field to the user choice : $choice_source_id, relating each choice to a reference table that can be created by mediarithmics for each client.
id
community_id
name
token
weight
1001
1426
CMP
me-cmp_local
1
1002
1426
Website user settings
me-user_settings
2
1003
1426
CRM file
me-member_crm_file
2
1004
1426
Exercise of rights
me-exercise_of_rights
3
To define the choice source :
  • via $set_user_choice events, use $choice_source_token . Il will be translated by the platform in to a $choice_source_id
  • via datamart /user_choices API, use directly the $choice_source_id
Impacts on choice update process
  • A new choice collected via $set_user_choice event will overwrite the existing one if and only if it has a choice source with a weight equal or superior to the existing one
  • The absence of choice source is equivalent to the lowest weight
  • This rule is not applied on a choice updated via Datamart authenticated APIs
  • This rule is not applied in the case of a merge