You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@unomi.apache.org by sh...@apache.org on 2022/12/01 15:35:34 UTC

svn commit: r1905673 [3/3] - in /unomi/website/manual: 1_1_x/ 1_2_x/ 1_3_x/ 1_4_x/ 1_5_x/ 1_6_x/ 2_0_x/ 2_1_x/ 2_1_x/connectors/ 2_1_x/images/ 2_1_x/jsonSchema/ 2_1_x/migrations/ 2_1_x/samples/ latest/ latest/images/

Added: unomi/website/manual/latest/images/profile-alias-example.png
URL: http://svn.apache.org/viewvc/unomi/website/manual/latest/images/profile-alias-example.png?rev=1905673&view=auto
==============================================================================
Binary file - no diff available.

Propchange: unomi/website/manual/latest/images/profile-alias-example.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: unomi/website/manual/latest/images/profile-alias-external-ids.png
URL: http://svn.apache.org/viewvc/unomi/website/manual/latest/images/profile-alias-external-ids.png?rev=1905673&view=auto
==============================================================================
Binary file - no diff available.

Propchange: unomi/website/manual/latest/images/profile-alias-external-ids.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: unomi/website/manual/latest/images/profile-alias-overview.png
URL: http://svn.apache.org/viewvc/unomi/website/manual/latest/images/profile-alias-overview.png?rev=1905673&view=auto
==============================================================================
Binary file - no diff available.

Propchange: unomi/website/manual/latest/images/profile-alias-overview.png
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: unomi/website/manual/latest/index.html
URL: http://svn.apache.org/viewvc/unomi/website/manual/latest/index.html?rev=1905673&r1=1905672&r2=1905673&view=diff
==============================================================================
--- unomi/website/manual/latest/index.html (original)
+++ unomi/website/manual/latest/index.html Thu Dec  1 15:35:33 2022
@@ -22,13 +22,14 @@
 <ul class="sectlevel2">
 <li><a href="#_whats_new_in_apache_unomi_2_0">1.1. What&#8217;s new in Apache Unomi 2.0</a>
 <ul class="sectlevel3">
-<li><a href="#_scopes_declarations_are_now_required">1.1.1. Scopes declarations are now required</a></li>
-<li><a href="#_json_schemas">1.1.2. JSON Schemas</a></li>
-<li><a href="#_updated_data_model">1.1.3. Updated data model</a></li>
-<li><a href="#_new_web_tracker">1.1.4. New Web Tracker</a></li>
-<li><a href="#_graphql_api_beta">1.1.5. GraphQL API - beta</a></li>
-<li><a href="#_migrate_from_unomi_1_x">1.1.6. Migrate from Unomi 1.x</a></li>
-<li><a href="#_elasticsearch_compatibility">1.1.7. Elasticsearch compatibility</a></li>
+<li><a href="#_introducing_profiles_aliases">1.1.1. Introducing profiles aliases</a></li>
+<li><a href="#_scopes_declarations_are_now_required">1.1.2. Scopes declarations are now required</a></li>
+<li><a href="#_json_schemas">1.1.3. JSON Schemas</a></li>
+<li><a href="#_updated_data_model">1.1.4. Updated data model</a></li>
+<li><a href="#_new_web_tracker">1.1.5. New Web Tracker</a></li>
+<li><a href="#_graphql_api_beta">1.1.6. GraphQL API - beta</a></li>
+<li><a href="#_migrate_from_unomi_1_x">1.1.7. Migrate from Unomi 1.x</a></li>
+<li><a href="#_elasticsearch_compatibility">1.1.8. Elasticsearch compatibility</a></li>
 </ul>
 </li>
 </ul>
@@ -71,6 +72,7 @@
 <li><a href="#_how_to_search_for_profiles">3.1.7. How to search for profiles</a></li>
 <li><a href="#_getting_updating_consents">3.1.8. Getting / updating consents</a></li>
 <li><a href="#_how_to_send_a_login_event_to_unomi">3.1.9. How to send a login event to Unomi</a></li>
+<li><a href="#_what_profile_aliases_are_and_how_to_use_them">3.1.10. What profile aliases are and how to use them</a></li>
 </ul>
 </li>
 <li><a href="#_request_examples">3.2. Request examples</a>
@@ -245,7 +247,7 @@
 <li><a href="#_data_model_overview">13.4. Data Model Overview</a></li>
 <li><a href="#_scope">13.5. Scope</a>
 <ul class="sectlevel3">
-<li><a href="#_example">13.5.1. Example</a></li>
+<li><a href="#_example_2">13.5.1. Example</a></li>
 </ul>
 </li>
 <li><a href="#_item">13.6. Item</a>
@@ -256,13 +258,13 @@
 <li><a href="#_metadata">13.7. Metadata</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_2">13.7.1. Structure definition</a></li>
-<li><a href="#_example_2">13.7.2. Example</a></li>
+<li><a href="#_example_3">13.7.2. Example</a></li>
 </ul>
 </li>
 <li><a href="#_metadataitem">13.8. MetadataItem</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_3">13.8.1. Structure definition</a></li>
-<li><a href="#_example_3">13.8.2. Example</a></li>
+<li><a href="#_example_4">13.8.2. Example</a></li>
 </ul>
 </li>
 <li><a href="#_event">13.9. Event</a>
@@ -274,109 +276,115 @@
 <li><a href="#_profile">13.10. Profile</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_4">13.10.1. Structure definition</a></li>
-<li><a href="#_example_4">13.10.2. Example</a></li>
+<li><a href="#_example_5">13.10.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_persona">13.11. Persona</a>
+<li><a href="#_profile_aliases">13.11. Profile aliases</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_5">13.11.1. Structure definition</a></li>
-<li><a href="#_example_5">13.11.2. Example</a></li>
+<li><a href="#_example_6">13.11.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_consent">13.12. Consent</a>
+<li><a href="#_persona">13.12. Persona</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_6">13.12.1. Structure definition</a></li>
-<li><a href="#_example_6">13.12.2. Example</a></li>
+<li><a href="#_example_7">13.12.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_session">13.13. Session</a>
+<li><a href="#_consent">13.13. Consent</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_7">13.13.1. Structure definition</a></li>
-<li><a href="#_example_7">13.13.2. Example</a></li>
+<li><a href="#_example_8">13.13.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_segment">13.14. Segment</a>
+<li><a href="#_session">13.14. Session</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_8">13.14.1. Structure definition</a></li>
-<li><a href="#_example_8">13.14.2. Example</a></li>
+<li><a href="#_example_9">13.14.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_condition">13.15. Condition</a>
+<li><a href="#_segment">13.15. Segment</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_9">13.15.1. Structure definition</a></li>
-<li><a href="#_example_9">13.15.2. Example</a></li>
+<li><a href="#_example_10">13.15.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_rule">13.16. Rule</a>
+<li><a href="#_condition">13.16. Condition</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_10">13.16.1. Structure definition</a></li>
-<li><a href="#_example_10">13.16.2. Example</a></li>
+<li><a href="#_example_11">13.16.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_action">13.17. Action</a>
+<li><a href="#_rule">13.17. Rule</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_11">13.17.1. Structure definition</a></li>
-<li><a href="#_example_11">13.17.2. Example</a></li>
+<li><a href="#_example_12">13.17.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_list">13.18. List</a>
+<li><a href="#_action">13.18. Action</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_12">13.18.1. Structure definition</a></li>
-<li><a href="#_example_12">13.18.2. Example</a></li>
+<li><a href="#_example_13">13.18.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_goal">13.19. Goal</a>
+<li><a href="#_list">13.19. List</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_13">13.19.1. Structure definition</a></li>
-<li><a href="#_example_13">13.19.2. Example</a></li>
+<li><a href="#_example_14">13.19.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_campaign">13.20. Campaign</a>
+<li><a href="#_goal">13.20. Goal</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_14">13.20.1. Structure definition</a></li>
-<li><a href="#_example_14">13.20.2. Example</a></li>
+<li><a href="#_example_15">13.20.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_scoring_plan">13.21. Scoring plan</a>
+<li><a href="#_campaign">13.21. Campaign</a>
 <ul class="sectlevel3">
 <li><a href="#_structure_definition_15">13.21.1. Structure definition</a></li>
-<li><a href="#_example_15">13.21.2. Example</a></li>
+<li><a href="#_example_16">13.21.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_built_in_event_types">13.22. Built-in Event types</a>
+<li><a href="#_scoring_plan">13.22. Scoring plan</a>
 <ul class="sectlevel3">
-<li><a href="#_login_event_type">13.22.1. Login event type</a></li>
-<li><a href="#_view_event_type">13.22.2. View event type</a></li>
-<li><a href="#_form_event_type">13.22.3. Form event type</a></li>
-<li><a href="#_update_properties_event_type">13.22.4. Update properties event type</a></li>
-<li><a href="#_identify_event_type">13.22.5. Identify event type</a></li>
-<li><a href="#_session_created_event_type">13.22.6. Session created event type</a></li>
-<li><a href="#_goal_event_type">13.22.7. Goal event type</a></li>
-<li><a href="#_modify_consent_event_type">13.22.8. Modify consent event type</a></li>
+<li><a href="#_structure_definition_16">13.22.1. Structure definition</a></li>
+<li><a href="#_example_17">13.22.2. Example</a></li>
 </ul>
 </li>
-<li><a href="#_built_in_condition_types">13.23. Built-in condition types</a>
+<li><a href="#_built_in_event_types">13.23. Built-in Event types</a>
 <ul class="sectlevel3">
-<li><a href="#_existing_condition_type_descriptors">13.23.1. Existing condition type descriptors</a></li>
+<li><a href="#_login_event_type">13.23.1. Login event type</a></li>
+<li><a href="#_view_event_type">13.23.2. View event type</a></li>
+<li><a href="#_form_event_type">13.23.3. Form event type</a></li>
+<li><a href="#_update_properties_event_type">13.23.4. Update properties event type</a></li>
+<li><a href="#_identify_event_type">13.23.5. Identify event type</a></li>
+<li><a href="#_session_created_event_type">13.23.6. Session created event type</a></li>
+<li><a href="#_goal_event_type">13.23.7. Goal event type</a></li>
+<li><a href="#_modify_consent_event_type">13.23.8. Modify consent event type</a></li>
 </ul>
 </li>
-<li><a href="#_built_in_action_types">13.24. Built-in action types</a>
+<li><a href="#_built_in_condition_types">13.24. Built-in condition types</a>
 <ul class="sectlevel3">
-<li><a href="#_existing_action_types_descriptors">13.24.1. Existing action types descriptors</a></li>
+<li><a href="#_existing_condition_type_descriptors">13.24.1. Existing condition type descriptors</a></li>
 </ul>
 </li>
-<li><a href="#_updating_events_using_the_context_servlet">13.25. Updating Events Using the Context Servlet</a>
+<li><a href="#_built_in_action_types">13.25. Built-in action types</a>
 <ul class="sectlevel3">
-<li><a href="#_solution">13.25.1. Solution</a></li>
-<li><a href="#_defining_rules">13.25.2. Defining Rules</a></li>
+<li><a href="#_existing_action_types_descriptors">13.25.1. Existing action types descriptors</a></li>
 </ul>
 </li>
-<li><a href="#_unomi_web_tracker_reference">13.26. Unomi Web Tracker reference</a>
+<li><a href="#_updating_events_using_the_context_servlet">13.26. Updating Events Using the Context Servlet</a>
 <ul class="sectlevel3">
-<li><a href="#_custom_events">13.26.1. Custom events</a></li>
-<li><a href="#_integrating_with_tag_managers">13.26.2. Integrating with tag managers</a></li>
-<li><a href="#_cookiesession_handling">13.26.3. Cookie/session handling</a></li>
-<li><a href="#_javascript_api">13.26.4. JavaScript API</a></li>
+<li><a href="#_solution">13.26.1. Solution</a></li>
+<li><a href="#_defining_rules">13.26.2. Defining Rules</a></li>
+</ul>
+</li>
+<li><a href="#_unomi_web_tracker_reference">13.27. Unomi Web Tracker reference</a>
+<ul class="sectlevel3">
+<li><a href="#_custom_events">13.27.1. Custom events</a></li>
+<li><a href="#_integrating_with_tag_managers">13.27.2. Integrating with tag managers</a></li>
+<li><a href="#_cookiesession_handling">13.27.3. Cookie/session handling</a></li>
+<li><a href="#_javascript_api">13.27.4. JavaScript API</a></li>
 </ul>
 </li>
 </ul>
@@ -397,7 +405,7 @@
 <li><a href="#_retrieving_context_information_from_unomi_using_the_context_servlet">14.3.3. Retrieving context information from Unomi using the context servlet</a></li>
 </ul>
 </li>
-<li><a href="#_example_24">14.4. Example</a>
+<li><a href="#_example_26">14.4. Example</a>
 <ul class="sectlevel3">
 <li><a href="#_html_page">14.4.1. HTML page</a></li>
 <li><a href="#_javascript">14.4.2. Javascript</a></li>
@@ -505,14 +513,22 @@
 <div class="sect2">
 <h3 id="_whats_new_in_apache_unomi_2_0">1.1. What&#8217;s new in Apache Unomi 2.0</h3>
 <div class="paragraph">
-<p>Apache Unomi 2 is a new release focused on improving core functionalities and robustness of the product.
-The introduction of tighter data validation with JSON Schemas required some changes in the product data model, which presented an opportunity for noticeable improvements in the overall performance.</p>
+<p>Apache Unomi 2 is a new release focused on improving core functionalities and robustness of the product.</p>
+</div>
+<div class="paragraph">
+<p>The introduction of tighter data validation with JSON Schemas required some changes in the product data model, which presented an opportunity for noticeable improvements in the overall performance.</p>
 </div>
 <div class="paragraph">
 <p>This new release also introduces a first (beta) version of the Unomi GraphQL API.</p>
 </div>
 <div class="sect3">
-<h4 id="_scopes_declarations_are_now_required">1.1.1. Scopes declarations are now required</h4>
+<h4 id="_introducing_profiles_aliases">1.1.1. Introducing profiles aliases</h4>
+<div class="paragraph">
+<p>Profiles may now have alias IDs, which is a new way to reference profiles using multiple IDs. The Unomi ID still exists, but a new index with aliases can reference a single Unomi profile. This enables more flexible integrations with external systems, as well as provide more flexible and reliable merging mechanisms. A new REST API makes it easy to define, update and remove aliases for profiles. You can read more about <a href="#_what_profile_aliases_are_and_how_to_use_them">profile aliases here</a>.</p>
+</div>
+</div>
+<div class="sect3">
+<h4 id="_scopes_declarations_are_now_required">1.1.2. Scopes declarations are now required</h4>
 <div class="paragraph">
 <p>Scopes declarations are now required in Unomi 2. When submitting an event and specifying a scope,
 that scope must already be declared on the platform.</p>
@@ -536,7 +552,7 @@ that scope must already be declared on t
 </div>
 </div>
 <div class="sect3">
-<h4 id="_json_schemas">1.1.2. JSON Schemas</h4>
+<h4 id="_json_schemas">1.1.3. JSON Schemas</h4>
 <div class="paragraph">
 <p>Apache Unomi 2 introduces support for <a href="https://json-schema.org/specification.html">JSON Schema</a> for all of its publicly exposed endpoints.
 Data received by Apache Unomi 2 will first be validated against a known schema to make sure it complies with an expected payload.
@@ -550,7 +566,7 @@ If the received payload does not match a
 </div>
 </div>
 <div class="sect3">
-<h4 id="_updated_data_model">1.1.3. Updated data model</h4>
+<h4 id="_updated_data_model">1.1.4. Updated data model</h4>
 <div class="paragraph">
 <p>The introduction of JSON schema required us to modify Apache Unomi data model, One of the key differences is the removal of open maps.</p>
 </div>
@@ -645,21 +661,23 @@ stored as flattened and will not create
 </div>
 </div>
 <div class="paragraph">
-<p>If using the default Apache 1.x data model, our Unomi 2 migration process will handle the data model changes for you.
-If you are using custom events/objects, please refer to the detailed migration guide for more details.</p>
+<p>If using the default Apache 1.x data model, our Unomi 2 migration process will handle the data model changes for you.</p>
+</div>
+<div class="paragraph">
+<p>If you are using custom events/objects, please refer to the detailed <a href="#_migration_overview">migration guide</a> for more details.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_new_web_tracker">1.1.4. New Web Tracker</h4>
+<h4 id="_new_web_tracker">1.1.5. New Web Tracker</h4>
 <div class="paragraph">
 <p>Apache Unomi 2.0 Web Tracker, located in <code>extensions/web-tracker/</code> has been completely rewritten. It is no longer based on an external library and is fully self-sufficient. It is based on an external contribution that has been used in production on many sites.</p>
 </div>
 <div class="paragraph">
-<p>You can find more information about the new web tracker here: [TODO ADD LINK]</p>
+<p>You can find more information about the <a href="#_unomi_web_tracking_tutorial">new web tracker here</a>.</p>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_graphql_api_beta">1.1.5. GraphQL API - beta</h4>
+<h4 id="_graphql_api_beta">1.1.6. GraphQL API - beta</h4>
 <div class="paragraph">
 <p>Apache Unomi 2.0 sees the introduction of a new (beta) GraphQL API.
 Available behind a feature flag (the API disabled by default), the GraphQL API is available for you to play with.</p>
@@ -672,7 +690,7 @@ Available behind a feature flag (the API
 </div>
 </div>
 <div class="sect3">
-<h4 id="_migrate_from_unomi_1_x">1.1.6. Migrate from Unomi 1.x</h4>
+<h4 id="_migrate_from_unomi_1_x">1.1.7. Migrate from Unomi 1.x</h4>
 <div class="paragraph">
 <p>To facilitate migration we prepared a set of scripts that will automatically handle the migration of your data from Apache Unomi 1.5+ to Apache Unomi 2.0.</p>
 </div>
@@ -686,7 +704,7 @@ More details about migration (incl. of c
 </div>
 </div>
 <div class="sect3">
-<h4 id="_elasticsearch_compatibility">1.1.7. Elasticsearch compatibility</h4>
+<h4 id="_elasticsearch_compatibility">1.1.8. Elasticsearch compatibility</h4>
 <div class="paragraph">
 <p>We currently recommend using Elasticsearch 7.17.5 with Apache Unomi 2.0,
 this ensure you are on a recent version that is not impacted by the log4j vulnerabilities (fixed in Elasticsearch 7.16.3).</p>
@@ -866,22 +884,25 @@ requests you can do once your server is
 <div class="paragraph">
 <p>In this tutorial we will guide through the basic steps of getting started with a web tracking project. You will see how to integrate the built-in web tracker with an existing web site and what this enables.</p>
 </div>
+<div class="paragraph">
+<p>If you prefer to use existing HTML and Javascript rather than building your own, all the code we feature in this tutorial is extracted from our tracker sample which is available here: <a href="https://github.com/apache/unomi/blob/master/extensions/web-tracker/wab/src/main/webapp/index.html" class="bare">https://github.com/apache/unomi/blob/master/extensions/web-tracker/wab/src/main/webapp/index.html</a> . However you will still need to use the REST API calls to create the scope and rule to make it all work.</p>
+</div>
 <div class="sect3">
 <h4 id="_installing_the_web_tracker_in_a_web_page">2.4.1. Installing the web tracker in a web page</h4>
 <div class="paragraph">
 <p>Using the built-in tracker is pretty simple, simply add the following code to your HTML page :</p>
 </div>
-<div class="literalblock">
+<div class="listingblock">
 <div class="content">
-<pre>&lt;script type="text/javascript" src="/tracker/unomi-web-tracker.min.js"&gt;&lt;/script&gt;</pre>
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">    &lt;script type="text/javascript" src="/tracker/unomi-web-tracker.min.js"&gt;&lt;/script&gt;</code></pre>
 </div>
 </div>
 <div class="paragraph">
 <p>or you can also use the non-minified version that is available here:</p>
 </div>
-<div class="literalblock">
+<div class="listingblock">
 <div class="content">
-<pre>&lt;script type="text/javascript" src="/tracker/unomi-web-tracker.js"&gt;&lt;/script&gt;</pre>
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">    &lt;script type="text/javascript" src="/tracker/unomi-web-tracker.js"&gt;&lt;/script&gt;</code></pre>
 </div>
 </div>
 <div class="paragraph">
@@ -948,7 +969,7 @@ requests you can do once your server is
 </div>
 <div class="listingblock">
 <div class="content">
-<pre class="highlight"><code class="language-sh" data-lang="sh">curl --location --request POST 'http://localhost:8181/cxs/scopes' \
+<pre class="highlight"><code class="language-shell" data-lang="shell">curl --location --request POST 'http://localhost:8181/cxs/scopes' \
   --header 'Authorization: Basic a2FyYWY6a2FyYWY=' \
   --header 'Content-Type: application/json' \
   --data-raw '{
@@ -977,9 +998,9 @@ requests you can do once your server is
 <div class="paragraph">
 <p>Here&#8217;s an example on how to use it:</p>
 </div>
-<div class="literalblock">
+<div class="listingblock">
 <div class="content">
-<pre>yarn add apache-unomi-tracker</pre>
+<pre class="highlight"><code class="language-shell" data-lang="shell">    yarn add apache-unomi-tracker</code></pre>
 </div>
 </div>
 <div class="paragraph">
@@ -1047,7 +1068,7 @@ requests you can do once your server is
 </div>
 <div class="listingblock">
 <div class="content">
-<pre class="highlight"><code class="language-sh" data-lang="sh">curl --location --request POST 'http://localhost:8181/cxs/events/search' \
+<pre class="highlight"><code class="language-shell" data-lang="shell">curl --location --request POST 'http://localhost:8181/cxs/events/search' \
   --header 'Authorization: Basic a2FyYWY6a2FyYWY=' \
   --header 'Content-Type: application/json' \
   --data-raw '{
@@ -1061,9 +1082,9 @@ requests you can do once your server is
 <div class="paragraph">
 <p>Another (powerful) way to look at events is to use the SSH Console. You can connect to it with the following shell command:</p>
 </div>
-<div class="literalblock">
+<div class="listingblock">
 <div class="content">
-<pre>ssh -p 8102 karaf@localhost</pre>
+<pre class="highlight"><code class="language-shell" data-lang="shell">    ssh -p 8102 karaf@localhost</code></pre>
 </div>
 </div>
 <div class="paragraph">
@@ -1102,7 +1123,7 @@ Another interesting command is <code>pro
 </div>
 <div class="listingblock">
 <div class="content">
-<pre class="highlight"><code class="language-sh" data-lang="sh">curl --location --request GET 'http://localhost:8181/cxs/profiles/PROFILE_UUID' \
+<pre class="highlight"><code class="language-shell" data-lang="shell">curl --location --request GET 'http://localhost:8181/cxs/profiles/PROFILE_UUID' \
 --header 'Authorization: Basic a2FyYWY6a2FyYWY=' \</code></pre>
 </div>
 </div>
@@ -1117,7 +1138,7 @@ Another interesting command is <code>pro
 </div>
 <div class="listingblock">
 <div class="content">
-<pre class="highlight"><code class="language-sh" data-lang="sh">curl --location --request POST 'http://localhost:8181/cxs/rules' \
+<pre class="highlight"><code class="language-shell" data-lang="shell">curl --location --request POST 'http://localhost:8181/cxs/rules' \
 --header 'Authorization: Basic a2FyYWY6a2FyYWY=' \
 --header 'Content-Type: application/json' \
 --data-raw '{
@@ -1156,7 +1177,7 @@ Another interesting command is <code>pro
 <div class="sect3">
 <h4 id="_adding_personalization">2.4.7. Adding personalization</h4>
 <div class="paragraph">
-<p>The last step is to use the newly added property to the profile to perform some page personalization. In order to do that we will use the tracker&#8217;s API to register a personalization that will be</p>
+<p>The last step is to use the newly added property to the profile to perform some page personalization. In order to do that we will use the tracker&#8217;s API to register a personalization that will be using a condition that checks if the <code>pageViewCount</code> is higher than 5. If it has, <code>variant1</code> will be displayed, otherwise the fallback variant <code>variant2</code> will be used instead.</p>
 </div>
 <div class="listingblock">
 <div class="content">
@@ -1178,7 +1199,7 @@ Another interesting command is <code>pro
                         "condition": {
                             "type": "profilePropertyCondition",
                             "parameterValues": {
-                                "propertyName" : "properties.pageViewCount",
+                                "propertyName" : "properties.pageViewCount.&lt;scope&gt;",
                                 "comparisonOperator" : "greaterThan",
                                 "propertyValueInteger" : 5
                             }
@@ -1194,6 +1215,25 @@ Another interesting command is <code>pro
             });</code></pre>
 </div>
 </div>
+<div class="paragraph">
+<p>As you can see in the above code snippet, a <code>variants</code> array is created with two objects that associated personalization IDs with content IDs. Then we build the personalization object that contains the two IDs and their associated conditions (only a condition on <code>var1</code> is passed in this case) as well as an option to indicate which is the fallback variant in case no conditions are matched.</p>
+</div>
+<div class="paragraph">
+<p>The HTML part of this example looks like this:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-html" data-lang="html">    &lt;div id="variant1" style="display: none"&gt;
+        You have already seen this page 5 times
+    &lt;/div&gt;
+    &lt;div id="variant2" style="display: none"&gt;
+        Welcome. Please reload this page 5 times until it triggers the personalization change
+    &lt;/div&gt;</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>As you can see we hide the variants by default so that there is no "flashing" effect and then use the callback function to display to variant resolve by Unomi&#8217;s personalization engine.</p>
+</div>
 </div>
 <div class="sect3">
 <h4 id="_conclusion">2.4.8. Conclusion</h4>
@@ -1203,24 +1243,47 @@ Another interesting command is <code>pro
 <div class="ulist">
 <ul>
 <li>
-<p>Installed a tracker
--</p>
+<p>Installed a tracker in a web page</p>
+</li>
+<li>
+<p>Created a scope in which to collect the data</p>
+</li>
+<li>
+<p>Learned how to use the tracker as an NPM library</p>
+</li>
+<li>
+<p>How to view the collected events</p>
+</li>
+<li>
+<p>How to view the current visitor profile</p>
+</li>
+<li>
+<p>How to add a rule to update a profile property</p>
+</li>
+<li>
+<p>How to personalize a web page&#8217;s content based on the property updated by the rule</p>
 </li>
 </ul>
 </div>
+<div class="paragraph">
+<p>Of course this tutorial is just one example of what could be achieved, and hasn&#8217;t even yet introduced more advanced notions such as profile segmentation or Groovy action scripting. The system is capable of much more, for example by directly using its actions to integrate with third-party systems (CRM, social networks, etc..)</p>
+</div>
 </div>
 <div class="sect3">
 <h4 id="_next_steps">2.4.9. Next steps</h4>
 <div class="ulist">
 <ul>
 <li>
-<p>Learn more about the tracker, custom events, API, etc&#8230;&#8203;</p>
+<p>Learn more about the <a href="#_unomi_web_tracker_reference">web tracker, custom events, API, &#8230;&#8203;</a></p>
+</li>
+<li>
+<p>Learn more about <a href="#_segment">segmentation</a></p>
 </li>
 <li>
-<p>Learn more about segmentation,</p>
+<p>View some more <a href="#_integration_samples">samples</a></p>
 </li>
 <li>
-<p>Read Unomi&#8217;s user manual to see all that is possible with this technology</p>
+<p>Continue reading Unomi&#8217;s user manual to see all that is possible with this technology</p>
 </li>
 </ul>
 </div>
@@ -1817,6 +1880,139 @@ a single profile. Because of the merge,
 security issue since it could be a way to load data from other profiles by merging their data !</p>
 </div>
 </div>
+<div class="sect3">
+<h4 id="_what_profile_aliases_are_and_how_to_use_them">3.1.10. What profile aliases are and how to use them</h4>
+<div class="paragraph">
+<p>Profile aliases make it possible to reference profiles using multiple identifiers.
+The profile alias object basically contains a link between the alias ID and the profile ID. The <code>itemId</code> of a profile alias is the actual alias ID, which the <code>profileID</code> field contains the reference to the aliased profile.</p>
+</div>
+<div class="sect4">
+<h5 id="_what_they_are">What they are</h5>
+<div class="imageblock">
+<div class="content">
+<img src="images/profile-alias-overview.png" alt="Profile alias overview">
+</div>
+</div>
+<div class="paragraph">
+<p>Profile aliases:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Make it possible to lookup profiles by main (Unomi) ID or by any other alias ID</p>
+</li>
+<li>
+<p>Aliases are just IDs stored in a dedicated index</p>
+</li>
+<li>
+<p>A profile may have an unlimited number of aliases attached to it.</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_how_to_use_them">How to use them</h5>
+<div class="imageblock">
+<div class="content">
+<img src="images/profile-alias-external-ids.png" alt="Profile with external IDs">
+</div>
+</div>
+<div class="paragraph">
+<p>Here are different use cases for profile aliases:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Connect different systems to Unomi such as a CRM, CMS and native mobile app that all have their own iD for a single customer</p>
+</li>
+<li>
+<p>Merging profiles when a visitor is identified</p>
+</li>
+<li>
+<p>Adding new IDs at a later time</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_example">Example</h5>
+<div class="paragraph">
+<p>Here is an example of multiple external aliases pointing to a single Unomi profile</p>
+</div>
+<div class="imageblock">
+<div class="content">
+<img src="images/profile-alias-example.png" alt="Profile alias example">
+</div>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_interactions_with_merging">Interactions with merging</h5>
+<div class="paragraph">
+<p>Profile merges have been modified to use aliases starting Unomi 2</p>
+</div>
+<div class="paragraph">
+<p>Upon merge:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>Properties are copied to the master profile as before</p>
+</li>
+<li>
+<p>An alias is created for the "master" profile with the ID of the merged profile</p>
+</li>
+<li>
+<p>Merged profiles are now deleted</p>
+</li>
+<li>
+<p>"mergedWith" property is no longer used since we deleted the merged profiles</p>
+</li>
+</ul>
+</div>
+</div>
+<div class="sect4">
+<h5 id="_api">API</h5>
+<div class="paragraph">
+<p>/context.json and /eventcollector will now look up profiles by profile ID or aliases from the same cookie (<code>context-profile-id</code>) or body parameters (<code>profileId</code>)</p>
+</div>
+<table class="tableblock frame-all grid-all stretch">
+<colgroup>
+<col style="width: 33.3333%;">
+<col style="width: 33.3333%;">
+<col style="width: 33.3334%;">
+</colgroup>
+<thead>
+<tr>
+<th class="tableblock halign-left valign-top"><strong>Verb</strong></th>
+<th class="tableblock halign-left valign-top"><strong>Path</strong></th>
+<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">GET</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">/cxs/profiles/PROFILE_ID_OR_ALIAS</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Retrieves a profile by ID or Alias ID (useful if an external system wants to get a profile)</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">GET</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">/cxs/profiles/PROFILE_ID/aliases</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Get all the aliases for a profile</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">POST</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">/cxs/profiles/PROFILE_ID/aliases/ALIAS_ID</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Add an alias to a profile</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">DELETE</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">/cxs/profiles/PROFILE_ID/aliases/ALIAS_ID</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">Remove an alias from a profile</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+</div>
 </div>
 <div class="sect2">
 <h3 id="_request_examples">3.2. Request examples</h3>
@@ -5440,7 +5636,7 @@ For example, when using scopes with a we
 </blockquote>
 </div>
 <div class="sect3">
-<h4 id="_example">13.5.1. Example</h4>
+<h4 id="_example_2">13.5.1. Example</h4>
 <div class="paragraph">
 <p>In the following example, the scope uses the unique identifier of a web site called “digitall”.</p>
 </div>
@@ -5597,7 +5793,7 @@ It is usually associated with an Item ob
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_2">13.7.2. Example</h4>
+<h4 id="_example_3">13.7.2. Example</h4>
 <div class="paragraph">
 <p>This example of a Metadata object structure was taken from a List associated object.
 See the MetadataItem to understand how the two fit together.</p>
@@ -5650,7 +5846,7 @@ See the MetadataItem to understand how t
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_3">13.8.2. Example</h4>
+<h4 id="_example_4">13.8.2. Example</h4>
 <div class="paragraph">
 <p>The following example is actually the definition of a <a href="#_list">List</a> object, which is simply a <a href="#_metadataitem">MetadataItem</a> sub-type with no additional fields.
 We can see here the “itemId” and “itemType” fields that come from the Item parent class and the “metadata” field that contains the object structure coming from the Metadata object type.</p>
@@ -5849,7 +6045,7 @@ action in a context where the user hadn�
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_4">13.10.2. Example</h4>
+<h4 id="_example_5">13.10.2. Example</h4>
 <div class="paragraph">
 <p>In the example below, a profile for a visitor called “Bill Galileo” is detailed.
 A lot of user properties (such as first name, last name, gender, job title and more) were copied over from the CMS upon initial login.
@@ -5960,14 +6156,74 @@ It has also been engaged in some goals (
 </div>
 </div>
 <div class="sect2">
-<h3 id="_persona">13.11. Persona</h3>
+<h3 id="_profile_aliases">13.11. Profile aliases</h3>
+<div class="paragraph">
+<p>Profile aliases make it possible to reference profiles using multiple identifiers.
+The profile alias object basically contains a link between the alias ID and the profile ID. The <code>itemId</code> of a profile alias is the actual alias ID, which the <code>profileID</code> field contains the reference to the aliased profile.</p>
+</div>
+<div class="sect3">
+<h4 id="_structure_definition_5">13.11.1. Structure definition</h4>
+<div class="paragraph">
+<p>Inherits all the fields from: <a href="#_item">Item</a></p>
+</div>
+<table class="tableblock frame-all grid-all stretch">
+<colgroup>
+<col style="width: 33.3333%;">
+<col style="width: 33.3333%;">
+<col style="width: 33.3334%;">
+</colgroup>
+<thead>
+<tr>
+<th class="tableblock halign-left valign-top"><strong>Field name</strong></th>
+<th class="tableblock halign-left valign-top"><strong>Type</strong></th>
+<th class="tableblock halign-left valign-top"><strong>Description</strong></th>
+</tr>
+</thead>
+<tbody>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">profileID</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">String</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">The identifier of the profile this aliases points to</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">creationTime</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">DateTime</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">The date and time of creation of the alias</p></td>
+</tr>
+<tr>
+<td class="tableblock halign-left valign-top"><p class="tableblock">modifiedTime</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">DateTime</p></td>
+<td class="tableblock halign-left valign-top"><p class="tableblock">The date and time of last modification of the alias</p></td>
+</tr>
+</tbody>
+</table>
+</div>
+<div class="sect3">
+<h4 id="_example_6">13.11.2. Example</h4>
+<div class="paragraph">
+<p>In the following example we show an alias ID <code>facebook_johndoe</code> for the profile with ID <code>f72242d2-3145-43b1-8be7-d1d47cf4ad0e</code></p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-json" data-lang="json">    {
+      "profileID": "f72242d2-3145-43b1-8be7-d1d47cf4ad0e",
+      "itemId" : "facebook_johndoe",
+      "creationTime" : "2022-09-16T19:23:51Z",
+      "modifiedTime" : "2022-09-16T19:23:51Z"
+    }</code></pre>
+</div>
+</div>
+</div>
+</div>
+<div class="sect2">
+<h3 id="_persona">13.12. Persona</h3>
 <div class="paragraph">
 <p>A persona is a specialized version of a <a href="#_profile">Profile</a> object. It basically represents a "typical" profile and can be used
 notably to simulate personalized for a type of profiles. Usually personas are created from Profile data and then edited
 to represent a specific marketing persona.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_5">13.11.1. Structure definition</h4>
+<h4 id="_structure_definition_6">13.12.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: <a href="#_profile">Profile</a></p>
 </div>
@@ -5976,7 +6232,7 @@ to represent a specific marketing person
 </div>
 </div>
 <div class="sect3">
-<h4 id="_example_5">13.11.2. Example</h4>
+<h4 id="_example_7">13.12.2. Example</h4>
 <div class="paragraph">
 <p>In the following example a Persona represents a visitor from Europe, that can be used to match by location.</p>
 </div>
@@ -6001,13 +6257,13 @@ to represent a specific marketing person
 </div>
 </div>
 <div class="sect2">
-<h3 id="_consent">13.12. Consent</h3>
+<h3 id="_consent">13.13. Consent</h3>
 <div class="paragraph">
 <p>A consent represents a single instance of a consent granted/refused or revoked by a profile.
 A profile will contain multiple instances of consent identified by unique identifiers.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_6">13.12.1. Structure definition</h4>
+<h4 id="_structure_definition_7">13.13.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: n/a</p>
 </div>
@@ -6054,7 +6310,7 @@ A profile will contain multiple instance
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_6">13.12.2. Example</h4>
+<h4 id="_example_8">13.13.2. Example</h4>
 <div class="paragraph">
 <p>In this example, the consent called “newsletter” was given on the “digitall” website.</p>
 </div>
@@ -6072,13 +6328,13 @@ A profile will contain multiple instance
 </div>
 </div>
 <div class="sect2">
-<h3 id="_session">13.13. Session</h3>
+<h3 id="_session">13.14. Session</h3>
 <div class="paragraph">
 <p>A session represents a period of time during which a visitor/profile has been active.
 It makes it possible to gather data and then use it for reporting and further analysis by regrouping all the events that occurred during the session.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_7">13.13.1. Structure definition</h4>
+<h4 id="_structure_definition_8">13.14.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: <a href="#_item">Item</a></p>
 </div>
@@ -6135,7 +6391,7 @@ It makes it possible to gather data and
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_7">13.13.2. Example</h4>
+<h4 id="_example_9">13.14.2. Example</h4>
 <div class="paragraph">
 <p>In this example the session contains a copy of the profile of the visitor.
 It is a visitor that has previously authentified in a CMS and who’se information was copied at the time of login from the CMS user account to the profile.
@@ -6243,7 +6499,7 @@ The visitor’s location is also reso
 </div>
 </div>
 <div class="sect2">
-<h3 id="_segment">13.14. Segment</h3>
+<h3 id="_segment">13.15. Segment</h3>
 <div class="paragraph">
 <p>Segments are used to group profiles together, and are based on conditions that are executed on profiles to determine
 if they are part of a segment or not.</p>
@@ -6253,7 +6509,7 @@ if they are part of a segment or not.</p
 highly dynamic concept.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_8">13.14.1. Structure definition</h4>
+<h4 id="_structure_definition_9">13.15.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: <a href="#_metadataitem">MetadataItem</a></p>
 </div>
@@ -6280,7 +6536,7 @@ highly dynamic concept.</p>
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_8">13.14.2. Example</h4>
+<h4 id="_example_10">13.15.2. Example</h4>
 <div class="listingblock">
 <div class="content">
 <pre class="highlight"><code class="language-json" data-lang="json">{
@@ -6366,7 +6622,7 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_condition">13.15. Condition</h3>
+<h3 id="_condition">13.16. Condition</h3>
 <div class="paragraph">
 <p>Conditions are a very useful notion inside of Apache Unomi, as they are used as the basis for multiple other objects.
 Conditions may be used as parts of:</p>
@@ -6404,7 +6660,7 @@ Composition is an essential element of b
 <p>For a more complete list of available condition types, see the <a href="#_built_in_condition_types">Built-in condition types</a> reference section.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_9">13.15.1. Structure definition</h4>
+<h4 id="_structure_definition_10">13.16.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: n/a</p>
 </div>
@@ -6440,7 +6696,7 @@ that contains a list of conditions to ev
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_9">13.15.2. Example</h4>
+<h4 id="_example_11">13.16.2. Example</h4>
 <div class="paragraph">
 <p>Here is an example of a complex condition:</p>
 </div>
@@ -6477,7 +6733,7 @@ or <code>sessionReassigned</code>.</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_rule">13.16. Rule</h3>
+<h3 id="_rule">13.17. Rule</h3>
 <div class="imageblock">
 <div class="content">
 <img src="images/unomi-rule-engine.png" alt="Unomi Rule Engine">
@@ -6507,7 +6763,7 @@ You can imagine conditions checking inco
 <p>For example the Salesforce CRM connector is simply a set of actions that pull and push data into the CRM. It is then just a matter of setting up the proper rules with the proper conditions to determine when and how the data will be pulled or pushed into the third-party system.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_10">13.16.1. Structure definition</h4>
+<h4 id="_structure_definition_11">13.17.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: <a href="#_metadataitem">MetadataItem</a></p>
 </div>
@@ -6564,7 +6820,7 @@ You can imagine conditions checking inco
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_10">13.16.2. Example</h4>
+<h4 id="_example_12">13.17.2. Example</h4>
 <div class="paragraph">
 <p>In this example we can see the default <code>updateProperties</code> built-in rule that matches the <code>updateProperties</code> event and
 executes the built-in <code>updatePropertiesAction</code></p>
@@ -6606,7 +6862,7 @@ executes the built-in <code>updateProper
 </div>
 </div>
 <div class="sect2">
-<h3 id="_action">13.17. Action</h3>
+<h3 id="_action">13.18. Action</h3>
 <div class="paragraph">
 <p>Actions are executed by rules in a sequence, and an action is only executed once the previous action has finished executing.
 If an action generates an exception, it will be logged and the execution sequence will continue unless in the case of a
@@ -6622,7 +6878,7 @@ an IP address),  or even pulling and/or
 You may find the list of built-in action types in the <a href="#_built_in_action_types">Built-in action types</a> section.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_11">13.17.1. Structure definition</h4>
+<h4 id="_structure_definition_12">13.18.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: n/a</p>
 </div>
@@ -6654,7 +6910,7 @@ You may find the list of built-in action
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_11">13.17.2. Example</h4>
+<h4 id="_example_13">13.18.2. Example</h4>
 <div class="paragraph">
 <p>In this example of an action, taking from the <code>form-mapping-example.json</code> rule, the <code>setPropertyAction</code> action is used
 to set the <code>properties.firstName</code> profile property to a value read from the event properties called <code>properties.firstName</code>.
@@ -6676,7 +6932,7 @@ overridden or not.</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_list">13.18. List</h3>
+<h3 id="_list">13.19. List</h3>
 <div class="paragraph">
 <p>Lists are a “manual” way to organize profiles, whereas Segments are a dynamic way to regroup them.
 List objects actually only define the list in terms of name, description and other metadata but the list of members is actually not represented in the object.
@@ -6684,7 +6940,7 @@ The profiles contain references to the l
 This property is an array of list identifiers so in order to retrieve all the list names for a given profile, a lookup of List objects is required using the identifiers.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_12">13.18.1. Structure definition</h4>
+<h4 id="_structure_definition_13">13.19.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: <a href="#_metadataitem">MetadataItem</a></p>
 </div>
@@ -6708,7 +6964,7 @@ This property is an array of list identi
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_12">13.18.2. Example</h4>
+<h4 id="_example_14">13.19.2. Example</h4>
 <div class="paragraph">
 <p>Here’s an example of a list called “First list”, along with its description, its scope, tags, etc.. . As a List object is basically a MetadataItem sub-class it simply has all the fields defined in that parent class.
 Note that the List does not contain Profiles, it is Profiles that reference the Lists, not the reverse.</p>
@@ -6736,7 +6992,7 @@ Note that the List does not contain Prof
 </div>
 </div>
 <div class="sect2">
-<h3 id="_goal">13.19. Goal</h3>
+<h3 id="_goal">13.20. Goal</h3>
 <div class="paragraph">
 <p>A goal can be defined with two conditions: a start event condition and an target event condition.
 Basically the goal will be “active” when its start event condition is satisfied, and “reached” when the target event condition is true.
@@ -6744,7 +7000,7 @@ Goals may also (optionally) be associate
 Once a goal is “reached”, a “goal” event triggered and the profile that is currently interacting with the system will see its system properties updated to indicate which goal has been reached.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_13">13.19.1. Structure definition</h4>
+<h4 id="_structure_definition_14">13.20.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: <a href="#_metadataitem">MetadataItem</a></p>
 </div>
@@ -6781,7 +7037,7 @@ Once a goal is “reached”, a â
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_13">13.19.2. Example</h4>
+<h4 id="_example_15">13.20.2. Example</h4>
 <div class="paragraph">
 <p>In the following example, a goal called “downloadGoalExample” is started when a new session is created (we use the “sessionCreatedEventCondition” for that) and is reached when a profile downloads a file called “ACME_WP.pdf” (that’s what the “downloadEventCondition” means).</p>
 </div>
@@ -6821,12 +7077,12 @@ Once a goal is “reached”, a â
 </div>
 </div>
 <div class="sect2">
-<h3 id="_campaign">13.20. Campaign</h3>
+<h3 id="_campaign">13.21. Campaign</h3>
 <div class="paragraph">
 <p>A Campaign object represents a digital marketing campaign, along with conditions to enter the campaign and a specific duration, target and costs.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_14">13.20.1. Structure definition</h4>
+<h4 id="_structure_definition_15">13.21.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: <a href="#_metadataitem">MetadataItem</a></p>
 </div>
@@ -6883,7 +7139,7 @@ Once a goal is “reached”, a â
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_14">13.20.2. Example</h4>
+<h4 id="_example_16">13.21.2. Example</h4>
 <div class="paragraph">
 <p>In the following example a campaign that starts January 1st 31, 2020 at 8:38am and finished on February 29th, 2020 at the same time has the following entry condition: the session duration must be less or equal to 3000 milliseconds (3 seconds) and the profile has viewed the “about” page on the “digitall” website.
 The cost of the campaign is USD 1’000’000 and the timezone is Europe/Zurich.
@@ -6943,13 +7199,13 @@ The primary goal for the campaign is the
 </div>
 </div>
 <div class="sect2">
-<h3 id="_scoring_plan">13.21. Scoring plan</h3>
+<h3 id="_scoring_plan">13.22. Scoring plan</h3>
 <div class="paragraph">
 <p>Scoring plans make it possible to define scores that will be tracked for profiles and use conditions to increment a score when the conditions are met.
 This makes it possible to then use threshold conditions on profiles when they reach a certain score.</p>
 </div>
 <div class="sect3">
-<h4 id="_structure_definition_15">13.21.1. Structure definition</h4>
+<h4 id="_structure_definition_16">13.22.1. Structure definition</h4>
 <div class="paragraph">
 <p>Inherits all the fields from: <a href="#_metadataitem">MetadataItem</a></p>
 </div>
@@ -6976,7 +7232,7 @@ This makes it possible to then use thres
 </table>
 </div>
 <div class="sect3">
-<h4 id="_example_15">13.21.2. Example</h4>
+<h4 id="_example_17">13.22.2. Example</h4>
 <div class="paragraph">
 <p>In this example a scoring plan contains a single element that will increment a score with an increment one 1 once the profile has viewed at least 3 pages (using the “hasSeenNPagesCondition” condition).</p>
 </div>
@@ -7018,12 +7274,12 @@ This makes it possible to then use thres
 </div>
 </div>
 <div class="sect2">
-<h3 id="_built_in_event_types">13.22. Built-in Event types</h3>
+<h3 id="_built_in_event_types">13.23. Built-in Event types</h3>
 <div class="paragraph">
 <p>Apache Unomi comes with built-in event types, which we describe below.</p>
 </div>
 <div class="sect3">
-<h4 id="_login_event_type">13.22.1. Login event type</h4>
+<h4 id="_login_event_type">13.23.1. Login event type</h4>
 <div class="paragraph">
 <p>The login event type is used to signal an authentication event has been triggered.
 This event should be “secured”, meaning that it should not be accepted from any location, and by default Apache Unomi will only accept this event from configured “third-party” servers (identified by their IP address and a Unomi application key).</p>
@@ -7074,7 +7330,7 @@ You can find an example of such a rule h
 </table>
 </div>
 <div class="sect4">
-<h5 id="_example_16">Example</h5>
+<h5 id="_example_18">Example</h5>
 <div class="paragraph">
 <p>In this case, a user has logged into a site called “digitall”, and his user information the following properties are associated with the active user..and perhaps show his visitor profile or user information.</p>
 </div>
@@ -7119,7 +7375,7 @@ You can find an example of such a rule h
 </div>
 </div>
 <div class="sect3">
-<h4 id="_view_event_type">13.22.2. View event type</h4>
+<h4 id="_view_event_type">13.23.2. View event type</h4>
 <div class="paragraph">
 <p>This event is triggered when a web page is viewed by a user.
 Some integrators might also want to trigger it when a single-page-application screen is displayed or when a mobile application screen is displayed.</p>
@@ -7161,7 +7417,7 @@ Some integrators might also want to trig
 </table>
 </div>
 <div class="sect4">
-<h5 id="_example_17">Example</h5>
+<h5 id="_example_19">Example</h5>
 <div class="paragraph">
 <p>In this case a use has visited the home page of the digitall site.
 As this is the first page upon login, the destination and referring URL are the same.</p>
@@ -7211,7 +7467,7 @@ As this is the first page upon login, th
 </div>
 </div>
 <div class="sect3">
-<h4 id="_form_event_type">13.22.3. Form event type</h4>
+<h4 id="_form_event_type">13.23.3. Form event type</h4>
 <div class="paragraph">
 <p>This event type is used to track form submissions.
 These could range from login to survey form data captured and processed in Apache Unomi using rules.</p>
@@ -7253,7 +7509,7 @@ These could range from login to survey f
 </table>
 </div>
 <div class="sect4">
-<h5 id="_example_18">Example</h5>
+<h5 id="_example_20">Example</h5>
 <div class="paragraph">
 <p>A form exists on the digitall site, and has been submitted by a visitor.
 In this case it was a search form that contains fields to adjust the search parameters.</p>
@@ -7320,7 +7576,7 @@ In this case it was a search form that c
 </div>
 </div>
 <div class="sect3">
-<h4 id="_update_properties_event_type">13.22.4. Update properties event type</h4>
+<h4 id="_update_properties_event_type">13.23.4. Update properties event type</h4>
 <div class="paragraph">
 <p>This event is usually used by user interfaces that make it possible to modify profile properties, for example a form where a user can edit his profile properties, or a management UI to modify.</p>
 </div>
@@ -7328,7 +7584,7 @@ In this case it was a search form that c
 <p>Note that this event type is a protected event type that is only accepted from configured third-party servers.</p>
 </div>
 <div class="sect4">
-<h5 id="_structure_definition_16">Structure definition</h5>
+<h5 id="_structure_definition_17">Structure definition</h5>
 <div class="paragraph">
 <p>Based on the structure of the following object: Event</p>
 </div>
@@ -7364,7 +7620,7 @@ In this case it was a search form that c
 </table>
 </div>
 <div class="sect4">
-<h5 id="_example_19">Example</h5>
+<h5 id="_example_21">Example</h5>
 <div class="paragraph">
 <p>In this example, this “updateProperties” event contains properties that must be added to the targetId profile.</p>
 </div>
@@ -7408,7 +7664,7 @@ In this case it was a search form that c
 </div>
 </div>
 <div class="sect3">
-<h4 id="_identify_event_type">13.22.5. Identify event type</h4>
+<h4 id="_identify_event_type">13.23.5. Identify event type</h4>
 <div class="paragraph">
 <p>This event type is used to add information learned about the current profile.
 This could be through a form that has asked the user to provide some information about himself, or it could be information sent by another system (CRM, SSO, DMP, LiveRamp or equivalent) to augment the data for the current profile.</p>
@@ -7492,7 +7748,7 @@ If you want to add/update/delete propert
 </table>
 </div>
 <div class="sect4">
-<h5 id="_example_20">Example</h5>
+<h5 id="_example_22">Example</h5>
 <div class="paragraph">
 <p>In this example, an event containing additional information about the user (his nickname, favorite compiler and industry) was sent to Apache Unomi.</p>
 </div>
@@ -7537,13 +7793,13 @@ If you want to add/update/delete propert
 </div>
 </div>
 <div class="sect3">
-<h4 id="_session_created_event_type">13.22.6. Session created event type</h4>
+<h4 id="_session_created_event_type">13.23.6. Session created event type</h4>
 <div class="paragraph">
 <p>The session created event is an internal event created by Apache Unomi when a new session is created.
 This indicates that a new visitor has interacted with a system that is using Apache Unomi to track their behavior.</p>
 </div>
 <div class="sect4">
-<h5 id="_structure_definition_17">Structure definition</h5>
+<h5 id="_structure_definition_18">Structure definition</h5>
 <div class="paragraph">
 <p>Based on the structure of the following object: Event</p>
 </div>
@@ -7579,7 +7835,7 @@ This indicates that a new visitor has in
 </table>
 </div>
 <div class="sect4">
-<h5 id="_example_21">Example</h5>
+<h5 id="_example_23">Example</h5>
 <div class="paragraph">
 <p>In this example, a new session was created for a visitor coming to the digitall website.
 The session contains the firstVisit property.
@@ -7627,12 +7883,12 @@ It may be augmented over time with more
 </div>
 </div>
 <div class="sect3">
-<h4 id="_goal_event_type">13.22.7. Goal event type</h4>
+<h4 id="_goal_event_type">13.23.7. Goal event type</h4>
 <div class="paragraph">
 <p>A goal event is triggered when the current profile (visitor) reaches a goal.</p>
 </div>
 <div class="sect4">
-<h5 id="_structure_definition_18">Structure definition</h5>
+<h5 id="_structure_definition_19">Structure definition</h5>
 <div class="paragraph">
 <p>Based on the structure of the following object: Event</p>
 </div>
@@ -7668,7 +7924,7 @@ It may be augmented over time with more
 </table>
 </div>
 <div class="sect4">
-<h5 id="_example_22">Example</h5>
+<h5 id="_example_24">Example</h5>
 <div class="paragraph">
 <p>In this example, a visitor has reached a goal by viewing a page called “sub-home” on the site “digitall” (event source).
 This goal event had the goal object as a target.
@@ -7752,14 +8008,14 @@ The goal object (see Goal object later i
 </div>
 </div>
 <div class="sect3">
-<h4 id="_modify_consent_event_type">13.22.8. Modify consent event type</h4>
+<h4 id="_modify_consent_event_type">13.23.8. Modify consent event type</h4>
 <div class="paragraph">
 <p>Consent type modification events are used to tell Unomi that consents were modified.
 A built-in rule will update the current profile with the consent modifications contained in the event.
 Consent events may be sent directly by a current profile to update their consents on the profile.</p>
 </div>
 <div class="sect4">
-<h5 id="_structure_definition_19">Structure definition</h5>
+<h5 id="_structure_definition_20">Structure definition</h5>
 <div class="paragraph">
 <p>Based on the structure of the following object: Event</p>
 </div>
@@ -7795,7 +8051,7 @@ Consent events may be sent directly by a
 </table>
 </div>
 <div class="sect4">
-<h5 id="_example_23">Example</h5>
+<h5 id="_example_25">Example</h5>
 <div class="paragraph">
 <p>In this example, a user-generated a consent modification when visiting the home page, possibly by interacting with a consent form that captured his preferences.
 Different consent types were present on the page and he decided to GRANT the “mailchimp” consent.</p>
@@ -7884,7 +8140,7 @@ Different consent types were present on
 </div>
 </div>
 <div class="sect2">
-<h3 id="_built_in_condition_types">13.23. Built-in condition types</h3>
+<h3 id="_built_in_condition_types">13.24. Built-in condition types</h3>
 <div class="paragraph">
 <p>Apache Unomi comes with an extensive collection of built-in condition types. Instead of detailing them one by one you will
 find here an overview of what a JSON condition descriptor looks like:</p>
@@ -7974,7 +8230,7 @@ type implementations. For more details o
 sections.</p>
 </div>
 <div class="sect3">
-<h4 id="_existing_condition_type_descriptors">13.23.1. Existing condition type descriptors</h4>
+<h4 id="_existing_condition_type_descriptors">13.24.1. Existing condition type descriptors</h4>
 <div class="paragraph">
 <p>Here is a non-exhaustive list of condition types built into Apache Unomi. Feel free to browse the source code if you want to
 discover more. But the list below should get you started with the most useful conditions:</p>
@@ -7996,7 +8252,7 @@ type to make them more specific.</p>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_built_in_action_types">13.24. Built-in action types</h3>
+<h3 id="_built_in_action_types">13.25. Built-in action types</h3>
 <div class="paragraph">
 <p>Unomi comes with quite a lot of built-in action types. Instead of detailing them one by one you will find here an overview of
 what an action type descriptor looks like:</p>
@@ -8046,7 +8302,7 @@ Here&#8217;s an example of such a regist
 <p>In the above example the ACTION_EXECUTOR_ID is <code>sendMail</code></p>
 </div>
 <div class="sect3">
-<h4 id="_existing_action_types_descriptors">13.24.1. Existing action types descriptors</h4>
+<h4 id="_existing_action_types_descriptors">13.25.1. Existing action types descriptors</h4>
 <div class="paragraph">
 <p>Here is a non-exhaustive list of actions built into Apache Unomi. Feel free to browse the source code if you want to
 discover more. But the list below should get you started with the most useful actions:</p>
@@ -8070,7 +8326,7 @@ discover more. But the list below should
 </div>
 </div>
 <div class="sect2">
-<h3 id="_updating_events_using_the_context_servlet">13.25. Updating Events Using the Context Servlet</h3>
+<h3 id="_updating_events_using_the_context_servlet">13.26. Updating Events Using the Context Servlet</h3>
 <div class="paragraph">
 <p>One of the use cases that needed to be supported by Unomi is the ability to build a user profile based on Internal System events or <a href="https://en.wikipedia.org/wiki/Change_data_capture">Change Data Capture</a> which usally transported through internal messaging queues such as Kafka.</p>
 </div>
@@ -8082,7 +8338,7 @@ discover more. But the list below should
 we need to have a way to guarantee we wont have duplicate events in the system.</p>
 </div>
 <div class="sect3">
-<h4 id="_solution">13.25.1. Solution</h4>
+<h4 id="_solution">13.26.1. Solution</h4>
 <div class="paragraph">
 <p>One of the solutions to this scenario is to have the ability to control and pass in the <code>eventId</code> property from outside of Unomi,
 Using an authorized 3rd party. This way whenever an event with the same <code>itemId</code> will be processed once again he wont be appended to list of events, but will be updated.</p>
@@ -8115,7 +8371,7 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_defining_rules">13.25.2. Defining Rules</h4>
+<h4 id="_defining_rules">13.26.2. Defining Rules</h4>
 <div class="paragraph">
 <p>Another use case we support is the ability to define a rule on the above mentioned events.
 If we have a rule that increment a property on profile level, we would want the action to be executed only once per event id.
@@ -8156,37 +8412,249 @@ EOF</code></pre>
 </div>
 </div>
 <div class="sect2">
-<h3 id="_unomi_web_tracker_reference">13.26. Unomi Web Tracker reference</h3>
+<h3 id="_unomi_web_tracker_reference">13.27. Unomi Web Tracker reference</h3>
+<div class="paragraph">
+<p>In this section of the documentation, more details are provided about the web tracker provided by Unomi.</p>
+</div>
 <div class="sect3">
-<h4 id="_custom_events">13.26.1. Custom events</h4>
+<h4 id="_custom_events">13.27.1. Custom events</h4>
+<div class="paragraph">
+<p>In order to be able to use your own custom events with the web tracker, you must first declare them in Unomi so that they are properly recognized and validated by the <code>/context.json</code> or <code>/eventcollector</code> endpoints.</p>
+</div>
 <div class="sect4">
 <h5 id="_declaring_json_schema">Declaring JSON schema</h5>
-
+<div class="paragraph">
+<p>The first step is to declare a JSON schema for your custom event type. Here&#8217;s an example of such a declaration:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-json" data-lang="json">{
+  "$id": "https://unomi.apache.org/schemas/json/events/click/1-0-0",
+  "$schema": "https://json-schema.org/draft/2019-09/schema",
+  "self": {
+    "vendor": "org.apache.unomi",
+    "target": "events",
+    "name": "click",
+    "format": "jsonschema",
+    "version": "1-0-0"
+  },
+  "title": "ClickEvent",
+  "type": "object",
+  "allOf": [
+    {
+      "$ref": "https://unomi.apache.org/schemas/json/event/1-0-0"
+    }
+  ],
+  "properties": {
+    "source": {
+      "$ref": "https://unomi.apache.org/schemas/json/items/page/1-0-0"
+    },
+    "target": {
+      "$ref": "https://unomi.apache.org/schemas/json/item/1-0-0"
+    }
+  },
+  "unevaluatedProperties": false
+}</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>The above example comes from a built-in event type that is already declared in Unomi but that illustrates the structure of a JSON schema. It is not however the objective of this section of the documentation to go into the details of how to declare a JSON schema, instead, we recommend you go to the <a href="#_json_schemas_2">corresponding section</a> of the documentation.</p>
+</div>
 </div>
 <div class="sect4">
 <h5 id="_sending_event_from_tracker">Sending event from tracker</h5>
-
+<div class="paragraph">
+<p>In the Unomi web tracker, you can use the following function to send an event to Unomi:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">        /**
+         * This function will send an event to Apache Unomi
+         * @param {object} event The event object to send, you can build it using wem.buildEvent(eventType, target, source)
+         * @param {function} successCallback optional, will be executed in case of success
+         * @param {function} errorCallback optional, will be executed in case of error
+         * @return {undefined}
+         */
+        collectEvent: function (event, successCallback = undefined, errorCallback = undefined)</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>As you can see this function is quite straight forward to use. There are also helper functions to build events, such as :</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">        /**
+         * This function return the basic structure for an event, it must be adapted to your need
+         *
+         * @param {string} eventType The name of your event
+         * @param {object} [target] The target object for your event can be build with wem.buildTarget(targetId, targetType, targetProperties)
+         * @param {object} [source] The source object for your event can be build with wem.buildSource(sourceId, sourceType, sourceProperties)
+         * @returns {object} the event
+         */
+        buildEvent: function (eventType, target, source)
+
+        /**
+         * This function return an event of type form
+         *
+         * @param {string} formName The HTML name of id of the form to use in the target of the event
+         * @param {HTMLFormElement} form optional HTML form element, if provided will be used to extract the form fields and populate the form event
+         * @returns {object} the form event
+         */
+        buildFormEvent: function (formName, form = undefined)
+
+        /**
+         * This function return the source object for a source of type page
+         *
+         * @returns {object} the target page
+         */
+        buildTargetPage: function ()
+
+        /**
+         * This function return the source object for a source of type page
+         *
+         * @returns {object} the source page
+         */
+        buildSourcePage: function ()
+
+        /**
+         * This function return the basic structure for the target of your event
+         *
+         * @param {string} targetId The ID of the target
+         * @param {string} targetType The type of the target
+         * @param {object} [targetProperties] The optional properties of the target
+         * @returns {object} the target
+         */
+        buildTarget: function (targetId, targetType, targetProperties = undefined)
+
+        /**
+         * This function return the basic structure for the source of your event
+         *
+         * @param {string} sourceId The ID of the source
+         * @param {string} sourceType The type of the source
+         * @param {object} [sourceProperties] The optional properties of the source
+         * @returns {object} the source
+         */
+        buildSource: function (sourceId, sourceType, sourceProperties = undefined)</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Here&#8217;s an example of using these helper functions and the <code>collectEvent</code> function alltogether:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">    var clickEvent = wem.buildEvent('click',
+        wem.buildTarget('buttonId', 'button'),
+        wem.buildSourcePage());
+
+    wem.collectEvent(clickEvent, function (xhr) {
+        console.info('Click event successfully collected.');
+    }, function (xhr) {
+        console.error('Could not send click event.');
+    });</code></pre>
+</div>
+</div>
 </div>
 <div class="sect4">
 <h5 id="_sending_multiple_events">Sending multiple events</h5>
-
+<div class="paragraph">
+<p>In some cases, especially when multiple events must be sent fast and the order of the events is critical for rules to be properly executed, it is better to use another function called <code>collectEvents</code> that will batch the sending of events to Unomi in a single HTTP request. Here&#8217;s the signature of this function:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">        /**
+         * This function will send the events to Apache Unomi
+         *
+         * @param {object} events Javascript object { events: [event1, event2] }
+         * @param {function} successCallback optional, will be executed in case of success
+         * @param {function} errorCallback optional, will be executed in case of error
+         * @return {undefined}
+         */
+        collectEvents: function (events, successCallback = undefined, errorCallback = undefined)</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>This function is almost exactly the same as the <code>collectEvent</code> method except that it takes an events array instead of a single one. The events in the array may be of any mixture of types.</p>
+</div>
 </div>
 <div class="sect4">
 <h5 id="_extending_existing_events">Extending existing events</h5>
-
+<div class="paragraph">
+<p>An alternative to defining custom event types is to extend existing event types. This, for example, can be used to add new properties to the built-in <code>view</code> event type.</p>
+</div>
+<div class="paragraph">
+<p>For more information about event type extensions, please read the <a href="#_extend_an_existing_schema">JSON schema section</a> of this documentation.</p>
+</div>
 </div>
 </div>
 <div class="sect3">
-<h4 id="_integrating_with_tag_managers">13.26.2. Integrating with tag managers</h4>
-
+<h4 id="_integrating_with_tag_managers">13.27.2. Integrating with tag managers</h4>
+<div class="paragraph">
+<p>Integrating with tag managers such as Google Tag Manager is an important part of the way trackers can be added to an existing site. Unomi&#8217;s web tracker should be pretty easy to integrate with such tools: you simply need to insert the script tag to load the script and then another tag to initialize it and map any tag manager variables you want.</p>
+</div>
+<div class="paragraph">
+<p>Personalization scripts should however be modified to check for the existence of the tracker object in the page because tag managers might deactivate scripts based on conditions such as GDPR approval, cookie preferences, &#8230;&#8203;</p>
+</div>
 </div>
 <div class="sect3">
-<h4 id="_cookiesession_handling">13.26.3. Cookie/session handling</h4>
-
+<h4 id="_cookiesession_handling">13.27.3. Cookie/session handling</h4>
+<div class="paragraph">
+<p>In order to track profiles, an identifier must be stored in the browser so that subsequent requests can keep a reference to the visitor&#8217;s profile. Also, a session identifier must be generated to group the current visitor interactions.</p>
+</div>
+<div class="paragraph">
+<p>Unomi&#8217;s web tracker uses 3 cookies in the tracker by default:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>server profile ID, called <code>context-profile-id</code> by default, that is sent from the Unomi server</p>
+</li>
+<li>
+<p>web tracker profile ID, called <code>web-profile-id</code> by default (this is a copy of the server profile ID that can be managed by the tracker directly)</p>
+</li>
+<li>
+<p>web tracker session ID, called <code>wem-session-id</code> by default</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>It is possible to change the name of these cookie by passing the following properties to the start&#8217;s initialization:</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">    "wemInitConfig": {
+        ...
+        "contextServerCookieName": "context-profile-id",
+        "trackerSessionIdCookieName": "unomi-tracker-test-session-id",
+        "trackerProfileIdCookieName": "unomi-tracker-test-profile-id"
+    }</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Please note however that the <code>contextServerCookieName</code> will also have to be changed in the server configuration in order for it to work. See the <a href="#_configuration">Configuration</a> section for details on how to do this.</p>
+</div>
+<div class="paragraph">
+<p>For session tracking, it is important to provide a value for the cookie otherwise the tracker will not initialize (a message is displayed in the console that explains that the session cookie is missing). Here is the code excerpt from the initialization code used in the tutorial that creates the initial cookie value.</p>
+</div>
+<div class="listingblock">
+<div class="content">
+<pre class="highlight"><code class="language-javascript" data-lang="javascript">    // generate a new session
+    if (unomiWebTracker.getCookie(unomiTrackerTestConf.wemInitConfig.trackerSessionIdCookieName) == null) {
+        unomiWebTracker.setCookie(unomiTrackerTestConf.wemInitConfig.trackerSessionIdCookieName, unomiWebTracker.generateGuid(), 1);
+    }</code></pre>
+</div>
+</div>
+<div class="paragraph">
+<p>Note that this is just an example, you could very well customize this code to create session IDs another way.</p>
+</div>
 </div>
 <div class="sect3">
-<h4 id="_javascript_api">13.26.4. JavaScript API</h4>
-
+<h4 id="_javascript_api">13.27.4. JavaScript API</h4>
+<div class="paragraph">
+<p>The JavaScript API for the web tracker is directly provided in the source code of the web tracker. You can find it here: <a href="https://github.com/apache/unomi-tracker/blob/main/src/apache-unomi-tracker.js" class="bare">https://github.com/apache/unomi-tracker/blob/main/src/apache-unomi-tracker.js</a></p>
+</div>
+<div class="paragraph">
+<p>Please note that only the functions that do NOT start with an underscore should be used. The ones that start with an underscore are not considered part of the public API and could change or even be removed at any point in the future.</p>
+</div>
 </div>
 </div>
 </div>
@@ -8389,7 +8857,7 @@ information about the context for the cu
 </div>
 </div>
 <div class="sect2">
-<h3 id="_example_24">14.4. Example</h3>
+<h3 id="_example_26">14.4. Example</h3>
 <div class="sect3">
 <h4 id="_html_page">14.4.1. HTML page</h4>
 <div class="paragraph">
@@ -10798,7 +11266,7 @@ They allow to modify an item, that would
 </div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2022-09-30 10:36:29 +0200
+Last updated 2022-10-28 15:43:21 +0200
 </div>
 </div>
 </body>