# Tracking API

{% hint style="warning" %}
Beware of the [authentication method](/resources/api-overview/authentication.md) you choose, so that it is adapted to the context running API calls.
{% endhint %}

## UserActivity API

### General information

You can import [UserActivit](/user-points/user-activities.md)y using our dedicated API endpoint.

## Import a UserActivity

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

The body of the request must be a UserActivity object.

#### Path Parameters

| Name       | Type    | Description                                                         |
| ---------- | ------- | ------------------------------------------------------------------- |
| datamartId | integer | The ID of the datamart in which the UserActivity should be imported |

#### Headers

| Name         | Type   | Description      |
| ------------ | ------ | ---------------- |
| Content-Type | string | application/json |

#### Request Body

| Name | Type   | Description                       |
| ---- | ------ | --------------------------------- |
| body | object | The UserActivity object to import |

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

```
```

{% endtab %}
{% endtabs %}

The body must be a valid [UserActivity](/user-points/user-activities.md) object.

Identification of the user or of the device is achieved through the `$user_identifiers` property. We encourage you to use as many identifiers as available in your environment at the time of the capture.

```json
{ 
	"$ts" : 3489009384393,
	"$type" : "APP_VISIT",
	"$session_status" : "IN_SESSION",
	"$user_identifiers" : [{
		"$type": "USER_ACCOUNT",
		"$compartment_id" : "<COMPARTMENT_ID-1>",
		"$user_account_id" : "<ACCOUNT_ID-1>"
	},
	{
		"$type": "USER_ACCOUNT",
		"$compartment_id" : "<COMPARTMENT_ID-1>",
		"$user_account_id" : "<ACCOUNT_ID-2>"
	},
	{
		"$type": "USER_AGENT",
		"$user_agent_id" : "<USER_AGENT_ID>"
	},
	{
		"$type": "USER_EMAIL",
		"$hash" : "<USER_EMAIl_HASH>",
		"$email" : "<USER_EMAIl>"
	}],
	"$app_id" : "1023",
	"$events" : [
	{
		"$ts" : 3489009384393,
		"$event_name" : "$app_open",
		"$properties" : {}
	}]
}
```

{% hint style="info" %}
It is still possible to use the identifiers properties at the activity root level (`$user_agent_id`, `$user_account_id` + `$compartment_id`, `$email_hash)`, however these are to be considered as legacy.

`$user_identifiers` property is to be preferred.
{% endhint %}

<pre class="language-json"><code class="lang-json"><strong>{ 
</strong>	"$ts" : 3489009384393,
	"$type" : "APP_VISIT",
	"$session_status" : "IN_SESSION",
	"$user_agent_id" : "&#x3C;USER_AGENT_ID>",
	"$compartment_id" : "&#x3C;COMPARTMENT_ID>",
	"$user_account_id" : "&#x3C;ACCOUNT_ID>",
	"$app_id" : "1023",
	"$events" : [
	{
		"$ts" : 3489009384393,
		"$event_name" : "$app_open",
		"$properties" : {}
	}]
}
</code></pre>

### Create / Update a UserProfile from within an activity

A UserProfile can be created / updated by registering a UserActivity containing a `$set_user_profile_properties` event. In that case you would need to use `$user_account_id` and `$compartment_id` inside `$properties` to identify the UserProfile to update:

```json
{ 
	"$ts" : 3489009384393,
	"$type" : "APP_VISIT",
	"$session_status" : "IN_SESSION",
	"$user_identifiers" : [{
		"$type": "USER_ACCOUNT",
		"$compartment_id" : "<COMPARTMENT_ID>",
		"$user_account_id" : "<ACCOUNT_ID>"
	}],
	"$app_id" : "1023",
	"$events" :[{
        	"$ts" : 1679588413000,
	        "$event_name" : "$set_user_profile_properties",
        	"$properties" : {
               		"$compartment_id" : "<COMPARTMENT_ID>",
               		"$user_account_id" : "<ACCOUNT_ID>",
               		"gender" : "Male",
	               	"zipcode" : "78000"
        	}
	}]
}
```

{% hint style="info" %}
Note that you can used any identifier available on the UserPoint in the UserActivity object
{% endhint %}

### Create / Update a UserChoice from within an activity

A UserChoice can be created / updated by registering a UserActivity containing a `$set_user_choice` event.&#x20;

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

```javascript
// Sample UserActivity to add using the tracking 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_id": "<your_processing_id>", // Mandatory
            "$choice_acceptance_value":<true/false>, // Mandatory
            "<your_custom_field>" : "<your_custom field_value>"
            }
        }
    ]
}
```

## UserPoint API

### UserPoint selector

The attribute `:userPointSelector` is used to select the UserPoint on which apply the query. You can provide the following values :

```
// Select a UserPoint using a user_point_id
/v1/datamarts/<DATAMART_ID>/user_points/<USER_POINT_ID>/user_profiles/compartment_id=:compartmentId/user_account_id=:userAccountId
/v1/datamarts/<DATAMART_ID>/user_points/user_point_id=<USER_POINT_ID>/user_profiles/compartment_id=:compartmentId/user_account_id=:userAccountId

// Select a UserPoint using a user_agent_id
/v1/datamarts/<DATAMART_ID>/user_points/user_agent_id=<USER_AGENT_ID>/user_profiles/compartment_id=:compartmentId/user_account_id=:userAccountId

// Select a UserPoint using a user_account_id + compartment_id
/v1/datamarts/<DATAMART_ID>/user_points/compartment_id=<COMPARTMENT_ID>,user_account_id=<USER_ACCOUNT_ID>/user_profiles/compartment_id=:compartmentId/user_account_id=:userAccountId

// Select a UserPoint using an email_hash
/v1/datamarts/<DATAMART_ID>/user_points/email_hash=<EMAIL_HASH>/user_profiles/compartment_id=:compartmentId/user_account_id=:userAccountId
```

### Create / Update a UserProfile

An other way to create / update a UserProfile is to use the *user\_profiles* API endpoint . Prefer this method if you are able to integrate various API endpoints and if you don't need to track the UserProfile  update as an event for further retrieval.

## Create/Update a UserProfile

<mark style="color:orange;">`PUT`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/user_points/:userPointSelector/user_profiles/compartment_id=:compartmentId/user_account_id=:userAccount`

The body of the request must be a UserProfile object.

#### Path Parameters

| Name          | Type    | Description                                                                                                             |
| ------------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
| userAccount   | string  | The user\_account\_id linked to the user\_profile that should be imported                                               |
| compartmentId | integer | The ID of the compartment in which the UserProfile should be imported                                                   |
| datamartId    | integer | The ID of the datamart in which the UserProfile should be imported                                                      |
| userSelector  | string  | <p>The identifier of the user for whom the UserProfile should be imported.<br>see the options of the user selector.</p> |

#### Query Parameters

| Name             | Type            | Description                                                                                                                                                                                                                                |
| ---------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| update\_strategy | Enum (Optional) | <p>Values are <code>PARTIAL\_UPDATE</code>, <code>PARTIAL\_DELETE</code>, <code>FORCE\_REPLACE</code><br>(<a href="/pages/-MNSvimCtmT12-YwS_RZ#possible-update-strategies-when-updating-existing-user-profiles">Detailed examples</a>)</p> |

***Legacy parameters (use update\_strategy instead)***

| Name             | Type                 | Description                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ---------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *force\_replace* | *boolean (optional)* | <p><em>If true, then the UserProfile will be completely replaced by the object passed in the user\_profile field.</em><br><em>If false, the object passed in the <code>user\_profile</code> field will be merged with the existing UserProfile of the UserPoint.</em></p>                                                                                                                                                        |
| *merge\_objects* | *boolean (optional)* | <p><em>Only considered if <code>force\_replace</code> is false.</em></p><p><br><em>Manage the comportement between two objects with a same property.</em> </p><p><br><em>If false (default value), the new object overrides the existing one.</em> </p><p><em>If true the new object is merged in deep to the existing one (see</em> <a href="/pages/-MNSvimCtmT12-YwS_RZ#legacy-parameters"><em>example</em></a><em>).</em></p> |

#### Headers

| Name         | Type   | Description      |
| ------------ | ------ | ---------------- |
| Content-Type | string | application/json |

#### Request Body

| Name | Type   | Description                      |
| ---- | ------ | -------------------------------- |
| body | object | The UserProfile object to import |

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

```
```

{% endtab %}
{% endtabs %}

The body must be a valid [UserProfile](https://app.gitbook.com/@mediarithmics/s/developer-guide/~/drafts/-MiLHGsNDWXB4IJ4_i8w/getting-started/user-profiles) object.

```javascript
{ 
	"$compartment_id" : ":compartment_id",
	"$user_account_id" : ":user_account_id",
	"gender" : "female",
	"zipcode" : "75001"
}
```

{% hint style="info" %}
`$compartment_id` & `$user_account_id` in the payload are not mandatory since they are already provided as query parameters.
{% endhint %}

{% hint style="warning" %}
Beware of :

* `<COMPARTMENT_ID>` & `<USER_ACCOUNT_ID>` which are used to select the UserPoint
* `:compartmentId` & `:userAccountId` which are used to select the profile to update
  {% endhint %}

### Create / Update a UserChoice

An other way to create / update a UserChoice is to use the *user\_choices* API endpoint . Prefer this method if you are able to integrate various API endpoints.

## Create/Update UserChoice

<mark style="color:orange;">`PUT`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/user_points/:userSelector/user_choices/processing_id=:processingId`

#### Path Parameters

| Name         | Type    | Description                                                              |
| ------------ | ------- | ------------------------------------------------------------------------ |
| datamartId   | integer | The datamart ID                                                          |
| userSelector | integer | An identifier to the UserPoint for which the UserChoice should be added. |
| processingId | integer | The ID of the associated processing                                      |

#### Request Body

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

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

```
```

{% endtab %}
{% endtabs %}

```json
// Sample payload
{
    "$choice_ts": "<a_timestamp (ex:1573135588140)>", // Mandatory
    "$choice_acceptance_value":<true/false>, // Mandatory
    "<your_custom_field>" : "<your_custom field_value> // Optional
}
```

## List UserChoice

<mark style="color:blue;">`GET`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/user_points/:userSelector/user_choices/processing_id=:processingId`

#### Path Parameters

| Name         | Type    | Description                                                                  |
| ------------ | ------- | ---------------------------------------------------------------------------- |
| datamartId   | integer | The datamart ID                                                              |
| userSelector | integer | An identifier to the UserPoint for which the UserChoice should be added.     |
| processingId | integer | *Optional*. The ID of the processing for which you want to list UserChoices. |

#### Request Body

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

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

```
```

{% endtab %}
{% endtabs %}

## UserChoice history

<mark style="color:blue;">`GET`</mark> `https://api.mediarithmics.com/v1/datamarts/:datamartId/user_points/:userSelector/user_choices/processing_id=:processingId/change_log`

#### Path Parameters

| Name         | Type    | Description                                                              |
| ------------ | ------- | ------------------------------------------------------------------------ |
| datamartId   | integer | The datamart ID                                                          |
| userSelector | integer | An identifier to the UserPoint for which the UserChoice should be added. |
| processingId | integer | The ID of the processing for which you want to get UserChoice history.   |

#### Request Body

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

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

```
```

{% endtab %}
{% endtabs %}


---

# 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/data-streams/data-ingestion/real-time-user-tracking/api.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.
