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

{% hint style="warning" %}
**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.
  {% endhint %}

## 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&#x20;
* Offer the **possibility to object** to the processing of his personal data&#x20;
* (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

{% hint style="info" %}
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, ...*)
   {% endhint %}

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](https://developer.mediarithmics.io/user-points/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 and user choices](https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MTaRqePE5hJbhOi2SKQ%2F-MTaSDvte3VRd_6MnKaH%2Fimage.png?alt=media\&token=6496e528-da56-467b-b7d6-63b2a7c68587)

## 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  | <p>Defined by the platform.</p><p>The processing primary ID on mediarithmics platform.</p><p>Can be used to identify a processing in an authenticated environment.</p>                                               |
| 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    | <p>The legal basis of your processing. Its value has impacts on the ability to use the processing in user choices.</p><p><em>Can only be set when creating a processing activity, cannot be modified later.</em></p> |
| 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 | <p>To de-activate and hide a processing.</p><p>No new user choice can be attached to archived processing and it will not be displayed in the UI.</p>                                                                 |

```javascript
[
    {
    "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
    }
]
```

### Legal basis

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.

#### `CONSENT`

> 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

#### `LEGAL_OBLIGATION`

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

{% hint style="info" %}
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*"
{% endhint %}

## Create a processing

<mark style="color:green;">`POST`</mark> `https://api.mediarithmics.com/v1/processings`

#### Request Body

| Name | Type   | Description |
| ---- | ------ | ----------- |
| Body | object | The payload |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

```javascript
// 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

<mark style="color:blue;">`GET`</mark> `https://api.mediarithmics.com/v1/processings?community_id=:communityId`

#### Path Parameters

| Name        | Type    | Description             |
| ----------- | ------- | ----------------------- |
| communityId | integer | The ID of the community |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## Update a processing

<mark style="color:orange;">`PUT`</mark> `https://api.mediarithmics.com/v1/processings/:processingId`

#### Path Parameters

| Name         | Type    | Description                        |
| ------------ | ------- | ---------------------------------- |
| processingId | integer | The ID of the processing to update |

#### Request Body

| Name | Type   | Description |
| ---- | ------ | ----------- |
| Body | object | The payload |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

```javascript
// 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

<mark style="color:red;">`DELETE`</mark> `https://api.mediarithmics.com/v1/processings/:processingId?community_id=:communityId`

#### Path Parameters

| Name         | Type    | Description                        |
| ------------ | ------- | ---------------------------------- |
| communityId  | integer | The ID of the community            |
| processingId | integer | The ID of the processing to update |

{% tabs %}
{% tab title="200 " %}

```
```

{% endtab %}
{% endtabs %}

## 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](https://developer.mediarithmics.io/user-points/user-activities) 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 :

```javascript
{
    "$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                       | <p>The ID of the associated processing activity.</p><p>Mandatory via API. Automatically set with <code>$set\_user\_choice</code> events from the <code>$processing\_token</code> property</p>                                                                                                                                                                                                                                                                                                                                                       |
| $choice\_ts                                                                                                                            | Timestamp                    | <p>Timestamp at which the choice has been given by the user.</p><p>Mandatory via API. Automatically set with <code>$set\_user\_choice</code> events from the <code>$ts</code> property</p>                                                                                                                                                                                                                                                                                                                                                          |
| $choice\_acceptance\_value                                                                                                             | Boolean                      | <p>Choice acceptance value</p><p>Mandatory via API. Automatically set with <code>$set\_user\_choice</code> events from the <code>$choice\_acceptance\_value</code> property</p>                                                                                                                                                                                                                                                                                                                                                                     |
| $creation\_ts                                                                                                                          | Timestamp                    | <p><em>System field</em>. Creation timestamp of the user choice</p><p>Forbidden modification (via API or event). Automatically defined at the user choice creation.</p>                                                                                                                                                                                                                                                                                                                                                                             |
| $channel\_id                                                                                                                           | String                       | <p>Channel on which the choice has been collected</p><p>Optional via API. Automatically set with <code>$set\_user\_choice</code> events from the <a href="../../../user-points/user-activities#activity-origin">activity origin</a>.</p>                                                                                                                                                                                                                                                                                                            |
| $choice\_source\_id                                                                                                                    | String                       | <p>Source of the choice</p><p>Optional via API. Automatically set with <code>$set\_user\_choice</code> events from the <code>$choice\_source\_token</code> property. Allowing a choice update will depend on the source weight (see below).</p>                                                                                                                                                                                                                                                                                                     |
| <p>$user\_agent\_id<br><a href="../../../user-points#user-identifiers">User Identifier</a></p>                                         | String                       | <p>The identifier of the user device as provided by the user id mapping service. ex: <code>vec:89090939434</code></p><p>\<code>\</code></p><ul><li>If choice defined by a <code>$set\_user\_choice</code> event (pixel or /user\_activities API): we copy the identifiers from the activity origin (after interpreting those within events if pixel)</li><li>If choice defined by <code>/user\_choices</code> API, we consider those in the request payload. If no identifier is defined in the request payload, we copy those in the URL</li></ul> |
| <p>$user\_account\_id</p><p><a href="../../../user-points#user-identifiers">User Identifier</a> with <code>$compartment\_id</code></p> | String                       | <p>The user account id of the user.</p><ul><li>If choice defined by a <code>$set\_user\_choice</code> event (pixel or /user\_activities API): we copy the identifiers from the activity origin (after interpreting those within events if pixel)</li><li>If choice defined by <code>/user\_choices</code> API, we consider those in the request payload. If no identifier is defined in the request payload, we copy those in the URL</li></ul>                                                                                                     |
| <p>$compartment\_id</p><p><a href="../../../user-points#user-identifiers">User Identifier</a> with <code>$user\_account\_id</code></p> | Integer                      | <p>The ID of the compartment associated with this activity.</p><ul><li>If choice defined by a <code>$set\_user\_choice</code> event (pixel or /user\_activities API): we copy the identifiers from the activity origin (after interpreting those within events if pixel)</li><li>If choice defined by <code>/user\_choices</code> API, we consider those in the request payload. If no identifier is defined in the request payload, we copy those in the URL</li></ul>                                                                             |
| <p>$email\_hash</p><p><a href="../../../user-points#user-identifiers">User Identifier</a></p>                                          | Email Hash Object (Optional) | <p>The email hash object { “$hash”:…, “$email”:…}.</p><ul><li><p>If choice defined by a <code>$set\_user\_choice</code> event (pixel or /user\_activities API): we copy the identifiers from the activity origin (after interpreting those within events if pixel)</p><ul><li>If choice defined by <code>/user\_choices</code> API, we consider those in the request payload. If no identifier is defined in the request payload, we copy those in the URL</li></ul></li></ul>                                                                      |
| \[any custom property]                                                                                                                 | String                       | <p>Custom properties</p><p>Optional via API. Automatically set with <code>$set\_user\_choices</code> events from the events custom properties</p>                                                                                                                                                                                                                                                                                                                                                                                                   |

## Registering user choices

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

![](https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MTdtu-hIzrDesm3F0_D%2F-MTdxS00LRHg90zx0dVo%2Fimage.png?alt=media\&token=16308532-7a40-4dea-bb9e-ff48447e94a4)

### 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](https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MTdxXItUi3W4oi-rrFb%2F-MTe-Gy2mOpSxbrfaWw3%2Fimage.png?alt=media\&token=1f6da600-00f6-4701-b263-f498fc00c01f)

#### With Website tracking

Use the [real-time user tracking](https://developer.mediarithmics.io/data-streams/data-ingestion/real-time-user-tracking) to push a `$set_user_choice` [event](https://developer.mediarithmics.io/user-points/user-activities#user-events-object). No authentication is required.

{% hint style="success" %}
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](https://developer.mediarithmics.io/data-streams/data-ingestion/real-time-user-tracking#the-processing-pipeline) before being stored as a user choice. You must ensure no [activity analyzers](https://developer.mediarithmics.io/data-streams/data-ingestion/real-time-user-tracking/activity-analyzers) is removing them during that process.
{% endhint %}

Here is a sample code to include in your mediarithmics snippet :

```javascript
// 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 :

```javascript
// 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](https://developer.mediarithmics.io/data-ingestion/real-time-user-tracking/api#set-update-a-user-choice) 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](https://developer.mediarithmics.io/data-streams/data-ingestion/bulk-processing/imports/offline-activities) with `$set_user_choice` events from external sources (CRM files, server-side CMPs, ...).

{% hint style="success" %}
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](https://developer.mediarithmics.io/data-streams/data-ingestion/real-time-user-tracking#the-processing-pipeline) before being stored as a user choice. You must ensure they are already formatted.
{% endhint %}

```javascript
// 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 UserPoint

Use the [UserPoint tracking API ](https://developer.mediarithmics.io/data-ingestion/real-time-user-tracking/api#set-update-a-user-choice-1)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](https://developer.mediarithmics.io/user-points#compartments). 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](https://developer.mediarithmics.io/user-points/segments) 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.

{% hint style="info" %}
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.
{% endhint %}

![](https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MTeQ4pCidF-z1upz5Up%2F-MTeQCtfIoQIEufre3VX%2Fimage.png?alt=media\&token=17065de3-b670-4ab5-9bd5-8c643cd347b8)

**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](https://developer.mediarithmics.io/advanced-usages/data-privacy-compliance/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?

## UserPoint merge

Like other data, **choices are taken into account** [**when two UserPoint are merging**](https://developer.mediarithmics.io/user-points#user-points-merges). 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 UserPoint survivor**, the other one being added to the change log.

![Example 1 of UserPoint merge](https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MTeS-soWdM1mXAHBKXm%2F-MTeSkaYWYnk5jZ7N3_Q%2Fimage.png?alt=media\&token=4d0bc28f-fdcc-4ed4-a0e1-3bec160e2574)

![Example 2 of UserPoint merge](https://4196284719-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MMuoqM-5hJ5JY0WnAKL%2F-MTeS-soWdM1mXAHBKXm%2F-MTeStHFBSQhX9iMGY4G%2Fimage.png?alt=media\&token=40f82574-4c8c-469d-a9c0-e120784a4724)

## User choices in the schema

{% hint style="warning" %}
User choices and their custom properties should be declared in the [schema](https://developer.mediarithmics.io/schema) for the feature to work.
{% endhint %}

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.

```graphql
# 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 :

```sql
// 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

{% hint style="info" %}
You should ask your mediarithmics contact to activate this feature for you if needed
{% endhint %}

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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.mediarithmics.io/advanced-usages/data-privacy-compliance/user-choices.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
