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. 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. 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. 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. 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. 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. Where the data subject objects to processing for direct marketing purposes, the personal data shall no longer be processed for such purposes.

  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. 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. 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. Define your data processing activities (purpose, legal basis,...)

  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. Identify your choice sources (front-end CMP, settings in logged-in environment, CRM files, ...)

You perform the following steps:

  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. 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. 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

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.

[
    {
    "id": "1",
    "community_id": "1125",
    "name": "Analytics",
    "purpose": "Collecting navigation events to
    build aggregated reports on site usage (pages
    views etc.)",
    "legal_basis": "LEGITIMATE_INTEREST",
    "technical_name": "mics-analytics-processing",
    "token": "mics-analytics-processing",
    "archived": false
    },
    {
    "id": "2",
    "community_id": "1125",
    "name": "Targeted advertising",
    "purpose": "Collecting navigation events to
    perform user profiling and broadcast targeted
    advertising",
    "legal_basis": "CONSENT",
    "technical_name": "mics-advertisingprocessing",
    "token": "mics-advertising-processing",
    "archived": false
    }
]

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"

Create a processing

POST https://api.mediarithmics.com/v1/processings

Request Body

NameTypeDescription

Body

object

The payload

// Sample payload
{
  "id":"",
  "community_id":"<your_community_id>",
  "name": "Testing",
  "purpose": "Test the delete",
  "legal_basis": "CONSENT",
  "technical_name": "me-testing-delete-processing",
  "token": "me-testing-delete-processing"
}

List the processings

GET https://api.mediarithmics.com/v1/processings?community_id=:communityId

Path Parameters

NameTypeDescription

communityId

integer

The ID of the community

Update a processing

PUT https://api.mediarithmics.com/v1/processings/:processingId

Path Parameters

NameTypeDescription

processingId

integer

The ID of the processing to update

Request Body

NameTypeDescription

Body

object

The payload

// Sample payload
{
  "id":"",
  "community_id":"<your_community_id>",
  "name": "Testing",
  "purpose": "Collecting navigation events to perform R&D tests ONLY. Test Update.",
  "legal_basis": "CONSENT",
  "technical_name": "me-testing-delete-processing",
  "token": "me-testing-delete-processing"
}

Delete a processing

DELETE https://api.mediarithmics.com/v1/processings/:processingId?community_id=:communityId

Path Parameters

NameTypeDescription

communityId

integer

The ID of the community

processingId

integer

The ID of the processing to update

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 :

{
    "$processing_id": “1004",
    "$choice_ts": 1561622248000,
    "$choice_acceptance_value": true,
    "$creation_ts": 1561622248000,
    "$channel_id": "1234",
    "$choice_source_id": "1001",
    "$user_agent_id": "vec:123456789",
    "$compartment_id": "1234",
    "$user_account_id": "123456789",
    "$email_hash": {
        "$hash": "a1b2c3d4e5",
        "$email": "random@gmail.com"
    },
    "custom_property_1": "custom_value_1",
    "custom_property_2": "custom_value_2"
}

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

User Identifier

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.

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 :

// Function to be triggered when the user made a choice
// Could be triggered by the front-end CMP
// or in the user settings page
function triggetSetUserChoice(value){
    // Include the mediarithmics snippet if not already included
    ...
    mics.init("mycorm");

    // Create the consent event metadata
    var userConsent = {
        // The token of the associated processing activity
        $processing_token: "mics-advertising-processing" 
        // The acceptance value
        $choice_acceptance_value: value
        // Any custom property
        mycustomproperty: "hello there"
    }

    // Push the event
    mics.push("$set_user_choice",userConsent);
}

This code will result in a user activity after processing :

// Sample result user activity with a $set_user_choice event
{
    "$type": "SITE_VISIT",
    "$session_status": "CLOSED_SESSION",
    "$ttl": 0,
    "$user_account_id": null,
    "$email_hash": null,
    "$user_agent_id": "vec:123456789",
    "$origin": null,
    "$location": null,
    "$unique_key": "bfff1e50-15d0-11ea-bc21-d5761024f5d0",
    "$error_analyzer_id": null,
    "$ts": 1575379690677,
    "$session_duration": 3,
    "$topics": {},
    "$site_id": "3407“,
    ...
    "$events": [
        {
        "$ts": 1575379693722,
        "$event_name": "$set_user_choice",
        "$properties": {
            "$processing_token": "mics-advertising-processing",
            "$choice_acceptance_value": true,
            "mycustomproperty": "hello there",
            "$url": "https://www.mediarithmics.com/fr-fr"
            }
        },
        {
        "$ts": 1575379690677,
        "$event_name": "Page View",
        "$properties": {
            "$url": "https://www.mediarithmics.com/fr-fr",
            "$referrer": "",
            "level0": "fr-fr"
            }
        }
    ]
}

With API

Use the User activity 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.

With 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.

// Sample user activity to add using the document import API
{
    "$user_account_id":"<your_user_account_id>",
    "$compartment_id":<your_compartement_id>,
    "$type":"<your_activity_type (ex: SITE_VISIT)",
    "$site_id": "<your_site_id>",
    "$session_status":"NO_SESSION",
    "$ts":<a_timestamp (ex:1572947762)>,
    "$events": [
        {
        "$event_name":"$set_user_choice",
        "$ts":<a_timestamp (ex:1572948120)>,
        "$properties":{
            "$processing_token": "<your_processing_token>", // Mandatory
            "$choice_acceptance_value":<true/false>, // Mandatory
            "<your_custom_field>" : "<your_custom field_value>"
            }
        }
    ]
}

Via user points

Use the User point tracking API to set directly the user choice, without creating any user activity.

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.

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.

# User choices in the schema
type UserPoint @TreeIndexRoot(index:"USER_INDEX") {
    id:ID!

    activity_events:[ActivityEvent!]!
    choices:[UserChoice!]!
}
type UserChoice {
    id:ID!
    processing_id: String! @TreeIndex(index:"USER_INDEX")
    choice_acceptance_value:Boolean! @TreeIndex(index:"USER_INDEX")
    choice_ts: Timestamp! @TreeIndex(index:"USER_INDEX")
    creation_ts: Timestamp! @TreeIndex(index:"USER_INDEX")
    channel_id: String 
    user_agent_id: String
    email_hash: String
    compartment_id: String
    user_account_id: String
    custom_field: String @Property(path: "custom_field")
}

Here are examples of OTQL queries that can be built :

// Listing all processings and their available values
SELECT {
    processing_id @map {
        choice_acceptance_value @map
    }
}
FROM UserChoice

// Count the number of users who accepted a processing
SELECT @count {}
FROM UserPoint
WHERE choices {
    processing_id = "1001"
    AND choice_acceptance_value = true
}

// Choice-based segments
SELECT {id}
FROM UserPoint
WHERE [segment_query_conditions]
    AND choices {
        processing_id = "1001"
        AND choice_acceptance_value = true
    }

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

Last updated